Hi,
Yet another colleague of the reporter here. I found that some
precondition maybe not sound when tg->slice_end[rw] is initialized with
0, which time_before(INITIAL_JIFFIES, 0) holds true in 32-bit Linux.
As in v5.15-rc6/block/blk-throttle.c
1. L833
/* Determine if previously allocated or extended slice is complete or
not */
static bool throtl_slice_used(struct throtl_grp *tg, bool rw)
{
if (time_in_range(jiffies, tg->slice_start[rw], tg->slice_end[rw]))
return false;
return true;
}
throtl_slice_used will always return true for a newly initialized slice.
This may be intentional behavior but not mentioned in comment.
(except when jiffies == 0, which is another topic: will
time_in_range_open do better here?)
2. L791, in throtl_start_new_slice_with_credit
/*
* Previous slice has expired. We must have trimmed it after last
* bio dispatch. That means since start of last slice, we never used
* that bandwidth. Do try to make use of that bandwidth while giving
* credit.
*/
if (time_after_eq(start, tg->slice_start[rw]))
tg->slice_start[rw] = start;
As mentioned in my colleague Haoran Luo's reply, time_after_eq(start,
tg->slice_start[rw]) is falsy when the jiffies had not wrapped around.
A easy solution is to add a check for tg->slice_start[rw] == 0, or we
should initialize tg->slice_start[rw] and tg->slice_end[rw] with
INITIAL_JIFFIES.