]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: bwlim: Use a read-lock on the sticky session to apply a shared limit
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 28 Aug 2024 08:04:42 +0000 (10:04 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 2 Sep 2024 13:50:25 +0000 (15:50 +0200)
There is no reason to acquire a write-lock on the sticky session when a
shared limit is applied because only the frequency is updated. The sticky
session itself is not modified. We must just take care it is not removed in
the mean time. So a read-lock may be used instead.

src/flt_bwlim.c

index 1d07598033a48facaab8c0b4773d39d298ce5eb4..3c75b9bb0e027c498c1ca1fed918b1ffabae9001 100644 (file)
@@ -106,7 +106,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
                if (!ptr)
                        goto end;
 
-               HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &st->ts->lock);
+               HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &st->ts->lock);
                bytes_rate = &stktable_data_cast(ptr, std_t_frqp);
                period = conf->table.t->data_arg[type].u;
                limit = conf->limit;
@@ -137,7 +137,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
        overshoot = freq_ctr_overshoot_period(bytes_rate, period, limit);
        if (overshoot > 0) {
                if (conf->flags & BWLIM_FL_SHARED)
-                       HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &st->ts->lock);
+                       HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &st->ts->lock);
                wait = div64_32((uint64_t)(conf->min_size + overshoot) * period * users,
                                limit);
                st->exp = tick_add(now_ms, (wait ? wait : 1));
@@ -178,7 +178,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
        }
 
        if (conf->flags & BWLIM_FL_SHARED)
-               HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &st->ts->lock);
+               HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &st->ts->lock);
 
   end:
        chn->analyse_exp = tick_first((tick_is_expired(chn->analyse_exp, now_ms) ? TICK_ETERNITY : chn->analyse_exp),