cvs commit: src/sys/i386/i386 nexus.c src/sys/i386/include atomic.h src/sys/kern kern_poll.c lwkt_serialize.c src/sys/net if.c if_var.h rtsock.c src/sbin/ifconfig ifconfig.c src/sys/dev/netif/dc if_dc.c src/sys/dev/netif/em if_em.c if_em.h ...

Joerg Sonnenberger joerg at britannica.bec.de
Fri May 27 12:26:17 PDT 2005


[forgotten patch]
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.24
diff -u -r1.24 ifconfig.c
--- sbin/ifconfig/ifconfig.c	26 May 2005 09:06:40 -0000	1.24
+++ sbin/ifconfig/ifconfig.c	26 May 2005 19:05:45 -0000
@@ -193,8 +193,6 @@
 } cmds[] = {
 	{ "up",		IFF_UP,		setifflags,	NULL },
 	{ "down",	-IFF_UP,	setifflags,	NULL },
-	{ "polling",	IFF_POLLING,	setifflags,	NULL },
-	{ "-polling",	-IFF_POLLING,	setifflags,	NULL },
 	{ "arp",	-IFF_NOARP,	setifflags,	NULL },
 	{ "-arp",	IFF_NOARP,	setifflags,	NULL },
 	{ "debug",	IFF_DEBUG,	setifflags,	NULL },
@@ -291,6 +289,8 @@
 	{ "-txcsum",	-IFCAP_TXCSUM,	setifcap,	NULL },
 	{ "netcons",	IFCAP_NETCONS,	setifcap,	NULL },
 	{ "-netcons",	-IFCAP_NETCONS,	setifcap,	NULL },
+	{ "polling",	IFCAP_POLLING,	setifcap,	NULL },
+	{ "-polling",	-IFCAP_POLLING,	setifcap,	NULL },
 	{ "vlanmtu",	IFCAP_VLAN_MTU,		setifcap,	NULL },
 	{ "-vlanmtu",	-IFCAP_VLAN_MTU,	setifcap,	NULL },
 	{ "vlanhwtag",	IFCAP_VLAN_HWTAGGING,	setifcap,	NULL },
Index: sys/dev/netif/em/if_em.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/em/if_em.c,v
retrieving revision 1.34
diff -u -r1.34 if_em.c
--- sys/dev/netif/em/if_em.c	27 May 2005 19:11:49 -0000	1.34
+++ sys/dev/netif/em/if_em.c	27 May 2005 19:12:26 -0000
@@ -730,6 +730,11 @@
 		break;
 	case SIOCSIFCAP:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
+#ifdef DEVICE_POLLING
+		ifp->if_capenable &= ~IFCAP_POLLING;
+		ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+		ether_poll_update(ifp);
+#endif
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 		if (mask & IFCAP_HWCSUM) {
 			if (IFCAP_HWCSUM & ifp->if_capenable)
Index: sys/dev/netif/re/if_re.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/re/if_re.c,v
retrieving revision 1.12
diff -u -r1.12 if_re.c
--- sys/dev/netif/re/if_re.c	25 May 2005 01:44:27 -0000	1.12
+++ sys/dev/netif/re/if_re.c	27 May 2005 19:20:30 -0000
@@ -2114,15 +2114,15 @@
 		break;
 	case SIOCSIFCAP:
 		ifp->if_capenable &= ~(IFCAP_HWCSUM);
-		ifp->if_capenable |=
-		    ifr->ifr_reqcap & (IFCAP_HWCSUM);
+		ifp->if_capenable |= ifr->ifr_reqcap & (IFCAP_HWCSUM);
 		if (ifp->if_capenable & IFCAP_TXCSUM)
 			ifp->if_hwassist = RE_CSUM_FEATURES;
 		else
 			ifp->if_hwassist = 0;
 		if (ifp->if_flags & IFF_RUNNING)
 			re_init(sc);
-		break;
+		ifr->ifr_reqcap &= ~IFCAP_HWCSUM;
+		/* FALLTHROUGH */
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
Index: sys/kern/kern_poll.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/kern/kern_poll.c,v
retrieving revision 1.15
diff -u -r1.15 kern_poll.c
--- sys/kern/kern_poll.c	25 May 2005 01:44:14 -0000	1.15
+++ sys/kern/kern_poll.c	25 May 2005 14:41:54 -0000
@@ -157,13 +157,7 @@
 SYSCTL_UINT(_kern_polling, OID_AUTO, stalled, CTLFLAG_RW,
 	&stalled, 0, "potential stalls");
 
-
-#define POLL_LIST_LEN  128
-struct pollrec {
-	struct ifnet	*ifp;
-};
-
-static struct pollrec pr[POLL_LIST_LEN];
+static LIST_HEAD(, ifnet) poll_list = LIST_HEAD_INITIALIZER(poll_list);
 
 /*
  * register relevant netisr. Called from kern_clock.c:
@@ -306,10 +300,10 @@
 static int
 netisr_poll(struct netmsg *msg)
 {
+	struct ifnet *ifp, *tmp_ifp;
 	static int reg_frac_count;
-	int i, cycles;
+	int cycles, s;
 	enum poll_cmd arg = POLL_ONLY;
-	int s;
 
 	lwkt_replymsg(&msg->nm_lmsg, 0);
 	s = splimp();
@@ -352,24 +346,16 @@
 	residual_burst -= cycles;
 
 	if (polling) {
-		for (i = 0 ; i < poll_handlers ; i++) {
-			struct pollrec *p = &pr[i];
-			if ((p->ifp->if_flags & (IFF_UP|IFF_RUNNING|IFF_POLLING)) == (IFF_UP|IFF_RUNNING|IFF_POLLING)) {
-				p->ifp->if_poll(p->ifp, arg, cycles);
-			}
+		LIST_FOREACH_MUTABLE(ifp, &poll_list, if_poll_link, tmp_ifp) {
+			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+			    (IFF_UP | IFF_RUNNING))
+				ifp->if_poll(ifp, arg, cycles);
 		}
 	} else {	/* unregister */
-		for (i = 0 ; i < poll_handlers ; i++) {
-			struct pollrec *p = &pr[i];
-			if (p->ifp->if_flags & IFF_POLLING) {
-				p->ifp->if_flags &= ~IFF_POLLING;
-				/*
-				 * Only call the interface deregistration
-				 * function if the interface is still 
-				 * running.
-				 */
-				if (p->ifp->if_flags & IFF_RUNNING)
-					p->ifp->if_poll(p->ifp, POLL_DEREGISTER, 1);
+		LIST_FOREACH_MUTABLE(ifp, &poll_list, if_poll_link, tmp_ifp) {
+			if (ifp->if_flags & IFF_RUNNING) {
+				ifp->if_flags &= ~IFF_POLLING;
+				ifp->if_poll(ifp, POLL_DEREGISTER, 1);
 			}
 		}
 		residual_burst = 0;
@@ -405,38 +391,16 @@
 	 * Attempt to register.  Interlock with IFF_POLLING.
 	 */
 	crit_enter();	/* XXX MP - not mp safe */
+	LIST_INSERT_HEAD(&poll_list, ifp, if_poll_link);
 	ifp->if_flags |= IFF_POLLING;
 	ifp->if_poll(ifp, POLL_REGISTER, 0);
+	poll_handlers++;
 	if ((ifp->if_flags & IFF_POLLING) == 0) {
 		crit_exit();
 		return 0;
 	}
+	rc = 1;
 
-	/*
-	 * Check if there is room.  If there isn't, deregister.
-	 */
-	if (poll_handlers >= POLL_LIST_LEN) {
-		/*
-		 * List full, cannot register more entries.
-		 * This should never happen; if it does, it is probably a
-		 * broken driver trying to register multiple times. Checking
-		 * this at runtime is expensive, and won't solve the problem
-		 * anyways, so just report a few times and then give up.
-		 */
-		static int verbose = 10 ;
-		if (verbose >0) {
-			printf("poll handlers list full, "
-				"maybe a broken driver ?\n");
-			verbose--;
-		}
-		ifp->if_flags &= ~IFF_POLLING;
-		ifp->if_poll(ifp, POLL_DEREGISTER, 0);
-		rc = 0;
-	} else {
-		pr[poll_handlers].ifp = ifp;
-		poll_handlers++;
-		rc = 1;
-	}
 	crit_exit();
 	return (rc);
 }
@@ -448,27 +412,14 @@
 int
 ether_poll_deregister(struct ifnet *ifp)
 {
-	int i;
-
 	crit_enter();
 	if (ifp == NULL || (ifp->if_flags & IFF_POLLING) == 0) {
 		crit_exit();
 		return 0;
 	}
-	for (i = 0 ; i < poll_handlers ; i++) {
-		if (pr[i].ifp == ifp) /* found it */
-			break;
-	}
-	ifp->if_flags &= ~IFF_POLLING; /* found or not... */
-	if (i == poll_handlers) {
-		crit_exit();
-		printf("ether_poll_deregister: ifp not found!!!\n");
-		return 0;
-	}
+	LIST_REMOVE(ifp, if_poll_link);
+	ifp->if_flags &= ~IFF_POLLING;
 	poll_handlers--;
-	if (i < poll_handlers) { /* Last entry replaces this one. */
-		pr[i].ifp = pr[poll_handlers].ifp;
-	}
 	crit_exit();
 
 	/*
@@ -488,3 +439,15 @@
 		printf("%s forced polling on\n", name);
 	}
 }
+
+void
+ether_poll_update(struct ifnet *ifp)
+{
+	if ((ifp->if_flags & IFF_POLLING) &&
+	    (ifp->if_capenable & IFCAP_POLLING) == 0) {
+		ether_poll_deregister(ifp);
+	} else if ((ifp->if_flags & (IFF_POLLING | IFF_UP)) == IFF_UP &&
+	    (ifp->if_capenable & IFCAP_POLLING)) {
+		ether_poll_register(ifp);
+	}
+}
Index: sys/net/if.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if.c,v
retrieving revision 1.36
diff -u -r1.36 if.c
--- sys/net/if.c	25 May 2005 21:26:52 -0000	1.36
+++ sys/net/if.c	26 May 2005 19:02:25 -0000
@@ -318,10 +318,6 @@
 	 * Remove routes and flush queues.
 	 */
 	s = splnet();
-#ifdef DEVICE_POLLING
-	if (ifp->if_flags & IFF_POLLING)
-		ether_poll_deregister(ifp);
-#endif
 	if_down(ifp);
 
 	if (ifq_is_enabled(&ifp->if_snd))
@@ -942,6 +938,10 @@
 void
 if_down(struct ifnet *ifp)
 {
+#ifdef DEVICE_POLLING
+	if (ifp->if_flags & IFF_POLLING)
+		ether_poll_deregister(ifp);
+#endif
 	if_unroute(ifp, IFF_UP, AF_UNSPEC);
 	netmsg_service_sync();
 }
@@ -954,7 +954,9 @@
 void
 if_up(struct ifnet *ifp)
 {
-
+#ifdef DEVICE_POLLING
+	ether_poll_update(ifp);
+#endif
 	if_route(ifp, IFF_UP, AF_UNSPEC);
 }
 
@@ -1026,7 +1028,6 @@
 	return ifunit(ifname);
 }
 
-
 /*
  * Interface ioctls.
  */
@@ -1112,16 +1113,6 @@
 			splx(s);
 		}
 
-#ifdef DEVICE_POLLING
-		if ((new_flags ^ ifp->if_flags) & IFF_POLLING) {
-			if (new_flags & IFF_POLLING) {
-				ether_poll_register(ifp);
-			} else {
-				ether_poll_deregister(ifp);
-			}
-		}
-#endif
-
 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
 			(new_flags &~ IFF_CANTCHANGE);
 		if (new_flags & IFF_PPROMISC) {
Index: sys/net/if.h
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if.h,v
retrieving revision 1.13
diff -u -r1.13 if.h
--- sys/net/if.h	25 May 2005 14:59:05 -0000	1.13
+++ sys/net/if.h	26 May 2005 19:03:17 -0000
@@ -163,6 +163,7 @@
 #define IFCAP_VLAN_MTU		0x0008	/* VLAN-compatible MTU */
 #define IFCAP_VLAN_HWTAGGING	0x0010	/* hardware VLAN tag support */
 #define IFCAP_JUMBO_MTU		0x0020	/* 9000 byte MTU support */
+#define	IFCAP_POLLING		0x0040	/* driver supports polling */
 
 #define IFCAP_HWCSUM		(IFCAP_RXCSUM | IFCAP_TXCSUM)
 
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if_ethersubr.c,v
retrieving revision 1.30
diff -u -r1.30 if_ethersubr.c
--- sys/net/if_ethersubr.c	18 Apr 2005 14:26:57 -0000	1.30
+++ sys/net/if_ethersubr.c	27 May 2005 18:38:33 -0000
@@ -818,6 +818,14 @@
 	ifp->if_input = ether_input_internal;
 	ifp->if_resolvemulti = ether_resolvemulti;
 	ifp->if_broadcastaddr = etherbroadcastaddr;
+
+#ifdef DEVICE_POLLING
+	if (ifp->if_poll != NULL) {
+		ifp->if_capabilities |= IFCAP_POLLING;
+		ifp->if_capenable |= IFCAP_POLLING;
+	}
+#endif
+
 	ifa = ifnet_addrs[ifp->if_index - 1];
 	KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
 	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
@@ -940,6 +948,15 @@
 			ifp->if_mtu = ifr->ifr_mtu;
 		}
 		break;
+	case SIOCSIFCAP:
+#ifdef DEVICE_POLLING
+		if (ifp->if_capabilities & IFCAP_POLLING) {
+			ifp->if_capenable &= ~IFCAP_POLLING;
+			ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+			ether_poll_update(ifp);
+		}
+#endif
+		break;
 	default:
 		error = EINVAL;
 		break;
Index: sys/net/if_var.h
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if_var.h,v
retrieving revision 1.25
diff -u -r1.25 if_var.h
--- sys/net/if_var.h	25 May 2005 01:44:16 -0000	1.25
+++ sys/net/if_var.h	25 May 2005 14:48:32 -0000
@@ -179,11 +179,12 @@
 	int	(*if_resolvemulti)	/* validate/resolve multicast */
 		(struct ifnet *, struct sockaddr **, struct sockaddr *);
 #ifdef DEVICE_POLLING
-	void	(*if_poll)		/* IFF_POLLING support */
+	void	(*if_poll)		/* DEVICE_POLLING support */
 		(struct ifnet *, enum poll_cmd, int);
 #else
 	void	(*if_poll_unused)(void); /* placeholder */
 #endif
+	LIST_ENTRY(ifnet) if_poll_link;
 	struct	ifaltq if_snd;		/* output queue (includes altq) */
 	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
 	const uint8_t	*if_broadcastaddr;
@@ -454,8 +455,8 @@
     LLADDR((struct sockaddr_dl *) ifnet_addrs[ifp->if_index - 1]->ifa_addr)
 
 #ifdef DEVICE_POLLING
-typedef	void poll_handler_t (struct ifnet *ifp,
-		enum poll_cmd cmd, int count);
+typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
+void	ether_poll_update(struct ifnet *ifp);
 int	ether_poll_register(struct ifnet *ifp);
 int	ether_poll_deregister(struct ifnet *ifp);
 void	emergency_poll_enable(const char *name);




More information about the Commits mailing list