From owner-svn-src-head@FreeBSD.ORG Tue Nov 16 09:34:32 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 56CA01065672; Tue, 16 Nov 2010 09:34:32 +0000 (UTC) (envelope-from lstewart@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 089C88FC16; Tue, 16 Nov 2010 09:34:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAG9YVA3047278; Tue, 16 Nov 2010 09:34:31 GMT (envelope-from lstewart@svn.freebsd.org) Received: (from lstewart@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAG9YV4V047275; Tue, 16 Nov 2010 09:34:31 GMT (envelope-from lstewart@svn.freebsd.org) Message-Id: <201011160934.oAG9YV4V047275@svn.freebsd.org> From: Lawrence Stewart Date: Tue, 16 Nov 2010 09:34:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215395 - in head/sys/netinet: . cc X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Nov 2010 09:34:33 -0000 Author: lstewart Date: Tue Nov 16 09:34:31 2010 New Revision: 215395 URL: http://svn.freebsd.org/changeset/base/215395 Log: Make the CC framework more VIMAGE friendly by adding the machinery to allow vnets to select their own default CC algorithm independent of each other and the base system. If the base system or a vnet has set a default which gets unloaded, we reset that netstack's default to NewReno. Sponsored by: FreeBSD Foundation Tested by: Mikolaj Golub Reviewed by: bz (briefly) MFC after: 3 months Modified: head/sys/netinet/cc.h head/sys/netinet/cc/cc.c Modified: head/sys/netinet/cc.h ============================================================================== --- head/sys/netinet/cc.h Tue Nov 16 09:01:19 2010 (r215394) +++ head/sys/netinet/cc.h Tue Nov 16 09:34:31 2010 (r215395) @@ -58,6 +58,10 @@ extern STAILQ_HEAD(cc_head, cc_algo) cc_ extern const int tcprexmtthresh; extern struct cc_algo newreno_cc_algo; +/* Per-netstack bits. */ +VNET_DECLARE(struct cc_algo *, default_cc_ptr); +#define V_default_cc_ptr VNET(default_cc_ptr) + /* Define the new net.inet.tcp.cc sysctl tree. */ SYSCTL_DECL(_net_inet_tcp_cc); @@ -146,7 +150,7 @@ struct cc_algo { #define CC_DATA(tp) ((tp)->ccv->cc_data) /* Macro to obtain the system default CC algo's struct ptr. */ -#define CC_DEFAULT() STAILQ_FIRST(&cc_list) +#define CC_DEFAULT() V_default_cc_ptr extern struct rwlock cc_list_lock; #define CC_LIST_LOCK_INIT() rw_init(&cc_list_lock, "cc_list") @@ -155,6 +159,6 @@ extern struct rwlock cc_list_lock; #define CC_LIST_RUNLOCK() rw_runlock(&cc_list_lock) #define CC_LIST_WLOCK() rw_wlock(&cc_list_lock) #define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock) -#define CC_LIST_WLOCK_ASSERT() rw_assert(&cc_list_lock, RA_WLOCKED) +#define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED) #endif /* _NETINET_CC_H_ */ Modified: head/sys/netinet/cc/cc.c ============================================================================== --- head/sys/netinet/cc/cc.c Tue Nov 16 09:01:19 2010 (r215394) +++ head/sys/netinet/cc/cc.c Tue Nov 16 09:34:31 2010 (r215395) @@ -81,24 +81,7 @@ struct cc_head cc_list = STAILQ_HEAD_INI /* Protects the cc_list TAILQ. */ struct rwlock cc_list_lock; -/* - * Set the default CC algorithm to new_default. The default is identified - * by being the first element in the cc_list TAILQ. - */ -static void -cc_set_default(struct cc_algo *new_default) -{ - CC_LIST_WLOCK_ASSERT(); - - /* - * Make the requested system default CC algorithm the first element in - * the list if it isn't already. - */ - if (new_default != CC_DEFAULT()) { - STAILQ_REMOVE(&cc_list, new_default, cc_algo, entries); - STAILQ_INSERT_HEAD(&cc_list, new_default, entries); - } -} +VNET_DEFINE(struct cc_algo *, default_cc_ptr) = &newreno_cc_algo; /* * Sysctl handler to show and change the default CC algorithm. @@ -120,15 +103,15 @@ cc_default_algo(SYSCTL_HANDLER_ARGS) err = sysctl_handle_string(oidp, default_cc, 1, req); } else { /* Find algo with specified name and set it to default. */ - CC_LIST_WLOCK(); + CC_LIST_RLOCK(); STAILQ_FOREACH(funcs, &cc_list, entries) { if (strncmp((char *)req->newptr, funcs->name, TCP_CA_NAME_MAX) == 0) { found = 1; - cc_set_default(funcs); + V_default_cc_ptr = funcs; } } - CC_LIST_WUNLOCK(); + CC_LIST_RUNLOCK(); if (!found) err = ESRCH; @@ -173,6 +156,28 @@ cc_list_available(SYSCTL_HANDLER_ARGS) } /* + * Reset the default CC algo to NewReno for any netstack which is using the algo + * that is about to go away as its default. + */ +static void +cc_checkreset_default(struct cc_algo *remove_cc) +{ + VNET_ITERATOR_DECL(vnet_iter); + + CC_LIST_LOCK_ASSERT(); + + VNET_LIST_RLOCK_NOSLEEP(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + if (strncmp(CC_DEFAULT()->name, remove_cc->name, + TCP_CA_NAME_MAX) == 0) + V_default_cc_ptr = &newreno_cc_algo; + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK_NOSLEEP(); +} + +/* * Initialise CC subsystem on system boot. */ static void @@ -201,14 +206,7 @@ cc_deregister_algo(struct cc_algo *remov CC_LIST_WLOCK(); STAILQ_FOREACH_SAFE(funcs, &cc_list, entries, tmpfuncs) { if (funcs == remove_cc) { - /* - * If we're removing the current system default, - * reset the default to newreno. - */ - if (strncmp(CC_DEFAULT()->name, remove_cc->name, - TCP_CA_NAME_MAX) == 0) - cc_set_default(&newreno_cc_algo); - + cc_checkreset_default(remove_cc); STAILQ_REMOVE(&cc_list, funcs, cc_algo, entries); err = 0; break; @@ -302,7 +300,7 @@ SYSINIT(cc, SI_SUB_PROTO_IFATTACHDOMAIN, SYSCTL_NODE(_net_inet_tcp, OID_AUTO, cc, CTLFLAG_RW, NULL, "congestion control related settings"); -SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, algorithm, CTLTYPE_STRING|CTLFLAG_RW, +SYSCTL_VNET_PROC(_net_inet_tcp_cc, OID_AUTO, algorithm, CTLTYPE_STRING|CTLFLAG_RW, NULL, 0, cc_default_algo, "A", "default congestion control algorithm"); SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, available, CTLTYPE_STRING|CTLFLAG_RD,