MEDIUM: stick-tables: Limit the number of entries we expire
In process_table_expire(), limit the number of entries we remove in one call, and just reschedule the task if there's more to do. Removing entries require to use the heavily contended update write lock, and we don't want to hold it for too long. This helps getting stick tables perform better under heavy load.
This commit is contained in:
parent
d2d4c3eb65
commit
994cc58576
@ -884,7 +884,9 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
|
||||
struct stktable *t = context;
|
||||
struct stksess *ts;
|
||||
struct eb32_node *eb;
|
||||
int need_resched = 0;
|
||||
int updt_locked;
|
||||
int expired;
|
||||
int looped;
|
||||
int exp_next;
|
||||
int task_exp;
|
||||
@ -897,6 +899,7 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
|
||||
looped = 0;
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
|
||||
eb = eb32_lookup_ge(&t->shards[shard].exps, now_ms - TIMER_LOOK_BACK);
|
||||
expired = 0;
|
||||
|
||||
while (1) {
|
||||
if (unlikely(!eb)) {
|
||||
@ -952,6 +955,14 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
|
||||
continue;
|
||||
}
|
||||
|
||||
if (updt_locked == 1) {
|
||||
expired++;
|
||||
if (expired == STKTABLE_MAX_UPDATES_AT_ONCE) {
|
||||
need_resched = 1;
|
||||
exp_next = TICK_ETERNITY;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
/* if the entry is in the update list, we must be extremely careful
|
||||
* because peers can see it at any moment and start to use it. Peers
|
||||
* will take the table's updt_lock for reading when doing that, and
|
||||
@ -986,6 +997,9 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
|
||||
}
|
||||
|
||||
if (need_resched) {
|
||||
task_wakeup(task, TASK_WOKEN_OTHER);
|
||||
} else {
|
||||
/* Reset the task's expiration. We do this under the lock so as not
|
||||
* to ruin a call to task_queue() in stktable_requeue_exp() if we
|
||||
* were to update with TICK_ETERNITY.
|
||||
@ -993,6 +1007,7 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
task->expire = task_exp;
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user