OPTIM: peers: avoid the locking dance around peer_send_teach_process_msgs()

In peer_send_msg(), we take a lock before calling
peer_send_teach_process_msgs because of the check on the flags and update
indexes, and the function then drops it then takes it again just to resume
in the same situation, so that on return we can drop it again! Not only
this is absurd because it doubles the costs of taking the lock, it's also
totally inefficient because it takes a write lock while the only usage
that is done with it is to read the indexes! Let's drop the lock from
peer_send_teach_process_msgs() and move it explicitly in its only caller
around the condition, and turn it into a read lock only.
This commit is contained in:
Willy Tarreau 2024-04-02 18:27:36 +02:00
parent 1ea18fa8a3
commit 6a2f09de1c

View File

@ -1651,13 +1651,7 @@ static inline int peer_send_teachmsgs(struct appctx *appctx, struct peer *p,
static inline int peer_send_teach_process_msgs(struct appctx *appctx, struct peer *p,
struct shared_table *st)
{
int ret;
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
ret = peer_send_teachmsgs(appctx, p, peer_teach_process_stksess_lookup, st);
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
return ret;
return peer_send_teachmsgs(appctx, p, peer_teach_process_stksess_lookup, st);
}
/*
@ -2689,18 +2683,19 @@ static inline int peer_send_msgs(struct appctx *appctx,
}
if (!(peer->flags & PEER_F_TEACH_PROCESS)) {
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
if (!(peer->flags & PEER_F_LEARN_ASSIGN) &&
(st->last_pushed != st->table->localupdate)) {
int must_send;
HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
must_send = !(peer->flags & PEER_F_LEARN_ASSIGN) && (st->last_pushed != st->table->localupdate);
HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
if (must_send) {
repl = peer_send_teach_process_msgs(appctx, peer, st);
if (repl <= 0) {
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
peer->stop_local_table = peer->last_local_table;
return repl;
}
}
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
}
else if (!(peer->flags & PEER_F_TEACH_FINISHED)) {
if (!(st->flags & SHTABLE_F_TEACH_STAGE1)) {