diff options
author | Joseph Qi <qijiang.qj@alibaba-inc.com> | 2017-09-30 02:38:49 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-10-03 17:41:55 -0400 |
commit | 4f02fb7617ba12ac15d261c654b9759ea8f1f1ef (patch) | |
tree | 3fae18c740588451dd337bcbe601cf241d6e5204 | |
parent | 38b249bc0ca26d57dac65f5f659b39d88899d23d (diff) |
blk-throttle: fix possible io stall when upgrade to max
There is a case which will lead to io stall. The case is described as
follows.
/test1
|-subtest1
/test2
|-subtest2
And subtest1 and subtest2 each has 32 queued bios already.
Now upgrade to max. In throtl_upgrade_state, it will try to dispatch
bios as follows:
1) tg=subtest1, do nothing;
2) tg=test1, transfer 32 queued bios from subtest1 to test1; no pending
left, no need to schedule next dispatch;
3) tg=subtest2, do nothing;
4) tg=test2, transfer 32 queued bios from subtest2 to test2; no pending
left, no need to schedule next dispatch;
5) tg=/, transfer 8 queued bios from test1 to /, 8 queued bios from
test2 to /, 8 queued bios from test1 to /, and 8 queued bios from test2
to /; note that test1 and test2 each still has 16 queued bios left;
6) tg=/, try to schedule next dispatch, but since disptime is now
(update in tg_update_disptime, wait=0), pending timer is not scheduled
in fact;
7) In throtl_upgrade_state it totally dispatches 32 queued bios and with
32 left. test1 and test2 each has 16 queued bios;
8) throtl_pending_timer_fn sees the left over bios, but could do
nothing, because throtl_select_dispatch returns 0, and test1/test2 has
no pending tg.
The blktrace shows the following:
8,32 0 0 2.539007641 0 m N throtl upgrade to max
8,32 0 0 2.539072267 0 m N throtl /test2 dispatch nr_queued=16 read=0 write=16
8,32 7 0 2.539077142 0 m N throtl /test1 dispatch nr_queued=16 read=0 write=16
So force schedule dispatch if there are pending children.
Reviewed-by: Shaohua Li <shli@fb.com>
Signed-off-by: Joseph Qi <qijiang.qj@alibaba-inc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/blk-throttle.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 0fea76aa0f3f..17816a028dcb 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -1911,11 +1911,11 @@ static void throtl_upgrade_state(struct throtl_data *td) | |||
1911 | 1911 | ||
1912 | tg->disptime = jiffies - 1; | 1912 | tg->disptime = jiffies - 1; |
1913 | throtl_select_dispatch(sq); | 1913 | throtl_select_dispatch(sq); |
1914 | throtl_schedule_next_dispatch(sq, false); | 1914 | throtl_schedule_next_dispatch(sq, true); |
1915 | } | 1915 | } |
1916 | rcu_read_unlock(); | 1916 | rcu_read_unlock(); |
1917 | throtl_select_dispatch(&td->service_queue); | 1917 | throtl_select_dispatch(&td->service_queue); |
1918 | throtl_schedule_next_dispatch(&td->service_queue, false); | 1918 | throtl_schedule_next_dispatch(&td->service_queue, true); |
1919 | queue_work(kthrotld_workqueue, &td->dispatch_work); | 1919 | queue_work(kthrotld_workqueue, &td->dispatch_work); |
1920 | } | 1920 | } |
1921 | 1921 | ||