From owner-svn-src-stable@FreeBSD.ORG Fri Feb 10 19:10:11 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1F4191065677; Fri, 10 Feb 2012 19:10:11 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7DC8D8FC14; Fri, 10 Feb 2012 19:10:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1AJAApA089091; Fri, 10 Feb 2012 19:10:10 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1AJAA9C089081; Fri, 10 Feb 2012 19:10:10 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201202101910.q1AJAA9C089081@svn.freebsd.org> From: Michael Tuexen Date: Fri, 10 Feb 2012 19:10:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231403 - in stable/8/sys: conf netinet X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Feb 2012 19:10:11 -0000 Author: tuexen Date: Fri Feb 10 19:10:09 2012 New Revision: 231403 URL: http://svn.freebsd.org/changeset/base/231403 Log: MFC r218211: Adds an experimental option to create a pool of threads. These serve as input threads and are queued packets based on the V-tag number. This is similar to what a modern card can do with queue's for TCP... but alas modern cards know nothing about SCTP. From rrs@. Modified: stable/8/sys/conf/options stable/8/sys/netinet/sctp_bsd_addr.c stable/8/sys/netinet/sctp_constants.h stable/8/sys/netinet/sctp_input.c stable/8/sys/netinet/sctp_lock_bsd.h stable/8/sys/netinet/sctp_os_bsd.h stable/8/sys/netinet/sctp_pcb.c stable/8/sys/netinet/sctp_pcb.h stable/8/sys/netinet/sctp_structs.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/boot/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/e1000/ (props changed) Modified: stable/8/sys/conf/options ============================================================================== --- stable/8/sys/conf/options Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/conf/options Fri Feb 10 19:10:09 2012 (r231403) @@ -438,6 +438,7 @@ SCTP_PACKET_LOGGING opt_sctp.h # Log to SCTP_LTRACE_CHUNKS opt_sctp.h # Log to KTR chunks processed SCTP_LTRACE_ERRORS opt_sctp.h # Log to KTR error returns. SCTP_USE_PERCPU_STAT opt_sctp.h # Use per cpu stats. +SCTP_MCORE_INPUT opt_sctp.h # Have multiple input threads for input mbufs # # # Modified: stable/8/sys/netinet/sctp_bsd_addr.c ============================================================================== --- stable/8/sys/netinet/sctp_bsd_addr.c Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_bsd_addr.c Fri Feb 10 19:10:09 2012 (r231403) @@ -68,6 +68,7 @@ MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list"); MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control"); MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option"); +MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue"); /* Global NON-VNET structure that controls the iterator */ struct iterator_control sctp_it_ctl; Modified: stable/8/sys/netinet/sctp_constants.h ============================================================================== --- stable/8/sys/netinet/sctp_constants.h Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_constants.h Fri Feb 10 19:10:09 2012 (r231403) @@ -91,6 +91,8 @@ __FBSDID("$FreeBSD$"); #define SCTP_KTRHEAD_NAME "sctp_iterator" #define SCTP_KTHREAD_PAGES 0 +#define SCTP_MCORE_NAME "sctp_core_worker" + /* If you support Multi-VRF how big to * make the initial array of VRF's to. Modified: stable/8/sys/netinet/sctp_input.c ============================================================================== --- stable/8/sys/netinet/sctp_input.c Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_input.c Fri Feb 10 19:10:09 2012 (r231403) @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include @@ -5923,10 +5924,32 @@ bad: } return; } + + void -sctp_input(i_pak, off) - struct mbuf *i_pak; - int off; +sctp_input(struct mbuf *m, int off) { - sctp_input_with_port(i_pak, off, 0); +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) + struct ip *ip; + struct sctphdr *sh; + int offset; + int cpu_to_use; + + if (mp_ncpus > 1) { + ip = mtod(m, struct ip *); + offset = off + sizeof(*sh); + if (SCTP_BUF_LEN(m) < offset) { + if ((m = m_pullup(m, offset)) == 0) { + SCTP_STAT_INCR(sctps_hdrops); + return; + } + ip = mtod(m, struct ip *); + } + sh = (struct sctphdr *)((caddr_t)ip + off); + cpu_to_use = ntohl(sh->v_tag) % mp_ncpus; + sctp_queue_to_mcore(m, off, cpu_to_use); + return; + } +#endif + sctp_input_with_port(m, off, 0); } Modified: stable/8/sys/netinet/sctp_lock_bsd.h ============================================================================== --- stable/8/sys/netinet/sctp_lock_bsd.h Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_lock_bsd.h Fri Feb 10 19:10:09 2012 (r231403) @@ -97,6 +97,48 @@ extern int sctp_logoff_stuff; rw_rlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ } while (0) +#define SCTP_MCORE_QLOCK_INIT(cpstr) do { \ + mtx_init(&(cpstr)->que_mtx, \ + "sctp-mcore_queue","queue_lock", \ + MTX_DEF|MTX_DUPOK); \ +} while (0) + +#define SCTP_MCORE_QLOCK(cpstr) do { \ + mtx_lock(&(cpstr)->que_mtx); \ +} while (0) + +#define SCTP_MCORE_QUNLOCK(cpstr) do { \ + mtx_unlock(&(cpstr)->que_mtx); \ +} while (0) + +#define SCTP_MCORE_QDESTROY(cpstr) do { \ + if(mtx_owned(&(cpstr)->core_mtx)) { \ + mtx_unlock(&(cpstr)->que_mtx); \ + } \ + mtx_destroy(&(cpstr)->que_mtx); \ +} while (0) + + +#define SCTP_MCORE_LOCK_INIT(cpstr) do { \ + mtx_init(&(cpstr)->core_mtx, \ + "sctp-cpulck","cpu_proc_lock", \ + MTX_DEF|MTX_DUPOK); \ +} while (0) + +#define SCTP_MCORE_LOCK(cpstr) do { \ + mtx_lock(&(cpstr)->core_mtx); \ +} while (0) + +#define SCTP_MCORE_UNLOCK(cpstr) do { \ + mtx_unlock(&(cpstr)->core_mtx); \ +} while (0) + +#define SCTP_MCORE_DESTROY(cpstr) do { \ + if(mtx_owned(&(cpstr)->core_mtx)) { \ + mtx_unlock(&(cpstr)->core_mtx); \ + } \ + mtx_destroy(&(cpstr)->core_mtx); \ +} while (0) #define SCTP_INP_INFO_WLOCK() do { \ rw_wlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \ Modified: stable/8/sys/netinet/sctp_os_bsd.h ============================================================================== --- stable/8/sys/netinet/sctp_os_bsd.h Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_os_bsd.h Fri Feb 10 19:10:09 2012 (r231403) @@ -123,6 +123,7 @@ MALLOC_DECLARE(SCTP_M_TIMW); MALLOC_DECLARE(SCTP_M_MVRF); MALLOC_DECLARE(SCTP_M_ITER); MALLOC_DECLARE(SCTP_M_SOCKOPT); +MALLOC_DECLARE(SCTP_M_MCORE); #if defined(SCTP_LOCAL_TRACE_BUF) Modified: stable/8/sys/netinet/sctp_pcb.c ============================================================================== --- stable/8/sys/netinet/sctp_pcb.c Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_pcb.c Fri Feb 10 19:10:09 2012 (r231403) @@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include VNET_DEFINE(struct sctp_base_info, system_base_info); @@ -5435,6 +5438,148 @@ sctp_del_local_addr_restricted(struct sc static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC; static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR; + + +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) +struct sctp_mcore_ctrl *sctp_mcore_workers = NULL; + +void +sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use) +{ + /* Queue a packet to a processor for the specified core */ + struct sctp_mcore_queue *qent; + struct sctp_mcore_ctrl *wkq; + int need_wake = 0; + + if (sctp_mcore_workers == NULL) { + /* Something went way bad during setup */ + sctp_input_with_port(m, off, 0); + return; + } + SCTP_MALLOC(qent, struct sctp_mcore_queue *, + (sizeof(struct sctp_mcore_queue)), + SCTP_M_MCORE); + if (qent == NULL) { + /* This is trouble */ + sctp_input_with_port(m, off, 0); + return; + } + qent->vn = curvnet; + qent->m = m; + qent->off = off; + qent->v6 = 0; + wkq = &sctp_mcore_workers[cpu_to_use]; + SCTP_MCORE_QLOCK(wkq); + + TAILQ_INSERT_TAIL(&wkq->que, qent, next); + if (wkq->running == 0) { + need_wake = 1; + } + SCTP_MCORE_QUNLOCK(wkq); + if (need_wake) { + wakeup(&wkq->running); + } +} + +static void +sctp_mcore_thread(void *arg) +{ + + struct sctp_mcore_ctrl *wkq; + struct sctp_mcore_queue *qent; + + wkq = (struct sctp_mcore_ctrl *)arg; + struct mbuf *m; + int off, v6; + + /* Wait for first tickle */ + SCTP_MCORE_LOCK(wkq); + wkq->running = 0; + msleep(&wkq->running, + &wkq->core_mtx, + 0, "wait for pkt", 0); + SCTP_MCORE_UNLOCK(wkq); + + /* Bind to our cpu */ + thread_lock(curthread); + sched_bind(curthread, wkq->cpuid); + thread_unlock(curthread); + + /* Now lets start working */ + SCTP_MCORE_LOCK(wkq); + /* Now grab lock and go */ + while (1) { + SCTP_MCORE_QLOCK(wkq); +skip_sleep: + wkq->running = 1; + qent = TAILQ_FIRST(&wkq->que); + if (qent) { + TAILQ_REMOVE(&wkq->que, qent, next); + SCTP_MCORE_QUNLOCK(wkq); + CURVNET_SET(qent->vn); + m = qent->m; + off = qent->off; + v6 = qent->v6; + SCTP_FREE(qent, SCTP_M_MCORE); + if (v6 == 0) { + sctp_input_with_port(m, off, 0); + } else { + printf("V6 not yet supported\n"); + sctp_m_freem(m); + } + CURVNET_RESTORE(); + SCTP_MCORE_QLOCK(wkq); + } + wkq->running = 0; + if (!TAILQ_EMPTY(&wkq->que)) { + goto skip_sleep; + } + SCTP_MCORE_QUNLOCK(wkq); + msleep(&wkq->running, + &wkq->core_mtx, + 0, "wait for pkt", 0); + }; +} + +static void +sctp_startup_mcore_threads(void) +{ + int i; + + if (mp_ncpus == 1) + return; + + SCTP_MALLOC(sctp_mcore_workers, struct sctp_mcore_ctrl *, + (mp_ncpus * sizeof(struct sctp_mcore_ctrl)), + SCTP_M_MCORE); + if (sctp_mcore_workers == NULL) { + /* TSNH I hope */ + return; + } + memset(sctp_mcore_workers, 0, (mp_ncpus * + sizeof(struct sctp_mcore_ctrl))); + /* Init the structures */ + for (i = 0; i < mp_ncpus; i++) { + TAILQ_INIT(&sctp_mcore_workers[i].que); + SCTP_MCORE_LOCK_INIT(&sctp_mcore_workers[i]); + SCTP_MCORE_QLOCK_INIT(&sctp_mcore_workers[i]); + sctp_mcore_workers[i].cpuid = i; + } + /* Now start them all */ + for (i = 0; i < mp_ncpus; i++) { + (void)kproc_create(sctp_mcore_thread, + (void *)&sctp_mcore_workers[i], + &sctp_mcore_workers[i].thread_proc, + RFPROC, + SCTP_KTHREAD_PAGES, + SCTP_MCORE_NAME); + + } +} + +#endif + + void sctp_pcb_init() { @@ -5565,6 +5710,10 @@ sctp_pcb_init() sctp_startup_iterator(); +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) + sctp_startup_mcore_threads(); +#endif + /* * INIT the default VRF which for BSD is the only one, other O/S's * may have more. But initially they must start with one and then Modified: stable/8/sys/netinet/sctp_pcb.h ============================================================================== --- stable/8/sys/netinet/sctp_pcb.h Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_pcb.h Fri Feb 10 19:10:09 2012 (r231403) @@ -624,6 +624,12 @@ sctp_initiate_iterator(inp_func inpf, struct sctp_inpcb *, uint8_t co_off); +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) +void + sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use); + +#endif + #ifdef INVARIANTS void sctp_validate_no_locks(struct sctp_inpcb *inp); Modified: stable/8/sys/netinet/sctp_structs.h ============================================================================== --- stable/8/sys/netinet/sctp_structs.h Fri Feb 10 19:07:32 2012 (r231402) +++ stable/8/sys/netinet/sctp_structs.h Fri Feb 10 19:10:09 2012 (r231403) @@ -106,6 +106,31 @@ typedef void (*asoc_func) (struct sctp_i typedef int (*inp_func) (struct sctp_inpcb *, void *ptr, uint32_t val); typedef void (*end_func) (void *ptr, uint32_t val); +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) +/* whats on the mcore control struct */ +struct sctp_mcore_queue { + TAILQ_ENTRY(sctp_mcore_queue) next; + struct vnet *vn; + struct mbuf *m; + int off; + int v6; +}; + +TAILQ_HEAD(sctp_mcore_qhead, sctp_mcore_queue); + +struct sctp_mcore_ctrl { + SCTP_PROCESS_STRUCT thread_proc; + struct sctp_mcore_qhead que; + struct mtx core_mtx; + struct mtx que_mtx; + int running; + int cpuid; +}; + + +#endif + + struct sctp_iterator { TAILQ_ENTRY(sctp_iterator) sctp_nxt_itr; struct vnet *vn;