Date: Sat, 23 May 2009 12:44:26 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r192635 - in projects/pnet/sys: kern net Message-ID: <200905231244.n4NCiQna055892@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rwatson Date: Sat May 23 12:44:26 2009 New Revision: 192635 URL: http://svn.freebsd.org/changeset/base/192635 Log: ttempt to adapt DEVICE_POLLING for the netisr2 world: if device polling is configured into the kernel, use at most one worker thread and don't bind the thread to a CPU, restoring device polling's expectation of a single netisr thread running all interface and protocol code. Teach netisr2 explicitly about polling rather than having polling pretend to be a normal protocol dispatch, as netisr2 is more packet-centric than netisr. Modified: projects/pnet/sys/kern/kern_poll.c projects/pnet/sys/net/netisr2.c projects/pnet/sys/net/netisr2.h Modified: projects/pnet/sys/kern/kern_poll.c ============================================================================== --- projects/pnet/sys/kern/kern_poll.c Sat May 23 12:42:57 2009 (r192634) +++ projects/pnet/sys/kern/kern_poll.c Sat May 23 12:44:26 2009 (r192635) @@ -28,6 +28,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_netisr.h" #include "opt_route.h" #include "opt_device_polling.h" @@ -45,11 +46,10 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> /* for IFF_* flags */ #include <net/netisr.h> /* for NETISR_POLL */ +#include <net/netisr2.h> #include <net/route.h> #include <net/vnet.h> -static void netisr_poll(void); /* the two netisr handlers */ -static void netisr_pollmore(void); static int poll_switch(SYSCTL_HANDLER_ARGS); void hardclock_device_poll(void); /* hook from hardclock */ @@ -111,6 +111,11 @@ SYSCTL_NODE(_kern, OID_AUTO, polling, CT SYSCTL_UINT(_kern_polling, OID_AUTO, burst, CTLFLAG_RD, &poll_burst, 0, "Current polling burst size"); +#ifdef NETISR2 +static int netisr_poll_scheduled; +static int netisr_pollmore_scheduled; +#endif + static int poll_burst_max_sysctl(SYSCTL_HANDLER_ARGS) { uint32_t val = poll_burst_max; @@ -265,8 +270,10 @@ init_device_poll(void) { mtx_init(&poll_mtx, "polling", NULL, MTX_DEF); +#ifndef NETISR2 netisr_register(NETISR_POLL, (netisr_t *)netisr_poll, NULL, 0); netisr_register(NETISR_POLLMORE, (netisr_t *)netisr_pollmore, NULL, 0); +#endif } SYSINIT(device_poll, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, init_device_poll, NULL); @@ -315,7 +322,13 @@ hardclock_device_poll(void) if (phase != 0) suspect++; phase = 1; +#ifdef NETISR2 + netisr_poll_scheduled = 1; + netisr_pollmore_scheduled = 1; + netisr2_sched_poll(); +#else schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); +#endif phase = 2; } if (pending_polls++ > 0) @@ -366,9 +379,22 @@ netisr_pollmore() int kern_load; mtx_lock(&poll_mtx); +#ifdef NETISR2 + if (!netisr_pollmore_scheduled) { + mtx_unlock(&poll_mtx); + return; + } + netisr_pollmore_scheduled = 0; +#endif phase = 5; if (residual_burst > 0) { +#ifdef NETISR2 + netisr_poll_scheduled = 1; + netisr_pollmore_scheduled = 1; + netisr2_sched_poll(); +#else schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); +#endif mtx_unlock(&poll_mtx); /* will run immediately on return, followed by netisrs */ return; @@ -398,7 +424,13 @@ netisr_pollmore() poll_burst -= (poll_burst / 8); if (poll_burst < 1) poll_burst = 1; +#ifdef NETISR2 + netisr_poll_scheduled = 1; + netisr_pollmore_scheduled = 1; + netisr2_sched_poll(); +#else schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); +#endif phase = 6; } mtx_unlock(&poll_mtx); @@ -408,13 +440,20 @@ netisr_pollmore() * netisr_poll is scheduled by schednetisr when appropriate, typically once * per tick. */ -static void +void netisr_poll(void) { int i, cycles; enum poll_cmd arg = POLL_ONLY; mtx_lock(&poll_mtx); +#ifdef NETISR2 + if (!netisr_poll_scheduled) { + mtx_unlock(&poll_mtx); + return; + } + netisr_poll_scheduled = 0; +#endif phase = 3; if (residual_burst == 0) { /* first call in this tick */ microuptime(&poll_start_t); Modified: projects/pnet/sys/net/netisr2.c ============================================================================== --- projects/pnet/sys/net/netisr2.c Sat May 23 12:42:57 2009 (r192634) +++ projects/pnet/sys/net/netisr2.c Sat May 23 12:44:26 2009 (r192635) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); */ #include "opt_ddb.h" +#include "opt_device_polling.h" #include <sys/param.h> #include <sys/bus.h> @@ -733,6 +734,12 @@ swi_net(void *arg) nwsp = arg; +#ifdef DEVICE_POLLING + KASSERT(nws_count == 1, + ("swi_net: device_polling but nws_count != 1")); + netisr_poll(); +#endif + NETISR_RLOCK(&tracker); NWS_LOCK(nwsp); KASSERT(!(nwsp->nws_flags & NWS_RUNNING), ("swi_net: running")); @@ -746,6 +753,10 @@ swi_net(void *arg) out: NWS_UNLOCK(nwsp); NETISR_RUNLOCK(&tracker); + +#ifdef DEVICE_POLLING + netisr_pollmore(); +#endif } static int @@ -973,6 +984,22 @@ netisr_dispatch(int proto, struct mbuf * (void)netisr2_dispatch(proto, m); } +#ifdef DEVICE_POLLING +/* + * Kernel polling borrows a netisr2 thread to run interface polling in; this + * function allows kernel polling to request that the netisr2 thread be + * scheduled even if no packets are pending for protocols. + */ +void +netisr2_sched_poll(void) +{ + struct netisr_workstream *nwsp; + + nwsp = &nws[nws_array[0]]; + NWS_SIGNAL(nwsp); +} +#endif + static void netisr2_start_swi(u_int cpuid, struct pcpu *pc) { @@ -1020,6 +1047,15 @@ netisr2_init(void *arg) netisr_maxthreads = 1; if (netisr_maxthreads > MAXCPU) netisr_maxthreads = MAXCPU; +#ifdef DEVICE_POLLING + /* + * The device polling code is not yet aware of how to deal with + * multiple netisr threads, so for the time being compiling in device + * polling disables parallel netisr workers. + */ + netisr_maxthreads = 1; + netisr_bindthreads = 0; +#endif netisr2_start_swi(curcpu, pcpu_find(curcpu)); } Modified: projects/pnet/sys/net/netisr2.h ============================================================================== --- projects/pnet/sys/net/netisr2.h Sat May 23 12:42:57 2009 (r192634) +++ projects/pnet/sys/net/netisr2.h Sat May 23 12:44:26 2009 (r192635) @@ -124,4 +124,11 @@ u_int netisr2_default_flow2cpu(u_int flo u_int netisr2_get_cpucount(void); u_int netisr2_get_cpuid(u_int cpunumber); +/* + * Interfaces between DEVICE_POLLING and netisr2. + */ +void netisr2_sched_poll(void); +void netisr_poll(void); +void netisr_pollmore(void); + #endif /* !_NET_NETISR2_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905231244.n4NCiQna055892>