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