Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Mar 2017 00:29:28 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r315289 - head/sys/kern
Message-ID:  <201703150029.v2F0TSSE031684@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)) {
 			



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703150029.v2F0TSSE031684>