PERFORCE change 124786 for review
Kip Macy
kmacy at FreeBSD.org
Mon Aug 6 17:30:36 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=124786
Change 124786 by kmacy at 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)
More information about the p4-projects
mailing list