From 378d5c6c8931fca5554737b391fa2a55929305b1 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 1 Sep 2015 09:27:14 +0000 Subject: [PATCH] callout_reset: fix a reversed check for cc_exec_cancel The typo was introduced in r278469 / 344ecf88af2dfb. As a result of the bug there was a timing window where callout_reset() would fail to cancel a concurrent execution of a callout that is about to start and would schedule the callout again. The callout would fire more times than it is scheduled. That would happen even if the callout is initialized with a lock. For example, the bug triggered the "Stray timeout" assertion in taskqueue_timeout_func(). MFC after: 5 days --- sys/kern/kern_timeout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 01da596643d3..71c88e0290b9 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -1032,7 +1032,7 @@ callout_reset_sbt_on(struct callout *c, sbintime_t sbt, sbintime_t precision, * currently in progress. If there is a lock then we * can cancel the callout if it has not really started. */ - if (c->c_lock != NULL && cc_exec_cancel(cc, direct)) + if (c->c_lock != NULL && !cc_exec_cancel(cc, direct)) cancelled = cc_exec_cancel(cc, direct) = true; if (cc_exec_waiting(cc, direct)) { /*