BUG/MEDIUM: stick-tables: don't loop on non-expirable entries

The stick-table expiration of ref-counted entries was insufficiently
addresse by commit 324f0a60ab ("BUG/MINOR: stick-tables: never leave
used entries without expiration"), because now entries are just requeued
where they were, so they're visited over and over for long sessions,
causing process_table_expire() to loop, eating CPU and causing lock
contention.

Here we take care of refreshing their timeer when they are met, so
that we don't meet them more than once per stick-table lifetime. It
should address at least a part of the recent degradation that Felipe
noticed in GH #3084.

Since the fix above was marked for backporting to 3.2, this one should
be backported there as well.
This commit is contained in:
Willy Tarreau 2025-09-10 11:27:27 +02:00
parent 997d217dee
commit 993c09438b

View File

@ -988,8 +988,17 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
*/ */
eb32_delete(&ts->exp); eb32_delete(&ts->exp);
if (!tick_is_expired(ts->expire, now_ms) || HA_ATOMIC_LOAD(&ts->ref_cnt) != 0) { if (HA_ATOMIC_LOAD(&ts->ref_cnt) != 0) {
requeue: requeue:
/* we can't trash this entry yet because it's in use,
* so we must refresh it with the table's lifetime to
* postpone its expiration.
*/
if (tick_is_expired(ts->expire, now_ms))
ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
}
if (!tick_is_expired(ts->expire, now_ms)) {
if (!tick_isset(ts->expire)) if (!tick_isset(ts->expire))
continue; continue;