diff -r 243ff612f6cd -r c7137074391a sys/netinet/cc/cc.c --- a/sys/netinet/cc/cc.c Sun Nov 14 13:13:13 2010 +1100 +++ b/sys/netinet/cc/cc.c Sun Nov 14 15:46:25 2010 +1100 @@ -193,6 +193,7 @@ struct tcpcb *tp; struct inpcb *inp; int err; + VNET_ITERATOR_DECL(vnet_iter); err = ENOENT; @@ -218,12 +219,13 @@ } } CC_LIST_WUNLOCK(); - + if (!err) { /* - * Check all active control blocks and change any that are - * using this algorithm back to newreno. If the algorithm that - * was in use requires cleanup code to be run, call it. + * Check all active control blocks across all network stacks and + * change any that are using this algorithm back to newreno. If + * the algorithm that was in use requires cleanup code to be + * run, call it. * * New connections already part way through being initialised * with the CC algo we're removing will not race with this code @@ -231,30 +233,39 @@ * We therefore don't enter the loop below until the connection * list has stabilised. */ - INP_INFO_RLOCK(&V_tcbinfo); - LIST_FOREACH(inp, &V_tcb, inp_list) { - INP_WLOCK(inp); - /* Important to skip tcptw structs. */ - if (!(inp->inp_flags & INP_TIMEWAIT) && - (tp = intotcpcb(inp)) != NULL) { - /* - * By holding INP_WLOCK here, we are - * assured that the connection is not - * currently executing inside the CC - * module's functions i.e. it is safe to - * make the switch back to newreno. - */ - if (CC_ALGO(tp) == remove_cc) { - tmpfuncs = CC_ALGO(tp); - /* Newreno does not require any init. */ - CC_ALGO(tp) = &newreno_cc_algo; - if (tmpfuncs->cb_destroy != NULL) - tmpfuncs->cb_destroy(tp->ccv); + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + INP_INFO_RLOCK(&V_tcbinfo); + LIST_FOREACH(inp, &V_tcb, inp_list) { + INP_WLOCK(inp); + /* Important to skip tcptw structs. */ + if (!(inp->inp_flags & INP_TIMEWAIT) && + (tp = intotcpcb(inp)) != NULL) { + /* + * By holding INP_WLOCK here, we are + * assured that the connection is not + * currently executing inside the CC + * module's functions i.e. it is safe + * to make the switch back to newreno. + */ + if (CC_ALGO(tp) == remove_cc) { + tmpfuncs = CC_ALGO(tp); + /* + * Newreno does not + * require any init. + */ + CC_ALGO(tp) = &newreno_cc_algo; + if (tmpfuncs->cb_destroy != NULL) + tmpfuncs->cb_destroy(tp->ccv); + } } + INP_WUNLOCK(inp); } - INP_WUNLOCK(inp); + INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); } - INP_INFO_RUNLOCK(&V_tcbinfo); + VNET_LIST_RUNLOCK(); } return (err);