* [PATCH 0/3] Misc changes for md again
@ 2021-10-17 13:50 Guoqing Jiang
2021-10-17 13:50 ` [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device Guoqing Jiang
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Guoqing Jiang @ 2021-10-17 13:50 UTC (permalink / raw)
To: song; +Cc: linux-raid
Hello,
This patchset addresses previous comment, please review.
Thanks,
Guoqing
Guoqing Jiang (3):
md/bitmap: don't set max_write_behind if there is no write mostly
device
md/raid10: add 'read_err' to raid10_read_request
md/raid10: factor out a get_error_dev helper
drivers/md/md-bitmap.c | 18 +++++++++++++++
drivers/md/raid10.c | 52 ++++++++++++++++++++++--------------------
2 files changed, 45 insertions(+), 25 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device
2021-10-17 13:50 [PATCH 0/3] Misc changes for md again Guoqing Jiang
@ 2021-10-17 13:50 ` Guoqing Jiang
2021-10-19 6:29 ` Song Liu
2021-10-17 13:50 ` [PATCH 2/3] md/raid10: add 'read_err' to raid10_read_request Guoqing Jiang
2021-10-17 13:50 ` [PATCH 3/3] md/raid10: factor out a get_error_dev helper Guoqing Jiang
2 siblings, 1 reply; 7+ messages in thread
From: Guoqing Jiang @ 2021-10-17 13:50 UTC (permalink / raw)
To: song; +Cc: linux-raid
We shouldn't set it since write behind IO should only happen to write
mostly device.
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
---
drivers/md/md-bitmap.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index e29c6298ef5c..9424879d8d7e 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -2469,11 +2469,29 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
{
unsigned long backlog;
unsigned long old_mwb = mddev->bitmap_info.max_write_behind;
+ struct md_rdev *rdev;
+ bool has_write_mostly = false;
int rv = kstrtoul(buf, 10, &backlog);
if (rv)
return rv;
if (backlog > COUNTER_MAX)
return -EINVAL;
+
+ /*
+ * Without write mostly device, it doesn't make sense to set
+ * backlog for max_write_behind.
+ */
+ rdev_for_each(rdev, mddev)
+ if (test_bit(WriteMostly, &rdev->flags)) {
+ has_write_mostly = true;
+ break;
+ }
+ if (!has_write_mostly) {
+ pr_warn_ratelimited("%s: can't set backlog, no write mostly"
+ " device available\n", mdname(mddev));
+ return -EINVAL;
+ }
+
mddev->bitmap_info.max_write_behind = backlog;
if (!backlog && mddev->serial_info_pool) {
/* serial_info_pool is not needed if backlog is zero */
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] md/raid10: add 'read_err' to raid10_read_request
2021-10-17 13:50 [PATCH 0/3] Misc changes for md again Guoqing Jiang
2021-10-17 13:50 ` [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device Guoqing Jiang
@ 2021-10-17 13:50 ` Guoqing Jiang
2021-10-17 13:50 ` [PATCH 3/3] md/raid10: factor out a get_error_dev helper Guoqing Jiang
2 siblings, 0 replies; 7+ messages in thread
From: Guoqing Jiang @ 2021-10-17 13:50 UTC (permalink / raw)
To: song; +Cc: linux-raid
Add the paramenter since the err retry logic is only meaningful when
the caller is handle_read_error.
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
---
drivers/md/raid10.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index dde98f65bd04..49f3187b2d46 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1116,7 +1116,7 @@ static void regular_request_wait(struct mddev *mddev, struct r10conf *conf,
}
static void raid10_read_request(struct mddev *mddev, struct bio *bio,
- struct r10bio *r10_bio)
+ struct r10bio *r10_bio, bool handle_read_err)
{
struct r10conf *conf = mddev->private;
struct bio *read_bio;
@@ -1129,7 +1129,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
struct md_rdev *err_rdev = NULL;
gfp_t gfp = GFP_NOIO;
- if (slot >= 0 && r10_bio->devs[slot].rdev) {
+ if (handle_read_err && slot >= 0 && r10_bio->devs[slot].rdev) {
/*
* This is an error retry, but we cannot
* safely dereference the rdev in the r10_bio,
@@ -1519,7 +1519,7 @@ static void __make_request(struct mddev *mddev, struct bio *bio, int sectors)
conf->geo.raid_disks);
if (bio_data_dir(bio) == READ)
- raid10_read_request(mddev, bio, r10_bio);
+ raid10_read_request(mddev, bio, r10_bio, false);
else
raid10_write_request(mddev, bio, r10_bio);
}
@@ -2918,7 +2918,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
rdev_dec_pending(rdev, mddev);
allow_barrier(conf);
r10_bio->state = 0;
- raid10_read_request(mddev, r10_bio->master_bio, r10_bio);
+ raid10_read_request(mddev, r10_bio->master_bio, r10_bio, true);
}
static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] md/raid10: factor out a get_error_dev helper
2021-10-17 13:50 [PATCH 0/3] Misc changes for md again Guoqing Jiang
2021-10-17 13:50 ` [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device Guoqing Jiang
2021-10-17 13:50 ` [PATCH 2/3] md/raid10: add 'read_err' to raid10_read_request Guoqing Jiang
@ 2021-10-17 13:50 ` Guoqing Jiang
2021-10-19 6:59 ` Song Liu
2 siblings, 1 reply; 7+ messages in thread
From: Guoqing Jiang @ 2021-10-17 13:50 UTC (permalink / raw)
To: song; +Cc: linux-raid
Add a helper to find error_dev in case handle_read_err is true.
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
---
drivers/md/raid10.c | 44 +++++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 49f3187b2d46..35d842ec377b 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1115,6 +1115,27 @@ static void regular_request_wait(struct mddev *mddev, struct r10conf *conf,
}
}
+static void get_error_dev(struct mddev *mddev, struct r10conf *conf, int slot,
+ struct md_rdev **err_rdev, struct r10bio *r10_bio)
+{
+ /*
+ * This is an error retry, but we cannot
+ * safely dereference the rdev in the r10_bio,
+ * we must use the one in conf.
+ * If it has already been disconnected (unlikely)
+ * we lose the device name in error messages.
+ */
+ int disk;
+
+ rcu_read_lock();
+ disk = r10_bio->devs[slot].devnum;
+ *err_rdev = rcu_dereference(conf->mirrors[disk].rdev);
+ if (!*err_rdev)
+ /* This never gets dereferenced */
+ *err_rdev = r10_bio->devs[slot].rdev;
+ rcu_read_unlock();
+}
+
static void raid10_read_request(struct mddev *mddev, struct bio *bio,
struct r10bio *r10_bio, bool handle_read_err)
{
@@ -1130,37 +1151,18 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
gfp_t gfp = GFP_NOIO;
if (handle_read_err && slot >= 0 && r10_bio->devs[slot].rdev) {
- /*
- * This is an error retry, but we cannot
- * safely dereference the rdev in the r10_bio,
- * we must use the one in conf.
- * If it has already been disconnected (unlikely)
- * we lose the device name in error messages.
- */
- int disk;
/*
* As we are blocking raid10, it is a little safer to
* use __GFP_HIGH.
*/
gfp = GFP_NOIO | __GFP_HIGH;
-
- rcu_read_lock();
- disk = r10_bio->devs[slot].devnum;
- err_rdev = rcu_dereference(conf->mirrors[disk].rdev);
- if (err_rdev)
- bdevname(err_rdev->bdev, b);
- else {
- strcpy(b, "???");
- /* This never gets dereferenced */
- err_rdev = r10_bio->devs[slot].rdev;
- }
- rcu_read_unlock();
+ get_error_dev(mddev, conf, slot, &err_rdev, r10_bio);
}
-
regular_request_wait(mddev, conf, bio, r10_bio->sectors);
rdev = read_balance(conf, r10_bio, &max_sectors);
if (!rdev) {
if (err_rdev) {
+ bdevname(err_rdev->bdev, b);
pr_crit_ratelimited("md/raid10:%s: %s: unrecoverable I/O read error for block %llu\n",
mdname(mddev), b,
(unsigned long long)r10_bio->sector);
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device
2021-10-17 13:50 ` [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device Guoqing Jiang
@ 2021-10-19 6:29 ` Song Liu
0 siblings, 0 replies; 7+ messages in thread
From: Song Liu @ 2021-10-19 6:29 UTC (permalink / raw)
To: Guoqing Jiang; +Cc: linux-raid
On Sun, Oct 17, 2021 at 6:50 AM Guoqing Jiang <guoqing.jiang@linux.dev> wrote:
>
> We shouldn't set it since write behind IO should only happen to write
> mostly device.
>
> Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
Applied to md-next with a couple minor changes.
> ---
> drivers/md/md-bitmap.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
> index e29c6298ef5c..9424879d8d7e 100644
> --- a/drivers/md/md-bitmap.c
> +++ b/drivers/md/md-bitmap.c
> @@ -2469,11 +2469,29 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
> {
> unsigned long backlog;
> unsigned long old_mwb = mddev->bitmap_info.max_write_behind;
> + struct md_rdev *rdev;
> + bool has_write_mostly = false;
> int rv = kstrtoul(buf, 10, &backlog);
> if (rv)
> return rv;
> if (backlog > COUNTER_MAX)
> return -EINVAL;
> +
> + /*
> + * Without write mostly device, it doesn't make sense to set
> + * backlog for max_write_behind.
> + */
> + rdev_for_each(rdev, mddev)
> + if (test_bit(WriteMostly, &rdev->flags)) {
> + has_write_mostly = true;
> + break;
> + }
Added curly brackets for multi-line block.
> + if (!has_write_mostly) {
> + pr_warn_ratelimited("%s: can't set backlog, no write mostly"
> + " device available\n", mdname(mddev));
Merged the two strings to a single line. checkpatch.pl should complain
about splitting a print string.
> + return -EINVAL;
> + }
> +
> mddev->bitmap_info.max_write_behind = backlog;
> if (!backlog && mddev->serial_info_pool) {
> /* serial_info_pool is not needed if backlog is zero */
> --
> 2.31.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] md/raid10: factor out a get_error_dev helper
2021-10-17 13:50 ` [PATCH 3/3] md/raid10: factor out a get_error_dev helper Guoqing Jiang
@ 2021-10-19 6:59 ` Song Liu
2021-10-19 8:00 ` Guoqing Jiang
0 siblings, 1 reply; 7+ messages in thread
From: Song Liu @ 2021-10-19 6:59 UTC (permalink / raw)
To: Guoqing Jiang; +Cc: linux-raid
On Sun, Oct 17, 2021 at 6:50 AM Guoqing Jiang <guoqing.jiang@linux.dev> wrote:
>
> Add a helper to find error_dev in case handle_read_err is true.
>
> Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
For 2/3 and 3/3, I was thinking about something like below (only
compile tested).
Would this work?
Thanks,
Song
diff --git i/drivers/md/raid10.c w/drivers/md/raid10.c
index dde98f65bd04f..c2387f55343dd 100644
--- i/drivers/md/raid10.c
+++ w/drivers/md/raid10.c
@@ -1116,7 +1116,7 @@ static void regular_request_wait(struct mddev
*mddev, struct r10conf *conf,
}
static void raid10_read_request(struct mddev *mddev, struct bio *bio,
- struct r10bio *r10_bio)
+ struct r10bio *r10_bio, struct md_rdev
*err_rdev)
{
struct r10conf *conf = mddev->private;
struct bio *read_bio;
@@ -1126,36 +1126,17 @@ static void raid10_read_request(struct mddev
*mddev, struct bio *bio,
struct md_rdev *rdev;
char b[BDEVNAME_SIZE];
int slot = r10_bio->read_slot;
- struct md_rdev *err_rdev = NULL;
gfp_t gfp = GFP_NOIO;
- if (slot >= 0 && r10_bio->devs[slot].rdev) {
- /*
- * This is an error retry, but we cannot
- * safely dereference the rdev in the r10_bio,
- * we must use the one in conf.
- * If it has already been disconnected (unlikely)
- * we lose the device name in error messages.
- */
- int disk;
- /*
- * As we are blocking raid10, it is a little safer to
- * use __GFP_HIGH.
- */
+ /*
+ * As we are blocking raid10, it is a little safer to
+ * use __GFP_HIGH.
+ */
+ if (err_rdev) {
gfp = GFP_NOIO | __GFP_HIGH;
-
- rcu_read_lock();
- disk = r10_bio->devs[slot].devnum;
- err_rdev = rcu_dereference(conf->mirrors[disk].rdev);
- if (err_rdev)
- bdevname(err_rdev->bdev, b);
- else {
- strcpy(b, "???");
- /* This never gets dereferenced */
- err_rdev = r10_bio->devs[slot].rdev;
- }
- rcu_read_unlock();
- }
+ bdevname(err_rdev->bdev, b);
+ } else
+ strcpy(b, "???");
regular_request_wait(mddev, conf, bio, r10_bio->sectors);
rdev = read_balance(conf, r10_bio, &max_sectors);
@@ -1519,7 +1500,7 @@ static void __make_request(struct mddev *mddev,
struct bio *bio, int sectors)
conf->geo.raid_disks);
if (bio_data_dir(bio) == READ)
- raid10_read_request(mddev, bio, r10_bio);
+ raid10_read_request(mddev, bio, r10_bio, NULL);
else
raid10_write_request(mddev, bio, r10_bio);
}
@@ -2887,6 +2868,31 @@ static int narrow_write_error(struct r10bio
*r10_bio, int i)
return ok;
}
+static struct md_rdev *get_error_dev(struct mddev *mddev, struct
r10conf *conf, int slot,
+ struct r10bio *r10_bio)
+{
+ struct md_rdev *err_rdev = NULL;
+
+ /*
+ * This is an error retry, but we cannot
+ * safely dereference the rdev in the r10_bio,
+ * we must use the one in conf.
+ * If it has already been disconnected (unlikely)
+ * we lose the device name in error messages.
+ */
+ int disk;
+
+ rcu_read_lock();
+ disk = r10_bio->devs[slot].devnum;
+ err_rdev = rcu_dereference(conf->mirrors[disk].rdev);
+ if (!err_rdev) {
+ /* This never gets dereferenced */
+ err_rdev = r10_bio->devs[slot].rdev;
+ }
+ rcu_read_unlock();
+ return err_rdev;
+}
+
static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
{
int slot = r10_bio->read_slot;
@@ -2918,7 +2924,8 @@ static void handle_read_error(struct mddev
*mddev, struct r10bio *r10_bio)
rdev_dec_pending(rdev, mddev);
allow_barrier(conf);
r10_bio->state = 0;
- raid10_read_request(mddev, r10_bio->master_bio, r10_bio);
+ raid10_read_request(mddev, r10_bio->master_bio, r10_bio,
+ get_error_dev(mddev, conf, slot, r10_bio));
}
static void handle_write_completed(struct r10conf *conf, struct
r10bio *r10_bio)
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] md/raid10: factor out a get_error_dev helper
2021-10-19 6:59 ` Song Liu
@ 2021-10-19 8:00 ` Guoqing Jiang
0 siblings, 0 replies; 7+ messages in thread
From: Guoqing Jiang @ 2021-10-19 8:00 UTC (permalink / raw)
To: Song Liu; +Cc: linux-raid
On 10/19/21 2:59 PM, Song Liu wrote:
> On Sun, Oct 17, 2021 at 6:50 AM Guoqing Jiang<guoqing.jiang@linux.dev> wrote:
>> Add a helper to find error_dev in case handle_read_err is true.
>>
>> Signed-off-by: Guoqing Jiang<guoqing.jiang@linux.dev>
> For 2/3 and 3/3, I was thinking about something like below (only
> compile tested).
> Would this work?
Thanks for clarification, I guess it works.
> Thanks,
> Song
>
> diff --git i/drivers/md/raid10.c w/drivers/md/raid10.c
> index dde98f65bd04f..c2387f55343dd 100644
> --- i/drivers/md/raid10.c
> +++ w/drivers/md/raid10.c
> @@ -1116,7 +1116,7 @@ static void regular_request_wait(struct mddev
> *mddev, struct r10conf *conf,
> }
>
> static void raid10_read_request(struct mddev *mddev, struct bio *bio,
> - struct r10bio *r10_bio)
> + struct r10bio *r10_bio, struct md_rdev
> *err_rdev)
> {
> struct r10conf *conf = mddev->private;
> struct bio *read_bio;
> @@ -1126,36 +1126,17 @@ static void raid10_read_request(struct mddev
> *mddev, struct bio *bio,
> struct md_rdev *rdev;
> char b[BDEVNAME_SIZE];
> int slot = r10_bio->read_slot;
> - struct md_rdev *err_rdev = NULL;
> gfp_t gfp = GFP_NOIO;
>
> - if (slot >= 0 && r10_bio->devs[slot].rdev) {
> - /*
> - * This is an error retry, but we cannot
> - * safely dereference the rdev in the r10_bio,
> - * we must use the one in conf.
> - * If it has already been disconnected (unlikely)
> - * we lose the device name in error messages.
> - */
> - int disk;
> - /*
> - * As we are blocking raid10, it is a little safer to
> - * use __GFP_HIGH.
> - */
> + /*
> + * As we are blocking raid10, it is a little safer to
> + * use __GFP_HIGH.
> + */
> + if (err_rdev) {
> gfp = GFP_NOIO | __GFP_HIGH;
> -
> - rcu_read_lock();
> - disk = r10_bio->devs[slot].devnum;
> - err_rdev = rcu_dereference(conf->mirrors[disk].rdev);
> - if (err_rdev)
> - bdevname(err_rdev->bdev, b);
> - else {
> - strcpy(b, "???");
> - /* This never gets dereferenced */
> - err_rdev = r10_bio->devs[slot].rdev;
> - }
> - rcu_read_unlock();
> - }
> + bdevname(err_rdev->bdev, b);
> + } else
> + strcpy(b, "???");
>
> regular_request_wait(mddev, conf, bio, r10_bio->sectors);
> rdev = read_balance(conf, r10_bio, &max_sectors);
> @@ -1519,7 +1500,7 @@ static void __make_request(struct mddev *mddev,
> struct bio *bio, int sectors)
> conf->geo.raid_disks);
>
> if (bio_data_dir(bio) == READ)
> - raid10_read_request(mddev, bio, r10_bio);
> + raid10_read_request(mddev, bio, r10_bio, NULL);
> else
> raid10_write_request(mddev, bio, r10_bio);
> }
> @@ -2887,6 +2868,31 @@ static int narrow_write_error(struct r10bio
> *r10_bio, int i)
> return ok;
> }
>
> +static struct md_rdev *get_error_dev(struct mddev *mddev, struct
> r10conf *conf, int slot,
> + struct r10bio *r10_bio)
> +{
> + struct md_rdev *err_rdev = NULL;
> +
We need the original check ("slot >= 0 && r10_bio->devs[slot].rdev ")
in the function I think. Will take a closer look and send a new version.
Thanks,
Guoqing
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-10-19 8:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-17 13:50 [PATCH 0/3] Misc changes for md again Guoqing Jiang
2021-10-17 13:50 ` [PATCH 1/3] md/bitmap: don't set max_write_behind if there is no write mostly device Guoqing Jiang
2021-10-19 6:29 ` Song Liu
2021-10-17 13:50 ` [PATCH 2/3] md/raid10: add 'read_err' to raid10_read_request Guoqing Jiang
2021-10-17 13:50 ` [PATCH 3/3] md/raid10: factor out a get_error_dev helper Guoqing Jiang
2021-10-19 6:59 ` Song Liu
2021-10-19 8:00 ` Guoqing Jiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).