diff options
author | zec <zec@FreeBSD.org> | 2009-05-05 10:56:12 +0000 |
---|---|---|
committer | zec <zec@FreeBSD.org> | 2009-05-05 10:56:12 +0000 |
commit | d78a1b1a824c4f5eb8cb3583bb5265f73dcc24dd (patch) | |
tree | 79a0bccccf2c92504cdf23ad15f7c1813bb3f926 /sys/netinet | |
parent | 8e4ffe653f6c9ff6da3eed58566ef35e77d530d0 (diff) | |
download | FreeBSD-src-d78a1b1a824c4f5eb8cb3583bb5265f73dcc24dd.zip FreeBSD-src-d78a1b1a824c4f5eb8cb3583bb5265f73dcc24dd.tar.gz |
Change the curvnet variable from a global const struct vnet *,
previously always pointing to the default vnet context, to a
dynamically changing thread-local one. The currvnet context
should be set on entry to networking code via CURVNET_SET() macros,
and reverted to previous state via CURVNET_RESTORE(). Recursions
on curvnet are permitted, though strongly discuouraged.
This change should have no functional impact on nooptions VIMAGE
kernel builds, where CURVNET_* macros expand to whitespace.
The curthread->td_vnet (aka curvnet) variable's purpose is to be an
indicator of the vnet context in which the current network-related
operation takes place, in case we cannot deduce the current vnet
context from any other source, such as by looking at mbuf's
m->m_pkthdr.rcvif->if_vnet, sockets's so->so_vnet etc. Moreover, so
far curvnet has turned out to be an invaluable consistency checking
aid: it helps to catch cases when sockets, ifnets or any other
vnet-aware structures may have leaked from one vnet to another.
The exact placement of the CURVNET_SET() / CURVNET_RESTORE() macros
was a result of an empirical iterative process, whith an aim to
reduce recursions on CURVNET_SET() to a minimum, while still reducing
the scope of CURVNET_SET() to networking only operations - the
alternative would be calling CURVNET_SET() on each system call entry.
In general, curvnet has to be set in three typicall cases: when
processing socket-related requests from userspace or from within the
kernel; when processing inbound traffic flowing from device drivers
to upper layers of the networking stack, and when executing
timer-driven networking functions.
This change also introduces a DDB subcommand to show the list of all
vnet instances.
Approved by: julian (mentor)
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/if_ether.c | 2 | ||||
-rw-r--r-- | sys/netinet/igmp.c | 7 | ||||
-rw-r--r-- | sys/netinet/in_rmx.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 2 | ||||
-rw-r--r-- | sys/netinet/tcp_hostcache.c | 6 |
5 files changed, 14 insertions, 9 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 38e420e..d24b459 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -143,10 +143,12 @@ arp_ifscrub(struct ifnet *ifp, uint32_t addr) addr4.sin_len = sizeof(addr4); addr4.sin_family = AF_INET; addr4.sin_addr.s_addr = addr; + CURVNET_SET(ifp->if_vnet); IF_AFDATA_LOCK(ifp); lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR), (struct sockaddr *)&addr4); IF_AFDATA_UNLOCK(ifp); + CURVNET_RESTORE(); } #endif diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 2bbd10d..3fb3711 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1117,6 +1117,9 @@ igmp_input_v3_group_query(struct in_multi *inm, struct igmp_ifinfo *igi, nsrc = ntohs(igmpv3->igmp_numsrc); + if (!IS_DEFAULT_VNET(curvnet)) + return (retval); + /* * Deal with group-specific queries upfront. * If any group query is already pending, purge any recorded @@ -3372,7 +3375,7 @@ igmp_intr(struct mbuf *m) * indexes to guard against interface detach, they are * unique to each VIMAGE and must be retrieved. */ - CURVNET_SET(m->m_pkthdr.header); + CURVNET_SET((struct vnet *)(m->m_pkthdr.header)); INIT_VNET_NET(curvnet); INIT_VNET_INET(curvnet); ifindex = igmp_restore_context(m); @@ -3654,9 +3657,7 @@ igmp_modevent(module_t mod, int type, void *unused __unused) break; case MOD_UNLOAD: #ifndef VIMAGE_GLOBALS -#ifdef NOTYET vnet_mod_deregister(&vnet_igmp_modinfo); -#endif #else vnet_igmp_idetach(NULL); #endif diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index 695f473..19cd5fb 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -250,14 +250,13 @@ static void in_rtqtimo_one(void *rock); static void in_rtqtimo(void *rock) { + CURVNET_SET((struct vnet *) rock); INIT_VNET_NET(curvnet); INIT_VNET_INET(curvnet); int fibnum; void *newrock; struct timeval atv; - KASSERT((rock == (void *)V_rt_tables[0][AF_INET]), - ("in_rtqtimo: unexpected arg")); for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { if ((newrock = V_rt_tables[fibnum][AF_INET]) != NULL) in_rtqtimo_one(newrock); @@ -265,6 +264,7 @@ in_rtqtimo(void *rock) atv.tv_usec = 0; atv.tv_sec = V_rtq_timeout; callout_reset(&V_rtq_timer, tvtohz(&atv), in_rtqtimo, rock); + CURVNET_RESTORE(); } static void @@ -377,7 +377,7 @@ in_inithead(void **head, int off) rnh->rnh_close = in_clsroute; if (_in_rt_was_here == 0 ) { callout_init(&V_rtq_timer, CALLOUT_MPSAFE); - in_rtqtimo(rnh); /* kick off timeout first time */ + callout_reset(&V_rtq_timer, 1, in_rtqtimo, curvnet); _in_rt_was_here = 1; } return 1; diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7ee5a13..973c392 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -339,7 +339,7 @@ ip_init(void) /* Start ipport_tick. */ callout_init(&ipport_tick_callout, CALLOUT_MPSAFE); - ipport_tick(NULL); + callout_reset(&ipport_tick_callout, 1, ipport_tick, NULL); EVENTHANDLER_REGISTER(shutdown_pre_sync, ip_fini, NULL, SHUTDOWN_PRI_DEFAULT); EVENTHANDLER_REGISTER(nmbclusters_change, ipq_zone_change, diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c index 71f4626..84586db 100644 --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -227,7 +227,7 @@ tcp_hc_init(void) */ callout_init(&V_tcp_hc_callout, CALLOUT_MPSAFE); callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz, - tcp_hc_purge, 0); + tcp_hc_purge, curvnet); } /* @@ -634,9 +634,10 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) static void tcp_hc_purge(void *arg) { + CURVNET_SET((struct vnet *) arg); INIT_VNET_INET(curvnet); struct hc_metrics *hc_entry, *hc_next; - int all = (intptr_t)arg; + int all = 0; /* XXX was: (intptr_t)arg - makes no sense? */ int i; if (V_tcp_hostcache.purgeall) { @@ -662,4 +663,5 @@ tcp_hc_purge(void *arg) callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz, tcp_hc_purge, arg); + CURVNET_RESTORE(); } |