Author: lstewart
Date: Tue Nov 16 08:30:39 2010
New Revision: 215392
URL: http://svn.freebsd.org/changeset/base/215392

Log:
  Move protocol specific implementation detail out of the core CC framework.
  
  Sponsored by: FreeBSD Foundation
  Tested by:    Mikolaj Golub <to.my.trociny at gmail com>
  MFC after:    11 weeks
  X-MFC with:   r215166

Modified:
  head/sys/netinet/cc/cc.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_var.h

Modified: head/sys/netinet/cc/cc.c
==============================================================================
--- head/sys/netinet/cc/cc.c    Tue Nov 16 07:57:56 2010        (r215391)
+++ head/sys/netinet/cc/cc.c    Tue Nov 16 08:30:39 2010        (r215392)
@@ -190,10 +190,7 @@ int
 cc_deregister_algo(struct cc_algo *remove_cc)
 {
        struct cc_algo *funcs, *tmpfuncs;
-       struct tcpcb *tp;
-       struct inpcb *inp;
        int err;
-       VNET_ITERATOR_DECL(vnet_iter);
 
        err = ENOENT;
 
@@ -220,53 +217,14 @@ cc_deregister_algo(struct cc_algo *remov
        }
        CC_LIST_WUNLOCK();
        
-       if (!err) {
+       if (!err)
                /*
-                * 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
-                * because the INP_INFO_WLOCK is held during initialisation.
-                * We therefore don't enter the loop below until the connection
-                * list has stabilised.
+                * XXXLAS:
+                * - We may need to handle non-zero return values in future.
+                * - If we add CC framework support for protocols other than
+                *   TCP, we may want a more generic way to handle this step.
                 */
-               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_INFO_RUNLOCK(&V_tcbinfo);
-                       CURVNET_RESTORE();
-               }
-               VNET_LIST_RUNLOCK();
-       }
+               tcp_ccalgounload(remove_cc);
 
        return (err);
 }

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c Tue Nov 16 07:57:56 2010        (r215391)
+++ head/sys/netinet/tcp_subr.c Tue Nov 16 08:30:39 2010        (r215392)
@@ -708,6 +708,69 @@ tcp_newtcpcb(struct inpcb *inp)
 }
 
 /*
+ * Switch the congestion control algorithm back to NewReno for any active
+ * control blocks using an algorithm which is about to go away.
+ * This ensures the CC framework can allow the unload to proceed without 
leaving
+ * any dangling pointers which would trigger a panic.
+ * Returning non-zero would inform the CC framework that something went wrong
+ * and it would be unsafe to allow the unload to proceed. However, there is no
+ * way for this to occur with this implementation so we always return zero.
+ */
+int
+tcp_ccalgounload(struct cc_algo *unload_algo)
+{
+       struct cc_algo *tmpalgo;
+       struct inpcb *inp;
+       struct tcpcb *tp;
+       VNET_ITERATOR_DECL(vnet_iter);
+
+       /*
+        * Check all active control blocks across all network stacks and change
+        * any that are using "unload_algo" back to NewReno. If "unload_algo"
+        * requires cleanup code to be run, call it.
+        */
+       VNET_LIST_RLOCK();
+       VNET_FOREACH(vnet_iter) {
+               CURVNET_SET(vnet_iter);
+               INP_INFO_RLOCK(&V_tcbinfo);
+               /*
+                * New connections already part way through being initialised
+                * with the CC algo we're removing will not race with this code
+                * because the INP_INFO_WLOCK is held during initialisation. We
+                * therefore don't enter the loop below until the connection
+                * list has stabilised.
+                */
+               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) == unload_algo) {
+                                       tmpalgo = CC_ALGO(tp);
+                                       /* NewReno does not require any init. */
+                                       CC_ALGO(tp) = &newreno_cc_algo;
+                                       if (tmpalgo->cb_destroy != NULL)
+                                               tmpalgo->cb_destroy(tp->ccv);
+                               }
+                       }
+                       INP_WUNLOCK(inp);
+               }
+               INP_INFO_RUNLOCK(&V_tcbinfo);
+               CURVNET_RESTORE();
+       }
+       VNET_LIST_RUNLOCK();
+
+       return (0);
+}
+
+/*
  * Drop a TCP connection, reporting
  * the specified error.  If connection is synchronized,
  * then send a RST to peer.

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h  Tue Nov 16 07:57:56 2010        (r215391)
+++ head/sys/netinet/tcp_var.h  Tue Nov 16 08:30:39 2010        (r215392)
@@ -605,6 +605,7 @@ VNET_DECLARE(int, tcp_ecn_maxretries);
 #define        V_tcp_ecn_maxretries    VNET(tcp_ecn_maxretries)
 
 int     tcp_addoptions(struct tcpopt *, u_char *);
+int     tcp_ccalgounload(struct cc_algo *unload_algo);
 struct tcpcb *
         tcp_close(struct tcpcb *);
 void    tcp_discardcb(struct tcpcb *);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to