All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.