Skip to content

blk-mq-sched: support request batch dispatching for sq elevator#55

Closed
blktests-ci[bot] wants to merge 7 commits intolinus-master_basefrom
series/984570=>linus-master
Closed

blk-mq-sched: support request batch dispatching for sq elevator#55
blktests-ci[bot] wants to merge 7 commits intolinus-master_basefrom
series/984570=>linus-master

Conversation

@blktests-ci
Copy link
Copy Markdown

@blktests-ci blktests-ci Bot commented Jul 23, 2025

Pull request for series with
subject: blk-mq-sched: support request batch dispatching for sq elevator
version: 1
url: https://patchwork.kernel.org/project/linux-block/list/?series=984570

@blktests-ci
Copy link
Copy Markdown
Author

blktests-ci Bot commented Jul 23, 2025

Upstream branch: 89be9a8
series: https://patchwork.kernel.org/project/linux-block/list/?series=984570
version: 1

@blktests-ci blktests-ci Bot force-pushed the linus-master_base branch from 81f31a4 to 87bbbbc Compare July 24, 2025 05:40
Introduce a new spinlock in elevator_queue, and switch dd->lock to
use the new lock. There are no functional changes.

Signed-off-by: Yu Kuai <[email protected]>
Currently issue io can grab queue_lock three times from bfq_bio_merge(),
bfq_limit_depth() and bfq_prepare_request(), the queue_lock is not
necessary if icq is already created:

- queue_usage_counter is already grabbed and queue won't exist;
- current thread won't exist;
- if other thread is allocating and inserting new icq to ioc->icq_tree,
  rcu can be used to protect lookup icq from the raidx tree, it's safe
  to use extracted icq until queue or current thread exit;

If ioc or icq is not created, then bfq_prepare_request() will create it,
which means the task is issuing io to queue the first time, this can
consider a slow path and queue_lock will still be held to protect
inserting allocated icq to ioc->icq_tree.

Signed-off-by: Yu Kuai <[email protected]>
Replace the internal spinlock bfqd->lock with the new spinlock in
elevator_queue. There are no functional changes.

Signed-off-by: Yu Kuai <[email protected]>
Reviewed-by: Damien Le Moal <[email protected]>
Currently, both mq-deadline and bfq have global spin lock that will be
grabbed inside elevator methods like dispatch_request, insert_requests,
and bio_merge. And the global lock is the main reason mq-deadline and
bfq can't scale very well.

For dispatch_request method, current behavior is dispatching one request at
a time. In the case of multiple dispatching contexts, this behavior will
cause huge lock contention and messing up the requests dispatching
order. And folloiwng patches will support requests batch dispatching to
fix thoses problems.

While dispatching request, blk_mq_get_disatpch_budget() and
blk_mq_get_driver_tag() must be called, and they are not ready to be
called inside elevator methods, hence introduce a new method like
dispatch_requests is not possible.

In conclusion, this patch factor the global lock out of dispatch_request
method, and following patches will support request batch dispatch by
calling the methods multiple time while holding the lock.

Signed-off-by: Yu Kuai <[email protected]>
Introduce struct sched_dispatch_ctx, and split the helper into
elevator_dispatch_one_request() and elevator_finish_dispatch(). Also
and comments about the non-error return value.

Make code cleaner, and make it easier to add a new branch to dispatch
a batch of requests at a time in the next patch.

Signed-off-by: Yu Kuai <[email protected]>
@blktests-ci
Copy link
Copy Markdown
Author

blktests-ci Bot commented Jul 24, 2025

Upstream branch: 25fae0b
series: https://patchwork.kernel.org/project/linux-block/list/?series=984570
version: 1

For dispatch_request method, current behavior is dispatching one request at
a time. In the case of multiple dispatching contexts, This behavior, on the
one hand, introduce intense lock contention:

t1:                     t2:                     t3:
lock                    lock                    lock
// grab lock
ops.dispatch_request
unlock
                        // grab lock
                        ops.dispatch_request
                        unlock
                                                // grab lock
                                                ops.dispatch_request
                                                unlock

on the other hand, messing up the requests dispatching order:
t1:

lock
rq1 = ops.dispatch_request
unlock
                        t2:
                        lock
                        rq2 = ops.dispatch_request
                        unlock

lock
rq3 = ops.dispatch_request
unlock

                        lock
                        rq4 = ops.dispatch_request
                        unlock

//rq1,rq3 issue to disk
                        // rq2, rq4 issue to disk

In this case, the elevator dispatch order is rq 1-2-3-4, however,
such order in disk is rq 1-3-2-4, the order for rq2 and rq3 is inversed.

Fix those problems by introducing elevator_dispatch_requests(), this
helper will grab the lock and dispatch a batch of requests while holding
the lock.

Signed-off-by: Yu Kuai <[email protected]>
@blktests-ci blktests-ci Bot force-pushed the series/984570=>linus-master branch from 25076c3 to 7a12bca Compare July 24, 2025 06:52
@blktests-ci blktests-ci Bot force-pushed the linus-master_base branch 2 times, most recently from 6637119 to f092a9b Compare July 31, 2025 04:25
@blktests-ci blktests-ci Bot closed this Jul 31, 2025
@blktests-ci blktests-ci Bot deleted the series/984570=>linus-master branch August 1, 2025 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants