OPTIM: stick-tables: check the stksess without taking the read lock
Thanks to the previous commit, we can now simply perform an atomic read on stksess->seen and take the write lock to recreate the entry only if at least one peer has seen it, otherwise leave it untouched. On a test on 40 cores, the performance used to drop from 2.10 to 1.14M RPS when one peer was connected, now it drops to 2.05, thus there's basically no impact of connecting a peer vs ~45% previously, all spent in the read lock. This can be particularly important when often updating the same entries (user-agent, source address during an attack etc).
This commit is contained in:
parent
4c1480f13b
commit
864ac31174
@ -475,7 +475,7 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts)
|
||||
* The node will be also inserted into the update tree if needed, at a position
|
||||
* depending if the update is a local or coming from a remote node.
|
||||
* If <decrefcnt> is set, the ts entry's ref_cnt will be decremented. The table's
|
||||
* write lock may be taken.
|
||||
* updt_lock may be taken for writes.
|
||||
*/
|
||||
void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local, int expire, int decrefcnt)
|
||||
{
|
||||
@ -491,7 +491,6 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local,
|
||||
|
||||
/* If sync is enabled */
|
||||
if (t->sync_task) {
|
||||
try_lock_again:
|
||||
/* We'll need to reliably check that the entry is in the tree.
|
||||
* It's only inserted/deleted using a write lock so a read lock
|
||||
* is sufficient to verify this. We may then need to upgrade it
|
||||
@ -500,25 +499,15 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local,
|
||||
*/
|
||||
if (use_wrlock)
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
else
|
||||
HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
|
||||
if (local) {
|
||||
/* Check if this entry is not in the tree or not
|
||||
* scheduled for at least one peer.
|
||||
*/
|
||||
if (!ts->upd.node.leaf_p
|
||||
|| (int)(t->commitupdate - ts->upd.key) >= 0
|
||||
|| (int)(ts->upd.key - t->localupdate) >= 0) {
|
||||
if (!ts->upd.node.leaf_p || _HA_ATOMIC_LOAD(&ts->seen)) {
|
||||
/* Time to upgrade the read lock to write lock if needed */
|
||||
if (!use_wrlock) {
|
||||
if (HA_RWLOCK_TRYRDTOSK(STK_TABLE_LOCK, &t->updt_lock) != 0) {
|
||||
/* failed, try again */
|
||||
HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
use_wrlock = 1;
|
||||
goto try_lock_again;
|
||||
}
|
||||
HA_RWLOCK_SKTOWR(STK_TABLE_LOCK, &t->updt_lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
use_wrlock = 1;
|
||||
}
|
||||
|
||||
@ -542,13 +531,7 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local,
|
||||
if (!ts->upd.node.leaf_p) {
|
||||
/* Time to upgrade the read lock to write lock if needed */
|
||||
if (!use_wrlock) {
|
||||
if (HA_RWLOCK_TRYRDTOSK(STK_TABLE_LOCK, &t->updt_lock) != 0) {
|
||||
/* failed, try again */
|
||||
HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
use_wrlock = 1;
|
||||
goto try_lock_again;
|
||||
}
|
||||
HA_RWLOCK_SKTOWR(STK_TABLE_LOCK, &t->updt_lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
use_wrlock = 1;
|
||||
}
|
||||
|
||||
@ -567,8 +550,6 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local,
|
||||
/* drop the lock now */
|
||||
if (use_wrlock)
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
else
|
||||
HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
|
||||
}
|
||||
|
||||
if (decrefcnt)
|
||||
|
Loading…
Reference in New Issue
Block a user