BUG/MINOR: stick-table: make sure never to miss a process_table_expire update

In stktable_requeue_exp(), there's a tiny race at the beginning during
which we check the task's expiration date to decide whether or not to
wake process_table_expire() up. During this race, the task might just
have finished running on its owner thread and we can miss a task_queue()
opportunity, which probably explains why during testing it seldom happens
that a few entries are left at the end.

Let's perform a CAS to confirm the value is still the same before
leaving. This way we're certain that our value has been seen at least
once.

This should be backported to 3.2.
This commit is contained in:
Willy Tarreau 2025-09-10 18:45:01 +02:00
parent 2ce5e0edcc
commit 2831cb104f

View File

@ -724,14 +724,18 @@ void stktable_requeue_exp(struct stktable *t, const struct stksess *ts)
old_exp = HA_ATOMIC_LOAD(&t->exp_task->expire);
new_exp = tick_first(expire, old_exp);
/* let's not go further if we're already up to date */
if (new_exp == old_exp)
/* let's not go further if we're already up to date. We have
* to make sure the compared date doesn't change under us.
*/
if (new_exp == old_exp &&
HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp))
return;
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
while (new_exp != old_exp &&
!HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp)) {
while (!HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp)) {
if (new_exp == old_exp)
break;
__ha_cpu_relax();
new_exp = tick_first(expire, old_exp);
}