allocate VLAN tags from UMA

Gleb Smirnoff glebius at FreeBSD.org
Mon Dec 19 06:45:45 PST 2005


  Colleagues,

  I've made a patch, implementing Sam's advice to allocate VLAN
tags for hwvlantagging capable drivers from UMA zone.

The patch gives 6% improvement on a singlethreaded UDP flood. Unfortunately
I don't have enough hardware to test it under two simultaneous floods. It
probably should give even more improvement in this case.

x head-flood
+ mtag-flood
+--------------------------------------------------------------------------+
|x       x             x x      x x             +          +    +  ++     +|
|       |____________A___M________|                   |________A___M____|  |
+--------------------------------------------------------------------------+
    N           Min           Max        Median           Avg        Stddev
x   6        242001        253604        250265     248885.17     4568.0712
+   6        258408        267557        264955      263794.5     3132.2551
Difference at 95.0% confidence
        14909.3 +/- 5037.97
        5.99045% +/- 2.02421%
        (Student's t, pooled s = 3916.52)

The problem with the patch is the namespace pollution - vlan UMA zone
is declared in kern_mbuf.c and mtag cookie is declared in mbuf.h. I can't
make then private to if_vlan.c, because this will make NIC drivers dependent
on vlan(4).

Can we accept this?

-- 
Totus tuus, Glebius.
GLEBIUS-RIPN GLEB-RIPE
-------------- next part --------------
Index: sys/mbuf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/mbuf.h,v
retrieving revision 1.184
diff -u -r1.184 mbuf.h
--- sys/mbuf.h	10 Dec 2005 15:21:04 -0000	1.184
+++ sys/mbuf.h	19 Dec 2005 13:07:05 -0000
@@ -758,6 +758,10 @@
 #define	PACKET_TAG_IPOPTIONS			27 /* Saved IP options */
 #define	PACKET_TAG_CARP                         28 /* CARP info */
 
+/* Specific cookies and tags. */
+#define	MTAG_VLAN				1035328035
+#define	MTAG_VLAN_TAG				0 /* tag of VLAN interface */
+
 /* Packet tag routines. */
 struct	m_tag	*m_tag_alloc(u_int32_t, int, int, int);
 void		 m_tag_delete(struct mbuf *, struct m_tag *);
@@ -768,6 +772,9 @@
 int		 m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
 void		 m_tag_delete_nonpersistent(struct mbuf *);
 
+/* Specific tags routines. */
+struct m_tag *mt_vlan_alloc(int flags);
+
 /*
  * Initialize the list of tags associated with an mbuf.
  */
Index: kern/kern_mbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_mbuf.c,v
retrieving revision 1.17
diff -u -r1.17 kern_mbuf.c
--- kern/kern_mbuf.c	10 Dec 2005 15:21:04 -0000	1.17
+++ kern/kern_mbuf.c	19 Dec 2005 13:06:17 -0000
@@ -133,6 +133,7 @@
 uma_zone_t	zone_jumbo9;
 uma_zone_t	zone_jumbo16;
 uma_zone_t	zone_ext_refcnt;
+uma_zone_t	zone_mtag_vlan;
 
 /*
  * Local prototypes.
@@ -225,6 +226,12 @@
 	    NULL, NULL,
 	    UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
 
+	zone_mtag_vlan = uma_zcreate("mtag_vlan",
+	    sizeof(struct m_tag) + sizeof(u_int),
+	    NULL, NULL,
+	    NULL, NULL,
+	    UMA_ALIGN_INT, 0);
+
 	/* uma_prealloc() goes here... */
 
 	/*
@@ -511,6 +518,25 @@
 	return (0);
 }
 
+static void
+mt_vlan_free(struct m_tag *mtag)
+{
+	uma_zfree(zone_mtag_vlan, mtag);
+}
+
+struct m_tag *
+mt_vlan_alloc(int flags)
+{
+	struct m_tag *mtag;
+
+	mtag = uma_zalloc(zone_mtag_vlan, flags);
+	if (mtag) {
+		m_tag_setup(mtag, MTAG_VLAN, MTAG_VLAN_TAG, sizeof(u_int));
+		mtag->m_tag_free = mt_vlan_free;
+	}
+	return (mtag);
+}
+
 /*
  * This is the protocol drain routine.
  *
Index: net/if_vlan.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_vlan.c,v
retrieving revision 1.93
diff -u -r1.93 if_vlan.c
--- net/if_vlan.c	28 Nov 2005 12:46:35 -0000	1.93
+++ net/if_vlan.c	19 Dec 2005 12:51:23 -0000
@@ -507,10 +507,7 @@
 		 * packet tag that holds it.
 		 */
 		if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
-			struct m_tag *mtag = m_tag_alloc(MTAG_VLAN,
-							 MTAG_VLAN_TAG,
-							 sizeof(u_int),
-							 M_NOWAIT);
+			struct m_tag *mtag = mt_vlan_alloc(M_NOWAIT);
 			if (mtag == NULL) {
 				ifp->if_oerrors++;
 				m_freem(m);
Index: net/if_vlan_var.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_vlan_var.h,v
retrieving revision 1.23
diff -u -r1.23 if_vlan_var.h
--- net/if_vlan_var.h	18 Dec 2005 18:24:27 -0000	1.23
+++ net/if_vlan_var.h	19 Dec 2005 13:01:03 -0000
@@ -93,8 +93,6 @@
  * Note that a driver must indicate it supports hardware VLAN
  * tagging by marking IFCAP_VLAN_HWTAGGING in if_capabilities.
  */
-#define	MTAG_VLAN	1035328035
-#define	MTAG_VLAN_TAG	0		/* tag of VLAN interface */
 
 /*
  * This macro must expand to a lvalue so that it can be used
@@ -103,9 +101,7 @@
 #define	VLAN_TAG_VALUE(_mt)	(*(u_int *)((_mt) + 1))
 
 #define	VLAN_INPUT_TAG(_ifp, _m, _t) do {			\
-	struct m_tag *mtag;					\
-	mtag = m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG,		\
-			   sizeof (u_int), M_NOWAIT);		\
+	struct m_tag *mtag = mt_vlan_alloc(M_NOWAIT);		\
 	if (mtag != NULL) {					\
 		VLAN_TAG_VALUE(mtag) = (_t);			\
 		m_tag_prepend((_m), mtag);			\


More information about the freebsd-net mailing list