Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1587737 > unrolled thread
| Started by | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| First post | 2017-02-24 16:50 +0100 |
| Last post | 2017-02-28 13:30 +0100 |
| Articles | 10 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v1 00/14] md: cleanup on direct access to bvec table Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 06/14] md: raid1: simplify r1buf_pool_free() Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 04/14] md: move two macros into md.h Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 08/14] md: raid1: retrieve page from pre-allocated resync page array Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 13/14] md: raid10: retrieve page from preallocated resync page array Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 14/14] md: raid10: avoid direct access to bvec table in handle_reshape_read_error Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 03/14] md: raid1/raid10: use bio_remove_last_page() Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
[PATCH v1 01/14] block: introduce bio_segments_all() Ming Lei <tom.leiming@gmail.com> - 2017-02-24 16:50 +0100
Re: [PATCH v1 01/14] block: introduce bio_segments_all() Christoph Hellwig <hch@infradead.org> - 2017-02-25 19:30 +0100
Re: [PATCH v1 01/14] block: introduce bio_segments_all() Ming Lei <tom.leiming@gmail.com> - 2017-02-28 13:30 +0100
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 00/14] md: cleanup on direct access to bvec table |
| Message-ID | <teqi5-2bp-5@gated-at.bofh.it> |
In MD's resync I/O path, there are lots of direct access to bio's
bvec table. This patchset kills almost all, and the conversion
is quite straightforward. One root cause of direct access to bvec
table is that resync I/O uses the bio's bvec to manage pages.
In V1, as suggested by Shaohua, a new approach is used to manage
these pages for resync I/O, turns out code becomes more clean
and readable.
Once direct access to bvec table in MD is cleaned up, we may make
multipage bvec moving on.
V1:
- allocate page array to manage resync pages
Thanks,
Ming
Ming Lei (14):
block: introduce bio_segments_all()
block: introduce bio_remove_last_page()
md: raid1/raid10: use bio_remove_last_page()
md: move two macros into md.h
md: prepare for managing resync I/O pages in clean way
md: raid1: simplify r1buf_pool_free()
md: raid1: don't use bio's vec table to manage resync pages
md: raid1: retrieve page from pre-allocated resync page array
md: raid1: use bio helper in process_checks()
md: raid1: use bio_segments_all()
md: raid10: refactor code of read reshape's .bi_end_io
md: raid10: don't use bio's vec table to manage resync pages
md: raid10: retrieve page from preallocated resync page array
md: raid10: avoid direct access to bvec table in
handle_reshape_read_error
block/bio.c | 23 +++++++
drivers/md/md.h | 66 +++++++++++++++++++
drivers/md/raid1.c | 125 +++++++++++++++++++++--------------
drivers/md/raid10.c | 187 +++++++++++++++++++++++++++++++---------------------
include/linux/bio.h | 8 +++
5 files changed, 285 insertions(+), 124 deletions(-)
--
2.7.4
[toc] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 06/14] md: raid1: simplify r1buf_pool_free() |
| Message-ID | <teqi7-2bp-37@gated-at.bofh.it> |
| In reply to | #1587737 |
This patch gets each page's reference of each bio for resync,
then r1buf_pool_free() gets simplified a lot.
The same policy has been taken in raid10's buf pool allocation/free
too.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
drivers/md/raid1.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 2013e5870761..2de0bd69d8da 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -139,9 +139,12 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
/* If not user-requests, copy the page pointers to all bios */
if (!test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery)) {
for (i=0; i<RESYNC_PAGES ; i++)
- for (j=1; j<pi->raid_disks; j++)
- r1_bio->bios[j]->bi_io_vec[i].bv_page =
+ for (j=1; j<pi->raid_disks; j++) {
+ struct page *page =
r1_bio->bios[0]->bi_io_vec[i].bv_page;
+ get_page(page);
+ r1_bio->bios[j]->bi_io_vec[i].bv_page = page;
+ }
}
r1_bio->master_bio = NULL;
@@ -166,12 +169,8 @@ static void r1buf_pool_free(void *__r1_bio, void *data)
struct r1bio *r1bio = __r1_bio;
for (i = 0; i < RESYNC_PAGES; i++)
- for (j = pi->raid_disks; j-- ;) {
- if (j == 0 ||
- r1bio->bios[j]->bi_io_vec[i].bv_page !=
- r1bio->bios[0]->bi_io_vec[i].bv_page)
- safe_put_page(r1bio->bios[j]->bi_io_vec[i].bv_page);
- }
+ for (j = pi->raid_disks; j-- ;)
+ safe_put_page(r1bio->bios[j]->bi_io_vec[i].bv_page);
for (i=0 ; i < pi->raid_disks; i++)
bio_put(r1bio->bios[i]);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 04/14] md: move two macros into md.h |
| Message-ID | <teqi6-2bp-31@gated-at.bofh.it> |
| In reply to | #1587737 |
Both raid1 and raid10 share common resync block size and page count, so move them into md.h. Signed-off-by: Ming Lei <tom.leiming@gmail.com> --- drivers/md/md.h | 5 +++++ drivers/md/raid1.c | 2 -- drivers/md/raid10.c | 3 --- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/md/md.h b/drivers/md/md.h index b8859cbf84b6..1d63239a1be4 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -715,4 +715,9 @@ static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio) !bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors) mddev->queue->limits.max_write_same_sectors = 0; } + +/* Maximum size of each resync request */ +#define RESYNC_BLOCK_SIZE (64*1024) +#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) + #endif /* _MD_MD_H */ diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 2a0bf5b430c9..2013e5870761 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -91,10 +91,8 @@ static void r1bio_pool_free(void *r1_bio, void *data) kfree(r1_bio); } -#define RESYNC_BLOCK_SIZE (64*1024) #define RESYNC_DEPTH 32 #define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9) -#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) #define RESYNC_WINDOW (RESYNC_BLOCK_SIZE * RESYNC_DEPTH) #define RESYNC_WINDOW_SECTORS (RESYNC_WINDOW >> 9) #define CLUSTER_RESYNC_WINDOW (16 * RESYNC_WINDOW) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 125d74dba27e..227dd6ad7716 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -125,9 +125,6 @@ static void r10bio_pool_free(void *r10_bio, void *data) kfree(r10_bio); } -/* Maximum size of each resync request */ -#define RESYNC_BLOCK_SIZE (64*1024) -#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) /* amount of memory to reserve for resync requests */ #define RESYNC_WINDOW (1024*1024) /* maximum number of concurrent requests, memory permitting */ -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 08/14] md: raid1: retrieve page from pre-allocated resync page array |
| Message-ID | <teqi7-2bp-39@gated-at.bofh.it> |
| In reply to | #1587737 |
Now one page array is allocated for each resync bio, and we can
retrieve page from this table directly.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
drivers/md/raid1.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4a208220ff0f..9371caace379 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1970,6 +1970,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
struct mddev *mddev = r1_bio->mddev;
struct r1conf *conf = mddev->private;
struct bio *bio = r1_bio->bios[r1_bio->read_disk];
+ struct page **pages = get_resync_pages(bio)->pages;
sector_t sect = r1_bio->sector;
int sectors = r1_bio->sectors;
int idx = 0;
@@ -2003,7 +2004,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
*/
rdev = conf->mirrors[d].rdev;
if (sync_page_io(rdev, sect, s<<9,
- bio->bi_io_vec[idx].bv_page,
+ pages[idx],
REQ_OP_READ, 0, false)) {
success = 1;
break;
@@ -2058,7 +2059,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
continue;
rdev = conf->mirrors[d].rdev;
if (r1_sync_page_io(rdev, sect, s,
- bio->bi_io_vec[idx].bv_page,
+ pages[idx],
WRITE) == 0) {
r1_bio->bios[d]->bi_end_io = NULL;
rdev_dec_pending(rdev, mddev);
@@ -2073,7 +2074,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
continue;
rdev = conf->mirrors[d].rdev;
if (r1_sync_page_io(rdev, sect, s,
- bio->bi_io_vec[idx].bv_page,
+ pages[idx],
READ) != 0)
atomic_add(s, &rdev->corrected_errors);
}
@@ -2149,6 +2150,8 @@ static void process_checks(struct r1bio *r1_bio)
struct bio *pbio = r1_bio->bios[primary];
struct bio *sbio = r1_bio->bios[i];
int error = sbio->bi_error;
+ struct page **ppages = get_resync_pages(pbio)->pages;
+ struct page **spages = get_resync_pages(sbio)->pages;
if (sbio->bi_end_io != end_sync_read)
continue;
@@ -2157,11 +2160,8 @@ static void process_checks(struct r1bio *r1_bio)
if (!error) {
for (j = vcnt; j-- ; ) {
- struct page *p, *s;
- p = pbio->bi_io_vec[j].bv_page;
- s = sbio->bi_io_vec[j].bv_page;
- if (memcmp(page_address(p),
- page_address(s),
+ if (memcmp(page_address(ppages[j]),
+ page_address(spages[j]),
sbio->bi_io_vec[j].bv_len))
break;
}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 13/14] md: raid10: retrieve page from preallocated resync page array |
| Message-ID | <teqi7-2bp-43@gated-at.bofh.it> |
| In reply to | #1587737 |
Now one page array is allocated for each resync bio, and we can
retrieve page from this table directly.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
drivers/md/raid10.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 931f5d80608b..ae162d542bf4 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2065,6 +2065,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
int i, first;
struct bio *tbio, *fbio;
int vcnt;
+ struct page **tpages, **fpages;
atomic_set(&r10_bio->remaining, 1);
@@ -2080,6 +2081,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
fbio = r10_bio->devs[i].bio;
fbio->bi_iter.bi_size = r10_bio->sectors << 9;
fbio->bi_iter.bi_idx = 0;
+ fpages = get_resync_pages(fbio)->pages;
vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
/* now find blocks with errors */
@@ -2094,6 +2096,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
continue;
if (i == first)
continue;
+
+ tpages = get_resync_pages(tbio)->pages;
d = r10_bio->devs[i].devnum;
rdev = conf->mirrors[d].rdev;
if (!r10_bio->devs[i].bio->bi_error) {
@@ -2106,8 +2110,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
int len = PAGE_SIZE;
if (sectors < (len / 512))
len = sectors * 512;
- if (memcmp(page_address(fbio->bi_io_vec[j].bv_page),
- page_address(tbio->bi_io_vec[j].bv_page),
+ if (memcmp(page_address(fpages[j]),
+ page_address(tpages[j]),
len))
break;
sectors -= len/512;
@@ -2205,6 +2209,7 @@ static void fix_recovery_read_error(struct r10bio *r10_bio)
int idx = 0;
int dr = r10_bio->devs[0].devnum;
int dw = r10_bio->devs[1].devnum;
+ struct page **pages = get_resync_pages(bio)->pages;
while (sectors) {
int s = sectors;
@@ -2220,7 +2225,7 @@ static void fix_recovery_read_error(struct r10bio *r10_bio)
ok = sync_page_io(rdev,
addr,
s << 9,
- bio->bi_io_vec[idx].bv_page,
+ pages[idx],
REQ_OP_READ, 0, false);
if (ok) {
rdev = conf->mirrors[dw].rdev;
@@ -2228,7 +2233,7 @@ static void fix_recovery_read_error(struct r10bio *r10_bio)
ok = sync_page_io(rdev,
addr,
s << 9,
- bio->bi_io_vec[idx].bv_page,
+ pages[idx],
REQ_OP_WRITE, 0, false);
if (!ok) {
set_bit(WriteErrorSeen, &rdev->flags);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 14/14] md: raid10: avoid direct access to bvec table in handle_reshape_read_error |
| Message-ID | <teqi7-2bp-49@gated-at.bofh.it> |
| In reply to | #1587737 |
The cost is 128bytes(8*16) stack space in kernel thread context, and just use the bio helper to retrieve pages from bio. Signed-off-by: Ming Lei <tom.leiming@gmail.com> --- drivers/md/raid10.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ae162d542bf4..705cb9af03ef 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4689,7 +4689,15 @@ static int handle_reshape_read_error(struct mddev *mddev, struct r10bio *r10b = &on_stack.r10_bio; int slot = 0; int idx = 0; - struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; + struct bio_vec *bvl; + struct page *pages[RESYNC_PAGES]; + + /* + * This bio is allocated in reshape_request(), and size + * is still RESYNC_PAGES + */ + bio_for_each_segment_all(bvl, r10_bio->master_bio, idx) + pages[idx] = bvl->bv_page; r10b->sector = r10_bio->sector; __raid10_find_phys(&conf->prev, r10b); @@ -4718,7 +4726,7 @@ static int handle_reshape_read_error(struct mddev *mddev, success = sync_page_io(rdev, addr, s << 9, - bvec[idx].bv_page, + pages[idx], REQ_OP_READ, 0, false); rdev_dec_pending(rdev, mddev); rcu_read_lock(); -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 03/14] md: raid1/raid10: use bio_remove_last_page() |
| Message-ID | <teqi7-2bp-47@gated-at.bofh.it> |
| In reply to | #1587737 |
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
drivers/md/raid1.c | 3 +--
drivers/md/raid10.c | 6 ++----
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 0628c07dd16d..2a0bf5b430c9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2912,8 +2912,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
if (bio->bi_end_io==NULL)
continue;
/* remove last page from this bio */
- bio->bi_vcnt--;
- bio->bi_iter.bi_size -= len;
+ bio_remove_last_page(bio);
bio_clear_flag(bio, BIO_SEG_VALID);
}
goto bio_full;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 33f6a535dc1f..125d74dba27e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3446,8 +3446,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
bio2 && bio2 != bio;
bio2 = bio2->bi_next) {
/* remove last page from this bio */
- bio2->bi_vcnt--;
- bio2->bi_iter.bi_size -= len;
+ bio_remove_last_page(bio2);
bio_clear_flag(bio2, BIO_SEG_VALID);
}
goto bio_full;
@@ -4537,8 +4536,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
bio2 && bio2 != bio;
bio2 = bio2->bi_next) {
/* Remove last page from this bio */
- bio2->bi_vcnt--;
- bio2->bi_iter.bi_size -= len;
+ bio_remove_last_page(bio2);
bio_clear_flag(bio2, BIO_SEG_VALID);
}
goto bio_full;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-24 16:50 +0100 |
| Subject | [PATCH v1 01/14] block: introduce bio_segments_all() |
| Message-ID | <teqi7-2bp-53@gated-at.bofh.it> |
| In reply to | #1587737 |
So that we can replace the direct access to .bi_vcnt.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
include/linux/bio.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8e521194f6fc..3364b3ed90e7 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -293,6 +293,13 @@ static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
bv->bv_len = iter.bi_bvec_done;
}
+static inline unsigned bio_segments_all(struct bio *bio)
+{
+ WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
+
+ return bio->bi_vcnt;
+}
+
enum bip_flags {
BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */
BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2017-02-25 19:30 +0100 |
| Subject | Re: [PATCH v1 01/14] block: introduce bio_segments_all() |
| Message-ID | <tePgu-3lD-5@gated-at.bofh.it> |
| In reply to | #1587746 |
> +static inline unsigned bio_segments_all(struct bio *bio)
> +{
> + WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
> +
> + return bio->bi_vcnt;
> +}
I don't think this helpers really adds any benefit.
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-28 13:30 +0100 |
| Subject | Re: [PATCH v1 01/14] block: introduce bio_segments_all() |
| Message-ID | <tfP4J-4lm-9@gated-at.bofh.it> |
| In reply to | #1588189 |
On Sun, Feb 26, 2017 at 2:22 AM, Christoph Hellwig <hch@infradead.org> wrote:
>> +static inline unsigned bio_segments_all(struct bio *bio)
>> +{
>> + WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
>> +
>> + return bio->bi_vcnt;
>> +}
>
> I don't think this helpers really adds any benefit.
IMO the first benefit is that misusing of .bi_vcnt can be warned, and
another one is that we have to introduce this helper if multipage bvec
is supported.
Thanks,
Ming Lei
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web