When allocating resync pages,judge the queue limit of mddev.
From d5c0ad3ac03c805747f71338d30282f9f8d8d953 Mon Sep 17 00:00:00 2001
From: majianpeng <[email protected]>
Date: Fri, 30 Mar 2012 13:37:42 +0800
Subject: [PATCH] md/raid1:When allocating resync pages,judge the queue limit of mddev.
When max_sectors of mddev is smaller than
RESYNC_PAGES(at present 64k),then: 1:alloc enough resync
pags. 2:when do bio_add_page can goto bio_fill.
--- drivers/md/raid1.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-)
drivers/md/raid1.c +11 -7
@@ -82,16 +82,19 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)struct r1bio *r1_bio;struct bio *bio;int i, j; +int sync_pages; r1_bio =r1bio_pool_alloc (gfp_flags, pi);if (!r1_bio)return NULL ; + sync_pages =queue_max_sectors (pi->mddev->gendisk->queue) <<9 ; + sync_pages =min (RESYNC_PAGES , (sync_pages +PAGE_SIZE -1 ) /PAGE_SIZE );/* * Allocate bios : 1 for reading, n-1 for writing */ for (j = pi->raid_disks ; j-- ; ) { - bio =bio_kmalloc (gfp_flags,RESYNC_PAGES ); + bio =bio_kmalloc (gfp_flags, sync_pages);if (!bio) goto out_free_bio; r1_bio->bios[j] = bio;
@@ -108,7 +111,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) j =1 ;while (j--) { bio = r1_bio->bios[j]; -for (i =0 ; i <RESYNC_PAGES ; i++) { +for (i =0 ; i < sync_pages; i++) { page =alloc_page (gfp_flags);if (unlikely (!page)) goto out_free_pages;
@@ -119,8 +122,8 @@ 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++) +for (i =0 ; i < sync_pages ; i++) +for (j =1 ; j < pi->raid_disks; j++) r1_bio->bios[j]->bi_io_vec[i].bv_page = r1_bio->bios[0 ]->bi_io_vec[i].bv_page; }
@@ -147,7 +150,7 @@ static void r1buf_pool_free(void *__r1_bio, void *data)int i,j;struct r1bio *r1bio = __r1_bio; - for (i = 0; i < RESYNC_PAGES; i++) + for (i = 0; i < r1bio->bios[0]->bi_max_vecs; i++) for (j = pi->raid_disks; j-- ;) { if (j == 0 || r1bio->bios[j]->bi_io_vec[i].bv_page !=
@@ -2243,7 +2246,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skippint write_targets =0 , read_targets =0 ;sector_t sync_blocks;int still_degraded =0 ; -int good_sectors =RESYNC_SECTORS ; +int good_sectors;int min_bad =0 ;/* number of sectors that are bad in all devices */ if (!conf->r1buf_pool)
@@ -2296,6 +2299,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp r1_bio =mempool_alloc (conf->r1buf_pool,GFP_NOIO );raise_barrier (conf); + good_sectors = r1_bio->bios[0 ]->bi_max_vecs <<9 ; conf->next_resync = sector_nr;rcu_read_lock ();
@@ -2477,7 +2481,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp nr_sectors += len>>9 ; sector_nr += len>>9 ; sync_blocks -= (len>>9 ); - }while (r1_bio->bios[disk]->bi_vcnt <RESYNC_PAGES ); + }while (r1_bio->bios[disk]->bi_vcnt < r1_bio->bios[0 ]->bi_max_vecs); bio_full: r1_bio->sectors = nr_sectors;
Signature · 6 lines
1.7.5.4 -------------- majianpeng 2012-03-30
Quoted 19 lines · On Fri, 30 Mar 2012 13:53:05 +0800 "majianpeng" <[email protected]> wrote:
Quoted 1 line
From
d5c0ad3ac03c805747f71338d30282f9f8d8d953Mon Sep 17 00:00:00 2001From: majianpeng <[email protected]>
Date: Fri, 30 Mar 2012 13:37:42 +0800
Subject: [PATCH] md/raid1:When allocating resync pages,judge the queue limit of mddev.
Whenmax_sectorsof mddev is smaller than
RESYNC_PAGES(at present 64k),then: 1:alloc enough resync
pags. 2:when dobio_add_pagecan gotobio_fill.Signed-off-by majianpeng <[email protected]>--- drivers/md/raid1.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-)drivers/md/raid1.c +0
-0
drivers/md/raid1.c static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) · line 91
Quoted 10 lines
drivers/md/raid1.c +2
-0@@ -82,16 +82,19 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)struct r1bio *r1_bio;struct bio *bio;int i, j; +int sync_pages; r1_bio =r1bio_pool_alloc (gfp_flags, pi);if (!r1_bio)return NULL ; + sync_pages =queue_max_sectors (pi->mddev->gendisk->queue) <<9 ;
I don't thing '<< 9' is correct. Maybe '<< (PAGE_SHIFT - 9)'.
drivers/md/raid1.c static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) · line 92
Quoted 1 line
drivers/md/raid1.c +1
-0+ sync_pages =min (RESYNC_PAGES , (sync_pages +PAGE_SIZE -1 ) /PAGE_SIZE );
And this is definitely wrong. you don't want to round up the number of page to be a multiple of the number of bytes in a page....
What is the value of this patch? It allocates a few fewer pages for the rare case where the device cannot accept 64K IO requests?
I don't think it is really worth it, and given the obvious bugs, I won't apply it.
Thanks,
NeilBrown
Quoted 64 lines
drivers/md/raid1.c +8
-7/* * Allocate bios : 1 for reading, n-1 for writing */ for (j = pi->raid_disks ; j-- ; ) { - bio =bio_kmalloc (gfp_flags,RESYNC_PAGES ); + bio =bio_kmalloc (gfp_flags, sync_pages);if (!bio) goto out_free_bio; r1_bio->bios[j] = bio;@@ -108,7 +111,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) j =1 ;while (j--) { bio = r1_bio->bios[j]; -for (i =0 ; i <RESYNC_PAGES ; i++) { +for (i =0 ; i < sync_pages; i++) { page =alloc_page (gfp_flags);if (unlikely (!page)) goto out_free_pages;@@ -119,8 +122,8 @@ 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++) +for (i =0 ; i < sync_pages ; i++) +for (j =1 ; j < pi->raid_disks; j++) r1_bio->bios[j]->bi_io_vec[i].bv_page = r1_bio->bios[0 ]->bi_io_vec[i].bv_page; }@@ -147,7 +150,7 @@ static void r1buf_pool_free(void *__r1_bio, void *data)int i,j;struct r1bio *r1bio = __r1_bio; - for (i = 0; i < RESYNC_PAGES; i++) + for (i = 0; i < r1bio->bios[0]->bi_max_vecs; i++) for (j = pi->raid_disks; j-- ;) { if (j == 0 || r1bio->bios[j]->bi_io_vec[i].bv_page !=@@ -2243,7 +2246,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skippint write_targets =0 , read_targets =0 ;sector_t sync_blocks;int still_degraded =0 ; -int good_sectors =RESYNC_SECTORS ; +int good_sectors;int min_bad =0 ;/* number of sectors that are bad in all devices */ if (!conf->r1buf_pool)@@ -2296,6 +2299,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp r1_bio =mempool_alloc (conf->r1buf_pool,GFP_NOIO );raise_barrier (conf); + good_sectors = r1_bio->bios[0 ]->bi_max_vecs <<9 ; conf->next_resync = sector_nr;rcu_read_lock ();@@ -2477,7 +2481,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp nr_sectors += len>>9 ; sector_nr += len>>9 ; sync_blocks -= (len>>9 ); - }while (r1_bio->bios[disk]->bi_vcnt <RESYNC_PAGES ); + }while (r1_bio->bios[disk]->bi_vcnt < r1_bio->bios[0 ]->bi_max_vecs); bio_full: r1_bio->sectors = nr_sectors;