Date: Thu, 18 Jun 2009 16:50:29 GMT From: Marko Zec <zec@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 164673 for review Message-ID: <200906181650.n5IGoTgF053123@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=164673 Change 164673 by zec@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 21help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906181650.n5IGoTgF053123>
