diff --git a/include/haproxy/freq_ctr.h b/include/haproxy/freq_ctr.h index 6ddcde842..dfb187483 100644 --- a/include/haproxy/freq_ctr.h +++ b/include/haproxy/freq_ctr.h @@ -31,7 +31,7 @@ ullong _freq_ctr_total_from_values(uint period, int pend, uint tick, ullong past, ullong curr); ullong freq_ctr_total(const struct freq_ctr *ctr, uint period, int pend); ullong freq_ctr_total_estimate(const struct freq_ctr *ctr, uint period, int pend); -int freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq); +uint freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq); uint update_freq_ctr_period_slow(struct freq_ctr *ctr, uint period, uint inc); /* Only usable during single threaded startup phase. */ diff --git a/src/flt_bwlim.c b/src/flt_bwlim.c index 0ca768091..ebb33a5f1 100644 --- a/src/flt_bwlim.c +++ b/src/flt_bwlim.c @@ -79,9 +79,9 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne struct bwlim_state *st = filter->ctx; struct freq_ctr *bytes_rate; uint64_t remain; - unsigned int period, limit, tokens, users, factor; + unsigned int period, limit, tokens, users, factor, overshoot; unsigned int wait = 0; - int overshoot, ret = 0; + int ret = 0; /* Don't forward anything if there is nothing to forward or the waiting * time is not expired diff --git a/src/freq_ctr.c b/src/freq_ctr.c index f072ce554..205e43147 100644 --- a/src/freq_ctr.c +++ b/src/freq_ctr.c @@ -184,17 +184,17 @@ ullong freq_ctr_total_estimate(const struct freq_ctr *ctr, uint period, int pend return _freq_ctr_total_from_values(period, pend, tick, past, curr); } -/* Returns the excess of events (may be negative) over the current period for - * target frequency . It returns 0 if the counter is in the future or if - * the counter is empty. The result considers the position of the current time - * within the current period. +/* Returns the excess of events over the current period for target frequency + * . It returns 0 if the counter is in the future or if the counter is + * empty. The result considers the position of the current time within the + * current period. * - * The caller may safely add new events if result is negative or null. + * The caller may safely add new events if result is zero. */ -int freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq) +uint freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq) { ullong curr, old_curr; - uint tick, old_tick; + uint tick, old_tick, linear_usage; int elapsed; tick = HA_ATOMIC_LOAD(&ctr->curr_tick); @@ -245,7 +245,12 @@ int freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq return 0; } - return curr - div64_32((uint64_t)elapsed * freq, period); + linear_usage = div64_32((uint64_t)elapsed * freq, period); + if (curr < linear_usage) { + /* The counter is below a uniform linear increase across the period, no overshoot */ + return 0; + } + return curr - linear_usage; } /*