mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-19 12:16:59 +00:00
MEDIUM: stick-table: switch the table lock to rwlock
Right now a spinlock is used, but most accesses are for reads, so let's switch the lock to an rwlock and switch all accesses to exclusive locks for now. There should be no visible difference at this point.
This commit is contained in:
parent
f6a42c3a37
commit
76642223f0
@ -199,7 +199,7 @@ struct stktable {
|
||||
const char *file; /* The file where the stick-table is declared. */
|
||||
int line; /* The line in this <file> the stick-table is declared. */
|
||||
} conf;
|
||||
__decl_thread(HA_SPINLOCK_T lock); /* spin lock related to the table */
|
||||
__decl_thread(HA_RWLOCK_T lock); /* lock related to the table */
|
||||
};
|
||||
|
||||
extern struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
|
||||
|
@ -198,7 +198,7 @@ static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess *
|
||||
|
||||
static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *ts, int decrefcnt)
|
||||
{
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
if (decrefcnt)
|
||||
ts->ref_cnt--;
|
||||
@ -206,7 +206,7 @@ static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *t
|
||||
if (t->expire != TICK_ETERNITY && tick_is_expired(ts->expire, now_ms))
|
||||
__stksess_kill_if_expired(t, ts);
|
||||
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
/* sets the stick counter's entry pointer */
|
||||
|
@ -649,9 +649,9 @@ int hlua_stktable_lookup(lua_State *L)
|
||||
lua_settable(L, -3);
|
||||
|
||||
hlua_stktable_entry(L, t, ts);
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts->ref_cnt--;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -761,16 +761,16 @@ int hlua_stktable_dump(lua_State *L)
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
eb = ebmb_first(&t->keys);
|
||||
for (n = eb; n; n = ebmb_next(n)) {
|
||||
ts = ebmb_entry(n, struct stksess, key);
|
||||
if (!ts) {
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
return 1;
|
||||
}
|
||||
ts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
/* multi condition/value filter */
|
||||
skip_entry = 0;
|
||||
@ -810,7 +810,7 @@ int hlua_stktable_dump(lua_State *L)
|
||||
}
|
||||
|
||||
if (skip_entry) {
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts->ref_cnt--;
|
||||
continue;
|
||||
}
|
||||
@ -834,10 +834,10 @@ int hlua_stktable_dump(lua_State *L)
|
||||
lua_newtable(L);
|
||||
hlua_stktable_entry(L, t, ts);
|
||||
lua_settable(L, -3);
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts->ref_cnt--;
|
||||
}
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
24
src/peers.c
24
src/peers.c
@ -1583,7 +1583,7 @@ static inline int peer_send_teachmsgs(struct appctx *appctx, struct peer *p,
|
||||
new_pushed = 1;
|
||||
|
||||
if (!locked)
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
|
||||
while (1) {
|
||||
struct stksess *ts;
|
||||
@ -1598,16 +1598,16 @@ static inline int peer_send_teachmsgs(struct appctx *appctx, struct peer *p,
|
||||
|
||||
updateid = ts->upd.key;
|
||||
ts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
|
||||
ret = peer_send_updatemsg(st, appctx, ts, updateid, new_pushed, use_timed);
|
||||
if (ret <= 0) {
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
ts->ref_cnt--;
|
||||
break;
|
||||
}
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
ts->ref_cnt--;
|
||||
st->last_pushed = updateid;
|
||||
|
||||
@ -1631,7 +1631,7 @@ static inline int peer_send_teachmsgs(struct appctx *appctx, struct peer *p,
|
||||
|
||||
out:
|
||||
if (!locked)
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2585,17 +2585,17 @@ static inline int peer_send_msgs(struct appctx *appctx,
|
||||
}
|
||||
|
||||
if (!(peer->flags & PEER_F_TEACH_PROCESS)) {
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
if (!(peer->flags & PEER_F_LEARN_ASSIGN) &&
|
||||
(st->last_pushed != st->table->localupdate)) {
|
||||
|
||||
repl = peer_send_teach_process_msgs(appctx, peer, st);
|
||||
if (repl <= 0) {
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
return repl;
|
||||
}
|
||||
}
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
}
|
||||
else if (!(peer->flags & PEER_F_TEACH_FINISHED)) {
|
||||
if (!(st->flags & SHTABLE_F_TEACH_STAGE1)) {
|
||||
@ -2774,7 +2774,7 @@ static inline void init_accepted_peer(struct peer *peer, struct peers *peers)
|
||||
/* Init cursors */
|
||||
for (st = peer->tables; st ; st = st->next) {
|
||||
st->last_get = st->last_acked = 0;
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
/* if st->update appears to be in future it means
|
||||
* that the last acked value is very old and we
|
||||
* remain unconnected a too long time to use this
|
||||
@ -2790,7 +2790,7 @@ static inline void init_accepted_peer(struct peer *peer, struct peers *peers)
|
||||
st->flags = 0;
|
||||
if ((int)(st->last_pushed - st->table->commitupdate) > 0)
|
||||
st->table->commitupdate = st->last_pushed;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
}
|
||||
|
||||
/* reset teaching and learning flags to 0 */
|
||||
@ -2829,7 +2829,7 @@ static inline void init_connected_peer(struct peer *peer, struct peers *peers)
|
||||
/* Init cursors */
|
||||
for (st = peer->tables; st ; st = st->next) {
|
||||
st->last_get = st->last_acked = 0;
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
/* if st->update appears to be in future it means
|
||||
* that the last acked value is very old and we
|
||||
* remain unconnected a too long time to use this
|
||||
@ -2845,7 +2845,7 @@ static inline void init_connected_peer(struct peer *peer, struct peers *peers)
|
||||
st->flags = 0;
|
||||
if ((int)(st->last_pushed - st->table->commitupdate) > 0)
|
||||
st->table->commitupdate = st->last_pushed;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
|
||||
}
|
||||
|
||||
/* Init confirm counter */
|
||||
|
@ -103,9 +103,9 @@ void stksess_free(struct stktable *t, struct stksess *ts)
|
||||
dict_entry_unref(&server_key_dict, stktable_data_cast(data, std_t_dict));
|
||||
stktable_data_cast(data, std_t_dict) = NULL;
|
||||
}
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
__stksess_free(t, ts);
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -132,11 +132,11 @@ int stksess_kill(struct stktable *t, struct stksess *ts, int decrefcnt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
if (decrefcnt)
|
||||
ts->ref_cnt--;
|
||||
ret = __stksess_kill(t, ts);
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -249,9 +249,9 @@ int stktable_trash_oldest(struct stktable *t, int to_batch)
|
||||
{
|
||||
int ret;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ret = __stktable_trash_oldest(t, to_batch);
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -297,9 +297,9 @@ struct stksess *stksess_new(struct stktable *t, struct stktable_key *key)
|
||||
{
|
||||
struct stksess *ts;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts = __stksess_new(t, key);
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return ts;
|
||||
}
|
||||
@ -335,11 +335,11 @@ struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key
|
||||
{
|
||||
struct stksess *ts;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts = __stktable_lookup_key(t, key);
|
||||
if (ts)
|
||||
ts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return ts;
|
||||
}
|
||||
@ -373,11 +373,11 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts)
|
||||
{
|
||||
struct stksess *lts;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
lts = __stktable_lookup(t, ts);
|
||||
if (lts)
|
||||
lts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
|
||||
return lts;
|
||||
}
|
||||
@ -437,11 +437,11 @@ void __stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local
|
||||
*/
|
||||
void stktable_touch_remote(struct stktable *t, struct stksess *ts, int decrefcnt)
|
||||
{
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
__stktable_touch_with_exp(t, ts, 0, ts->expire);
|
||||
if (decrefcnt)
|
||||
ts->ref_cnt--;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
/* Update the expiration timer for <ts> but do not touch its expiration node.
|
||||
@ -454,20 +454,20 @@ void stktable_touch_local(struct stktable *t, struct stksess *ts, int decrefcnt)
|
||||
{
|
||||
int expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
__stktable_touch_with_exp(t, ts, 1, expire);
|
||||
if (decrefcnt)
|
||||
ts->ref_cnt--;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
/* Just decrease the ref_cnt of the current session. Does nothing if <ts> is NULL */
|
||||
static void stktable_release(struct stktable *t, struct stksess *ts)
|
||||
{
|
||||
if (!ts)
|
||||
return;
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
ts->ref_cnt--;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
}
|
||||
|
||||
/* Insert new sticky session <ts> in the table. It is assumed that it does not
|
||||
@ -516,11 +516,11 @@ struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *
|
||||
{
|
||||
struct stksess *ts;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
ts = __stktable_get_entry(table, key);
|
||||
if (ts)
|
||||
ts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
|
||||
return ts;
|
||||
}
|
||||
@ -548,10 +548,10 @@ struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts)
|
||||
{
|
||||
struct stksess *ts;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &table->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
ts = __stktable_set_entry(table, nts);
|
||||
ts->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &table->lock);
|
||||
|
||||
return ts;
|
||||
}
|
||||
@ -565,7 +565,7 @@ static int stktable_trash_expired(struct stktable *t)
|
||||
struct eb32_node *eb;
|
||||
int looped = 0;
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
|
||||
|
||||
while (1) {
|
||||
@ -620,7 +620,7 @@ static int stktable_trash_expired(struct stktable *t)
|
||||
/* We have found no task to expire in any tree */
|
||||
t->exp_next = TICK_ETERNITY;
|
||||
out_unlock:
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||
return t->exp_next;
|
||||
}
|
||||
|
||||
@ -4783,16 +4783,16 @@ static int cli_io_handler_table(struct appctx *appctx)
|
||||
if (ctx->target &&
|
||||
(strm_li(s)->bind_conf->level & ACCESS_LVL_MASK) >= ACCESS_LVL_OPER) {
|
||||
/* dump entries only if table explicitly requested */
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
eb = ebmb_first(&ctx->t->keys);
|
||||
if (eb) {
|
||||
ctx->entry = ebmb_entry(eb, struct stksess, key);
|
||||
ctx->entry->ref_cnt++;
|
||||
ctx->state = STATE_DUMP;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
break;
|
||||
}
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
}
|
||||
}
|
||||
ctx->t = ctx->t->next;
|
||||
@ -4860,7 +4860,7 @@ static int cli_io_handler_table(struct appctx *appctx)
|
||||
|
||||
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &ctx->entry->lock);
|
||||
|
||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
ctx->entry->ref_cnt--;
|
||||
|
||||
eb = ebmb_next(&ctx->entry->key);
|
||||
@ -4872,7 +4872,7 @@ static int cli_io_handler_table(struct appctx *appctx)
|
||||
else if (!skip_entry && !ctx->entry->ref_cnt)
|
||||
__stksess_kill(ctx->t, old);
|
||||
ctx->entry->ref_cnt++;
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4882,7 +4882,7 @@ static int cli_io_handler_table(struct appctx *appctx)
|
||||
else if (!skip_entry && !ctx->entry->ref_cnt)
|
||||
__stksess_kill(ctx->t, ctx->entry);
|
||||
|
||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||
|
||||
ctx->t = ctx->t->next;
|
||||
ctx->state = STATE_NEXT;
|
||||
|
Loading…
Reference in New Issue
Block a user