When a sticky session is killed, we must be sure no other entity is still
referencing it. The session's ref_cnt must be 0. However, there is a race
with peers, as decribed in
21447b1dd4 ("BUG/MAJOR: stick-tables: fix race
with peers in entry expiration"). When the update lock is acquire, we must
recheck the ref_cnt value.
This patch is part of a debugging session about issue #2552. It must be
backported to 2.9.
*/
int __stksess_kill(struct stktable *t, struct stksess *ts)
{
+ int updt_locked = 0;
+
if (HA_ATOMIC_LOAD(&ts->ref_cnt))
return 0;
- eb32_delete(&ts->exp);
if (ts->upd.node.leaf_p) {
+ updt_locked = 1;
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
- eb32_delete(&ts->upd);
- HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ if (HA_ATOMIC_LOAD(&ts->ref_cnt))
+ goto out_unlock;
}
+ eb32_delete(&ts->exp);
+ eb32_delete(&ts->upd);
ebmb_delete(&ts->key);
__stksess_free(t, ts);
+
+ out_unlock:
+ if (updt_locked)
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
return 1;
}