Re: [PATCH v2 1/3] md/raid1,raid10: fix deadlock in read error recovery path

Xiao Ni <[email protected]>
Newsgroups gmane.linux.raid,gmane.linux.kernel
Message-ID <CAF-RUYXNAYhtQsz0e6-zRC4a02+aXn6_mr4+6SSeBrTJ-KZxbA@mail.gmail.com>
On Fri, May 1, 2026 at 7:47 PM Abd-Alrhman Masalkhi
<[email protected]> wrote:
>
> raid1d and raid10d may resubmit a split md cloned bio while handling
> a read error. In this case, resubmitting the bio can lead to a deadlock
> if the array is suspended before md_handle_request() acquires an
> active_io reference via percpu_ref_tryget_live().
>
> Since the cloned bio already holds an active_io reference,
> trying to acquire another reference via percpu_ref_tryget_live()
> can lead to a deadlock while the array is suspended.
>
> Fix this by using percpu_ref_get() for md cloned bios.
>
> Fixes: bb2a9acefaf9 ("md/raid1: switch to use md_account_bio() for io accounting")
> Fixes: 820455238366 ("md/raid10: switch to use md_account_bio() for io accounting")
> Signed-off-by: Abd-Alrhman Masalkhi <[email protected]>
> ---
> Changes in v2:
>  - Use md_cloned_bio() consistently to detect cloned bios.
>  - Recognize that raid10 has the same issue and fix it in this series
>  - Allow splitting bios.
>  - Handle md cloned bios explicitly in md_handle_request()
>  - Link v1: https://lore.kernel.org/linux-raid/[email protected]/
>
> Please let me know if I should add a Suggested-by tag for Yu Kuai,
> as the solution approach was suggested during review.
>
> Link to Yu Kuai' email: https://lore.kernel.org/linux-raid/[email protected]/T/#m714020a38b60fc5f84b9a24f0c46acbe5d7342d6
>
> Thanks
> Abd-alrhman
> ---
>  drivers/md/md.c | 25 ++++++++++++++++---------
>  drivers/md/md.h |  5 +++++
>  2 files changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index e926aef9ec43..96db1e7850e9 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -396,17 +396,24 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio)
>  bool md_handle_request(struct mddev *mddev, struct bio *bio)
>  {
>  check_suspended:
> -       if (is_suspended(mddev, bio)) {
> -               /* Bail out if REQ_NOWAIT is set for the bio */
> -               if (bio->bi_opf & REQ_NOWAIT) {
> -                       bio_wouldblock_error(bio);
> -                       return true;
> +       if (unlikely(md_cloned_bio(mddev, bio))) {
> +               /*
> +                * This bio is an MD cloned bio and already holds an
> +                * active_io reference, so percpu_ref_get() is safe here.
> +                */
> +               percpu_ref_get(&mddev->active_io);
> +       } else {
> +               if (is_suspended(mddev, bio)) {
> +                       /* Bail out if REQ_NOWAIT is set for the bio */
> +                       if (bio->bi_opf & REQ_NOWAIT) {
> +                               bio_wouldblock_error(bio);
> +                               return true;
> +                       }
> +                       wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
>                 }
> -               wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
> +               if (!percpu_ref_tryget_live(&mddev->active_io))
> +                       goto check_suspended;
>         }
> -       if (!percpu_ref_tryget_live(&mddev->active_io))
> -               goto check_suspended;
> -
>         if (!mddev->pers->make_request(mddev, bio)) {
>                 percpu_ref_put(&mddev->active_io);
>                 if (mddev_is_dm(mddev) && mddev->pers->prepare_suspend)
> diff --git a/drivers/md/md.h b/drivers/md/md.h
> index 3bfbee595156..e44074d30cf9 100644
> --- a/drivers/md/md.h
> +++ b/drivers/md/md.h
> @@ -1038,6 +1038,11 @@ void mddev_update_io_opt(struct mddev *mddev, unsigned int nr_stripes);
>
>  extern const struct block_device_operations md_fops;
>
> +static inline bool md_cloned_bio(struct mddev *mddev, struct bio *bio)
> +{
> +       return bio->bi_pool == &mddev->io_clone_set;
> +}
> +
>  /*
>   * MD devices can be used undeneath by DM, in which case ->gendisk is NULL.
>   */
> --
> 2.43.0
>
>

This patch looks good to me.
Reviewed-by: Xiao Ni <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.