All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request
@ 2020-08-24  4:11 Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 1/5] md/raid10: move codes related with submitting discard bio into one function Xiao Ni
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

Hi all

Now mkfs on raid10 which is combined with ssd/nvme disks takes a long time.
This patch set tries to resolve this problem.

v1:
Coly helps to review these patches and give some suggestions:
One bug is found. If discard bio is across one stripe but bio size is
bigger than one stripe size. After spliting, the bio will be NULL.
In this version, it checks whether discard bio size is bigger than
(2*stripe_size). 
In raid10_end_discard_request, it's better to check R10BIO_Uptodate
is set or not. It can avoid write memory to improve performance. 
Add more comments for calculating addresses.

v2:
Fix error by checkpatch.pl
Fix one bug for offset layout. v1 calculates wrongly split size
Add more comments to explain how the discard range of each component disk
is decided.

v3:
add support for far layout
Change the patch name

v4:
Pull codes that wait for blocked device into a seprate function
It can't use (stripe_size-1) as a mask to calculate. (stripe_size-1) may
not be power of 2.
It doesn't need to use a full copy of geo.
Fix warning by checkpatch.pl

Xiao Ni (5):
  md/raid10: move codes related with submitting discard bio into one
    function
  md/raid10: extend r10bio devs to raid disks
  md/raid10: pull codes that wait for blocked dev into one function
  md/raid10: improve raid10 discard request
  md/raid10: improve discard request for far layout

 drivers/md/md.c     |  23 +++
 drivers/md/md.h     |   3 +
 drivers/md/raid0.c  |  15 +-
 drivers/md/raid10.c | 419 +++++++++++++++++++++++++++++++++++++++++++++-------
 drivers/md/raid10.h |   1 +
 5 files changed, 391 insertions(+), 70 deletions(-)

-- 
2.7.5


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH V4 1/5] md/raid10: move codes related with submitting discard bio into one function
  2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
@ 2020-08-24  4:11 ` Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 2/5] md/raid10: extend r10bio devs to raid disks Xiao Ni
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

These codes can be used in raid10. So we can move these codes into
md.c. raid0 and raid10 can share these codes.

Reviewed-by: Coly Li <colyli@suse.de>
Reviewed-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Xiao Ni <xni@redhat.com>
---
 drivers/md/md.c    | 23 +++++++++++++++++++++++
 drivers/md/md.h    |  3 +++
 drivers/md/raid0.c | 15 ++-------------
 3 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6072782..10743be 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8583,6 +8583,29 @@ void md_write_end(struct mddev *mddev)
 
 EXPORT_SYMBOL(md_write_end);
 
+/* This is used by raid0 and raid10 */
+void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
+				struct bio *bio,
+				sector_t dev_start, sector_t dev_end)
+{
+	struct bio *discard_bio = NULL;
+
+	if (__blkdev_issue_discard(rdev->bdev,
+	    dev_start + rdev->data_offset,
+	    dev_end - dev_start, GFP_NOIO, 0, &discard_bio) ||
+	    !discard_bio)
+		return;
+
+	bio_chain(discard_bio, bio);
+	bio_clone_blkg_association(discard_bio, bio);
+	if (mddev->gendisk)
+		trace_block_bio_remap(bdev_get_queue(rdev->bdev),
+			discard_bio, disk_devt(mddev->gendisk),
+			bio->bi_iter.bi_sector);
+	submit_bio_noacct(discard_bio);
+}
+EXPORT_SYMBOL(md_submit_discard_bio);
+
 /* md_allow_write(mddev)
  * Calling this ensures that the array is marked 'active' so that writes
  * may proceed without blocking.  It is important to call this before
diff --git a/drivers/md/md.h b/drivers/md/md.h
index d9c4e6b..bae3bd5 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -713,6 +713,9 @@ extern void md_write_end(struct mddev *mddev);
 extern void md_done_sync(struct mddev *mddev, int blocks, int ok);
 extern void md_error(struct mddev *mddev, struct md_rdev *rdev);
 extern void md_finish_reshape(struct mddev *mddev);
+extern void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
+				struct bio *bio,
+				sector_t dev_start, sector_t dev_end);
 
 extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
 extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index f54a449..2868294 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -510,7 +510,6 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
 
 	for (disk = 0; disk < zone->nb_dev; disk++) {
 		sector_t dev_start, dev_end;
-		struct bio *discard_bio = NULL;
 		struct md_rdev *rdev;
 
 		if (disk < start_disk_index)
@@ -533,18 +532,8 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
 
 		rdev = conf->devlist[(zone - conf->strip_zone) *
 			conf->strip_zone[0].nb_dev + disk];
-		if (__blkdev_issue_discard(rdev->bdev,
-			dev_start + zone->dev_start + rdev->data_offset,
-			dev_end - dev_start, GFP_NOIO, 0, &discard_bio) ||
-		    !discard_bio)
-			continue;
-		bio_chain(discard_bio, bio);
-		bio_clone_blkg_association(discard_bio, bio);
-		if (mddev->gendisk)
-			trace_block_bio_remap(bdev_get_queue(rdev->bdev),
-				discard_bio, disk_devt(mddev->gendisk),
-				bio->bi_iter.bi_sector);
-		submit_bio_noacct(discard_bio);
+		dev_start += zone->dev_start;
+		md_submit_discard_bio(mddev, rdev, bio, dev_start, dev_end);
 	}
 	bio_endio(bio);
 }
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V4 2/5] md/raid10: extend r10bio devs to raid disks
  2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 1/5] md/raid10: move codes related with submitting discard bio into one function Xiao Ni
@ 2020-08-24  4:11 ` Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 3/5] md/raid10: pull codes that wait for blocked dev into one function Xiao Ni
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

Now it allocs r10bio->devs[conf->copies]. Discard bio needs to submit
to all member disks and it needs to use r10bio. So extend to
r10bio->devs[geo.raid_disks].

Reviewed-by: Coly Li <colyli@suse.de>
Signed-off-by: Xiao Ni <xni@redhat.com>
---
 drivers/md/raid10.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index da12e3d..c4c8477 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -91,7 +91,7 @@ static inline struct r10bio *get_resync_r10bio(struct bio *bio)
 static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
 {
 	struct r10conf *conf = data;
-	int size = offsetof(struct r10bio, devs[conf->copies]);
+	int size = offsetof(struct r10bio, devs[conf->geo.raid_disks]);
 
 	/* allocate a r10bio with room for raid_disks entries in the
 	 * bios array */
@@ -238,7 +238,7 @@ static void put_all_bios(struct r10conf *conf, struct r10bio *r10_bio)
 {
 	int i;
 
-	for (i = 0; i < conf->copies; i++) {
+	for (i = 0; i < conf->geo.raid_disks; i++) {
 		struct bio **bio = & r10_bio->devs[i].bio;
 		if (!BIO_SPECIAL(*bio))
 			bio_put(*bio);
@@ -327,7 +327,7 @@ static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio,
 	int slot;
 	int repl = 0;
 
-	for (slot = 0; slot < conf->copies; slot++) {
+	for (slot = 0; slot < conf->geo.raid_disks; slot++) {
 		if (r10_bio->devs[slot].bio == bio)
 			break;
 		if (r10_bio->devs[slot].repl_bio == bio) {
@@ -336,7 +336,6 @@ static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio,
 		}
 	}
 
-	BUG_ON(slot == conf->copies);
 	update_head_pos(slot, r10_bio);
 
 	if (slotp)
@@ -1493,7 +1492,7 @@ static void __make_request(struct mddev *mddev, struct bio *bio, int sectors)
 	r10_bio->mddev = mddev;
 	r10_bio->sector = bio->bi_iter.bi_sector;
 	r10_bio->state = 0;
-	memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * conf->copies);
+	memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * conf->geo.raid_disks);
 
 	if (bio_data_dir(bio) == READ)
 		raid10_read_request(mddev, bio, r10_bio);
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V4 3/5] md/raid10: pull codes that wait for blocked dev into one function
  2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 1/5] md/raid10: move codes related with submitting discard bio into one function Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 2/5] md/raid10: extend r10bio devs to raid disks Xiao Ni
@ 2020-08-24  4:11 ` Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 4/5] md/raid10: improve raid10 discard request Xiao Ni
  2020-08-24  4:11 ` [PATCH V4 5/5] md/raid10: improve discard request for far layout Xiao Ni
  4 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

The following patch will do the same job. So pull the same codes
into one function.

Signed-off-by: Xiao Ni <xni@redhat.com>
---
 drivers/md/raid10.c | 119 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 68 insertions(+), 51 deletions(-)

diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c4c8477..68e7e6a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1275,12 +1275,76 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
 	}
 }
 
+static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
+{
+	int i;
+	struct r10conf *conf = mddev->private;
+	struct md_rdev *blocked_rdev;
+
+retry_wait:
+	blocked_rdev = NULL;
+	rcu_read_lock();
+	for (i = 0; i < conf->copies; i++) {
+		struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev);
+		struct md_rdev *rrdev = rcu_dereference(
+			conf->mirrors[i].replacement);
+		if (rdev == rrdev)
+			rrdev = NULL;
+		if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+			atomic_inc(&rdev->nr_pending);
+			blocked_rdev = rdev;
+			break;
+		}
+		if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) {
+			atomic_inc(&rrdev->nr_pending);
+			blocked_rdev = rrdev;
+			break;
+		}
+
+		if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
+			sector_t first_bad;
+			sector_t dev_sector = r10_bio->devs[i].addr;
+			int bad_sectors;
+			int is_bad;
+
+			/* Discard request doesn't care the write result
+			 * so it doesn't need to wait blocked disk here.
+			 */
+			if (!r10_bio->sectors)
+				continue;
+
+			is_bad = is_badblock(rdev, dev_sector, r10_bio->sectors,
+					     &first_bad, &bad_sectors);
+			if (is_bad < 0) {
+				/* Mustn't write here until the bad block
+				 * is acknowledged
+				 */
+				atomic_inc(&rdev->nr_pending);
+				set_bit(BlockedBadBlocks, &rdev->flags);
+				blocked_rdev = rdev;
+				break;
+			}
+		}
+
+	}
+	rcu_read_unlock();
+
+	if (unlikely(blocked_rdev)) {
+		/* Have to wait for this device to get unblocked, then retry */
+		allow_barrier(conf);
+		raid10_log(conf->mddev, "%s wait rdev %d blocked",
+				__func__, blocked_rdev->raid_disk);
+		md_wait_for_blocked_rdev(blocked_rdev, mddev);
+		wait_barrier(conf);
+		goto retry_wait;
+	}
+}
+
 static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 				 struct r10bio *r10_bio)
 {
 	struct r10conf *conf = mddev->private;
 	int i;
-	struct md_rdev *blocked_rdev;
 	sector_t sectors;
 	int max_sectors;
 
@@ -1338,8 +1402,9 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 
 	r10_bio->read_slot = -1; /* make sure repl_bio gets freed */
 	raid10_find_phys(conf, r10_bio);
-retry_write:
-	blocked_rdev = NULL;
+
+	wait_blocked_dev(mddev, r10_bio);
+
 	rcu_read_lock();
 	max_sectors = r10_bio->sectors;
 
@@ -1350,16 +1415,6 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 			conf->mirrors[d].replacement);
 		if (rdev == rrdev)
 			rrdev = NULL;
-		if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
-			atomic_inc(&rdev->nr_pending);
-			blocked_rdev = rdev;
-			break;
-		}
-		if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) {
-			atomic_inc(&rrdev->nr_pending);
-			blocked_rdev = rrdev;
-			break;
-		}
 		if (rdev && (test_bit(Faulty, &rdev->flags)))
 			rdev = NULL;
 		if (rrdev && (test_bit(Faulty, &rrdev->flags)))
@@ -1380,15 +1435,6 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 
 			is_bad = is_badblock(rdev, dev_sector, max_sectors,
 					     &first_bad, &bad_sectors);
-			if (is_bad < 0) {
-				/* Mustn't write here until the bad block
-				 * is acknowledged
-				 */
-				atomic_inc(&rdev->nr_pending);
-				set_bit(BlockedBadBlocks, &rdev->flags);
-				blocked_rdev = rdev;
-				break;
-			}
 			if (is_bad && first_bad <= dev_sector) {
 				/* Cannot write here at all */
 				bad_sectors -= (dev_sector - first_bad);
@@ -1424,35 +1470,6 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 	}
 	rcu_read_unlock();
 
-	if (unlikely(blocked_rdev)) {
-		/* Have to wait for this device to get unblocked, then retry */
-		int j;
-		int d;
-
-		for (j = 0; j < i; j++) {
-			if (r10_bio->devs[j].bio) {
-				d = r10_bio->devs[j].devnum;
-				rdev_dec_pending(conf->mirrors[d].rdev, mddev);
-			}
-			if (r10_bio->devs[j].repl_bio) {
-				struct md_rdev *rdev;
-				d = r10_bio->devs[j].devnum;
-				rdev = conf->mirrors[d].replacement;
-				if (!rdev) {
-					/* Race with remove_disk */
-					smp_mb();
-					rdev = conf->mirrors[d].rdev;
-				}
-				rdev_dec_pending(rdev, mddev);
-			}
-		}
-		allow_barrier(conf);
-		raid10_log(conf->mddev, "wait rdev %d blocked", blocked_rdev->raid_disk);
-		md_wait_for_blocked_rdev(blocked_rdev, mddev);
-		wait_barrier(conf);
-		goto retry_write;
-	}
-
 	if (max_sectors < r10_bio->sectors)
 		r10_bio->sectors = max_sectors;
 
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V4 4/5] md/raid10: improve raid10 discard request
  2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
                   ` (2 preceding siblings ...)
  2020-08-24  4:11 ` [PATCH V4 3/5] md/raid10: pull codes that wait for blocked dev into one function Xiao Ni
@ 2020-08-24  4:11 ` Xiao Ni
  2020-08-24 10:38     ` kernel test robot
  2020-08-24 13:31     ` kernel test robot
  2020-08-24  4:11 ` [PATCH V4 5/5] md/raid10: improve discard request for far layout Xiao Ni
  4 siblings, 2 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

Now the discard request is split by chunk size. So it takes a long time
to finish mkfs on disks which support discard function. This patch improve
handling raid10 discard request. It uses the similar way with patch
29efc390b (md/md0: optimize raid0 discard handling).

But it's a little complex than raid0. Because raid10 has different layout.
If raid10 is offset layout and the discard request is smaller than stripe
size. There are some holes when we submit discard bio to underlayer disks.

For example: five disks (disk1 - disk5)
D01 D02 D03 D04 D05
D05 D01 D02 D03 D04
D06 D07 D08 D09 D10
D10 D06 D07 D08 D09
The discard bio just wants to discard from D03 to D10. For disk3, there is
a hole between D03 and D08. For disk4, there is a hole between D04 and D09.
D03 is a chunk, raid10_write_request can handle one chunk perfectly. So
the part that is not aligned with stripe size is still handled by
raid10_write_request.

If reshape is running when discard bio comes and the discard bio spans the
reshape position, raid10_write_request is responsible to handle this
discard bio.

I did a test with this patch set.
Without patch:
time mkfs.xfs /dev/md0
real4m39.775s
user0m0.000s
sys0m0.298s

With patch:
time mkfs.xfs /dev/md0
real0m0.105s
user0m0.000s
sys0m0.007s

nvme3n1           259:1    0   477G  0 disk
└─nvme3n1p1       259:10   0    50G  0 part
nvme4n1           259:2    0   477G  0 disk
└─nvme4n1p1       259:11   0    50G  0 part
nvme5n1           259:6    0   477G  0 disk
└─nvme5n1p1       259:12   0    50G  0 part
nvme2n1           259:9    0   477G  0 disk
└─nvme2n1p1       259:15   0    50G  0 part
nvme0n1           259:13   0   477G  0 disk
└─nvme0n1p1       259:14   0    50G  0 part

Reviewed-by: Coly Li <colyli@suse.de>
Reviewed-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Xiao Ni <xni@redhat.com>
---
 drivers/md/raid10.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 250 insertions(+), 1 deletion(-)

diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 68e7e6a..58d36b9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1517,6 +1517,251 @@ static void __make_request(struct mddev *mddev, struct bio *bio, int sectors)
 		raid10_write_request(mddev, bio, r10_bio);
 }
 
+static struct bio *raid10_split_bio(struct r10conf *conf,
+			struct bio *bio, sector_t sectors, bool want_first)
+{
+	struct bio *split;
+
+	split = bio_split(bio, sectors,	GFP_NOIO, &conf->bio_split);
+	bio_chain(split, bio);
+	allow_barrier(conf);
+	if (want_first) {
+		submit_bio_noacct(bio);
+		bio = split;
+	} else
+		submit_bio_noacct(split);
+	wait_barrier(conf);
+
+	return bio;
+}
+
+static void raid10_end_discard_request(struct bio *bio)
+{
+	struct r10bio *r10_bio = bio->bi_private;
+	struct r10conf *conf = r10_bio->mddev->private;
+	struct md_rdev *rdev = NULL;
+	int dev;
+	int slot, repl;
+
+	/*
+	 * We don't care the return value of discard bio
+	 */
+	if (!test_bit(R10BIO_Uptodate, &r10_bio->state))
+		set_bit(R10BIO_Uptodate, &r10_bio->state);
+
+	dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl);
+	if (repl)
+		rdev = conf->mirrors[dev].replacement;
+	if (!rdev) {
+		/* raid10_remove_disk uses smp_mb to make sure rdev is set to
+		 * replacement before setting replacement to NULL. It can read
+		 * rdev first without barrier protect even replacment is NULL
+		 */
+		smp_rmb();
+		repl = 0;
+		rdev = conf->mirrors[dev].rdev;
+	}
+
+	if (atomic_dec_and_test(&r10_bio->remaining)) {
+		md_write_end(r10_bio->mddev);
+		raid_end_bio_io(r10_bio);
+	}
+
+	rdev_dec_pending(rdev, conf->mddev);
+}
+
+/* There are some limitations to handle discard bio
+ * 1st, the discard size is bigger than stripe_size*2.
+ * 2st, if the discard bio spans reshape progress, we use the old way to
+ * handle discard bio
+ */
+static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
+{
+	struct r10conf *conf = mddev->private;
+	struct geom *geo = &conf->geo;
+	struct r10bio *r10_bio;
+
+	int disk;
+	sector_t chunk;
+	int stripe_size;
+	sector_t split_size;
+
+	sector_t bio_start, bio_end;
+	sector_t first_stripe_index, last_stripe_index;
+	sector_t start_disk_offset;
+	unsigned int start_disk_index;
+	sector_t end_disk_offset;
+	unsigned int end_disk_index;
+
+	wait_barrier(conf);
+
+	if (conf->reshape_progress != MaxSector &&
+	    ((bio->bi_iter.bi_sector >= conf->reshape_progress) !=
+	     conf->mddev->reshape_backwards))
+		geo = &conf->prev;
+
+	stripe_size = geo->raid_disks << geo->chunk_shift;
+	bio_start = bio->bi_iter.bi_sector;
+	bio_end = bio_end_sector(bio);
+
+	/* Maybe one discard bio is smaller than strip size or across one stripe
+	 * and discard region is larger than one stripe size. For far offset layout,
+	 * if the discard region is not aligned with stripe size, there is hole
+	 * when we submit discard bio to member disk. For simplicity, we only
+	 * handle discard bio which discard region is bigger than stripe_size*2
+	 */
+	if (bio_sectors(bio) < stripe_size*2)
+		goto out;
+
+	if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+		bio_start < conf->reshape_progress &&
+		bio_end > conf->reshape_progress)
+		goto out;
+
+	/* For far offset layout, if bio is not aligned with stripe size, it splits
+	 * the part that is not aligned with strip size.
+	 */
+	if (geo->far_offset && (bio_start % stripe_size)) {
+		split_size = (stripe_size - bio_start % stripe_size);
+		bio = raid10_split_bio(conf, bio, split_size, false);
+	}
+	if (geo->far_offset && (bio_end % stripe_size)) {
+		split_size = bio_sectors(bio) - (bio_end % stripe_size);
+		bio = raid10_split_bio(conf, bio, split_size, true);
+	}
+
+	r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
+	r10_bio->mddev = mddev;
+	r10_bio->state = 0;
+	r10_bio->sectors = 0;
+	memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
+
+	wait_blocked_dev(mddev, r10_bio);
+
+	r10_bio->master_bio = bio;
+
+	bio_start = bio->bi_iter.bi_sector;
+	bio_end = bio_end_sector(bio);
+
+	/* raid10 uses chunk as the unit to store data. It's similar like raid0.
+	 * One stripe contains the chunks from all member disk (one chunk from
+	 * one disk at the same HBA address). For layout detail, see 'man md 4'
+	 */
+	chunk = bio_start >> geo->chunk_shift;
+	chunk *= geo->near_copies;
+	first_stripe_index = chunk;
+	start_disk_index = sector_div(first_stripe_index, geo->raid_disks);
+	if (geo->far_offset)
+		first_stripe_index *= geo->far_copies;
+	start_disk_offset = (bio_start & geo->chunk_mask) +
+				(first_stripe_index << geo->chunk_shift);
+
+	chunk = bio_end >> geo->chunk_shift;
+	chunk *= geo->near_copies;
+	last_stripe_index = chunk;
+	end_disk_index = sector_div(last_stripe_index, geo->raid_disks);
+	if (geo->far_offset)
+		last_stripe_index *= geo->far_copies;
+	end_disk_offset = (bio_end & geo->chunk_mask) +
+				(last_stripe_index << geo->chunk_shift);
+
+	rcu_read_lock();
+	for (disk = 0; disk < geo->raid_disks; disk++) {
+		struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
+		struct md_rdev *rrdev = rcu_dereference(
+			conf->mirrors[disk].replacement);
+
+		r10_bio->devs[disk].bio = NULL;
+		r10_bio->devs[disk].repl_bio = NULL;
+
+		if (rdev && (test_bit(Faulty, &rdev->flags)))
+			rdev = NULL;
+		if (rrdev && (test_bit(Faulty, &rrdev->flags)))
+			rrdev = NULL;
+		if (!rdev && !rrdev)
+			continue;
+
+		if (rdev) {
+			r10_bio->devs[disk].bio = bio;
+			atomic_inc(&rdev->nr_pending);
+		}
+		if (rrdev) {
+			r10_bio->devs[disk].repl_bio = bio;
+			atomic_inc(&rrdev->nr_pending);
+		}
+	}
+	rcu_read_unlock();
+
+	atomic_set(&r10_bio->remaining, 1);
+	for (disk = 0; disk < geo->raid_disks; disk++) {
+		sector_t dev_start, dev_end;
+		struct bio *mbio, *rbio = NULL;
+		struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
+		struct md_rdev *rrdev = rcu_dereference(
+			conf->mirrors[disk].replacement);
+
+		/*
+		 * Now start to calculate the start and end address for each disk.
+		 * The space between dev_start and dev_end is the discard region.
+		 *
+		 * For dev_start, it needs to consider three conditions:
+		 * 1st, the disk is before start_disk, you can imagine the disk in
+		 * the next stripe. So the dev_start is the start address of next
+		 * stripe.
+		 * 2st, the disk is after start_disk, it means the disk is at the
+		 * same stripe of first disk
+		 * 3st, the first disk itself, we can use start_disk_offset directly
+		 */
+		if (disk < start_disk_index)
+			dev_start = (first_stripe_index + 1) * mddev->chunk_sectors;
+		else if (disk > start_disk_index)
+			dev_start = first_stripe_index * mddev->chunk_sectors;
+		else
+			dev_start = start_disk_offset;
+
+		if (disk < end_disk_index)
+			dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
+		else if (disk > end_disk_index)
+			dev_end = last_stripe_index * mddev->chunk_sectors;
+		else
+			dev_end = end_disk_offset;
+
+		/* It only handles discard bio which size is >= stripe size, so
+		 * dev_end > dev_start all the time
+		 */
+		if (r10_bio->devs[disk].bio) {
+			mbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
+			mbio->bi_end_io = raid10_end_discard_request;
+			mbio->bi_private = r10_bio;
+			r10_bio->devs[disk].bio = mbio;
+			r10_bio->devs[disk].devnum = disk;
+			atomic_inc(&r10_bio->remaining);
+			md_submit_discard_bio(mddev, rdev, mbio, dev_start, dev_end);
+			bio_endio(mbio);
+		}
+		if (r10_bio->devs[disk].repl_bio) {
+			rbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
+			rbio->bi_end_io = raid10_end_discard_request;
+			rbio->bi_private = r10_bio;
+			r10_bio->devs[disk].repl_bio = rbio;
+			r10_bio->devs[disk].devnum = disk;
+			atomic_inc(&r10_bio->remaining);
+			md_submit_discard_bio(mddev, rrdev, rbio, dev_start, dev_end);
+			bio_endio(rbio);
+		}
+	}
+
+	if (atomic_dec_and_test(&r10_bio->remaining)) {
+		md_write_end(r10_bio->mddev);
+		raid_end_bio_io(r10_bio);
+	}
+
+	return 0;
+out:
+	allow_barrier(conf);
+	return -EAGAIN;
+}
+
 static bool raid10_make_request(struct mddev *mddev, struct bio *bio)
 {
 	struct r10conf *conf = mddev->private;
@@ -1531,6 +1776,10 @@ static bool raid10_make_request(struct mddev *mddev, struct bio *bio)
 	if (!md_write_start(mddev, bio))
 		return false;
 
+	if (unlikely(bio_op(bio) == REQ_OP_DISCARD))
+		if (!raid10_handle_discard(mddev, bio))
+			return true;
+
 	/*
 	 * If this request crosses a chunk boundary, we need to split
 	 * it.
@@ -3761,7 +4010,7 @@ static int raid10_run(struct mddev *mddev)
 	chunk_size = mddev->chunk_sectors << 9;
 	if (mddev->queue) {
 		blk_queue_max_discard_sectors(mddev->queue,
-					      mddev->chunk_sectors);
+					      UINT_MAX);
 		blk_queue_max_write_same_sectors(mddev->queue, 0);
 		blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
 		blk_queue_io_min(mddev->queue, chunk_size);
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V4 5/5] md/raid10: improve discard request for far layout
  2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
                   ` (3 preceding siblings ...)
  2020-08-24  4:11 ` [PATCH V4 4/5] md/raid10: improve raid10 discard request Xiao Ni
@ 2020-08-24  4:11 ` Xiao Ni
  4 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24  4:11 UTC (permalink / raw)
  To: linux-raid, song; +Cc: heinzm, ncroxon, guoqing.jiang, colyli

For far layout, the discard region is not continuous on disks. So it needs
far copies r10bio to cover all regions. It needs a way to know all r10bios
have finish or not. Similar with raid10_sync_request, only the first r10bio
master_bio records the discard bio. Other r10bios master_bio record the
first r10bio. The first r10bio can finish after other r10bios finish and
then return the discard bio.

Signed-off-by: Xiao Ni <xni@redhat.com>
---
 drivers/md/raid10.c | 86 +++++++++++++++++++++++++++++++++++++++--------------
 drivers/md/raid10.h |  1 +
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 58d36b9..c46fbec 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1535,6 +1535,28 @@ static struct bio *raid10_split_bio(struct r10conf *conf,
 	return bio;
 }
 
+static void raid_end_discard_bio(struct r10bio *r10bio)
+{
+	struct r10conf *conf = r10bio->mddev->private;
+	struct r10bio *first_r10bio;
+
+	while (atomic_dec_and_test(&r10bio->remaining)) {
+
+		allow_barrier(conf);
+
+		if (!test_bit(R10BIO_Discard, &r10bio->state)) {
+			first_r10bio = (struct r10bio *)r10bio->master_bio;
+			free_r10bio(r10bio);
+			r10bio = first_r10bio;
+		} else {
+			md_write_end(r10bio->mddev);
+			bio_endio(r10bio->master_bio);
+			free_r10bio(r10bio);
+			break;
+		}
+	}
+}
+
 static void raid10_end_discard_request(struct bio *bio)
 {
 	struct r10bio *r10_bio = bio->bi_private;
@@ -1562,11 +1584,7 @@ static void raid10_end_discard_request(struct bio *bio)
 		rdev = conf->mirrors[dev].rdev;
 	}
 
-	if (atomic_dec_and_test(&r10_bio->remaining)) {
-		md_write_end(r10_bio->mddev);
-		raid_end_bio_io(r10_bio);
-	}
-
+	raid_end_discard_bio(r10_bio);
 	rdev_dec_pending(rdev, conf->mddev);
 }
 
@@ -1579,7 +1597,9 @@ static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
 {
 	struct r10conf *conf = mddev->private;
 	struct geom *geo = &conf->geo;
-	struct r10bio *r10_bio;
+	struct r10bio *r10_bio, *first_r10bio;
+	int far_copies = geo->far_copies;
+	bool first_copy = true;
 
 	int disk;
 	sector_t chunk;
@@ -1618,28 +1638,18 @@ static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
 		bio_end > conf->reshape_progress)
 		goto out;
 
-	/* For far offset layout, if bio is not aligned with stripe size, it splits
-	 * the part that is not aligned with strip size.
+	/* For far and far offset layout, if bio is not aligned with stripe size,
+	 * it splits the part that is not aligned with strip size.
 	 */
-	if (geo->far_offset && (bio_start % stripe_size)) {
+	if ((far_copies > 1) && (bio_start % stripe_size)) {
 		split_size = (stripe_size - bio_start % stripe_size);
 		bio = raid10_split_bio(conf, bio, split_size, false);
 	}
-	if (geo->far_offset && (bio_end % stripe_size)) {
+	if ((far_copies > 1) && (bio_end % stripe_size)) {
 		split_size = bio_sectors(bio) - (bio_end % stripe_size);
 		bio = raid10_split_bio(conf, bio, split_size, true);
 	}
 
-	r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
-	r10_bio->mddev = mddev;
-	r10_bio->state = 0;
-	r10_bio->sectors = 0;
-	memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
-
-	wait_blocked_dev(mddev, r10_bio);
-
-	r10_bio->master_bio = bio;
-
 	bio_start = bio->bi_iter.bi_sector;
 	bio_end = bio_end_sector(bio);
 
@@ -1665,6 +1675,28 @@ static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
 	end_disk_offset = (bio_end & geo->chunk_mask) +
 				(last_stripe_index << geo->chunk_shift);
 
+retry_discard:
+	r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
+	r10_bio->mddev = mddev;
+	r10_bio->state = 0;
+	r10_bio->sectors = 0;
+	memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
+	wait_blocked_dev(mddev, r10_bio);
+
+	/* For far layout it needs more than one r10bio to cover all regions.
+	 * Inspired by raid10_sync_request, we can use the first r10bio->master_bio
+	 * to record the discard bio. Other r10bio->master_bio record the first
+	 * r10bio. The first r10bio only release after all other r10bios finish.
+	 * The discard bio returns only first r10bio finishes
+	 */
+	if (first_copy) {
+		r10_bio->master_bio = bio;
+		set_bit(R10BIO_Discard, &r10_bio->state);
+		first_copy = false;
+		first_r10bio = r10_bio;
+	} else
+		r10_bio->master_bio = (struct bio *)first_r10bio;
+
 	rcu_read_lock();
 	for (disk = 0; disk < geo->raid_disks; disk++) {
 		struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
@@ -1751,11 +1783,19 @@ static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
 		}
 	}
 
-	if (atomic_dec_and_test(&r10_bio->remaining)) {
-		md_write_end(r10_bio->mddev);
-		raid_end_bio_io(r10_bio);
+	if (!geo->far_offset && --far_copies) {
+		first_stripe_index += geo->stride >> geo->chunk_shift;
+		start_disk_offset += geo->stride;
+		last_stripe_index += geo->stride >> geo->chunk_shift;
+		end_disk_offset += geo->stride;
+		atomic_inc(&first_r10bio->remaining);
+		raid_end_discard_bio(r10_bio);
+		wait_barrier(conf);
+		goto retry_discard;
 	}
 
+	raid_end_discard_bio(r10_bio);
+
 	return 0;
 out:
 	allow_barrier(conf);
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h
index 79cd2b7..1461fd5 100644
--- a/drivers/md/raid10.h
+++ b/drivers/md/raid10.h
@@ -179,5 +179,6 @@ enum r10bio_state {
 	R10BIO_Previous,
 /* failfast devices did receive failfast requests. */
 	R10BIO_FailFast,
+	R10BIO_Discard,
 };
 #endif
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
  2020-08-24  4:11 ` [PATCH V4 4/5] md/raid10: improve raid10 discard request Xiao Ni
@ 2020-08-24 10:38     ` kernel test robot
  2020-08-24 13:31     ` kernel test robot
  1 sibling, 0 replies; 14+ messages in thread
From: kernel test robot @ 2020-08-24 10:38 UTC (permalink / raw)
  To: Xiao Ni, linux-raid, song
  Cc: kbuild-all, heinzm, ncroxon, guoqing.jiang, colyli

[-- Attachment #1: Type: text/plain, Size: 10460 bytes --]

Hi Xiao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on song-md/md-next]
[also build test ERROR on v5.9-rc2 next-20200824]
[cannot apply to md/for-next]
[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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
config: microblaze-randconfig-r004-20200824 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
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
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_remove':
   drivers/gpu/drm/bridge/sil-sii8620.c:2354: undefined reference to `extcon_unregister_notifier'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_work':
   drivers/gpu/drm/bridge/sil-sii8620.c:2139: undefined reference to `extcon_get_state'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_init':
   drivers/gpu/drm/bridge/sil-sii8620.c:2179: undefined reference to `extcon_find_edev_by_node'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.c:2191: undefined reference to `extcon_register_notifier'
   microblaze-linux-ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>> drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>> microblaze-linux-ld: drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1625: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.o:drivers/md/raid10.c:1629: more undefined references to `__umoddi3' follow

# https://github.com/0day-ci/linux/commit/51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
git checkout 51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
vim +1624 drivers/md/raid10.c

  1572	
  1573	/* There are some limitations to handle discard bio
  1574	 * 1st, the discard size is bigger than stripe_size*2.
  1575	 * 2st, if the discard bio spans reshape progress, we use the old way to
  1576	 * handle discard bio
  1577	 */
  1578	static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
  1579	{
  1580		struct r10conf *conf = mddev->private;
  1581		struct geom *geo = &conf->geo;
  1582		struct r10bio *r10_bio;
  1583	
  1584		int disk;
  1585		sector_t chunk;
  1586		int stripe_size;
  1587		sector_t split_size;
  1588	
  1589		sector_t bio_start, bio_end;
  1590		sector_t first_stripe_index, last_stripe_index;
  1591		sector_t start_disk_offset;
  1592		unsigned int start_disk_index;
  1593		sector_t end_disk_offset;
  1594		unsigned int end_disk_index;
  1595	
  1596		wait_barrier(conf);
  1597	
  1598		if (conf->reshape_progress != MaxSector &&
  1599		    ((bio->bi_iter.bi_sector >= conf->reshape_progress) !=
  1600		     conf->mddev->reshape_backwards))
  1601			geo = &conf->prev;
  1602	
  1603		stripe_size = geo->raid_disks << geo->chunk_shift;
  1604		bio_start = bio->bi_iter.bi_sector;
  1605		bio_end = bio_end_sector(bio);
  1606	
  1607		/* Maybe one discard bio is smaller than strip size or across one stripe
  1608		 * and discard region is larger than one stripe size. For far offset layout,
  1609		 * if the discard region is not aligned with stripe size, there is hole
  1610		 * when we submit discard bio to member disk. For simplicity, we only
  1611		 * handle discard bio which discard region is bigger than stripe_size*2
  1612		 */
  1613		if (bio_sectors(bio) < stripe_size*2)
  1614			goto out;
  1615	
  1616		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
  1617			bio_start < conf->reshape_progress &&
  1618			bio_end > conf->reshape_progress)
  1619			goto out;
  1620	
  1621		/* For far offset layout, if bio is not aligned with stripe size, it splits
  1622		 * the part that is not aligned with strip size.
  1623		 */
> 1624		if (geo->far_offset && (bio_start % stripe_size)) {
  1625			split_size = (stripe_size - bio_start % stripe_size);
  1626			bio = raid10_split_bio(conf, bio, split_size, false);
  1627		}
  1628		if (geo->far_offset && (bio_end % stripe_size)) {
  1629			split_size = bio_sectors(bio) - (bio_end % stripe_size);
  1630			bio = raid10_split_bio(conf, bio, split_size, true);
  1631		}
  1632	
  1633		r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
  1634		r10_bio->mddev = mddev;
  1635		r10_bio->state = 0;
  1636		r10_bio->sectors = 0;
  1637		memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
  1638	
  1639		wait_blocked_dev(mddev, r10_bio);
  1640	
  1641		r10_bio->master_bio = bio;
  1642	
  1643		bio_start = bio->bi_iter.bi_sector;
  1644		bio_end = bio_end_sector(bio);
  1645	
  1646		/* raid10 uses chunk as the unit to store data. It's similar like raid0.
  1647		 * One stripe contains the chunks from all member disk (one chunk from
  1648		 * one disk at the same HBA address). For layout detail, see 'man md 4'
  1649		 */
  1650		chunk = bio_start >> geo->chunk_shift;
  1651		chunk *= geo->near_copies;
  1652		first_stripe_index = chunk;
  1653		start_disk_index = sector_div(first_stripe_index, geo->raid_disks);
  1654		if (geo->far_offset)
  1655			first_stripe_index *= geo->far_copies;
  1656		start_disk_offset = (bio_start & geo->chunk_mask) +
  1657					(first_stripe_index << geo->chunk_shift);
  1658	
  1659		chunk = bio_end >> geo->chunk_shift;
  1660		chunk *= geo->near_copies;
  1661		last_stripe_index = chunk;
  1662		end_disk_index = sector_div(last_stripe_index, geo->raid_disks);
  1663		if (geo->far_offset)
  1664			last_stripe_index *= geo->far_copies;
  1665		end_disk_offset = (bio_end & geo->chunk_mask) +
  1666					(last_stripe_index << geo->chunk_shift);
  1667	
  1668		rcu_read_lock();
  1669		for (disk = 0; disk < geo->raid_disks; disk++) {
  1670			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1671			struct md_rdev *rrdev = rcu_dereference(
  1672				conf->mirrors[disk].replacement);
  1673	
  1674			r10_bio->devs[disk].bio = NULL;
  1675			r10_bio->devs[disk].repl_bio = NULL;
  1676	
  1677			if (rdev && (test_bit(Faulty, &rdev->flags)))
  1678				rdev = NULL;
  1679			if (rrdev && (test_bit(Faulty, &rrdev->flags)))
  1680				rrdev = NULL;
  1681			if (!rdev && !rrdev)
  1682				continue;
  1683	
  1684			if (rdev) {
  1685				r10_bio->devs[disk].bio = bio;
  1686				atomic_inc(&rdev->nr_pending);
  1687			}
  1688			if (rrdev) {
  1689				r10_bio->devs[disk].repl_bio = bio;
  1690				atomic_inc(&rrdev->nr_pending);
  1691			}
  1692		}
  1693		rcu_read_unlock();
  1694	
  1695		atomic_set(&r10_bio->remaining, 1);
  1696		for (disk = 0; disk < geo->raid_disks; disk++) {
  1697			sector_t dev_start, dev_end;
  1698			struct bio *mbio, *rbio = NULL;
  1699			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1700			struct md_rdev *rrdev = rcu_dereference(
  1701				conf->mirrors[disk].replacement);
  1702	
  1703			/*
  1704			 * Now start to calculate the start and end address for each disk.
  1705			 * The space between dev_start and dev_end is the discard region.
  1706			 *
  1707			 * For dev_start, it needs to consider three conditions:
  1708			 * 1st, the disk is before start_disk, you can imagine the disk in
  1709			 * the next stripe. So the dev_start is the start address of next
  1710			 * stripe.
  1711			 * 2st, the disk is after start_disk, it means the disk is at the
  1712			 * same stripe of first disk
  1713			 * 3st, the first disk itself, we can use start_disk_offset directly
  1714			 */
  1715			if (disk < start_disk_index)
  1716				dev_start = (first_stripe_index + 1) * mddev->chunk_sectors;
  1717			else if (disk > start_disk_index)
  1718				dev_start = first_stripe_index * mddev->chunk_sectors;
  1719			else
  1720				dev_start = start_disk_offset;
  1721	
  1722			if (disk < end_disk_index)
  1723				dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
  1724			else if (disk > end_disk_index)
  1725				dev_end = last_stripe_index * mddev->chunk_sectors;
  1726			else
  1727				dev_end = end_disk_offset;
  1728	
  1729			/* It only handles discard bio which size is >= stripe size, so
  1730			 * dev_end > dev_start all the time
  1731			 */
  1732			if (r10_bio->devs[disk].bio) {
  1733				mbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1734				mbio->bi_end_io = raid10_end_discard_request;
  1735				mbio->bi_private = r10_bio;
  1736				r10_bio->devs[disk].bio = mbio;
  1737				r10_bio->devs[disk].devnum = disk;
  1738				atomic_inc(&r10_bio->remaining);
  1739				md_submit_discard_bio(mddev, rdev, mbio, dev_start, dev_end);
  1740				bio_endio(mbio);
  1741			}
  1742			if (r10_bio->devs[disk].repl_bio) {
  1743				rbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1744				rbio->bi_end_io = raid10_end_discard_request;
  1745				rbio->bi_private = r10_bio;
  1746				r10_bio->devs[disk].repl_bio = rbio;
  1747				r10_bio->devs[disk].devnum = disk;
  1748				atomic_inc(&r10_bio->remaining);
  1749				md_submit_discard_bio(mddev, rrdev, rbio, dev_start, dev_end);
  1750				bio_endio(rbio);
  1751			}
  1752		}
  1753	
  1754		if (atomic_dec_and_test(&r10_bio->remaining)) {
  1755			md_write_end(r10_bio->mddev);
  1756			raid_end_bio_io(r10_bio);
  1757		}
  1758	
  1759		return 0;
  1760	out:
  1761		allow_barrier(conf);
  1762		return -EAGAIN;
  1763	}
  1764	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28611 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
@ 2020-08-24 10:38     ` kernel test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2020-08-24 10:38 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 10706 bytes --]

Hi Xiao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on song-md/md-next]
[also build test ERROR on v5.9-rc2 next-20200824]
[cannot apply to md/for-next]
[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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
config: microblaze-randconfig-r004-20200824 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
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
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_remove':
   drivers/gpu/drm/bridge/sil-sii8620.c:2354: undefined reference to `extcon_unregister_notifier'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_work':
   drivers/gpu/drm/bridge/sil-sii8620.c:2139: undefined reference to `extcon_get_state'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_init':
   drivers/gpu/drm/bridge/sil-sii8620.c:2179: undefined reference to `extcon_find_edev_by_node'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.c:2191: undefined reference to `extcon_register_notifier'
   microblaze-linux-ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>> drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>> microblaze-linux-ld: drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1625: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.o:drivers/md/raid10.c:1629: more undefined references to `__umoddi3' follow

# https://github.com/0day-ci/linux/commit/51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
git checkout 51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
vim +1624 drivers/md/raid10.c

  1572	
  1573	/* There are some limitations to handle discard bio
  1574	 * 1st, the discard size is bigger than stripe_size*2.
  1575	 * 2st, if the discard bio spans reshape progress, we use the old way to
  1576	 * handle discard bio
  1577	 */
  1578	static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
  1579	{
  1580		struct r10conf *conf = mddev->private;
  1581		struct geom *geo = &conf->geo;
  1582		struct r10bio *r10_bio;
  1583	
  1584		int disk;
  1585		sector_t chunk;
  1586		int stripe_size;
  1587		sector_t split_size;
  1588	
  1589		sector_t bio_start, bio_end;
  1590		sector_t first_stripe_index, last_stripe_index;
  1591		sector_t start_disk_offset;
  1592		unsigned int start_disk_index;
  1593		sector_t end_disk_offset;
  1594		unsigned int end_disk_index;
  1595	
  1596		wait_barrier(conf);
  1597	
  1598		if (conf->reshape_progress != MaxSector &&
  1599		    ((bio->bi_iter.bi_sector >= conf->reshape_progress) !=
  1600		     conf->mddev->reshape_backwards))
  1601			geo = &conf->prev;
  1602	
  1603		stripe_size = geo->raid_disks << geo->chunk_shift;
  1604		bio_start = bio->bi_iter.bi_sector;
  1605		bio_end = bio_end_sector(bio);
  1606	
  1607		/* Maybe one discard bio is smaller than strip size or across one stripe
  1608		 * and discard region is larger than one stripe size. For far offset layout,
  1609		 * if the discard region is not aligned with stripe size, there is hole
  1610		 * when we submit discard bio to member disk. For simplicity, we only
  1611		 * handle discard bio which discard region is bigger than stripe_size*2
  1612		 */
  1613		if (bio_sectors(bio) < stripe_size*2)
  1614			goto out;
  1615	
  1616		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
  1617			bio_start < conf->reshape_progress &&
  1618			bio_end > conf->reshape_progress)
  1619			goto out;
  1620	
  1621		/* For far offset layout, if bio is not aligned with stripe size, it splits
  1622		 * the part that is not aligned with strip size.
  1623		 */
> 1624		if (geo->far_offset && (bio_start % stripe_size)) {
  1625			split_size = (stripe_size - bio_start % stripe_size);
  1626			bio = raid10_split_bio(conf, bio, split_size, false);
  1627		}
  1628		if (geo->far_offset && (bio_end % stripe_size)) {
  1629			split_size = bio_sectors(bio) - (bio_end % stripe_size);
  1630			bio = raid10_split_bio(conf, bio, split_size, true);
  1631		}
  1632	
  1633		r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
  1634		r10_bio->mddev = mddev;
  1635		r10_bio->state = 0;
  1636		r10_bio->sectors = 0;
  1637		memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
  1638	
  1639		wait_blocked_dev(mddev, r10_bio);
  1640	
  1641		r10_bio->master_bio = bio;
  1642	
  1643		bio_start = bio->bi_iter.bi_sector;
  1644		bio_end = bio_end_sector(bio);
  1645	
  1646		/* raid10 uses chunk as the unit to store data. It's similar like raid0.
  1647		 * One stripe contains the chunks from all member disk (one chunk from
  1648		 * one disk at the same HBA address). For layout detail, see 'man md 4'
  1649		 */
  1650		chunk = bio_start >> geo->chunk_shift;
  1651		chunk *= geo->near_copies;
  1652		first_stripe_index = chunk;
  1653		start_disk_index = sector_div(first_stripe_index, geo->raid_disks);
  1654		if (geo->far_offset)
  1655			first_stripe_index *= geo->far_copies;
  1656		start_disk_offset = (bio_start & geo->chunk_mask) +
  1657					(first_stripe_index << geo->chunk_shift);
  1658	
  1659		chunk = bio_end >> geo->chunk_shift;
  1660		chunk *= geo->near_copies;
  1661		last_stripe_index = chunk;
  1662		end_disk_index = sector_div(last_stripe_index, geo->raid_disks);
  1663		if (geo->far_offset)
  1664			last_stripe_index *= geo->far_copies;
  1665		end_disk_offset = (bio_end & geo->chunk_mask) +
  1666					(last_stripe_index << geo->chunk_shift);
  1667	
  1668		rcu_read_lock();
  1669		for (disk = 0; disk < geo->raid_disks; disk++) {
  1670			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1671			struct md_rdev *rrdev = rcu_dereference(
  1672				conf->mirrors[disk].replacement);
  1673	
  1674			r10_bio->devs[disk].bio = NULL;
  1675			r10_bio->devs[disk].repl_bio = NULL;
  1676	
  1677			if (rdev && (test_bit(Faulty, &rdev->flags)))
  1678				rdev = NULL;
  1679			if (rrdev && (test_bit(Faulty, &rrdev->flags)))
  1680				rrdev = NULL;
  1681			if (!rdev && !rrdev)
  1682				continue;
  1683	
  1684			if (rdev) {
  1685				r10_bio->devs[disk].bio = bio;
  1686				atomic_inc(&rdev->nr_pending);
  1687			}
  1688			if (rrdev) {
  1689				r10_bio->devs[disk].repl_bio = bio;
  1690				atomic_inc(&rrdev->nr_pending);
  1691			}
  1692		}
  1693		rcu_read_unlock();
  1694	
  1695		atomic_set(&r10_bio->remaining, 1);
  1696		for (disk = 0; disk < geo->raid_disks; disk++) {
  1697			sector_t dev_start, dev_end;
  1698			struct bio *mbio, *rbio = NULL;
  1699			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1700			struct md_rdev *rrdev = rcu_dereference(
  1701				conf->mirrors[disk].replacement);
  1702	
  1703			/*
  1704			 * Now start to calculate the start and end address for each disk.
  1705			 * The space between dev_start and dev_end is the discard region.
  1706			 *
  1707			 * For dev_start, it needs to consider three conditions:
  1708			 * 1st, the disk is before start_disk, you can imagine the disk in
  1709			 * the next stripe. So the dev_start is the start address of next
  1710			 * stripe.
  1711			 * 2st, the disk is after start_disk, it means the disk is at the
  1712			 * same stripe of first disk
  1713			 * 3st, the first disk itself, we can use start_disk_offset directly
  1714			 */
  1715			if (disk < start_disk_index)
  1716				dev_start = (first_stripe_index + 1) * mddev->chunk_sectors;
  1717			else if (disk > start_disk_index)
  1718				dev_start = first_stripe_index * mddev->chunk_sectors;
  1719			else
  1720				dev_start = start_disk_offset;
  1721	
  1722			if (disk < end_disk_index)
  1723				dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
  1724			else if (disk > end_disk_index)
  1725				dev_end = last_stripe_index * mddev->chunk_sectors;
  1726			else
  1727				dev_end = end_disk_offset;
  1728	
  1729			/* It only handles discard bio which size is >= stripe size, so
  1730			 * dev_end > dev_start all the time
  1731			 */
  1732			if (r10_bio->devs[disk].bio) {
  1733				mbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1734				mbio->bi_end_io = raid10_end_discard_request;
  1735				mbio->bi_private = r10_bio;
  1736				r10_bio->devs[disk].bio = mbio;
  1737				r10_bio->devs[disk].devnum = disk;
  1738				atomic_inc(&r10_bio->remaining);
  1739				md_submit_discard_bio(mddev, rdev, mbio, dev_start, dev_end);
  1740				bio_endio(mbio);
  1741			}
  1742			if (r10_bio->devs[disk].repl_bio) {
  1743				rbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1744				rbio->bi_end_io = raid10_end_discard_request;
  1745				rbio->bi_private = r10_bio;
  1746				r10_bio->devs[disk].repl_bio = rbio;
  1747				r10_bio->devs[disk].devnum = disk;
  1748				atomic_inc(&r10_bio->remaining);
  1749				md_submit_discard_bio(mddev, rrdev, rbio, dev_start, dev_end);
  1750				bio_endio(rbio);
  1751			}
  1752		}
  1753	
  1754		if (atomic_dec_and_test(&r10_bio->remaining)) {
  1755			md_write_end(r10_bio->mddev);
  1756			raid_end_bio_io(r10_bio);
  1757		}
  1758	
  1759		return 0;
  1760	out:
  1761		allow_barrier(conf);
  1762		return -EAGAIN;
  1763	}
  1764	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28611 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
  2020-08-24  4:11 ` [PATCH V4 4/5] md/raid10: improve raid10 discard request Xiao Ni
@ 2020-08-24 13:31     ` kernel test robot
  2020-08-24 13:31     ` kernel test robot
  1 sibling, 0 replies; 14+ messages in thread
From: kernel test robot @ 2020-08-24 13:31 UTC (permalink / raw)
  To: Xiao Ni, linux-raid, song
  Cc: kbuild-all, heinzm, ncroxon, guoqing.jiang, colyli

[-- Attachment #1: Type: text/plain, Size: 1272 bytes --]

Hi Xiao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on song-md/md-next]
[also build test ERROR on v5.9-rc2 next-20200824]
[cannot apply to md/for-next]
[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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
config: i386-randconfig-a015-20200824 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: drivers/md/raid10.o: in function `raid10_handle_discard':
   drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 36735 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
@ 2020-08-24 13:31     ` kernel test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2020-08-24 13:31 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1305 bytes --]

Hi Xiao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on song-md/md-next]
[also build test ERROR on v5.9-rc2 next-20200824]
[cannot apply to md/for-next]
[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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
config: i386-randconfig-a015-20200824 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: drivers/md/raid10.o: in function `raid10_handle_discard':
   drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 36735 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
  2020-08-24 13:31     ` kernel test robot
@ 2020-08-24 15:12       ` Xiao Ni
  -1 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24 15:12 UTC (permalink / raw)
  To: kernel test robot, linux-raid, song
  Cc: kbuild-all, heinzm, ncroxon, guoqing.jiang, colyli

Hi all

I can build successfully based on the latest upstream version

[xni@xiao md]$ git branch
   master
* md-next
[xni@xiao md]$ git pull
Already up-to-date.

Makefile:
VERSION = 5
PATCHLEVEL = 9
SUBLEVEL = 0
EXTRAVERSION = -rc1

Regards
Xiao

On 08/24/2020 09:31 PM, kernel test robot wrote:
> Hi Xiao,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on song-md/md-next]
> [also build test ERROR on v5.9-rc2 next-20200824]
> [cannot apply to md/for-next]
> [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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
> base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
> config: i386-randconfig-a015-20200824 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
> reproduce (this is a W=1 build):
>          # save the attached .config to linux build tree
>          make W=1 ARCH=i386
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>     ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>     drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
@ 2020-08-24 15:12       ` Xiao Ni
  0 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24 15:12 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1679 bytes --]

Hi all

I can build successfully based on the latest upstream version

[xni(a)xiao md]$ git branch
   master
* md-next
[xni(a)xiao md]$ git pull
Already up-to-date.

Makefile:
VERSION = 5
PATCHLEVEL = 9
SUBLEVEL = 0
EXTRAVERSION = -rc1

Regards
Xiao

On 08/24/2020 09:31 PM, kernel test robot wrote:
> Hi Xiao,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on song-md/md-next]
> [also build test ERROR on v5.9-rc2 next-20200824]
> [cannot apply to md/for-next]
> [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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
> base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
> config: i386-randconfig-a015-20200824 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
> reproduce (this is a W=1 build):
>          # save the attached .config to linux build tree
>          make W=1 ARCH=i386
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>     ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>     drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
> ---
> 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] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
  2020-08-24 15:12       ` Xiao Ni
@ 2020-08-24 15:53         ` Xiao Ni
  -1 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24 15:53 UTC (permalink / raw)
  To: kernel test robot, linux-raid, song
  Cc: kbuild-all, heinzm, ncroxon, guoqing.jiang, colyli

I downloaded the .config in my environment and use `make W=1 ARCH=i386` 
to build the kernel.
It fails.
drivers/md/raid10.o: In function `raid10_handle_discard':
/home/xni/codes/md/drivers/md/raid10.c:1644: undefined reference to 
`__umoddi3'
/home/xni/codes/md/drivers/md/raid10.c:1648: undefined reference to 
`__umoddi3'
make: *** [Makefile:1167: vmlinux] Error 1

It's my first time to see these errors. I'll try to fix the error and 
send the patch again.

Regards
Xiao

On 08/24/2020 11:12 PM, Xiao Ni wrote:
> Hi all
>
> I can build successfully based on the latest upstream version
>
> [xni@xiao md]$ git branch
>   master
> * md-next
> [xni@xiao md]$ git pull
> Already up-to-date.
>
> Makefile:
> VERSION = 5
> PATCHLEVEL = 9
> SUBLEVEL = 0
> EXTRAVERSION = -rc1
>
> Regards
> Xiao
>
> On 08/24/2020 09:31 PM, kernel test robot wrote:
>> Hi Xiao,
>>
>> Thank you for the patch! Yet something to improve:
>>
>> [auto build test ERROR on song-md/md-next]
>> [also build test ERROR on v5.9-rc2 next-20200824]
>> [cannot apply to md/for-next]
>> [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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
>> base: git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
>> config: i386-randconfig-a015-20200824 (attached as .config)
>> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
>> reproduce (this is a W=1 build):
>>          # save the attached .config to linux build tree
>>          make W=1 ARCH=i386
>>
>> If you fix the issue, kindly add following tag as appropriate
>> Reported-by: kernel test robot <lkp@intel.com>
>>
>> All errors (new ones prefixed by >>):
>>
>>     ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>>     drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>>>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
>> ---
>> 0-DAY CI Kernel Test Service, Intel Corporation
>> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request
@ 2020-08-24 15:53         ` Xiao Ni
  0 siblings, 0 replies; 14+ messages in thread
From: Xiao Ni @ 2020-08-24 15:53 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2278 bytes --]

I downloaded the .config in my environment and use `make W=1 ARCH=i386` 
to build the kernel.
It fails.
drivers/md/raid10.o: In function `raid10_handle_discard':
/home/xni/codes/md/drivers/md/raid10.c:1644: undefined reference to 
`__umoddi3'
/home/xni/codes/md/drivers/md/raid10.c:1648: undefined reference to 
`__umoddi3'
make: *** [Makefile:1167: vmlinux] Error 1

It's my first time to see these errors. I'll try to fix the error and 
send the patch again.

Regards
Xiao

On 08/24/2020 11:12 PM, Xiao Ni wrote:
> Hi all
>
> I can build successfully based on the latest upstream version
>
> [xni(a)xiao md]$ git branch
>   master
> * md-next
> [xni(a)xiao md]$ git pull
> Already up-to-date.
>
> Makefile:
> VERSION = 5
> PATCHLEVEL = 9
> SUBLEVEL = 0
> EXTRAVERSION = -rc1
>
> Regards
> Xiao
>
> On 08/24/2020 09:31 PM, kernel test robot wrote:
>> Hi Xiao,
>>
>> Thank you for the patch! Yet something to improve:
>>
>> [auto build test ERROR on song-md/md-next]
>> [also build test ERROR on v5.9-rc2 next-20200824]
>> [cannot apply to md/for-next]
>> [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/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
>> base: git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
>> config: i386-randconfig-a015-20200824 (attached as .config)
>> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
>> reproduce (this is a W=1 build):
>>          # save the attached .config to linux build tree
>>          make W=1 ARCH=i386
>>
>> If you fix the issue, kindly add following tag as appropriate
>> Reported-by: kernel test robot <lkp@intel.com>
>>
>> All errors (new ones prefixed by >>):
>>
>>     ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>>     drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>>>> ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
>> ---
>> 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] 14+ messages in thread

end of thread, other threads:[~2020-08-24 15:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-24  4:11 [PATCH V4 0/4] md/raid10: Improve handling raid10 discard request Xiao Ni
2020-08-24  4:11 ` [PATCH V4 1/5] md/raid10: move codes related with submitting discard bio into one function Xiao Ni
2020-08-24  4:11 ` [PATCH V4 2/5] md/raid10: extend r10bio devs to raid disks Xiao Ni
2020-08-24  4:11 ` [PATCH V4 3/5] md/raid10: pull codes that wait for blocked dev into one function Xiao Ni
2020-08-24  4:11 ` [PATCH V4 4/5] md/raid10: improve raid10 discard request Xiao Ni
2020-08-24 10:38   ` kernel test robot
2020-08-24 10:38     ` kernel test robot
2020-08-24 13:31   ` kernel test robot
2020-08-24 13:31     ` kernel test robot
2020-08-24 15:12     ` Xiao Ni
2020-08-24 15:12       ` Xiao Ni
2020-08-24 15:53       ` Xiao Ni
2020-08-24 15:53         ` Xiao Ni
2020-08-24  4:11 ` [PATCH V4 5/5] md/raid10: improve discard request for far layout Xiao Ni

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.