Re: [PATCH for-6.12 3/4] block, bfq: don't break merge chain in bfq_split_bfqq()

From: Jan Kara
Date: Wed Sep 04 2024 - 08:21:18 EST


On Mon 02-09-24 21:03:28, Yu Kuai wrote:
> From: Yu Kuai <yukuai3@xxxxxxxxxx>
>
> Consider the following scenario:
>
> Process 1 Process 2 Process 3 Process 4
> (BIC1) (BIC2) (BIC3) (BIC4)
> Λ | | |
> \-------------\ \-------------\ \--------------\|
> V V V
> bfqq1--------->bfqq2---------->bfqq3----------->bfqq4
> ref 0 1 2 4
>
> If Process 1 issue a new IO and bfqq2 is found, and then bfq_init_rq()
> decide to spilt bfqq2 by bfq_split_bfqq(). Howerver, procress reference
> of bfqq2 is 1 and bfq_split_bfqq() just clear the coop flag, which will
> break the merge chain.
>
> Expected result: caller will allocate a new bfqq for BIC1
>
> Process 1 Process 2 Process 3 Process 4
> (BIC1) (BIC2) (BIC3) (BIC4)
> | | |
> \-------------\ \--------------\|
> V V
> bfqq1--------->bfqq2---------->bfqq3----------->bfqq4
> ref 0 0 1 3
>
> Since the condition is only used for the last bfqq4 when the previous
> bfqq2 and bfqq3 are already splited. Fix the problem by checking if
> bfqq is the last one in the merge chain as well.
>
> Fixes: 36eca8948323 ("block, bfq: add Early Queue Merge (EQM)")
> Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@xxxxxxx>

Honza

> ---
> block/bfq-iosched.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
> index ffaa0d56328a..ca766b7d5560 100644
> --- a/block/bfq-iosched.c
> +++ b/block/bfq-iosched.c
> @@ -6727,7 +6727,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
> {
> bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
>
> - if (bfqq_process_refs(bfqq) == 1) {
> + if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
> bfqq->pid = current->pid;
> bfq_clear_bfqq_coop(bfqq);
> bfq_clear_bfqq_split_coop(bfqq);
> --
> 2.39.2
>
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR