From owner-svn-src-projects@FreeBSD.ORG Sat May 23 12:44:27 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2EF78106566C; Sat, 23 May 2009 12:44:27 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 13E6F8FC13; Sat, 23 May 2009 12:44:27 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4NCiQeg055895; Sat, 23 May 2009 12:44:26 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4NCiQna055892; Sat, 23 May 2009 12:44:26 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200905231244.n4NCiQna055892@svn.freebsd.org> From: Robert Watson Date: Sat, 23 May 2009 12:44:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192635 - in projects/pnet/sys: kern net X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 May 2009 12:44:27 -0000 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 __FBSDID("$FreeBSD$"); +#include "opt_netisr.h" #include "opt_route.h" #include "opt_device_polling.h" @@ -45,11 +46,10 @@ __FBSDID("$FreeBSD$"); #include /* for IFF_* flags */ #include /* for NETISR_POLL */ +#include #include #include -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 #include @@ -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_ */