* [RFC PATCH] md: raid456 improve discard performance
[not found] <20220203051546.12337-1-vverma@digitalocean.com>
@ 2022-02-03 5:28 ` Vishal Verma
2022-02-07 7:24 ` Xiao Ni
0 siblings, 1 reply; 6+ messages in thread
From: Vishal Verma @ 2022-02-03 5:28 UTC (permalink / raw)
To: Song Liu; +Cc: xni, linux-raid
Hello,
I would like to get your feedback on the following patch for improving
raid456 discard performance. This seem to improve discard performance
for raid456 quite significantly (just like raid10 discard optimization did).
Unfortunately, this patch is not in stable form right now. I do not have
very good understanding of raid456 code and would really love to get
your guys feedback.
I basically tried to incorporate raid0's optimzed discard code logic
into raid456 make_discard fn, but I am sure I am missing some things
as the raid456 layout is very different than that of raid0 or 10.
Would appreciate the feedback.
This patch improves discard performance with raid456 by sending
discard bio directly to the underlying disk just like how raid0/10
handle discard request. Currently, the discard request for raid456
gets sent to the disks on a per stripe basis which involves lots of
bio split/merge and makes it pretty slow performant vs. sending
the requests directly to the disks. This patch is intended to issue
discard request in the the similar way with patch
29efc390b (md/md0: optimize raid0 discard handling).
Signed-off-by: Vishal Verma <vverma@digitalocean.com>
---
drivers/md/raid5.c | 184 ++++++++++++++++++++++++---------------------
1 file changed, 99 insertions(+), 85 deletions(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7c119208a214..2d57cf105471 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5681,93 +5681,108 @@ static void release_stripe_plug(struct mddev
*mddev,
static void make_discard_request(struct mddev *mddev, struct bio *bi)
{
- struct r5conf *conf = mddev->private;
- sector_t logical_sector, last_sector;
- struct stripe_head *sh;
- int stripe_sectors;
-
- /* We need to handle this when io_uring supports discard/trim */
- if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
+ struct r5conf *conf = mddev->private;
+ sector_t bio_start, bio_end;
+ unsigned int start_disk_index, end_disk_index;
+ sector_t start_disk_offset, end_disk_offset;
+ sector_t first_stripe_index, last_stripe_index;
+ sector_t split_size;
+ struct bio *split;
+ unsigned int remainder;
+ int d;
+ int stripe_sectors;
+
+ /* We need to handle this when io_uring supports discard/trim */
+ if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
+ return;
+
+ if (mddev->reshape_position != MaxSector)
+ /* Skip discard while reshape is happening */
+ return;
+
+ stripe_sectors = conf->chunk_sectors *
+ (conf->raid_disks - conf->max_degraded);
+
+ if (bio_sectors(bi) < stripe_sectors * 2)
return;
- if (mddev->reshape_position != MaxSector)
- /* Skip discard while reshape is happening */
- return;
-
- logical_sector = bi->bi_iter.bi_sector &
~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
- last_sector = bio_end_sector(bi);
-
- bi->bi_next = NULL;
-
- stripe_sectors = conf->chunk_sectors *
- (conf->raid_disks - conf->max_degraded);
- logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
- stripe_sectors);
- sector_div(last_sector, stripe_sectors);
-
- logical_sector *= conf->chunk_sectors;
- last_sector *= conf->chunk_sectors;
-
- for (; logical_sector < last_sector;
- logical_sector += RAID5_STRIPE_SECTORS(conf)) {
- DEFINE_WAIT(w);
- int d;
- again:
- sh = raid5_get_active_stripe(conf, logical_sector, 0, 0, 0);
- prepare_to_wait(&conf->wait_for_overlap, &w,
- TASK_UNINTERRUPTIBLE);
- set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
- if (test_bit(STRIPE_SYNCING, &sh->state)) {
- raid5_release_stripe(sh);
- schedule();
- goto again;
- }
- clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
- spin_lock_irq(&sh->stripe_lock);
- for (d = 0; d < conf->raid_disks; d++) {
- if (d == sh->pd_idx || d == sh->qd_idx)
- continue;
- if (sh->dev[d].towrite || sh->dev[d].toread) {
- set_bit(R5_Overlap, &sh->dev[d].flags);
- spin_unlock_irq(&sh->stripe_lock);
- raid5_release_stripe(sh);
- schedule();
- goto again;
- }
- }
- set_bit(STRIPE_DISCARD, &sh->state);
- finish_wait(&conf->wait_for_overlap, &w);
- sh->overwrite_disks = 0;
- for (d = 0; d < conf->raid_disks; d++) {
- if (d == sh->pd_idx || d == sh->qd_idx)
- continue;
- sh->dev[d].towrite = bi;
- set_bit(R5_OVERWRITE, &sh->dev[d].flags);
- bio_inc_remaining(bi);
- md_write_inc(mddev, bi);
- sh->overwrite_disks++;
- }
- spin_unlock_irq(&sh->stripe_lock);
- if (conf->mddev->bitmap) {
- for (d = 0;
- d < conf->raid_disks - conf->max_degraded;
- d++)
- md_bitmap_startwrite(mddev->bitmap,
- sh->sector,
- RAID5_STRIPE_SECTORS(conf),
- 0);
- sh->bm_seq = conf->seq_flush + 1;
- set_bit(STRIPE_BIT_DELAY, &sh->state);
- }
-
- set_bit(STRIPE_HANDLE, &sh->state);
- clear_bit(STRIPE_DELAYED, &sh->state);
- if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
- atomic_inc(&conf->preread_active_stripes);
- release_stripe_plug(mddev, sh);
- }
-
- bio_endio(bi);
+ bio_start = bi->bi_iter.bi_sector &
~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
+ bio_end = bio_end_sector(bi);
+
+ /*
+ * Keep bio aligned with strip size.
+ */
+ div_u64_rem(bio_start, stripe_sectors, &remainder);
+ if (remainder) {
+ split_size = stripe_sectors - remainder;
+ split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
+ bio_chain(split, bi);
+ /* Resend the fist split part */
+ submit_bio_noacct(split);
+ }
+ div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
+ if (remainder) {
+ split_size = bio_sectors(bi) - remainder;
+ split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
+ bio_chain(split, bi);
+ /* Resend the second split part */
+ submit_bio_noacct(bi);
+ bi = split;
+ }
+
+ bio_start = bi->bi_iter.bi_sector &
~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
+ bio_end = bio_end_sector(bi);
+
+ bi->bi_next = NULL;
+
+ first_stripe_index = bio_start;
+ sector_div(first_stripe_index, stripe_sectors);
+
+ last_stripe_index = bio_end;
+ sector_div(last_stripe_index, stripe_sectors);
+
+ start_disk_index = (int)(bio_start - first_stripe_index *
stripe_sectors) /
+ conf->chunk_sectors;
+ start_disk_offset = ((int)(bio_start - first_stripe_index *
stripe_sectors) %
+ conf->chunk_sectors) +
+ first_stripe_index * conf->chunk_sectors;
+ end_disk_index = (int)(bio_end - last_stripe_index * stripe_sectors) /
+ conf->chunk_sectors;
+ end_disk_offset = ((int)(bio_end - last_stripe_index * stripe_sectors) %
+ conf->chunk_sectors) +
+ last_stripe_index * conf->chunk_sectors;
+
+ for (d = 0; d < conf->raid_disks; d++) {
+ sector_t dev_start, dev_end;
+ struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
+
+ dev_start = bio_start;
+ dev_end = bio_end;
+
+ if (d < start_disk_index)
+ dev_start = (first_stripe_index + 1) *
+ conf->chunk_sectors;
+ else if (d > start_disk_index)
+ dev_start = first_stripe_index * conf->chunk_sectors;
+ else
+ dev_start = start_disk_offset;
+
+ if (d < end_disk_index)
+ dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
+ else if (d > end_disk_index)
+ dev_end = last_stripe_index * conf->chunk_sectors;
+ else
+ dev_end = end_disk_offset;
+
+ if (dev_end <= dev_start)
+ continue;
+
+ md_submit_discard_bio(mddev, rdev, bi,
+ dev_start + rdev->data_offset,
+ dev_end - dev_start);
+ }
+
+ bio_endio(bi);
}
static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] md: raid456 improve discard performance
2022-02-03 5:28 ` [RFC PATCH] md: raid456 improve discard performance Vishal Verma
@ 2022-02-07 7:24 ` Xiao Ni
2022-02-07 15:27 ` Vishal Verma
2022-02-07 15:32 ` Vishal Verma
0 siblings, 2 replies; 6+ messages in thread
From: Xiao Ni @ 2022-02-07 7:24 UTC (permalink / raw)
To: Vishal Verma; +Cc: Song Liu, linux-raid
Hi Vishal
Thanks for this. The thought of sending discard bio to member disk
directly should be
good. As you said, raid456 is more complicated with raid0/raid10. It
needs to think about
more things. First, it needs to avoid conflict with resync I/O. I
don't read the codes below.
The format is not right. There is no proper tab in the beginning of
each line of code.
And what's your specific question you want to talk about?
Regards
Xiao
On Thu, Feb 3, 2022 at 1:28 PM Vishal Verma <vverma@digitalocean.com> wrote:
>
> Hello,
>
> I would like to get your feedback on the following patch for improving
> raid456 discard performance. This seem to improve discard performance
> for raid456 quite significantly (just like raid10 discard optimization did).
> Unfortunately, this patch is not in stable form right now. I do not have
> very good understanding of raid456 code and would really love to get
> your guys feedback.
>
>
> I basically tried to incorporate raid0's optimzed discard code logic
> into raid456 make_discard fn, but I am sure I am missing some things
> as the raid456 layout is very different than that of raid0 or 10.
> Would appreciate the feedback.
>
>
> This patch improves discard performance with raid456 by sending
> discard bio directly to the underlying disk just like how raid0/10
> handle discard request. Currently, the discard request for raid456
> gets sent to the disks on a per stripe basis which involves lots of
> bio split/merge and makes it pretty slow performant vs. sending
> the requests directly to the disks. This patch is intended to issue
> discard request in the the similar way with patch
> 29efc390b (md/md0: optimize raid0 discard handling).
>
> Signed-off-by: Vishal Verma <vverma@digitalocean.com>
> ---
> drivers/md/raid5.c | 184 ++++++++++++++++++++++++---------------------
> 1 file changed, 99 insertions(+), 85 deletions(-)
>
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 7c119208a214..2d57cf105471 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -5681,93 +5681,108 @@ static void release_stripe_plug(struct mddev
> *mddev,
> static void make_discard_request(struct mddev *mddev, struct bio *bi)
> {
> - struct r5conf *conf = mddev->private;
> - sector_t logical_sector, last_sector;
> - struct stripe_head *sh;
> - int stripe_sectors;
> -
> - /* We need to handle this when io_uring supports discard/trim */
> - if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
> + struct r5conf *conf = mddev->private;
> + sector_t bio_start, bio_end;
> + unsigned int start_disk_index, end_disk_index;
> + sector_t start_disk_offset, end_disk_offset;
> + sector_t first_stripe_index, last_stripe_index;
> + sector_t split_size;
> + struct bio *split;
> + unsigned int remainder;
> + int d;
> + int stripe_sectors;
> +
> + /* We need to handle this when io_uring supports discard/trim */
> + if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
> + return;
> +
> + if (mddev->reshape_position != MaxSector)
> + /* Skip discard while reshape is happening */
> + return;
> +
> + stripe_sectors = conf->chunk_sectors *
> + (conf->raid_disks - conf->max_degraded);
> +
> + if (bio_sectors(bi) < stripe_sectors * 2)
> return;
> - if (mddev->reshape_position != MaxSector)
> - /* Skip discard while reshape is happening */
> - return;
> -
> - logical_sector = bi->bi_iter.bi_sector &
> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
> - last_sector = bio_end_sector(bi);
> -
> - bi->bi_next = NULL;
> -
> - stripe_sectors = conf->chunk_sectors *
> - (conf->raid_disks - conf->max_degraded);
> - logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
> - stripe_sectors);
> - sector_div(last_sector, stripe_sectors);
> -
> - logical_sector *= conf->chunk_sectors;
> - last_sector *= conf->chunk_sectors;
> -
> - for (; logical_sector < last_sector;
> - logical_sector += RAID5_STRIPE_SECTORS(conf)) {
> - DEFINE_WAIT(w);
> - int d;
> - again:
> - sh = raid5_get_active_stripe(conf, logical_sector, 0, 0, 0);
> - prepare_to_wait(&conf->wait_for_overlap, &w,
> - TASK_UNINTERRUPTIBLE);
> - set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
> - if (test_bit(STRIPE_SYNCING, &sh->state)) {
> - raid5_release_stripe(sh);
> - schedule();
> - goto again;
> - }
> - clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
> - spin_lock_irq(&sh->stripe_lock);
> - for (d = 0; d < conf->raid_disks; d++) {
> - if (d == sh->pd_idx || d == sh->qd_idx)
> - continue;
> - if (sh->dev[d].towrite || sh->dev[d].toread) {
> - set_bit(R5_Overlap, &sh->dev[d].flags);
> - spin_unlock_irq(&sh->stripe_lock);
> - raid5_release_stripe(sh);
> - schedule();
> - goto again;
> - }
> - }
> - set_bit(STRIPE_DISCARD, &sh->state);
> - finish_wait(&conf->wait_for_overlap, &w);
> - sh->overwrite_disks = 0;
> - for (d = 0; d < conf->raid_disks; d++) {
> - if (d == sh->pd_idx || d == sh->qd_idx)
> - continue;
> - sh->dev[d].towrite = bi;
> - set_bit(R5_OVERWRITE, &sh->dev[d].flags);
> - bio_inc_remaining(bi);
> - md_write_inc(mddev, bi);
> - sh->overwrite_disks++;
> - }
> - spin_unlock_irq(&sh->stripe_lock);
> - if (conf->mddev->bitmap) {
> - for (d = 0;
> - d < conf->raid_disks - conf->max_degraded;
> - d++)
> - md_bitmap_startwrite(mddev->bitmap,
> - sh->sector,
> - RAID5_STRIPE_SECTORS(conf),
> - 0);
> - sh->bm_seq = conf->seq_flush + 1;
> - set_bit(STRIPE_BIT_DELAY, &sh->state);
> - }
> -
> - set_bit(STRIPE_HANDLE, &sh->state);
> - clear_bit(STRIPE_DELAYED, &sh->state);
> - if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
> - atomic_inc(&conf->preread_active_stripes);
> - release_stripe_plug(mddev, sh);
> - }
> -
> - bio_endio(bi);
> + bio_start = bi->bi_iter.bi_sector &
> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
> + bio_end = bio_end_sector(bi);
> +
> + /*
> + * Keep bio aligned with strip size.
> + */
> + div_u64_rem(bio_start, stripe_sectors, &remainder);
> + if (remainder) {
> + split_size = stripe_sectors - remainder;
> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
> + bio_chain(split, bi);
> + /* Resend the fist split part */
> + submit_bio_noacct(split);
> + }
> + div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
> + if (remainder) {
> + split_size = bio_sectors(bi) - remainder;
> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
> + bio_chain(split, bi);
> + /* Resend the second split part */
> + submit_bio_noacct(bi);
> + bi = split;
> + }
> +
> + bio_start = bi->bi_iter.bi_sector &
> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
> + bio_end = bio_end_sector(bi);
> +
> + bi->bi_next = NULL;
> +
> + first_stripe_index = bio_start;
> + sector_div(first_stripe_index, stripe_sectors);
> +
> + last_stripe_index = bio_end;
> + sector_div(last_stripe_index, stripe_sectors);
> +
> + start_disk_index = (int)(bio_start - first_stripe_index *
> stripe_sectors) /
> + conf->chunk_sectors;
> + start_disk_offset = ((int)(bio_start - first_stripe_index *
> stripe_sectors) %
> + conf->chunk_sectors) +
> + first_stripe_index * conf->chunk_sectors;
> + end_disk_index = (int)(bio_end - last_stripe_index * stripe_sectors) /
> + conf->chunk_sectors;
> + end_disk_offset = ((int)(bio_end - last_stripe_index * stripe_sectors) %
> + conf->chunk_sectors) +
> + last_stripe_index * conf->chunk_sectors;
> +
> + for (d = 0; d < conf->raid_disks; d++) {
> + sector_t dev_start, dev_end;
> + struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
> +
> + dev_start = bio_start;
> + dev_end = bio_end;
> +
> + if (d < start_disk_index)
> + dev_start = (first_stripe_index + 1) *
> + conf->chunk_sectors;
> + else if (d > start_disk_index)
> + dev_start = first_stripe_index * conf->chunk_sectors;
> + else
> + dev_start = start_disk_offset;
> +
> + if (d < end_disk_index)
> + dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
> + else if (d > end_disk_index)
> + dev_end = last_stripe_index * conf->chunk_sectors;
> + else
> + dev_end = end_disk_offset;
> +
> + if (dev_end <= dev_start)
> + continue;
> +
> + md_submit_discard_bio(mddev, rdev, bi,
> + dev_start + rdev->data_offset,
> + dev_end - dev_start);
> + }
> +
> + bio_endio(bi);
> }
> static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
>
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC PATCH] md: raid456 improve discard performance
2022-02-07 7:24 ` Xiao Ni
@ 2022-02-07 15:27 ` Vishal Verma
2022-02-07 15:32 ` Vishal Verma
1 sibling, 0 replies; 6+ messages in thread
From: Vishal Verma @ 2022-02-07 15:27 UTC (permalink / raw)
To: xni, song; +Cc: linux-raid, Vishal Verma
This patch improves discard performance with raid456 by sending
discard bio directly to the underlying disk just like how raid0/10
handle discard request. Currently, the discard request for raid456
gets sent to the disks on a per stripe basis which involves lots of
bio split/merge and makes it pretty slow performant vs. sending
the requests directly to the disks. This patch is intended to issue
discard request in the the similar way with patch
29efc390b (md/md0: optimize raid0 discard handling).
Signed-off-by: Vishal Verma <vverma@digitalocean.com>
---
drivers/md/raid5.c | 182 ++++++++++++++++++++++++---------------------
1 file changed, 99 insertions(+), 83 deletions(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7c119208a214..a17bc951fb9e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5681,93 +5681,110 @@ static void release_stripe_plug(struct mddev *mddev,
static void make_discard_request(struct mddev *mddev, struct bio *bi)
{
- struct r5conf *conf = mddev->private;
- sector_t logical_sector, last_sector;
- struct stripe_head *sh;
- int stripe_sectors;
+ struct r5conf *conf = mddev->private;
+ sector_t bio_start, bio_end;
+ unsigned int start_disk_index, end_disk_index;
+ sector_t start_disk_offset, end_disk_offset;
+ sector_t first_stripe_index, last_stripe_index;
+ sector_t split_size;
+ struct bio *split;
+ unsigned int remainder;
+ int d;
+ int stripe_sectors;
+
+ /* We need to handle this when io_uring supports discard/trim */
+ if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
+ return;
+
+ /* Skip discard while reshape or resync is happening */
+ if ((mddev->reshape_position != MaxSector) ||
+ test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+ return;
+ }
- /* We need to handle this when io_uring supports discard/trim */
- if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
- return;
+ stripe_sectors = conf->chunk_sectors *
+ (conf->raid_disks - conf->max_degraded);
- if (mddev->reshape_position != MaxSector)
- /* Skip discard while reshape is happening */
+ if (bio_sectors(bi) < stripe_sectors * 2)
return;
- logical_sector = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
- last_sector = bio_end_sector(bi);
-
- bi->bi_next = NULL;
-
- stripe_sectors = conf->chunk_sectors *
- (conf->raid_disks - conf->max_degraded);
- logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
- stripe_sectors);
- sector_div(last_sector, stripe_sectors);
-
- logical_sector *= conf->chunk_sectors;
- last_sector *= conf->chunk_sectors;
-
- for (; logical_sector < last_sector;
- logical_sector += RAID5_STRIPE_SECTORS(conf)) {
- DEFINE_WAIT(w);
- int d;
- again:
- sh = raid5_get_active_stripe(conf, logical_sector, 0, 0, 0);
- prepare_to_wait(&conf->wait_for_overlap, &w,
- TASK_UNINTERRUPTIBLE);
- set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
- if (test_bit(STRIPE_SYNCING, &sh->state)) {
- raid5_release_stripe(sh);
- schedule();
- goto again;
- }
- clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
- spin_lock_irq(&sh->stripe_lock);
- for (d = 0; d < conf->raid_disks; d++) {
- if (d == sh->pd_idx || d == sh->qd_idx)
- continue;
- if (sh->dev[d].towrite || sh->dev[d].toread) {
- set_bit(R5_Overlap, &sh->dev[d].flags);
- spin_unlock_irq(&sh->stripe_lock);
- raid5_release_stripe(sh);
- schedule();
- goto again;
- }
- }
- set_bit(STRIPE_DISCARD, &sh->state);
- finish_wait(&conf->wait_for_overlap, &w);
- sh->overwrite_disks = 0;
- for (d = 0; d < conf->raid_disks; d++) {
- if (d == sh->pd_idx || d == sh->qd_idx)
- continue;
- sh->dev[d].towrite = bi;
- set_bit(R5_OVERWRITE, &sh->dev[d].flags);
- bio_inc_remaining(bi);
- md_write_inc(mddev, bi);
- sh->overwrite_disks++;
- }
- spin_unlock_irq(&sh->stripe_lock);
- if (conf->mddev->bitmap) {
- for (d = 0;
- d < conf->raid_disks - conf->max_degraded;
- d++)
- md_bitmap_startwrite(mddev->bitmap,
- sh->sector,
- RAID5_STRIPE_SECTORS(conf),
- 0);
- sh->bm_seq = conf->seq_flush + 1;
- set_bit(STRIPE_BIT_DELAY, &sh->state);
- }
-
- set_bit(STRIPE_HANDLE, &sh->state);
- clear_bit(STRIPE_DELAYED, &sh->state);
- if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
- atomic_inc(&conf->preread_active_stripes);
- release_stripe_plug(mddev, sh);
- }
-
- bio_endio(bi);
+ bio_start = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
+ bio_end = bio_end_sector(bi);
+
+ /*
+ * Keep bio aligned with strip size.
+ */
+ div_u64_rem(bio_start, stripe_sectors, &remainder);
+ if (remainder) {
+ split_size = stripe_sectors - remainder;
+ split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
+ bio_chain(split, bi);
+ /* Resend the fist split part */
+ submit_bio_noacct(split);
+ }
+ div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
+ if (remainder) {
+ split_size = bio_sectors(bi) - remainder;
+ split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
+ bio_chain(split, bi);
+ /* Resend the second split part */
+ submit_bio_noacct(bi);
+ bi = split;
+ }
+
+ bio_start = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
+ bio_end = bio_end_sector(bi);
+
+ bi->bi_next = NULL;
+
+ first_stripe_index = bio_start;
+ sector_div(first_stripe_index, stripe_sectors);
+
+ last_stripe_index = bio_end;
+ sector_div(last_stripe_index, stripe_sectors);
+
+ start_disk_index = (int)(bio_start - first_stripe_index * stripe_sectors) /
+ conf->chunk_sectors;
+ start_disk_offset = ((int)(bio_start - first_stripe_index * stripe_sectors) %
+ conf->chunk_sectors) +
+ first_stripe_index * conf->chunk_sectors;
+ end_disk_index = (int)(bio_end - last_stripe_index * stripe_sectors) /
+ conf->chunk_sectors;
+ end_disk_offset = ((int)(bio_end - last_stripe_index * stripe_sectors) %
+ conf->chunk_sectors) +
+ last_stripe_index * conf->chunk_sectors;
+
+ for (d = 0; d < conf->raid_disks; d++) {
+ sector_t dev_start, dev_end;
+ struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
+
+ dev_start = bio_start;
+ dev_end = bio_end;
+
+ if (d < start_disk_index)
+ dev_start = (first_stripe_index + 1) *
+ conf->chunk_sectors;
+ else if (d > start_disk_index)
+ dev_start = first_stripe_index * conf->chunk_sectors;
+ else
+ dev_start = start_disk_offset;
+
+ if (d < end_disk_index)
+ dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
+ else if (d > end_disk_index)
+ dev_end = last_stripe_index * conf->chunk_sectors;
+ else
+ dev_end = end_disk_offset;
+
+ if (dev_end <= dev_start)
+ continue;
+
+ md_submit_discard_bio(mddev, rdev, bi,
+ dev_start + rdev->data_offset,
+ dev_end - dev_start);
+ }
+
+ bio_endio(bi);
}
static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] md: raid456 improve discard performance
2022-02-07 7:24 ` Xiao Ni
2022-02-07 15:27 ` Vishal Verma
@ 2022-02-07 15:32 ` Vishal Verma
2022-02-11 14:45 ` Vishal Verma
1 sibling, 1 reply; 6+ messages in thread
From: Vishal Verma @ 2022-02-07 15:32 UTC (permalink / raw)
To: Xiao Ni; +Cc: Song Liu, linux-raid
On 2/7/22 12:24 AM, Xiao Ni wrote:
> Hi Vishal
>
> Thanks for this. The thought of sending discard bio to member disk
> directly should be
> good. As you said, raid456 is more complicated with raid0/raid10. It
> needs to think about
> more things. First, it needs to avoid conflict with resync I/O. I
> don't read the codes below.
> The format is not right. There is no proper tab in the beginning of
> each line of code.
Thanks!
Yeah somehow the formatting for messed up. Sorry about that. Just sent
it again.
> And what's your specific question you want to talk about?
Right, so I was struggling to debug the stabilty issue. It is working
when creating a raid6
array and mkfs.ext4 it with discard. But, as soon as I issue fstrim to
it, fstrim is hanging which
is pointing to probably some chunk mis-alignment issue. Thats where
would like help with
reviewing the code and see if I am calculating the discard region and
start/end correctly.
>
> Regards
> Xiao
>
> On Thu, Feb 3, 2022 at 1:28 PM Vishal Verma <vverma@digitalocean.com> wrote:
>> Hello,
>>
>> I would like to get your feedback on the following patch for improving
>> raid456 discard performance. This seem to improve discard performance
>> for raid456 quite significantly (just like raid10 discard optimization did).
>> Unfortunately, this patch is not in stable form right now. I do not have
>> very good understanding of raid456 code and would really love to get
>> your guys feedback.
>>
>>
>> I basically tried to incorporate raid0's optimzed discard code logic
>> into raid456 make_discard fn, but I am sure I am missing some things
>> as the raid456 layout is very different than that of raid0 or 10.
>> Would appreciate the feedback.
>>
>>
>> This patch improves discard performance with raid456 by sending
>> discard bio directly to the underlying disk just like how raid0/10
>> handle discard request. Currently, the discard request for raid456
>> gets sent to the disks on a per stripe basis which involves lots of
>> bio split/merge and makes it pretty slow performant vs. sending
>> the requests directly to the disks. This patch is intended to issue
>> discard request in the the similar way with patch
>> 29efc390b (md/md0: optimize raid0 discard handling).
>>
>> Signed-off-by: Vishal Verma <vverma@digitalocean.com>
>> ---
>> drivers/md/raid5.c | 184 ++++++++++++++++++++++++---------------------
>> 1 file changed, 99 insertions(+), 85 deletions(-)
>>
>> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
>> index 7c119208a214..2d57cf105471 100644
>> --- a/drivers/md/raid5.c
>> +++ b/drivers/md/raid5.c
>> @@ -5681,93 +5681,108 @@ static void release_stripe_plug(struct mddev
>> *mddev,
>> static void make_discard_request(struct mddev *mddev, struct bio *bi)
>> {
>> - struct r5conf *conf = mddev->private;
>> - sector_t logical_sector, last_sector;
>> - struct stripe_head *sh;
>> - int stripe_sectors;
>> -
>> - /* We need to handle this when io_uring supports discard/trim */
>> - if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
>> + struct r5conf *conf = mddev->private;
>> + sector_t bio_start, bio_end;
>> + unsigned int start_disk_index, end_disk_index;
>> + sector_t start_disk_offset, end_disk_offset;
>> + sector_t first_stripe_index, last_stripe_index;
>> + sector_t split_size;
>> + struct bio *split;
>> + unsigned int remainder;
>> + int d;
>> + int stripe_sectors;
>> +
>> + /* We need to handle this when io_uring supports discard/trim */
>> + if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
>> + return;
>> +
>> + if (mddev->reshape_position != MaxSector)
>> + /* Skip discard while reshape is happening */
>> + return;
>> +
>> + stripe_sectors = conf->chunk_sectors *
>> + (conf->raid_disks - conf->max_degraded);
>> +
>> + if (bio_sectors(bi) < stripe_sectors * 2)
>> return;
>> - if (mddev->reshape_position != MaxSector)
>> - /* Skip discard while reshape is happening */
>> - return;
>> -
>> - logical_sector = bi->bi_iter.bi_sector &
>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>> - last_sector = bio_end_sector(bi);
>> -
>> - bi->bi_next = NULL;
>> -
>> - stripe_sectors = conf->chunk_sectors *
>> - (conf->raid_disks - conf->max_degraded);
>> - logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
>> - stripe_sectors);
>> - sector_div(last_sector, stripe_sectors);
>> -
>> - logical_sector *= conf->chunk_sectors;
>> - last_sector *= conf->chunk_sectors;
>> -
>> - for (; logical_sector < last_sector;
>> - logical_sector += RAID5_STRIPE_SECTORS(conf)) {
>> - DEFINE_WAIT(w);
>> - int d;
>> - again:
>> - sh = raid5_get_active_stripe(conf, logical_sector, 0, 0, 0);
>> - prepare_to_wait(&conf->wait_for_overlap, &w,
>> - TASK_UNINTERRUPTIBLE);
>> - set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
>> - if (test_bit(STRIPE_SYNCING, &sh->state)) {
>> - raid5_release_stripe(sh);
>> - schedule();
>> - goto again;
>> - }
>> - clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
>> - spin_lock_irq(&sh->stripe_lock);
>> - for (d = 0; d < conf->raid_disks; d++) {
>> - if (d == sh->pd_idx || d == sh->qd_idx)
>> - continue;
>> - if (sh->dev[d].towrite || sh->dev[d].toread) {
>> - set_bit(R5_Overlap, &sh->dev[d].flags);
>> - spin_unlock_irq(&sh->stripe_lock);
>> - raid5_release_stripe(sh);
>> - schedule();
>> - goto again;
>> - }
>> - }
>> - set_bit(STRIPE_DISCARD, &sh->state);
>> - finish_wait(&conf->wait_for_overlap, &w);
>> - sh->overwrite_disks = 0;
>> - for (d = 0; d < conf->raid_disks; d++) {
>> - if (d == sh->pd_idx || d == sh->qd_idx)
>> - continue;
>> - sh->dev[d].towrite = bi;
>> - set_bit(R5_OVERWRITE, &sh->dev[d].flags);
>> - bio_inc_remaining(bi);
>> - md_write_inc(mddev, bi);
>> - sh->overwrite_disks++;
>> - }
>> - spin_unlock_irq(&sh->stripe_lock);
>> - if (conf->mddev->bitmap) {
>> - for (d = 0;
>> - d < conf->raid_disks - conf->max_degraded;
>> - d++)
>> - md_bitmap_startwrite(mddev->bitmap,
>> - sh->sector,
>> - RAID5_STRIPE_SECTORS(conf),
>> - 0);
>> - sh->bm_seq = conf->seq_flush + 1;
>> - set_bit(STRIPE_BIT_DELAY, &sh->state);
>> - }
>> -
>> - set_bit(STRIPE_HANDLE, &sh->state);
>> - clear_bit(STRIPE_DELAYED, &sh->state);
>> - if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
>> - atomic_inc(&conf->preread_active_stripes);
>> - release_stripe_plug(mddev, sh);
>> - }
>> -
>> - bio_endio(bi);
>> + bio_start = bi->bi_iter.bi_sector &
>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>> + bio_end = bio_end_sector(bi);
>> +
>> + /*
>> + * Keep bio aligned with strip size.
>> + */
>> + div_u64_rem(bio_start, stripe_sectors, &remainder);
>> + if (remainder) {
>> + split_size = stripe_sectors - remainder;
>> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
>> + bio_chain(split, bi);
>> + /* Resend the fist split part */
>> + submit_bio_noacct(split);
>> + }
>> + div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
>> + if (remainder) {
>> + split_size = bio_sectors(bi) - remainder;
>> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
>> + bio_chain(split, bi);
>> + /* Resend the second split part */
>> + submit_bio_noacct(bi);
>> + bi = split;
>> + }
>> +
>> + bio_start = bi->bi_iter.bi_sector &
>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>> + bio_end = bio_end_sector(bi);
>> +
>> + bi->bi_next = NULL;
>> +
>> + first_stripe_index = bio_start;
>> + sector_div(first_stripe_index, stripe_sectors);
>> +
>> + last_stripe_index = bio_end;
>> + sector_div(last_stripe_index, stripe_sectors);
>> +
>> + start_disk_index = (int)(bio_start - first_stripe_index *
>> stripe_sectors) /
>> + conf->chunk_sectors;
>> + start_disk_offset = ((int)(bio_start - first_stripe_index *
>> stripe_sectors) %
>> + conf->chunk_sectors) +
>> + first_stripe_index * conf->chunk_sectors;
>> + end_disk_index = (int)(bio_end - last_stripe_index * stripe_sectors) /
>> + conf->chunk_sectors;
>> + end_disk_offset = ((int)(bio_end - last_stripe_index * stripe_sectors) %
>> + conf->chunk_sectors) +
>> + last_stripe_index * conf->chunk_sectors;
>> +
>> + for (d = 0; d < conf->raid_disks; d++) {
>> + sector_t dev_start, dev_end;
>> + struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
>> +
>> + dev_start = bio_start;
>> + dev_end = bio_end;
>> +
>> + if (d < start_disk_index)
>> + dev_start = (first_stripe_index + 1) *
>> + conf->chunk_sectors;
>> + else if (d > start_disk_index)
>> + dev_start = first_stripe_index * conf->chunk_sectors;
>> + else
>> + dev_start = start_disk_offset;
>> +
>> + if (d < end_disk_index)
>> + dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
>> + else if (d > end_disk_index)
>> + dev_end = last_stripe_index * conf->chunk_sectors;
>> + else
>> + dev_end = end_disk_offset;
>> +
>> + if (dev_end <= dev_start)
>> + continue;
>> +
>> + md_submit_discard_bio(mddev, rdev, bi,
>> + dev_start + rdev->data_offset,
>> + dev_end - dev_start);
>> + }
>> +
>> + bio_endio(bi);
>> }
>> static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
>>
>> --
>> 2.17.1
>>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] md: raid456 improve discard performance
2022-02-07 15:32 ` Vishal Verma
@ 2022-02-11 14:45 ` Vishal Verma
0 siblings, 0 replies; 6+ messages in thread
From: Vishal Verma @ 2022-02-11 14:45 UTC (permalink / raw)
To: Xiao Ni; +Cc: Song Liu, linux-raid
On 2/7/22 8:32 AM, Vishal Verma wrote:
>
> On 2/7/22 12:24 AM, Xiao Ni wrote:
>> Hi Vishal
>>
>> Thanks for this. The thought of sending discard bio to member disk
>> directly should be
>> good. As you said, raid456 is more complicated with raid0/raid10. It
>> needs to think about
>> more things. First, it needs to avoid conflict with resync I/O. I
>> don't read the codes below.
>> The format is not right. There is no proper tab in the beginning of
>> each line of code.
> Thanks!
> Yeah somehow the formatting for messed up. Sorry about that. Just sent
> it again.
>> And what's your specific question you want to talk about?
> Right, so I was struggling to debug the stabilty issue. It is working
> when creating a raid6
> array and mkfs.ext4 it with discard. But, as soon as I issue fstrim to
> it, fstrim is hanging which
> is pointing to probably some chunk mis-alignment issue. Thats where
> would like help with
> reviewing the code and see if I am calculating the discard region and
> start/end correctly.
>
Hi Xiao,
Did you get chance to review this RFC patch?
Thanks,
Vishal
>>
>> Regards
>> Xiao
>>
>> On Thu, Feb 3, 2022 at 1:28 PM Vishal Verma <vverma@digitalocean.com>
>> wrote:
>>> Hello,
>>>
>>> I would like to get your feedback on the following patch for improving
>>> raid456 discard performance. This seem to improve discard performance
>>> for raid456 quite significantly (just like raid10 discard
>>> optimization did).
>>> Unfortunately, this patch is not in stable form right now. I do not
>>> have
>>> very good understanding of raid456 code and would really love to get
>>> your guys feedback.
>>>
>>>
>>> I basically tried to incorporate raid0's optimzed discard code logic
>>> into raid456 make_discard fn, but I am sure I am missing some things
>>> as the raid456 layout is very different than that of raid0 or 10.
>>> Would appreciate the feedback.
>>>
>>>
>>> This patch improves discard performance with raid456 by sending
>>> discard bio directly to the underlying disk just like how raid0/10
>>> handle discard request. Currently, the discard request for raid456
>>> gets sent to the disks on a per stripe basis which involves lots of
>>> bio split/merge and makes it pretty slow performant vs. sending
>>> the requests directly to the disks. This patch is intended to issue
>>> discard request in the the similar way with patch
>>> 29efc390b (md/md0: optimize raid0 discard handling).
>>>
>>> Signed-off-by: Vishal Verma <vverma@digitalocean.com>
>>> ---
>>> drivers/md/raid5.c | 184 ++++++++++++++++++++++++---------------------
>>> 1 file changed, 99 insertions(+), 85 deletions(-)
>>>
>>> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
>>> index 7c119208a214..2d57cf105471 100644
>>> --- a/drivers/md/raid5.c
>>> +++ b/drivers/md/raid5.c
>>> @@ -5681,93 +5681,108 @@ static void release_stripe_plug(struct mddev
>>> *mddev,
>>> static void make_discard_request(struct mddev *mddev, struct bio *bi)
>>> {
>>> - struct r5conf *conf = mddev->private;
>>> - sector_t logical_sector, last_sector;
>>> - struct stripe_head *sh;
>>> - int stripe_sectors;
>>> -
>>> - /* We need to handle this when io_uring supports discard/trim */
>>> - if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
>>> + struct r5conf *conf = mddev->private;
>>> + sector_t bio_start, bio_end;
>>> + unsigned int start_disk_index, end_disk_index;
>>> + sector_t start_disk_offset, end_disk_offset;
>>> + sector_t first_stripe_index, last_stripe_index;
>>> + sector_t split_size;
>>> + struct bio *split;
>>> + unsigned int remainder;
>>> + int d;
>>> + int stripe_sectors;
>>> +
>>> + /* We need to handle this when io_uring supports discard/trim */
>>> + if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
>>> + return;
>>> +
>>> + if (mddev->reshape_position != MaxSector)
>>> + /* Skip discard while reshape is happening */
>>> + return;
>>> +
>>> + stripe_sectors = conf->chunk_sectors *
>>> + (conf->raid_disks - conf->max_degraded);
>>> +
>>> + if (bio_sectors(bi) < stripe_sectors * 2)
>>> return;
>>> - if (mddev->reshape_position != MaxSector)
>>> - /* Skip discard while reshape is happening */
>>> - return;
>>> -
>>> - logical_sector = bi->bi_iter.bi_sector &
>>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>>> - last_sector = bio_end_sector(bi);
>>> -
>>> - bi->bi_next = NULL;
>>> -
>>> - stripe_sectors = conf->chunk_sectors *
>>> - (conf->raid_disks - conf->max_degraded);
>>> - logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
>>> - stripe_sectors);
>>> - sector_div(last_sector, stripe_sectors);
>>> -
>>> - logical_sector *= conf->chunk_sectors;
>>> - last_sector *= conf->chunk_sectors;
>>> -
>>> - for (; logical_sector < last_sector;
>>> - logical_sector += RAID5_STRIPE_SECTORS(conf)) {
>>> - DEFINE_WAIT(w);
>>> - int d;
>>> - again:
>>> - sh = raid5_get_active_stripe(conf, logical_sector, 0, 0, 0);
>>> - prepare_to_wait(&conf->wait_for_overlap, &w,
>>> - TASK_UNINTERRUPTIBLE);
>>> - set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
>>> - if (test_bit(STRIPE_SYNCING, &sh->state)) {
>>> - raid5_release_stripe(sh);
>>> - schedule();
>>> - goto again;
>>> - }
>>> - clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
>>> - spin_lock_irq(&sh->stripe_lock);
>>> - for (d = 0; d < conf->raid_disks; d++) {
>>> - if (d == sh->pd_idx || d == sh->qd_idx)
>>> - continue;
>>> - if (sh->dev[d].towrite || sh->dev[d].toread) {
>>> - set_bit(R5_Overlap, &sh->dev[d].flags);
>>> - spin_unlock_irq(&sh->stripe_lock);
>>> - raid5_release_stripe(sh);
>>> - schedule();
>>> - goto again;
>>> - }
>>> - }
>>> - set_bit(STRIPE_DISCARD, &sh->state);
>>> - finish_wait(&conf->wait_for_overlap, &w);
>>> - sh->overwrite_disks = 0;
>>> - for (d = 0; d < conf->raid_disks; d++) {
>>> - if (d == sh->pd_idx || d == sh->qd_idx)
>>> - continue;
>>> - sh->dev[d].towrite = bi;
>>> - set_bit(R5_OVERWRITE, &sh->dev[d].flags);
>>> - bio_inc_remaining(bi);
>>> - md_write_inc(mddev, bi);
>>> - sh->overwrite_disks++;
>>> - }
>>> - spin_unlock_irq(&sh->stripe_lock);
>>> - if (conf->mddev->bitmap) {
>>> - for (d = 0;
>>> - d < conf->raid_disks - conf->max_degraded;
>>> - d++)
>>> - md_bitmap_startwrite(mddev->bitmap,
>>> - sh->sector,
>>> - RAID5_STRIPE_SECTORS(conf),
>>> - 0);
>>> - sh->bm_seq = conf->seq_flush + 1;
>>> - set_bit(STRIPE_BIT_DELAY, &sh->state);
>>> - }
>>> -
>>> - set_bit(STRIPE_HANDLE, &sh->state);
>>> - clear_bit(STRIPE_DELAYED, &sh->state);
>>> - if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
>>> - atomic_inc(&conf->preread_active_stripes);
>>> - release_stripe_plug(mddev, sh);
>>> - }
>>> -
>>> - bio_endio(bi);
>>> + bio_start = bi->bi_iter.bi_sector &
>>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>>> + bio_end = bio_end_sector(bi);
>>> +
>>> + /*
>>> + * Keep bio aligned with strip size.
>>> + */
>>> + div_u64_rem(bio_start, stripe_sectors, &remainder);
>>> + if (remainder) {
>>> + split_size = stripe_sectors - remainder;
>>> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
>>> + bio_chain(split, bi);
>>> + /* Resend the fist split part */
>>> + submit_bio_noacct(split);
>>> + }
>>> + div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
>>> + if (remainder) {
>>> + split_size = bio_sectors(bi) - remainder;
>>> + split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
>>> + bio_chain(split, bi);
>>> + /* Resend the second split part */
>>> + submit_bio_noacct(bi);
>>> + bi = split;
>>> + }
>>> +
>>> + bio_start = bi->bi_iter.bi_sector &
>>> ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
>>> + bio_end = bio_end_sector(bi);
>>> +
>>> + bi->bi_next = NULL;
>>> +
>>> + first_stripe_index = bio_start;
>>> + sector_div(first_stripe_index, stripe_sectors);
>>> +
>>> + last_stripe_index = bio_end;
>>> + sector_div(last_stripe_index, stripe_sectors);
>>> +
>>> + start_disk_index = (int)(bio_start - first_stripe_index *
>>> stripe_sectors) /
>>> + conf->chunk_sectors;
>>> + start_disk_offset = ((int)(bio_start - first_stripe_index *
>>> stripe_sectors) %
>>> + conf->chunk_sectors) +
>>> + first_stripe_index * conf->chunk_sectors;
>>> + end_disk_index = (int)(bio_end - last_stripe_index *
>>> stripe_sectors) /
>>> + conf->chunk_sectors;
>>> + end_disk_offset = ((int)(bio_end - last_stripe_index *
>>> stripe_sectors) %
>>> + conf->chunk_sectors) +
>>> + last_stripe_index * conf->chunk_sectors;
>>> +
>>> + for (d = 0; d < conf->raid_disks; d++) {
>>> + sector_t dev_start, dev_end;
>>> + struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
>>> +
>>> + dev_start = bio_start;
>>> + dev_end = bio_end;
>>> +
>>> + if (d < start_disk_index)
>>> + dev_start = (first_stripe_index + 1) *
>>> + conf->chunk_sectors;
>>> + else if (d > start_disk_index)
>>> + dev_start = first_stripe_index * conf->chunk_sectors;
>>> + else
>>> + dev_start = start_disk_offset;
>>> +
>>> + if (d < end_disk_index)
>>> + dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
>>> + else if (d > end_disk_index)
>>> + dev_end = last_stripe_index * conf->chunk_sectors;
>>> + else
>>> + dev_end = end_disk_offset;
>>> +
>>> + if (dev_end <= dev_start)
>>> + continue;
>>> +
>>> + md_submit_discard_bio(mddev, rdev, bi,
>>> + dev_start + rdev->data_offset,
>>> + dev_end - dev_start);
>>> + }
>>> +
>>> + bio_endio(bi);
>>> }
>>> static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
>>>
>>> --
>>> 2.17.1
>>>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] md: raid456 improve discard performance
@ 2022-02-09 21:06 kernel test robot
0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2022-02-09 21:06 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 22038 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20220207152735.27381-1-vverma@digitalocean.com>
References: <20220207152735.27381-1-vverma@digitalocean.com>
TO: Vishal Verma <vverma@digitalocean.com>
Hi Vishal,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on song-md/md-next]
[also build test WARNING on v5.17-rc3 next-20220209]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Vishal-Verma/md-raid456-improve-discard-performance/20220207-234145
base: git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: x86_64-randconfig-c007 (https://download.01.org/0day-ci/archive/20220210/202202100503.q4GxZJj7-lkp(a)intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project e8bff9ae54a55b4dbfeb6ba55f723abbd81bf494)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/4af21de77f50109eca27fc515da03b83ebc7b91a
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Vishal-Verma/md-raid456-improve-discard-performance/20220207-234145
git checkout 4af21de77f50109eca27fc515da03b83ebc7b91a
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
6 warnings generated.
Suppressed 6 warnings (6 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
14 warnings generated.
drivers/md/raid5.c:2185:2: warning: Value stored to 'tx' is never read [clang-analyzer-deadcode.DeadStores]
tx = async_trigger_callback(&submit);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:2185:2: note: Value stored to 'tx' is never read
tx = async_trigger_callback(&submit);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:2841:4: warning: 2nd function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
set_bit(WriteErrorSeen, &rdev->flags);
^ ~~~~~~~~~~~~
drivers/md/raid5.c:2799:2: note: 'rdev' declared without an initial value
struct md_rdev *rdev;
^~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:2804:15: note: Assuming 'i' is >= 'disks'
for (i = 0 ; i < disks; i++) {
^~~~~~~~~
drivers/md/raid5.c:2804:2: note: Loop condition is false. Execution continues on line 2822
for (i = 0 ; i < disks; i++) {
^
drivers/md/raid5.c:2822:2: note: Taking false branch
pr_debug("end_write_request %llu/%d, count %d, error: %d.\n",
^
include/linux/printk.h:580:2: note: expanded from macro 'pr_debug'
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
^
include/linux/printk.h:131:2: note: expanded from macro 'no_printk'
if (0) \
^
drivers/md/raid5.c:2825:6: note: Assuming 'i' is not equal to 'disks'
if (i == disks) {
^~~~~~~~~~
drivers/md/raid5.c:2825:2: note: Taking false branch
if (i == disks) {
^
drivers/md/raid5.c:2831:6: note: 'replacement' is 0
if (replacement) {
^~~~~~~~~~~
drivers/md/raid5.c:2831:2: note: Taking false branch
if (replacement) {
^
drivers/md/raid5.c:2839:7: note: Assuming field 'bi_status' is not equal to 0
if (bi->bi_status) {
^~~~~~~~~~~~~
drivers/md/raid5.c:2839:3: note: Taking true branch
if (bi->bi_status) {
^
drivers/md/raid5.c:2841:4: note: 2nd function call argument is an uninitialized value
set_bit(WriteErrorSeen, &rdev->flags);
^ ~~~~~~~~~~~~
drivers/md/raid5.c:2846:14: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
} else if (is_badblock(rdev, sh->sector,
^ ~~~~
drivers/md/raid5.c:2799:2: note: 'rdev' declared without an initial value
struct md_rdev *rdev;
^~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:2804:15: note: Assuming 'i' is >= 'disks'
for (i = 0 ; i < disks; i++) {
^~~~~~~~~
drivers/md/raid5.c:2804:2: note: Loop condition is false. Execution continues on line 2822
for (i = 0 ; i < disks; i++) {
^
drivers/md/raid5.c:2822:2: note: Taking false branch
pr_debug("end_write_request %llu/%d, count %d, error: %d.\n",
^
include/linux/printk.h:580:2: note: expanded from macro 'pr_debug'
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
^
include/linux/printk.h:131:2: note: expanded from macro 'no_printk'
if (0) \
^
drivers/md/raid5.c:2825:6: note: Assuming 'i' is not equal to 'disks'
if (i == disks) {
^~~~~~~~~~
drivers/md/raid5.c:2825:2: note: Taking false branch
if (i == disks) {
^
drivers/md/raid5.c:2831:6: note: 'replacement' is 0
if (replacement) {
^~~~~~~~~~~
drivers/md/raid5.c:2831:2: note: Taking false branch
if (replacement) {
^
drivers/md/raid5.c:2839:7: note: Assuming field 'bi_status' is 0
if (bi->bi_status) {
^~~~~~~~~~~~~
drivers/md/raid5.c:2839:3: note: Taking false branch
if (bi->bi_status) {
^
drivers/md/raid5.c:2846:14: note: 1st function call argument is an uninitialized value
} else if (is_badblock(rdev, sh->sector,
^ ~~~~
drivers/md/raid5.c:4014:5: warning: Value stored to 'dev' is never read [clang-analyzer-deadcode.DeadStores]
dev = &sh->dev[i];
^ ~~~~~~~~~~~
drivers/md/raid5.c:4014:5: note: Value stored to 'dev' is never read
dev = &sh->dev[i];
^ ~~~~~~~~~~~
>> drivers/md/raid5.c:5761:3: warning: Value stored to 'dev_start' is never read [clang-analyzer-deadcode.DeadStores]
dev_start = bio_start;
^ ~~~~~~~~~
drivers/md/raid5.c:5761:3: note: Value stored to 'dev_start' is never read
dev_start = bio_start;
^ ~~~~~~~~~
>> drivers/md/raid5.c:5762:3: warning: Value stored to 'dev_end' is never read [clang-analyzer-deadcode.DeadStores]
dev_end = bio_end;
^ ~~~~~~~
drivers/md/raid5.c:5762:3: note: Value stored to 'dev_end' is never read
dev_end = bio_end;
^ ~~~~~~~
include/linux/list.h:284:9: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
return READ_ONCE(head->next) == head;
^
include/asm-generic/rwonce.h:50:2: note: expanded from macro 'READ_ONCE'
__READ_ONCE(x); \
^
include/asm-generic/rwonce.h:44:24: note: expanded from macro '__READ_ONCE'
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
^
drivers/md/raid5.c:6512:2: note: Taking false branch
pr_debug("+++ raid5d active\n");
^
include/linux/printk.h:580:2: note: expanded from macro 'pr_debug'
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
^
include/linux/printk.h:131:2: note: expanded from macro 'no_printk'
if (0) \
^
drivers/md/raid5.c:6519:2: note: Loop condition is true. Entering loop body
while (1) {
^
drivers/md/raid5.c:6525:7: note: 'released' is 0
if (released)
^~~~~~~~
drivers/md/raid5.c:6525:3: note: Taking false branch
if (released)
^
drivers/md/raid5.c:6529:7: note: Assuming the condition is false
!list_empty(&conf->bitmap_list)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:6528:3: note: Taking false branch
if (
^
drivers/md/raid5.c:6540:3: note: Loop condition is false. Execution continues on line 6550
while ((bio = remove_bio_from_retry(conf, &offset))) {
^
drivers/md/raid5.c:6550:16: note: Calling 'handle_active_stripes'
batch_size = handle_active_stripes(conf, ANY_GROUP, NULL,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:6413:9: note: 'batch_size' is < MAX_STRIPE_BATCH
while (batch_size < MAX_STRIPE_BATCH &&
^~~~~~~~~~
drivers/md/raid5.c:6413:9: note: Left side of '&&' is true
drivers/md/raid5.c:6414:10: note: Calling '__get_priority_stripe'
(sh = __get_priority_stripe(conf, group)) != NULL)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5520:2: note: 'handle_list' initialized to a null pointer value
struct list_head *handle_list = NULL;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5522:20: note: Assuming the condition is false
bool second_try = !r5c_is_writeback(conf->log) &&
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5522:49: note: Left side of '&&' is false
bool second_try = !r5c_is_writeback(conf->log) &&
^
drivers/md/raid5.c:5524:20: note: Assuming the condition is true
bool try_loprio = test_bit(R5C_LOG_TIGHT, &conf->cache_state) ||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5524:64: note: Left side of '||' is true
bool try_loprio = test_bit(R5C_LOG_TIGHT, &conf->cache_state) ||
^
drivers/md/raid5.c:5530:6: note: Assuming field 'worker_cnt_per_group' is not equal to 0
if (conf->worker_cnt_per_group == 0) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5530:2: note: Taking false branch
if (conf->worker_cnt_per_group == 0) {
^
drivers/md/raid5.c:5533:9: note: Taking false branch
} else if (group != ANY_GROUP) {
^
drivers/md/raid5.c:5539:15: note: Assuming 'i' is >= field 'group_cnt'
for (i = 0; i < conf->group_cnt; i++) {
^~~~~~~~~~~~~~~~~~~
drivers/md/raid5.c:5539:3: note: Loop condition is false. Execution continues on line 5548
for (i = 0; i < conf->group_cnt; i++) {
^
drivers/md/raid5.c:5548:2: note: Taking false branch
pr_debug("%s: handle: %s hold: %s full_writes: %d bypass_count: %d\n",
^
include/linux/printk.h:580:2: note: expanded from macro 'pr_debug'
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
^
include/linux/printk.h:131:2: note: expanded from macro 'no_printk'
if (0) \
^
drivers/md/raid5.c:5554:18: note: Passing null pointer value via 1st parameter 'head'
if (!list_empty(handle_list)) {
^~~~~~~~~~~
drivers/md/raid5.c:5554:7: note: Calling 'list_empty'
if (!list_empty(handle_list)) {
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/list.h:284:9: note: Left side of '||' is false
return READ_ONCE(head->next) == head;
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
vim +/dev_start +5761 drivers/md/raid5.c
8811b5968f6216e Shaohua Li 2012-08-02 5681
620125f2bf8ff0c Shaohua Li 2012-10-11 5682 static void make_discard_request(struct mddev *mddev, struct bio *bi)
620125f2bf8ff0c Shaohua Li 2012-10-11 5683 {
620125f2bf8ff0c Shaohua Li 2012-10-11 5684 struct r5conf *conf = mddev->private;
4af21de77f50109 Vishal Verma 2022-02-07 5685 sector_t bio_start, bio_end;
4af21de77f50109 Vishal Verma 2022-02-07 5686 unsigned int start_disk_index, end_disk_index;
4af21de77f50109 Vishal Verma 2022-02-07 5687 sector_t start_disk_offset, end_disk_offset;
4af21de77f50109 Vishal Verma 2022-02-07 5688 sector_t first_stripe_index, last_stripe_index;
4af21de77f50109 Vishal Verma 2022-02-07 5689 sector_t split_size;
4af21de77f50109 Vishal Verma 2022-02-07 5690 struct bio *split;
4af21de77f50109 Vishal Verma 2022-02-07 5691 unsigned int remainder;
4af21de77f50109 Vishal Verma 2022-02-07 5692 int d;
620125f2bf8ff0c Shaohua Li 2012-10-11 5693 int stripe_sectors;
620125f2bf8ff0c Shaohua Li 2012-10-11 5694
bf2c411bb1cfc45 Vishal Verma 2021-12-21 5695 /* We need to handle this when io_uring supports discard/trim */
bf2c411bb1cfc45 Vishal Verma 2021-12-21 5696 if (WARN_ON_ONCE(bi->bi_opf & REQ_NOWAIT))
bf2c411bb1cfc45 Vishal Verma 2021-12-21 5697 return;
bf2c411bb1cfc45 Vishal Verma 2021-12-21 5698
4af21de77f50109 Vishal Verma 2022-02-07 5699 /* Skip discard while reshape or resync is happening */
4af21de77f50109 Vishal Verma 2022-02-07 5700 if ((mddev->reshape_position != MaxSector) ||
4af21de77f50109 Vishal Verma 2022-02-07 5701 test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
620125f2bf8ff0c Shaohua Li 2012-10-11 5702 return;
4af21de77f50109 Vishal Verma 2022-02-07 5703 }
620125f2bf8ff0c Shaohua Li 2012-10-11 5704
620125f2bf8ff0c Shaohua Li 2012-10-11 5705 stripe_sectors = conf->chunk_sectors *
620125f2bf8ff0c Shaohua Li 2012-10-11 5706 (conf->raid_disks - conf->max_degraded);
620125f2bf8ff0c Shaohua Li 2012-10-11 5707
4af21de77f50109 Vishal Verma 2022-02-07 5708 if (bio_sectors(bi) < stripe_sectors * 2)
4af21de77f50109 Vishal Verma 2022-02-07 5709 return;
620125f2bf8ff0c Shaohua Li 2012-10-11 5710
4af21de77f50109 Vishal Verma 2022-02-07 5711 bio_start = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
4af21de77f50109 Vishal Verma 2022-02-07 5712 bio_end = bio_end_sector(bi);
4af21de77f50109 Vishal Verma 2022-02-07 5713
4af21de77f50109 Vishal Verma 2022-02-07 5714 /*
4af21de77f50109 Vishal Verma 2022-02-07 5715 * Keep bio aligned with strip size.
4af21de77f50109 Vishal Verma 2022-02-07 5716 */
4af21de77f50109 Vishal Verma 2022-02-07 5717 div_u64_rem(bio_start, stripe_sectors, &remainder);
4af21de77f50109 Vishal Verma 2022-02-07 5718 if (remainder) {
4af21de77f50109 Vishal Verma 2022-02-07 5719 split_size = stripe_sectors - remainder;
4af21de77f50109 Vishal Verma 2022-02-07 5720 split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
4af21de77f50109 Vishal Verma 2022-02-07 5721 bio_chain(split, bi);
4af21de77f50109 Vishal Verma 2022-02-07 5722 /* Resend the fist split part */
4af21de77f50109 Vishal Verma 2022-02-07 5723 submit_bio_noacct(split);
4af21de77f50109 Vishal Verma 2022-02-07 5724 }
4af21de77f50109 Vishal Verma 2022-02-07 5725 div_u64_rem(bio_end-bio_start, stripe_sectors, &remainder);
4af21de77f50109 Vishal Verma 2022-02-07 5726 if (remainder) {
4af21de77f50109 Vishal Verma 2022-02-07 5727 split_size = bio_sectors(bi) - remainder;
4af21de77f50109 Vishal Verma 2022-02-07 5728 split = bio_split(bi, split_size, GFP_NOIO, &conf->bio_split);
4af21de77f50109 Vishal Verma 2022-02-07 5729 bio_chain(split, bi);
4af21de77f50109 Vishal Verma 2022-02-07 5730 /* Resend the second split part */
4af21de77f50109 Vishal Verma 2022-02-07 5731 submit_bio_noacct(bi);
4af21de77f50109 Vishal Verma 2022-02-07 5732 bi = split;
620125f2bf8ff0c Shaohua Li 2012-10-11 5733 }
4af21de77f50109 Vishal Verma 2022-02-07 5734
4af21de77f50109 Vishal Verma 2022-02-07 5735 bio_start = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
4af21de77f50109 Vishal Verma 2022-02-07 5736 bio_end = bio_end_sector(bi);
4af21de77f50109 Vishal Verma 2022-02-07 5737
4af21de77f50109 Vishal Verma 2022-02-07 5738 bi->bi_next = NULL;
4af21de77f50109 Vishal Verma 2022-02-07 5739
4af21de77f50109 Vishal Verma 2022-02-07 5740 first_stripe_index = bio_start;
4af21de77f50109 Vishal Verma 2022-02-07 5741 sector_div(first_stripe_index, stripe_sectors);
4af21de77f50109 Vishal Verma 2022-02-07 5742
4af21de77f50109 Vishal Verma 2022-02-07 5743 last_stripe_index = bio_end;
4af21de77f50109 Vishal Verma 2022-02-07 5744 sector_div(last_stripe_index, stripe_sectors);
4af21de77f50109 Vishal Verma 2022-02-07 5745
4af21de77f50109 Vishal Verma 2022-02-07 5746 start_disk_index = (int)(bio_start - first_stripe_index * stripe_sectors) /
4af21de77f50109 Vishal Verma 2022-02-07 5747 conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5748 start_disk_offset = ((int)(bio_start - first_stripe_index * stripe_sectors) %
4af21de77f50109 Vishal Verma 2022-02-07 5749 conf->chunk_sectors) +
4af21de77f50109 Vishal Verma 2022-02-07 5750 first_stripe_index * conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5751 end_disk_index = (int)(bio_end - last_stripe_index * stripe_sectors) /
4af21de77f50109 Vishal Verma 2022-02-07 5752 conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5753 end_disk_offset = ((int)(bio_end - last_stripe_index * stripe_sectors) %
4af21de77f50109 Vishal Verma 2022-02-07 5754 conf->chunk_sectors) +
4af21de77f50109 Vishal Verma 2022-02-07 5755 last_stripe_index * conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5756
620125f2bf8ff0c Shaohua Li 2012-10-11 5757 for (d = 0; d < conf->raid_disks; d++) {
4af21de77f50109 Vishal Verma 2022-02-07 5758 sector_t dev_start, dev_end;
4af21de77f50109 Vishal Verma 2022-02-07 5759 struct md_rdev *rdev = READ_ONCE(conf->disks[d].rdev);
4af21de77f50109 Vishal Verma 2022-02-07 5760
4af21de77f50109 Vishal Verma 2022-02-07 @5761 dev_start = bio_start;
4af21de77f50109 Vishal Verma 2022-02-07 @5762 dev_end = bio_end;
4af21de77f50109 Vishal Verma 2022-02-07 5763
4af21de77f50109 Vishal Verma 2022-02-07 5764 if (d < start_disk_index)
4af21de77f50109 Vishal Verma 2022-02-07 5765 dev_start = (first_stripe_index + 1) *
4af21de77f50109 Vishal Verma 2022-02-07 5766 conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5767 else if (d > start_disk_index)
4af21de77f50109 Vishal Verma 2022-02-07 5768 dev_start = first_stripe_index * conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5769 else
4af21de77f50109 Vishal Verma 2022-02-07 5770 dev_start = start_disk_offset;
4af21de77f50109 Vishal Verma 2022-02-07 5771
4af21de77f50109 Vishal Verma 2022-02-07 5772 if (d < end_disk_index)
4af21de77f50109 Vishal Verma 2022-02-07 5773 dev_end = (last_stripe_index + 1) * conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5774 else if (d > end_disk_index)
4af21de77f50109 Vishal Verma 2022-02-07 5775 dev_end = last_stripe_index * conf->chunk_sectors;
4af21de77f50109 Vishal Verma 2022-02-07 5776 else
4af21de77f50109 Vishal Verma 2022-02-07 5777 dev_end = end_disk_offset;
4af21de77f50109 Vishal Verma 2022-02-07 5778
4af21de77f50109 Vishal Verma 2022-02-07 5779 if (dev_end <= dev_start)
620125f2bf8ff0c Shaohua Li 2012-10-11 5780 continue;
620125f2bf8ff0c Shaohua Li 2012-10-11 5781
4af21de77f50109 Vishal Verma 2022-02-07 5782 md_submit_discard_bio(mddev, rdev, bi,
4af21de77f50109 Vishal Verma 2022-02-07 5783 dev_start + rdev->data_offset,
4af21de77f50109 Vishal Verma 2022-02-07 5784 dev_end - dev_start);
620125f2bf8ff0c Shaohua Li 2012-10-11 5785 }
620125f2bf8ff0c Shaohua Li 2012-10-11 5786
4246a0b63bd8f56 Christoph Hellwig 2015-07-20 5787 bio_endio(bi);
620125f2bf8ff0c Shaohua Li 2012-10-11 5788 }
620125f2bf8ff0c Shaohua Li 2012-10-11 5789
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-02-11 14:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20220203051546.12337-1-vverma@digitalocean.com>
2022-02-03 5:28 ` [RFC PATCH] md: raid456 improve discard performance Vishal Verma
2022-02-07 7:24 ` Xiao Ni
2022-02-07 15:27 ` Vishal Verma
2022-02-07 15:32 ` Vishal Verma
2022-02-11 14:45 ` Vishal Verma
2022-02-09 21:06 kernel test robot
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.