Author: bz
Date: Sat Jan  8 22:08:23 2011
New Revision: 217168
URL: http://svn.freebsd.org/changeset/base/217168

Log:
  MFC r216855:
  
    Move the increment operation under the lock and split the condition
    variable into two so that we can see on which one we are waiting.
    This might also more properly propagate the update of the
    flowclean_cycles flag and avoid "hangs" people were seeing.
  
    Suggested by: rwatson [1]
    Sponsored by: ISPsystem [1]
    Reviewed by:  julian [1]
    Updated by:   Mikolaj Golub (to.my.trociny gmail.com)
    Tested by:    Mikolaj Golub (to.my.trociny gmail.com)
  
    [1] Early 2010, initial version.

Modified:
  stable/8/sys/net/flowtable.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/net/flowtable.c
==============================================================================
--- stable/8/sys/net/flowtable.c        Sat Jan  8 21:37:43 2011        
(r217167)
+++ stable/8/sys/net/flowtable.c        Sat Jan  8 22:08:23 2011        
(r217168)
@@ -195,7 +195,8 @@ static VNET_DEFINE(uma_zone_t, flow_ipv6
 #define        V_flow_ipv6_zone        VNET(flow_ipv6_zone)
 
 
-static struct cv       flowclean_cv;
+static struct cv       flowclean_f_cv;
+static struct cv       flowclean_c_cv;
 static struct mtx      flowclean_lock;
 static uint32_t                flowclean_cycles;
 static uint32_t                flowclean_freq;
@@ -954,7 +955,7 @@ flow_full(struct flowtable *ft)
                if ((ft->ft_flags & FL_HASH_ALL) == 0)
                        ft->ft_udp_idle = ft->ft_fin_wait_idle =
                            ft->ft_syn_idle = ft->ft_tcp_idle = 5;
-               cv_broadcast(&flowclean_cv);
+               cv_broadcast(&flowclean_c_cv);
        } else if (!full && ft->ft_full) {
                flowclean_freq = 20*hz;
                if ((ft->ft_flags & FL_HASH_ALL) == 0)
@@ -1567,14 +1568,14 @@ flowtable_cleaner(void)
                }
                VNET_LIST_RUNLOCK();
 
-               flowclean_cycles++;
                /*
                 * The 10 second interval between cleaning checks
                 * is arbitrary
                 */
                mtx_lock(&flowclean_lock);
-               cv_broadcast(&flowclean_cv);
-               cv_timedwait(&flowclean_cv, &flowclean_lock, flowclean_freq);
+               flowclean_cycles++;
+               cv_broadcast(&flowclean_f_cv);
+               cv_timedwait(&flowclean_c_cv, &flowclean_lock, flowclean_freq);
                mtx_unlock(&flowclean_lock);
        }
 }
@@ -1587,8 +1588,8 @@ flowtable_flush(void *unused __unused)
        mtx_lock(&flowclean_lock);
        start = flowclean_cycles;
        while (start == flowclean_cycles) {
-               cv_broadcast(&flowclean_cv);
-               cv_wait(&flowclean_cv, &flowclean_lock);
+               cv_broadcast(&flowclean_c_cv);
+               cv_wait(&flowclean_f_cv, &flowclean_lock);
        }
        mtx_unlock(&flowclean_lock);
 }
@@ -1620,7 +1621,8 @@ static void
 flowtable_init(const void *unused __unused)
 {
 
-       cv_init(&flowclean_cv, "flowcleanwait");
+       cv_init(&flowclean_c_cv, "c_flowcleanwait");
+       cv_init(&flowclean_f_cv, "f_flowcleanwait");
        mtx_init(&flowclean_lock, "flowclean lock", NULL, MTX_DEF);
        EVENTHANDLER_REGISTER(ifnet_departure_event, flowtable_flush, NULL,
            EVENTHANDLER_PRI_ANY);
_______________________________________________
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