diff options
author | Mark Johnston <markj@FreeBSD.org> | 2017-03-15 00:29:27 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2017-03-15 00:29:27 +0000 |
commit | 7d88be4c0302595347b962484e59449609fdc668 (patch) | |
tree | 940d4a6e446da3c037edf82d4c2e5cb6ef32c3b8 /sys/kern/kern_timeout.c | |
parent | 5e88838850a399ae1434c7a535dcf4dbc776dd1d (diff) | |
download | src-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.c | 8 |
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)) { |