All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mykola Marzhan" <mykola@meshstor.io>
Cc: linux-raid@vger.kernel.org, yukuai@fygo.io, linux-pci@vger.kernel.org
Subject: Re: [PATCH v5 08/10] md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA
Date: Thu, 23 Jul 2026 21:13:07 +0000	[thread overview]
Message-ID: <20260723211308.4058D1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723204206.76930-9-mykola@meshstor.io>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Bypassing `freeze_array()` for `BLK_STS_P2PDMA` in `raid1.c` introduces a hard deadlock against concurrent array freezes.

Pre-existing issues:
- [High] Race condition leading to a NULL pointer dereference in `raid1_read_request()` when logging an unrecoverable read error.
- [High] Double barrier drop (`nr_pending` underflow) when a `REQ_NOWAIT` read fails while the array is frozen.
--

--- Patch [8]: [PATCH v5 08/10] md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA ---
commit 39fd90f26512b119562fa95bb3bbc654fa9ed8a3
Author: Mykola Marzhan <mykola@meshstor.io>

md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA

A read that fails with BLK_STS_P2PDMA cannot succeed against that
member, so mark the leg IO_BLOCKED and let the retry redirect elsewhere.
Skip the read-error machinery: there is nothing on the medium to fix,
fix_read_error()'s probe reads into host pages and would "succeed", and
charging the read-error budget would evict a healthy member under a P2P
read workload.  FailFast eviction is skipped for the same reason -- the
request never reached the wire.

Fixes: 02666132403a ("md: propagate BLK_FEAT_PCI_P2PDMA from member devices to RAID device")
Assisted-by: Claude:claude-fable-5
Co-developed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Mykola Marzhan <mykola@meshstor.io>

> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index 83ebf40237d57..16a47568679f0 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c

[ ... ]

> @@ -2674,7 +2676,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
>  	 * read error.  This is all done synchronously while the array is
>  	 * frozen.
>  	 */
> -	if (mddev->ro) {
> +	if (mddev->ro || status == BLK_STS_P2PDMA) {
>  		r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;

[Severity: High]
Does skipping freeze_array() for P2PDMA errors here risk a hard deadlock?

If a concurrent thread calls freeze_array(conf, 0) during a management command,
it sets array_frozen = 1 and waits for get_unqueued_pending() == 0.

Meanwhile, this handle_read_error() thread bypasses freeze_array() and
proceeds to call raid1_read_request() while holding the original nr_pending
reference.

When raid1_read_request() calls wait_read_barrier():

drivers/md/raid1.c:raid1_read_request() {
    ...
    if (!wait_read_barrier(conf, bio->bi_iter.bi_sector, nowait)) {
    ...
}

And wait_read_barrier() sees the array is frozen:

drivers/md/raid1.c:wait_read_barrier() {
    ...
    if (unlikely(conf->array_frozen)) {
        ...
        wait_event_lock_irq_cmd(...)
    ...
}

The raid1d thread will block on array_frozen, but because it still holds its
nr_pending reference, get_unqueued_pending() will remain >= 1. The freezer
thread will wait forever for the reference to drop, and raid1d will wait
forever for the array to unfreeze.

>  	} else if (test_bit(FailFast, &rdev->flags)) {
>  		md_error(mddev, rdev);

[Severity: High]
This is a pre-existing issue, but does dropping the active reference to the
failing device later in handle_read_error() introduce a race condition with
concurrent disk removal?

Looking further down in handle_read_error():

    rdev_dec_pending(rdev, conf->mddev);
    sector = r1_bio->sector;
    ...
    raid1_read_request(mddev, bio, r1_bio->sectors, r1_bio);

Since raid1d doesn't hold reconfig_mutex, a concurrent raid1_remove_disk() can
observe nr_pending == 0 and clear the device pointer. If the subsequent call
to raid1_read_request() fails to find an alternative disk in read_balance(),
it attempts to log a critical error:

drivers/md/raid1.c:raid1_read_request() {
    ...
    if (r1_bio->read_disk < 0) {
        ...
        pr_crit_ratelimited("md/raid1:%s: %pg: unrecoverable I/O read...\n",
                            mdname(mddev),
                            conf->mirrors[r1_bio->read_disk].rdev->bdev,
                            ...);
    ...
}

Dereferencing conf->mirrors[r1_bio->read_disk].rdev->bdev when rdev has been
set to NULL would cause a fatal page fault.


[Severity: High]
This is also a pre-existing issue, but could the unconditional allow_barrier()
at the end of handle_read_error() lead to a double barrier drop if a
REQ_NOWAIT read fails while the array is frozen?

Looking at the end of the function:

    raid1_read_request(mddev, bio, r1_bio->sectors, r1_bio);
    allow_barrier(conf, sector);

If wait_read_barrier() inside raid1_read_request() encounters a frozen array
and returns false due to REQ_NOWAIT, it does not increment nr_pending:

drivers/md/raid1.c:raid1_read_request() {
    ...
    if (!wait_read_barrier(conf, bio->bi_iter.bi_sector, nowait)) {
        bio_wouldblock_error(bio);
        raid_end_bio_io(r1_bio);
        return;
    ...
}

raid_end_bio_io() internally calls allow_barrier() to drop the original
reference. After raid1_read_request() returns, handle_read_error() will
unconditionally execute this second allow_barrier(conf, sector).

This would cause nr_pending to underflow, leading to a permanent deadlock on
any subsequent array freeze since raise_barrier() will block forever waiting
for nr_pending == 0.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260723204206.76930-1-mykola@meshstor.io?part=8

  reply	other threads:[~2026-07-23 21:13 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 20:41 [PATCH v5 00/10] block,md,nvme: correct handling of unsupported P2PDMA transfers Mykola Marzhan
2026-07-23 20:41 ` [PATCH v5 01/10] block: add BLK_STS_P2PDMA for unsupported peer-to-peer transfers Mykola Marzhan
2026-07-23 20:51   ` sashiko-bot
2026-07-23 20:41 ` [PATCH v5 02/10] md: ensure REQ_NOMERGE is set on P2PDMA bios Mykola Marzhan
2026-07-23 20:51   ` sashiko-bot
2026-07-23 20:41 ` [PATCH v5 03/10] md/raid1: serialize non-write-behind writes on CollisionCheck rdevs Mykola Marzhan
2026-07-23 21:04   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 04/10] md/raid1: don't use write-behind for P2PDMA bios Mykola Marzhan
2026-07-23 21:01   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 05/10] md/raid1,raid10: factor out raid1_write_error() helper Mykola Marzhan
2026-07-23 20:54   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 06/10] md/raid1,raid10: keep REQ_NOMERGE on narrow_write_error() retry clones Mykola Marzhan
2026-07-23 21:05   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 07/10] md/raid1,raid10: skip futile retries on P2PDMA mapping failures Mykola Marzhan
2026-07-23 21:09   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 08/10] md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA Mykola Marzhan
2026-07-23 21:13   ` sashiko-bot [this message]
2026-07-23 20:42 ` [PATCH v5 09/10] nvme-rdma: use ib_dma_map_sgtable_attrs() Mykola Marzhan
2026-07-23 21:09   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 10/10] nvme-rdma: return BLK_STS_P2PDMA for unsupported P2P transfers Mykola Marzhan
2026-07-23 21:19   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260723211308.4058D1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=mykola@meshstor.io \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=yukuai@fygo.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.