svn commit: r192635 - in projects/pnet/sys: kern net
Robert Watson
rwatson at FreeBSD.org
Sat May 23 12:44:27 UTC 2009
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_ */
More information about the svn-src-projects
mailing list