[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230830092902.1236950-2-yukuai1@huaweicloud.com>
Date: Wed, 30 Aug 2023 17:29:01 +0800
From: Yu Kuai <yukuai1@...weicloud.com>
To: song@...nel.org, xni@...hat.com
Cc: linux-raid@...r.kernel.org, linux-kernel@...r.kernel.org,
yukuai3@...wei.com, yukuai1@...weicloud.com, yi.zhang@...wei.com,
yangerkun@...wei.com
Subject: [PATCH -next 1/2] md: factor out helpers to grab and put 'active_io'
From: Yu Kuai <yukuai3@...wei.com>
There are no functional changes, prepare to fix a problem that 'sb_wait'
is not woke up while 'active_io' is decreased to 0.
Signed-off-by: Yu Kuai <yukuai3@...wei.com>
---
drivers/md/md.c | 33 +++++++++++++++++++++++++++------
1 file changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0fe7ab6e8ab9..0d69b1a2e2d5 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -368,16 +368,18 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio)
return true;
}
-void md_handle_request(struct mddev *mddev, struct bio *bio)
+static bool md_array_enter(struct mddev *mddev, struct bio *bio)
{
check_suspended:
if (is_suspended(mddev, bio)) {
DEFINE_WAIT(__wait);
+
/* Bail out if REQ_NOWAIT is set for the bio */
if (bio->bi_opf & REQ_NOWAIT) {
bio_wouldblock_error(bio);
- return;
+ return false;
}
+
for (;;) {
prepare_to_wait(&mddev->sb_wait, &__wait,
TASK_UNINTERRUPTIBLE);
@@ -387,15 +389,34 @@ void md_handle_request(struct mddev *mddev, struct bio *bio)
}
finish_wait(&mddev->sb_wait, &__wait);
}
+
if (!percpu_ref_tryget_live(&mddev->active_io))
goto check_suspended;
+ return true;
+}
+
+static void md_array_exit(struct mddev *mddev)
+{
+ percpu_ref_put(&mddev->active_io);
+}
+
+void md_handle_request(struct mddev *mddev, struct bio *bio)
+{
+retry:
+ if (!md_array_enter(mddev, bio))
+ return;
+
if (!mddev->pers->make_request(mddev, bio)) {
- percpu_ref_put(&mddev->active_io);
- goto check_suspended;
+ md_array_exit(mddev);
+ goto retry;
}
- percpu_ref_put(&mddev->active_io);
+ /*
+ * pers->make_request() will grab additional reference until bio is
+ * done.
+ */
+ md_array_exit(mddev);
}
EXPORT_SYMBOL(md_handle_request);
@@ -8667,7 +8688,7 @@ static void md_end_clone_io(struct bio *bio)
bio_put(bio);
bio_endio(orig_bio);
- percpu_ref_put(&mddev->active_io);
+ md_array_exit(mddev);
}
static void md_clone_bio(struct mddev *mddev, struct bio **bio)
--
2.39.2
Powered by blists - more mailing lists