diff options
author | Joe Thornber <ejt@redhat.com> | 2014-10-06 15:28:30 +0100 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2014-11-10 15:25:27 -0500 |
commit | 8a01a6af75f839ff8eb25dab69b49224e855bfa1 (patch) | |
tree | 6e0c31ce682332cd8af5d6f77037b56421507542 /drivers | |
parent | 4646015d7e4ca5a4dc19427fb0a0aeff15a4fd91 (diff) |
dm thin: prefetch missing metadata pages
Prefetch metadata at the start of the worker thread and then again every
128th bio processed from the deferred list.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 5 | ||||
-rw-r--r-- | drivers/md/dm-thin-metadata.h | 5 | ||||
-rw-r--r-- | drivers/md/dm-thin.c | 10 |
3 files changed, 16 insertions, 4 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index ee42d1c52387..43adbb863f5a 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -1809,3 +1809,8 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd) return needs_check; } + +void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd) +{ + dm_tm_issue_prefetches(pmd->tm); +} diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index efedd5a4cd8f..921d15ee56a0 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h @@ -213,6 +213,11 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd); bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); +/* + * Issue any prefetches that may be useful. + */ +void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd); + /*----------------------------------------------------------------*/ #endif diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index eecfe7495232..97a7eb4d0412 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -1526,6 +1526,7 @@ static void process_thin_deferred_bios(struct thin_c *tc) struct bio *bio; struct bio_list bios; struct blk_plug plug; + unsigned count = 0; if (tc->requeue_mode) { requeue_bio_list(tc, &tc->deferred_bio_list); @@ -1567,6 +1568,10 @@ static void process_thin_deferred_bios(struct thin_c *tc) pool->process_discard(tc, bio); else pool->process_bio(tc, bio); + + if ((count++ & 127) == 0) { + dm_pool_issue_prefetches(pool->pmd); + } } blk_finish_plug(&plug); } @@ -1652,6 +1657,7 @@ static void do_worker(struct work_struct *ws) { struct pool *pool = container_of(ws, struct pool, worker); + dm_pool_issue_prefetches(pool->pmd); process_prepared(pool, &pool->prepared_mappings, &pool->process_prepared_mapping); process_prepared(pool, &pool->prepared_discards, &pool->process_prepared_discard); process_deferred_bios(pool); @@ -1996,10 +2002,6 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) /* fall through */ case -EWOULDBLOCK: - /* - * In future, the failed dm_thin_find_block above could - * provide the hint to load the metadata into cache. - */ thin_defer_bio(tc, bio); cell_defer_no_holder_no_free(tc, &cell1); return DM_MAPIO_SUBMITTED; |