Commit 89654f5b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] md: Avoid unnecessary bio allocation during raid1 resync

From: NeilBrown <neilb@cse.unsw.edu.au>

For each resync request, we allocate a "r1_bio" which has a bio "master_bio"
attached that goes largely unused.  We also allocate a read_bio which is
used.  This patch removes the read_bio and just uses the master_bio instead.

This fixes a bug wherein bi_bdev of the master_bio wasn't being set, but was
being used.

We also introduce a new "sectors" field into the r1_bio as we can no-longer
rely in master_bio->bi_sectors.
parent d0d464b1
...@@ -77,6 +77,9 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data) ...@@ -77,6 +77,9 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data)
if (!bio) if (!bio)
goto out_free_r1_bio; goto out_free_r1_bio;
/*
* Allocate RESYNC_PAGES data pages for this iovec.
*/
for (i = 0; i < RESYNC_PAGES; i++) { for (i = 0; i < RESYNC_PAGES; i++) {
page = alloc_page(gfp_flags); page = alloc_page(gfp_flags);
if (unlikely(!page)) if (unlikely(!page))
...@@ -87,9 +90,6 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data) ...@@ -87,9 +90,6 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data)
bio->bi_io_vec[i].bv_offset = 0; bio->bi_io_vec[i].bv_offset = 0;
} }
/*
* Allocate a single data page for this iovec.
*/
bio->bi_vcnt = RESYNC_PAGES; bio->bi_vcnt = RESYNC_PAGES;
bio->bi_idx = 0; bio->bi_idx = 0;
bio->bi_size = RESYNC_BLOCK_SIZE; bio->bi_size = RESYNC_BLOCK_SIZE;
...@@ -122,8 +122,6 @@ static void r1buf_pool_free(void *__r1_bio, void *data) ...@@ -122,8 +122,6 @@ static void r1buf_pool_free(void *__r1_bio, void *data)
__free_page(bio->bi_io_vec[i].bv_page); __free_page(bio->bi_io_vec[i].bv_page);
bio->bi_io_vec[i].bv_page = NULL; bio->bi_io_vec[i].bv_page = NULL;
} }
if (atomic_read(&bio->bi_cnt) != 1)
BUG();
bio_put(bio); bio_put(bio);
r1bio_pool_free(r1bio, conf->mddev); r1bio_pool_free(r1bio, conf->mddev);
} }
...@@ -249,7 +247,7 @@ static inline void update_head_pos(int disk, r1bio_t *r1_bio) ...@@ -249,7 +247,7 @@ static inline void update_head_pos(int disk, r1bio_t *r1_bio)
conf_t *conf = mddev_to_conf(r1_bio->mddev); conf_t *conf = mddev_to_conf(r1_bio->mddev);
conf->mirrors[disk].head_position = conf->mirrors[disk].head_position =
r1_bio->sector + (r1_bio->master_bio->bi_size >> 9); r1_bio->sector + (r1_bio->sectors);
} }
static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int error) static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int error)
...@@ -507,6 +505,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -507,6 +505,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO); r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO);
r1_bio->master_bio = bio; r1_bio->master_bio = bio;
r1_bio->sectors = bio->bi_size >> 9;
r1_bio->mddev = mddev; r1_bio->mddev = mddev;
r1_bio->sector = bio->bi_sector; r1_bio->sector = bio->bi_sector;
...@@ -799,7 +798,7 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) ...@@ -799,7 +798,7 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
update_head_pos(mirror, r1_bio); update_head_pos(mirror, r1_bio);
if (atomic_dec_and_test(&r1_bio->remaining)) { if (atomic_dec_and_test(&r1_bio->remaining)) {
md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, uptodate); md_done_sync(mddev, r1_bio->sectors, uptodate);
put_buf(r1_bio); put_buf(r1_bio);
} }
atomic_dec(&conf->mirrors[mirror].rdev->nr_pending); atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
...@@ -829,7 +828,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) ...@@ -829,7 +828,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
" for block %llu\n", " for block %llu\n",
bdevname(bio->bi_bdev,b), bdevname(bio->bi_bdev,b),
(unsigned long long)r1_bio->sector); (unsigned long long)r1_bio->sector);
md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0); md_done_sync(mddev, r1_bio->sectors, 0);
put_buf(r1_bio); put_buf(r1_bio);
return; return;
} }
...@@ -874,7 +873,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) ...@@ -874,7 +873,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
} }
if (atomic_dec_and_test(&r1_bio->remaining)) { if (atomic_dec_and_test(&r1_bio->remaining)) {
md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 1); md_done_sync(mddev, r1_bio->sectors, 1);
put_buf(r1_bio); put_buf(r1_bio);
} }
} }
...@@ -966,7 +965,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -966,7 +965,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
conf_t *conf = mddev_to_conf(mddev); conf_t *conf = mddev_to_conf(mddev);
mirror_info_t *mirror; mirror_info_t *mirror;
r1bio_t *r1_bio; r1bio_t *r1_bio;
struct bio *read_bio, *bio; struct bio *bio;
sector_t max_sector, nr_sectors; sector_t max_sector, nr_sectors;
int disk, partial; int disk, partial;
...@@ -1035,18 +1034,18 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1035,18 +1034,18 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
bio->bi_io_vec[bio->bi_vcnt-1].bv_len = partial; bio->bi_io_vec[bio->bi_vcnt-1].bv_len = partial;
read_bio = bio_clone(r1_bio->master_bio, GFP_NOIO); bio->bi_sector = sector_nr + mirror->rdev->data_offset;
bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_sector = sector_nr + mirror->rdev->data_offset; bio->bi_end_io = end_sync_read;
read_bio->bi_bdev = mirror->rdev->bdev; bio->bi_rw = READ;
read_bio->bi_end_io = end_sync_read; bio->bi_private = r1_bio;
read_bio->bi_rw = READ; bio_get(bio);
read_bio->bi_private = r1_bio; r1_bio->bios[r1_bio->read_disk] = bio;
r1_bio->bios[r1_bio->read_disk] = read_bio; r1_bio->sectors = nr_sectors;
md_sync_acct(mirror->rdev, nr_sectors); md_sync_acct(mirror->rdev, nr_sectors);
generic_make_request(read_bio); generic_make_request(bio);
return nr_sectors; return nr_sectors;
} }
......
...@@ -55,6 +55,7 @@ struct r1bio_s { ...@@ -55,6 +55,7 @@ struct r1bio_s {
* used from IRQ handlers * used from IRQ handlers
*/ */
sector_t sector; sector_t sector;
int sectors;
unsigned long state; unsigned long state;
mddev_t *mddev; mddev_t *mddev;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment