Hopefully this helps expand on things a little. Thinking about this further, we sort of already do something like this on the punishment side of things:
# rate adjustment parameters
# shaper rate is adjusted by a maximum of shaper_rate_max_adjust_down_bufferbloat on detection of bufferbloat
# and this is scaled by the average delta owd / average owd delta threshold
# otherwise shaper rate is adjusted up on load high, and down on load idle or low
shaper_rate_min_adjust_down_bufferbloat=0.99 # how rapidly to reduce shaper rate upon detection of bufferbloat (min reduction)
shaper_rate_max_adjust_down_bufferbloat=0.75 # how rapidly to reduce shaper rate upon detection of bufferbloat (max reduction)
shaper_rate_adjust_up_load_high=1.04 # how rapidly to increase shaper rate upon high load detected
shaper_rate_adjust_down_load_low=0.99 # how rapidly to return down to base shaper rate upon idle or low load detected
shaper_rate_adjust_up_load_low=1.01 # how rapidly to return up to base shaper rate upon idle or low load detected
Namely, in respect of the bufferbloat handling, we punish the shaper rate between 0.99 and 0.75 in dependence upon how the average OWD delta sits between the following two tresholds:
# owd delta threshold in ms is the extent of OWD increase to classify as a delay
# these are automatically adjusted based on maximum on the wire packet size
# (adjustment significant at sub 12Mbit/s rates, else negligible)
dl_owd_delta_thr_ms=30.0 # (milliseconds)
ul_owd_delta_thr_ms=30.0 # (milliseconds)
# average owd delta threshold in ms at which maximum adjust_down_bufferbloat is applied
dl_avg_owd_delta_thr_ms=60.0 # (milliseconds)
ul_avg_owd_delta_thr_ms=60.0 # (milliseconds)
So at present, where the average OWD delta sits around 30ms, then the factors are:
-
increase at 1.04 on high load once per achieved rates reading (every 200ms);
-
punish from 0.99 to 0.75 in dependence upon the extent of the overshoot.
Graphically, this looks like this:
Observe the big discontinuity between 1.04 and 0.99. Is this a good thing?
The question is whether it is still best to always simply increase at the 1.04 on high load once per achieved rates reading (every 200ms), or somehow scale that in dependence upon how close we are to either or both of the above thresholds.
Just thinking out loud, but what about something more like the following involving a crossover, with something like this:
That is, we actually still allow increase beyond owd_delta_thr_ms, but scale down and cross through zero as the delta reaches avg_owd_delta_thr_ms?
Something along these lines ameliorates the big discontinuity, and I'm wondering if it offers the prospect of reduced oscillations?