diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.c | 39 | ||||
-rw-r--r-- | sys/net/if.h | 7 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 5 | ||||
-rw-r--r-- | sys/net/netisr.h | 4 | ||||
-rw-r--r-- | sys/net/netisr_dispatch.h | 3 |
5 files changed, 51 insertions, 7 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 272c773336c..84a5f0409a9 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.168 2008/01/05 19:08:19 henning Exp $ */ +/* $OpenBSD: if.c,v 1.169 2008/04/10 23:15:45 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -174,6 +174,7 @@ int if_indexlim = 0; struct ifaddr **ifnet_addrs = NULL; struct ifnet **ifindex2ifnet = NULL; struct ifnet_head ifnet; +struct ifnet_head iftxlist = TAILQ_HEAD_INITIALIZER(iftxlist); struct ifnet *lo0ifp; /* @@ -459,6 +460,40 @@ if_attach(struct ifnet *ifp) if_attachsetup(ifp); } +void +if_start(struct ifnet *ifp) +{ + if (IF_QFULL(&ifp->if_snd) && !ISSET(ifp->if_flags, IFF_OACTIVE)) { + if (ISSET(ifp->if_xflags, IFXF_TXREADY)) { + TAILQ_REMOVE(&iftxlist, ifp, if_txlist); + CLR(ifp->if_xflags, IFXF_TXREADY); + } + ifp->if_start(ifp); + return; + } + + if (!ISSET(ifp->if_xflags, IFXF_TXREADY)) { + SET(ifp->if_xflags, IFXF_TXREADY); + TAILQ_INSERT_TAIL(&iftxlist, ifp, if_txlist); + schednetisr(NETISR_TX); + } +} + +void +nettxintr(void) +{ + struct ifnet *ifp; + int s; + + s = splnet(); + while ((ifp = TAILQ_FIRST(&iftxlist)) != NULL) { + TAILQ_REMOVE(&iftxlist, ifp, if_txlist); + CLR(ifp->if_xflags, IFXF_TXREADY); + ifp->if_start(ifp); + } + splx(s); +} + /* * Detach an interface from everything in the kernel. Also deallocate * private resources. @@ -559,6 +594,8 @@ do { \ /* Remove the interface from the list of all interfaces. */ TAILQ_REMOVE(&ifnet, ifp, if_list); + if (ISSET(ifp->if_xflags, IFXF_TXREADY)) + TAILQ_REMOVE(&iftxlist, ifp, if_txlist); /* * Deallocate private resources. diff --git a/sys/net/if.h b/sys/net/if.h index c2adb9e9a36..21dc8f31e4f 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.93 2007/11/18 12:51:48 mpf Exp $ */ +/* $OpenBSD: if.h,v 1.94 2008/04/10 23:15:45 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -178,6 +178,7 @@ TAILQ_HEAD(ifnet_head, ifnet); /* the actual queue head */ struct ifnet { /* and the entries */ void *if_softc; /* lower-level data for this if */ TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */ + TAILQ_ENTRY(ifnet) if_txlist; /* list of ifnets ready to tx */ TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */ TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ struct hook_desc_head *if_addrhooks; /* address change callbacks */ @@ -198,6 +199,7 @@ struct ifnet { /* and the entries */ u_short if_index; /* numeric abbreviation for this if */ short if_timer; /* time 'til if_watchdog called */ short if_flags; /* up/down, broadcast, etc. */ + int if_xflags; /* extra softnet flags */ struct if_data if_data; /* stats and other data about if */ u_int32_t if_hardmtu; /* maximum MTU device supports */ int if_capabilities; /* interface capabilities */ @@ -265,6 +267,8 @@ struct ifnet { /* and the entries */ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI) +#define IFXF_TXREADY 0x1 /* interface is ready to tx */ + /* * Some convenience macros used for setting ifi_baudrate. */ @@ -775,6 +779,7 @@ int if_addgroup(struct ifnet *, const char *); int if_delgroup(struct ifnet *, const char *); void if_group_routechange(struct sockaddr *, struct sockaddr *); struct ifnet *ifunit(const char *); +void if_start(struct ifnet *); struct ifaddr *ifa_ifwithaddr(struct sockaddr *); struct ifaddr *ifa_ifwithaf(int); diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 08c3c67968e..6d3247f628b 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.115 2008/04/10 22:33:14 brad Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.116 2008/04/10 23:15:45 dlg Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -432,8 +432,7 @@ ether_output(ifp0, m0, dst, rt0) #endif /* NCARP > 0 */ if (mflags & M_MCAST) ifp->if_omcasts++; - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); + if_start(ifp); splx(s); return (error); diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 4c56b7e5c17..2887556c754 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netisr.h,v 1.29 2008/01/19 18:26:18 mpf Exp $ */ +/* $OpenBSD: netisr.h,v 1.30 2008/04/10 23:15:45 dlg Exp $ */ /* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */ /* @@ -54,6 +54,7 @@ */ #define NETISR_RND 1 #define NETISR_IP 2 /* same as AF_INET */ +#define NETISR_TX 3 /* for if_snd processing */ #define NETISR_ATALK 16 /* same as AF_APPLETALK */ #define NETISR_ARP 18 /* same as AF_LINK */ #define NETISR_IPV6 24 /* same as AF_INET6 */ @@ -69,6 +70,7 @@ extern int netisr; /* scheduling bits for network */ void netrndintr(void); +void nettxintr(void); void arpintr(void); void ipintr(void); void ip6intr(void); diff --git a/sys/net/netisr_dispatch.h b/sys/net/netisr_dispatch.h index 3269806eaac..2f786985dac 100644 --- a/sys/net/netisr_dispatch.h +++ b/sys/net/netisr_dispatch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netisr_dispatch.h,v 1.13 2007/06/06 10:04:36 henning Exp $ */ +/* $OpenBSD: netisr_dispatch.h,v 1.14 2008/04/10 23:15:45 dlg Exp $ */ /* $NetBSD: netisr_dispatch.h,v 1.2 2000/07/02 04:40:47 cgd Exp $ */ /* @@ -63,3 +63,4 @@ #if NBLUETOOTH > 0 DONETISR(NETISR_BT,btintr); #endif + DONETISR(NETISR_TX,nettxintr); |