]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stick-table: switch the table lock to rwlock
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Oct 2022 10:02:50 +0000 (12:02 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Oct 2022 12:19:05 +0000 (14:19 +0200)
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.

include/haproxy/stick_table-t.h
include/haproxy/stick_table.h
src/hlua_fcn.c
src/peers.c
src/stick_table.c

index 57888e041a17c4ca49c47f42cbdc7ee0fb1720ab..b423f2d276dbd42be70ea429036ac6782d6a5f8b 100644 (file)
@@ -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];
index d5a56d11bf1c7ee8b0c3423e9e00e393c16cfc38..a495e7738e55e96891ef82fc40576937da890aa3 100644 (file)
@@ -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 */
index 0046e9ede45145231c3481815100876360081840..975ed246ea2c7654b9cd530534294b52a575b7e1 100644 (file)
@@ -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;
 }
index d4aa69f232eacb408549e7f93aa090306a41a50e..e0fedbdb4a02f901be9e98d7afb8224cd36d31f4 100644 (file)
@@ -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 */
index b1e7b59a5ef2623224a71b2e8ee21c256775cbb0..4e26a3ffdfa3559a8ae6873f61fb42c576f196d7 100644 (file)
@@ -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;