When the bandwidth limitation filter applies a limitation on a channel, it
returns the amount of data the stream is authorized to forward to the data
filtering layer.
This amount could be larger than the amount of pending data in the channel
input when the min-size burst was used: with a shared limitation, the stream
quota was shared between all users and the burst was not clamped to the
pending input data when the producer of the channel was still open. When
this happened, more output data than available were removed from the
channel. The channel was then corrupted and the stream spinned at 100% CPU
with its tasklet woken up in a loop while the response buffer shown a
negative input count.
The fix clamps the burst to the pending input data, as already done when the
producer closed its endpoint. This way the filter never reports more data
than the channel really holds.
This patch should fix the issue #3541. It must be backported as far as 2.6.
*/
ret = tokens;
if (tokens < conf->min_size) {
- ret = (chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_EOS|SC_FL_ABRT_DONE))
- ? MIN(len, conf->min_size)
- : conf->min_size;
+ /* The burst must never exceed the amount of pending data (<len>) */
+ ret = MIN(len, conf->min_size);
if (ret <= remain)
wait = div64_32((uint64_t)(ret - tokens) * period * users + limit * factor - 1, limit * factor);