PERFORCE change 164673 for review

Marko Zec zec at FreeBSD.org
Thu Jun 18 16:50:31 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=164673

Change 164673 by zec at zec_amdx4 on 2009/06/18 16:50:04

	A much belated first pass at V_irtualizing flowtable(s).

Affected files ...

.. //depot/projects/vimage-commit2/src/sys/net/flowtable.c#5 edit
.. //depot/projects/vimage-commit2/src/sys/net/flowtable.h#5 edit
.. //depot/projects/vimage-commit2/src/sys/net/vnet.h#23 edit
.. //depot/projects/vimage-commit2/src/sys/sys/vimage.h#73 edit

Differences ...

==== //depot/projects/vimage-commit2/src/sys/net/flowtable.c#5 (text+ko) ====

@@ -57,7 +57,6 @@
 #include <net/vnet.h>
 #include <net/flowtable.h>
 
-
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
@@ -165,10 +164,29 @@
 };
 
 static struct proc *flowcleanerproc;
+#ifdef VIMAGE_GLOBALS
 static struct flowtable *flow_list_head;
-static uint32_t hashjitter;
-static uma_zone_t ipv4_zone;
-static uma_zone_t ipv6_zone;
+static uint32_t flow_hashjitter;
+static uma_zone_t flow_ipv4_zone;
+static uma_zone_t flow_ipv6_zone;
+#endif
+
+static int	flowtable_iattach(const void *);
+#ifdef VIMAGE
+static int	flowtable_idetach(const void *);
+#endif
+
+#ifndef VIMAGE_GLOBALS
+static const vnet_modinfo_t flowtable_modinfo = {
+	.vmi_id		= VNET_MOD_FLOWTABLE,
+	.vmi_name	= "flowtable",
+	.vmi_dependson	= VNET_MOD_NET,
+	.vmi_iattach    = flowtable_iattach,
+#ifdef VIMAGE
+	.vmi_idetach    = flowtable_idetach
+#endif
+};
+#endif /* !VIMAGE_GLOBALS */
 
 /*
  * TODO:
@@ -185,6 +203,7 @@
  *   of flows with flag to indicate that a flow was imported so should
  *   not be considered for auto-cleaning
  * - support explicit connection state (currently only ad-hoc for DSR)
+ * - V_ flowtable sysctls and nmbflows
  */
 SYSCTL_NODE(_net_inet, OID_AUTO, flowtable, CTLFLAG_RD, NULL, "flowtable");
 int	flowtable_enable = 1;
@@ -242,6 +261,7 @@
 static int
 sysctl_nmbflows(SYSCTL_HANDLER_ARGS)
 {
+	INIT_VNET_NET(curvnet);
 	int error, newnmbflows;
 
 	newnmbflows = nmbflows;
@@ -249,8 +269,8 @@
 	if (error == 0 && req->newptr) {
 		if (newnmbflows > nmbflows) {
 			nmbflows = newnmbflows;
-			uma_zone_set_max(ipv4_zone, nmbflows);
-			uma_zone_set_max(ipv6_zone, nmbflows);
+			uma_zone_set_max(V_flow_ipv4_zone, nmbflows);
+			uma_zone_set_max(V_flow_ipv6_zone, nmbflows);
 		} else
 			error = EINVAL;
 	}
@@ -310,6 +330,7 @@
 ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro,
     uint32_t *key, uint16_t *flags, uint8_t *protop)
 {
+	INIT_VNET_NET(curvnet);
 	uint16_t sport = 0, dport = 0;
 	struct ip *ip = NULL;
 	uint8_t proto = 0;
@@ -382,7 +403,7 @@
 	((uint16_t *)key)[1] = dport; 
 
 skipports:
-	hash = jenkins_hashword(key, 3, hashjitter + proto);
+	hash = jenkins_hashword(key, 3, V_flow_hashjitter + proto);
 	if (m != NULL && (m->m_flags & M_FLOWID) == 0) {
 		m->m_flags |= M_FLOWID;
 		m->m_pkthdr.flowid = hash;
@@ -476,12 +497,13 @@
 flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
     uint8_t proto, struct route *ro, uint16_t flags)
 {
+	INIT_VNET_NET(curvnet);
 	struct flentry *fle, *fletail, *newfle, **flep;
 	int depth;
 	uma_zone_t flezone;
 	bitstr_t *mask;
 
-	flezone = (flags & FL_IPV6) ? ipv6_zone : ipv4_zone;
+	flezone = (flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone;
 	newfle = uma_zalloc(flezone, M_NOWAIT | M_ZERO);
 	if (newfle == NULL)
 		return (ENOMEM);
@@ -513,7 +535,7 @@
 			 */
 			FL_ENTRY_UNLOCK(ft, hash);
 			uma_zfree((newfle->f_flags & FL_IPV6) ?
-			    ipv6_zone : ipv4_zone, newfle);
+			    V_flow_ipv6_zone : V_flow_ipv4_zone, newfle);
 			return (EEXIST);
 		}
 		/*
@@ -687,11 +709,12 @@
 struct flowtable *
 flowtable_alloc(int nentry, int flags)
 {
+	INIT_VNET_NET(curvnet);
 	struct flowtable *ft, *fttail;
 	int i;
 
-	if (hashjitter == 0)
-		hashjitter = arc4random();
+	if (V_flow_hashjitter == 0)
+		V_flow_hashjitter = arc4random();
 
 	KASSERT(nentry > 0, ("nentry must be > 0, is %d\n", nentry));
 
@@ -752,10 +775,10 @@
 	/*
 	 * hook in to the cleaner list
 	 */
-	if (flow_list_head == NULL)
-		flow_list_head = ft;
+	if (V_flow_list_head == NULL)
+		V_flow_list_head = ft;
 	else {
-		fttail = flow_list_head;
+		fttail = V_flow_list_head;
 		while (fttail->ft_next != NULL)
 			fttail = fttail->ft_next;
 		fttail->ft_next = ft;
@@ -768,13 +791,38 @@
 flowtable_setup(void *arg)
 {
 
-	ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), NULL,
+#ifndef VIMAGE_GLOBALS
+	vnet_mod_register(&flowtable_modinfo);
+#else
+	flowtable_iattach(NULL);
+#endif
+}
+
+static int
+flowtable_iattach(const void *unused __unused)
+{
+	INIT_VNET_NET(curvnet);
+
+	V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), NULL,
 	    NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);
-	ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), NULL,
+	V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), NULL,
 	    NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);	
-	uma_zone_set_max(ipv4_zone, nmbflows);
-	uma_zone_set_max(ipv6_zone, nmbflows);
+	uma_zone_set_max(V_flow_ipv4_zone, nmbflows);
+	uma_zone_set_max(V_flow_ipv6_zone, nmbflows);
+	return (0);
+}
+
+#ifdef VIMAGE
+static int
+flowtable_idetach(const void *unused __unused)
+{
+	INIT_VNET_NET(curvnet);
+
+	uma_zdestroy(V_flow_ipv4_zone);
+	uma_zdestroy(V_flow_ipv6_zone);
+	return (0);
 }
+#endif
 
 SYSINIT(flowtable_setup, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_setup, NULL);
 
@@ -787,6 +835,7 @@
 static void
 fle_free(struct flentry *fle)
 {
+	INIT_VNET_NET(curvnet);
 	struct rtentry *rt;
 	struct llentry *lle;
 
@@ -794,7 +843,7 @@
 	lle = __DEVOLATILE(struct llentry *, fle->f_lle);
 	RTFREE(rt);
 	LLE_FREE(lle);
-	uma_zfree((fle->f_flags & FL_IPV6) ? ipv6_zone : ipv4_zone, fle);
+	uma_zfree((fle->f_flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone, fle);
 }
 
 static void
@@ -885,36 +934,52 @@
 }
 
 static void
-flowtable_cleaner(void)
+flowtable_clean_vnet(void)
 {
+	INIT_VNET_NET(curvnet);
 	struct flowtable *ft;
 	int i;
 
-	if (bootverbose)
-		log(LOG_INFO, "flowtable cleaner started\n");
-	while (1) {
-		ft = flow_list_head;
-		while (ft != NULL) {
-			if (ft->ft_flags & FL_PCPU) {
-				for (i = 0; i <= mp_maxid; i++) {
-					if (CPU_ABSENT(i))
-						continue;
+	ft = V_flow_list_head;
+	while (ft != NULL) {
+		if (ft->ft_flags & FL_PCPU) {
+			for (i = 0; i <= mp_maxid; i++) {
+				if (CPU_ABSENT(i))
+					continue;
 
-					thread_lock(curthread);
-					sched_bind(curthread, i);
-					thread_unlock(curthread);
+				thread_lock(curthread);
+				sched_bind(curthread, i);
+				thread_unlock(curthread);
 
-					flowtable_free_stale(ft);
+				flowtable_free_stale(ft);
 
-					thread_lock(curthread);
-					sched_unbind(curthread);
-					thread_unlock(curthread);
-				}
-			} else {
-				flowtable_free_stale(ft);
+				thread_lock(curthread);
+				sched_unbind(curthread);
+				thread_unlock(curthread);
 			}
-			ft = ft->ft_next;
+		} else {
+			flowtable_free_stale(ft);
+		}
+		ft = ft->ft_next;
+	}
+}
+
+static void
+flowtable_cleaner(void)
+{
+	VNET_ITERATOR_DECL(vnet_iter);
+
+	if (bootverbose)
+		log(LOG_INFO, "flowtable cleaner started\n");
+	while (1) {
+		VNET_LIST_RLOCK();
+		VNET_FOREACH(vnet_iter) {
+			CURVNET_SET(vnet_iter);
+			flowtable_clean_vnet();
+			CURVNET_RESTORE();
 		}
+		VNET_LIST_RUNLOCK();
+
 		/*
 		 * The 20 second interval between cleaning checks
 		 * is arbitrary

==== //depot/projects/vimage-commit2/src/sys/net/flowtable.h#5 (text+ko) ====


==== //depot/projects/vimage-commit2/src/sys/net/vnet.h#23 (text+ko) ====

@@ -53,6 +53,11 @@
 	struct if_clone *	_lo_cloner;
 	struct ifc_simple_data *_lo_cloner_data;
 
+	struct flowtable *	_flow_list_head;
+	uint32_t		_flow_hashjitter;
+	uma_zone_t		_flow_ipv4_zone;
+	uma_zone_t		_flow_ipv6_zone;
+
 	LIST_HEAD(, rawcb)	_rawcb_list;
 
 	LIST_HEAD(, if_clone)	_if_cloners;
@@ -79,6 +84,10 @@
 #define	VNET_NET(sym)	VSYM(vnet_net, sym)
 
 #define	V_ether_ipfw		VNET_NET(ether_ipfw)
+#define V_flow_hashjitter	VNET_NET(flow_hashjitter)
+#define V_flow_ipv4_zone	VNET_NET(flow_ipv4_zone)
+#define V_flow_ipv6_zone	VNET_NET(flow_ipv6_zone)
+#define V_flow_list_head	VNET_NET(flow_list_head)
 #define	V_if_index		VNET_NET(if_index)
 #define	V_if_indexlim		VNET_NET(if_indexlim)
 #define	V_if_cloners		VNET_NET(if_cloners)

==== //depot/projects/vimage-commit2/src/sys/sys/vimage.h#73 (text+ko) ====

@@ -122,6 +122,7 @@
 #define	VNET_MOD_MLD		13
 
 /* Stateless modules. */
+#define	VNET_MOD_FLOWTABLE	18
 #define	VNET_MOD_IF_CLONE	19
 #define	VNET_MOD_NG_ETHER	20
 #define	VNET_MOD_NG_IFACE	21


More information about the p4-projects mailing list