Date: Tue, 7 Aug 2007 00:30:34 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 124786 for review Message-ID: <200708070030.l770UY8d074251@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=124786 Change 124786 by kmacy@kmacy_home:ethng on 2007/08/07 00:30:21 first cut of ifnet extensions for supporting multiple queues Affected files ... .. //depot/projects/ethng/src/sys/conf/options#2 edit .. //depot/projects/ethng/src/sys/net/if.c#2 edit .. //depot/projects/ethng/src/sys/net/if.h#2 edit .. //depot/projects/ethng/src/sys/net/if_var.h#2 edit Differences ... ==== //depot/projects/ethng/src/sys/conf/options#2 (text+ko) ==== @@ -546,6 +546,7 @@ RWLOCK_NOINLINE opt_global.h SX_NOINLINE opt_global.h VFS_BIO_DEBUG opt_global.h +IFNET_MULTIQUEUE opt_global.h # These are VM related options VM_KMEM_SIZE opt_vm.h ==== //depot/projects/ethng/src/sys/net/if.c#2 (text+ko) ==== @@ -2680,6 +2680,42 @@ return (retval); } +#ifdef IFNET_MULTIQUEUE +int ifnet_multiqueue = 1; + +int +if_mq_start(struct ifnet *ifp, int32_t cookie, struct mbuf *m) +{ + + KASSERT((ifp->if_flags & IFF_NEEDSGIANT) == 0, ("IFF_NEEDSGIANT set on multi queue interface")); + + return (*(ifp)->if_mq_start)(ifp, cookie, m); +} + + +int +if_mq_enqueue_packet(struct ifnet *ifp, int32_t cookie, struct mbuf *m) +{ + + KASSERT((ifp->if_flags & IFF_NEEDSGIANT) == 0, ("IFF_NEEDSGIANT set on multi queue interface")); + + return (*(ifp)->if_mq_enqueue_packet)(ifp, cookie, m); +} + +int32_t +if_mq_get_cookie(struct ifnet *ifp, struct in6_addr *lip, uint16_t lport, struct in6_addr *rip, uint16_t rport, int ipv6) +{ + + KASSERT((ifp->if_flags & IFF_NEEDSGIANT) == 0, ("IFF_NEEDSGIANT set on multi queue interface")); + + return (*(ifp)->if_mq_get_cookie)(ifp, lip, lport, rip, rport, ipv6); +} +#else +int ifnet_multiqueue = 0; +#endif + + + /* * When an interface is marked IFF_NEEDSGIANT, its if_start() routine cannot * be called without Giant. However, we often can't acquire the Giant lock ==== //depot/projects/ethng/src/sys/net/if.h#2 (text+ko) ==== @@ -150,6 +150,7 @@ #define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */ #define IFF_STATICARP 0x80000 /* (n) static ARP */ #define IFF_NEEDSGIANT 0x100000 /* (i) hold Giant over if_start calls */ +#define IFF_MULTIQ 0x200000 /* (i) driver has multiple queues and manages them privately */ /* * Old names for driver flags so that user space tools can continue to use ==== //depot/projects/ethng/src/sys/net/if_var.h#2 (text+ko) ==== @@ -86,6 +86,9 @@ #define IF_DUNIT_NONE -1 #include <altq/if_altq.h> +#ifdef IFNET_MULTIQUEUE +#include <netinet/in.h> +#endif TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ @@ -152,6 +155,14 @@ (struct ifnet *, struct mbuf *); void (*if_start) /* initiate output routine */ (struct ifnet *); +#ifdef IFNET_MULTIQUEUE + int (*if_mq_start) /* initiate output routine with immediate */ + (struct ifnet *, int32_t, struct mbuf *); + int (*if_mq_enqueue_packet) /* enqueue packet to the appropriate queue */ + (struct ifnet *, int32_t, struct mbuf *); + int32_t (*if_mq_get_cookie) /* calculate the txq cookie for this connection */ + (struct ifnet *, struct in6_addr *, uint16_t, struct in6_addr *, uint16_t, int); +#endif int (*if_ioctl) /* ioctl routine */ (struct ifnet *, u_long, caddr_t); void (*if_watchdog) /* timer routine */ @@ -378,6 +389,13 @@ if_handoff((struct ifqueue *)ifq, m, ifp, adj) void if_start(struct ifnet *); +#ifdef IFNET_MULTIQUEUE +int if_mq_start(struct ifnet *, int32_t, struct mbuf *); +int if_mq_enqueue_packet(struct ifnet *, int32_t, struct mbuf *); +int32_t if_mq_get_cookie(struct ifnet *ifp, struct in6_addr *lip, uint16_t lport, struct in6_addr *rip, uint16_t rport, int ipv6); +#endif +extern int ifnet_multiqueue; /* allow driver module to confirm that multiqueue is supported */ + #define IFQ_ENQUEUE(ifq, m, err) \ do { \ @@ -459,10 +477,52 @@ #define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) #define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) + +#ifdef IFNET_MULTIQUEUE +#define IFQ_HANDOFF_ADJ_MQ(ifp, m, adj, err, cookie) \ +do { \ + int len; \ + short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + err = if_mq_start((ifp), cookie, m); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len + (adj); \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + } \ +} while (0) +#define IFQ_HANDOFF_MQ(ifp, m, err, cookie) \ + IFQ_HANDOFF_ADJ_MQ(ifp, m, 0, err, cookie) +#endif + /* * The IFF_DRV_OACTIVE test should really occur in the device driver, not in * the handoff logic, as that flag is locked by the device driver. */ +#ifdef IFNET_MULTIQUEUE +#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ +do { \ + int len; \ + short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + if ((ifp)->if_flags & IFF_MULTIQ) \ + err = if_mq_start((ifp), -1, m); \ + else \ + IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len + (adj); \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0 && \ + ((ifp)->if_flags & IFF_MULTIQ) == 0) \ + if_start(ifp); \ + } \ +} while (0) +#else #define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ do { \ int len; \ @@ -479,6 +539,7 @@ if_start(ifp); \ } \ } while (0) +#endif #define IFQ_HANDOFF(ifp, m, err) \ IFQ_HANDOFF_ADJ(ifp, m, 0, err)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708070030.l770UY8d074251>