summaryrefslogtreecommitdiffstats
path: root/sys/netinet/cc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/cc')
-rw-r--r--sys/netinet/cc/cc.c58
1 files changed, 28 insertions, 30 deletions
diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c
index dc50cda..f075327 100644
--- a/sys/netinet/cc/cc.c
+++ b/sys/netinet/cc/cc.c
@@ -81,24 +81,7 @@ struct cc_head cc_list = STAILQ_HEAD_INITIALIZER(cc_list);
/* 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 *remove_cc)
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, SI_ORDER_FIRST, cc_init, NULL);
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,
OpenPOWER on IntegriCloud