Skip site navigation (1)Skip section navigation (2)
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>