Author: markj
Date: Wed Mar 15 00:29:27 2017
New Revision: 315289
URL: https://svnweb.freebsd.org/changeset/base/315289

Log:
  When draining a callout, don't clear CALLOUT_ACTIVE while it is running.
  
  The callout may reschedule itself and execute again before callout_drain()
  returns, but we should not clear CALLOUT_ACTIVE until the callout is
  stopped.
  
  Tested by:    pho
  MFC after:    2 weeks
  Sponsored by: Dell EMC Isilon

Modified:
  head/sys/kern/kern_timeout.c

Modified: head/sys/kern/kern_timeout.c
==============================================================================
--- head/sys/kern/kern_timeout.c        Tue Mar 14 22:25:07 2017        
(r315288)
+++ head/sys/kern/kern_timeout.c        Wed Mar 15 00:29:27 2017        
(r315289)
@@ -1254,9 +1254,12 @@ again:
        if (cc_exec_curr(cc, direct) == c) {
                /*
                 * Succeed we to stop it or not, we must clear the
-                * active flag - this is what API users expect.
+                * active flag - this is what API users expect.  If we're
+                * draining and the callout is currently executing, first wait
+                * until it finishes.
                 */
-               c->c_flags &= ~CALLOUT_ACTIVE;
+               if ((flags & CS_DRAIN) == 0)
+                       c->c_flags &= ~CALLOUT_ACTIVE;
 
                if ((flags & CS_DRAIN) != 0) {
                        /*
@@ -1315,6 +1318,7 @@ again:
                                PICKUP_GIANT();
                                CC_LOCK(cc);
                        }
+                       c->c_flags &= ~CALLOUT_ACTIVE;
                } else if (use_lock &&
                           !cc_exec_cancel(cc, direct) && (drain == NULL)) {
                        
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to