BUG/MEDIUM: stick-tables: fix a small remaining race in expiration task
In 2.7 we addressed a race condition in the stick tables expiration task with commit fbb934d ("BUG/MEDIUM: stick-table: fix a race condition when updating the expiration task"). The issue was that the task could be running on another thread which would destroy its expiration timer while one had just recalculated it and prepares to queue it, causing a bug due to the attempt to queue an expired task. The fix consisted in enclosing the change into the stick-table's lock, which had a very low cost since it's done only after having checked that the date changed, i.e. no more than once every millisecond. But as reported by Ricardo and Felipe from Taghos in github issue #2508, a tiny race remained after the fix: the unlock() was done before the call to task_queue(), leaving a tiny window for another thread to run between unlock() and task_queue() and erase the timer. As confirmed, it's sufficient to also protect the task_queue() call. But overall this raises a point regarding the task_queue() API on tasks that may run anywhere. A while ago an attempt was made at removing the timer for woken up tasks, but something like this would be deserved with more atomicity on the timer manipulation (e.g. atomically use task_schedule() instead maybe). This should be backported to all stable branches.
This commit is contained in:
parent
faa8c3e024
commit
5fc1afb341
@ -654,9 +654,9 @@ void stktable_requeue_exp(struct stktable *t, const struct stksess *ts)
|
||||
new_exp = tick_first(expire, old_exp);
|
||||
}
|
||||
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
task_queue(t->exp_task);
|
||||
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
/* Returns a valid or initialized stksess for the specified stktable_key in the
|
||||
|
Loading…
x
Reference in New Issue
Block a user