aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_timeout.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2017-03-15 00:29:27 +0000
committerMark Johnston <markj@FreeBSD.org>2017-03-15 00:29:27 +0000
commit7d88be4c0302595347b962484e59449609fdc668 (patch)
tree940d4a6e446da3c037edf82d4c2e5cb6ef32c3b8 /sys/kern/kern_timeout.c
parent5e88838850a399ae1434c7a535dcf4dbc776dd1d (diff)
downloadsrc-7d88be4c0302595347b962484e59449609fdc668.tar.gz
src-7d88be4c0302595347b962484e59449609fdc668.zip
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
Notes
Notes: svn path=/head/; revision=315289
Diffstat (limited to 'sys/kern/kern_timeout.c')
-rw-r--r--sys/kern/kern_timeout.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 5b70cf2033f5..f4ff571eff2d 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -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)) {