svn commit: r218211 - in head/sys: conf netinet

Michael Tuexen tuexen at fh-muenster.de
Fri Feb 4 21:30:28 UTC 2011


On Feb 4, 2011, at 7:40 AM, Robert Watson wrote:

> 
> On Thu, 3 Feb 2011, Randall Stewart wrote:
> 
>> Author: rrs
>> Date: Thu Feb  3 10:05:30 2011
>> New Revision: 218211
>> URL: http://svn.freebsd.org/changeset/base/218211
>> 
>> Log:
>> 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.
> 
> Hmm.  It might be better to add a new NETISR_SCTP and use netisr's support for multithreading?
That sounds really good.

Is it possible that different network cards put packets in the same queue?
That would be helpful in the case of SCTP.
> 
> (I'm preparing a patch for review that enhances that a bit so that protocols can be a bit more expressive in terms of specifying dispatch policy, etc, currently).
Great!

Best regards
Michael
> 
> Robert
> 
> 
>> 
>> MFC after:	3 months (maybe)
>> 
>> Modified:
>> head/sys/conf/options
>> head/sys/netinet/sctp_bsd_addr.c
>> head/sys/netinet/sctp_constants.h
>> head/sys/netinet/sctp_input.c
>> head/sys/netinet/sctp_lock_bsd.h
>> head/sys/netinet/sctp_os_bsd.h
>> head/sys/netinet/sctp_pcb.c
>> head/sys/netinet/sctp_pcb.h
>> head/sys/netinet/sctp_structs.h
>> 
>> Modified: head/sys/conf/options
>> ==============================================================================
>> --- head/sys/conf/options	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/conf/options	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -439,6 +439,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: head/sys/netinet/sctp_bsd_addr.c
>> ==============================================================================
>> --- head/sys/netinet/sctp_bsd_addr.c	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_bsd_addr.c	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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: head/sys/netinet/sctp_constants.h
>> ==============================================================================
>> --- head/sys/netinet/sctp_constants.h	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_constants.h	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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: head/sys/netinet/sctp_input.c
>> ==============================================================================
>> --- head/sys/netinet/sctp_input.c	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_input.c	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
>> #include <netinet/sctp_timer.h>
>> #include <netinet/sctp_crc32.h>
>> #include <netinet/udp.h>
>> +#include <sys/smp.h>
>> 
>> 
>> 
>> @@ -5921,10 +5922,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: head/sys/netinet/sctp_lock_bsd.h
>> ==============================================================================
>> --- head/sys/netinet/sctp_lock_bsd.h	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_lock_bsd.h	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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: head/sys/netinet/sctp_os_bsd.h
>> ==============================================================================
>> --- head/sys/netinet/sctp_os_bsd.h	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_os_bsd.h	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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: head/sys/netinet/sctp_pcb.c
>> ==============================================================================
>> --- head/sys/netinet/sctp_pcb.c	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_pcb.c	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
>> #include <netinet/sctp_bsd_addr.h>
>> #include <netinet/sctp_dtrace_define.h>
>> #include <netinet/udp.h>
>> +#include <sys/sched.h>
>> +#include <sys/smp.h>
>> +#include <sys/unistd.h>
>> 
>> 
>> 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: head/sys/netinet/sctp_pcb.h
>> ==============================================================================
>> --- head/sys/netinet/sctp_pcb.h	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_pcb.h	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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: head/sys/netinet/sctp_structs.h
>> ==============================================================================
>> --- head/sys/netinet/sctp_structs.h	Thu Feb  3 08:55:45 2011	(r218210)
>> +++ head/sys/netinet/sctp_structs.h	Thu Feb  3 10:05:30 2011	(r218211)
>> @@ -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;
>> 
> 



More information about the svn-src-head mailing list