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