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>
This commit is contained in:
Joe Thornber 2014-10-06 15:28:30 +01:00 committed by Mike Snitzer
parent 4646015d7e
commit 8a01a6af75
3 changed files with 16 additions and 4 deletions

View File

@ -1809,3 +1809,8 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd)
return needs_check; return needs_check;
} }
void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd)
{
dm_tm_issue_prefetches(pmd->tm);
}

View File

@ -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); int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd);
bool dm_pool_metadata_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 #endif

View File

@ -1526,6 +1526,7 @@ static void process_thin_deferred_bios(struct thin_c *tc)
struct bio *bio; struct bio *bio;
struct bio_list bios; struct bio_list bios;
struct blk_plug plug; struct blk_plug plug;
unsigned count = 0;
if (tc->requeue_mode) { if (tc->requeue_mode) {
requeue_bio_list(tc, &tc->deferred_bio_list); 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); pool->process_discard(tc, bio);
else else
pool->process_bio(tc, bio); pool->process_bio(tc, bio);
if ((count++ & 127) == 0) {
dm_pool_issue_prefetches(pool->pmd);
}
} }
blk_finish_plug(&plug); 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); 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_mappings, &pool->process_prepared_mapping);
process_prepared(pool, &pool->prepared_discards, &pool->process_prepared_discard); process_prepared(pool, &pool->prepared_discards, &pool->process_prepared_discard);
process_deferred_bios(pool); process_deferred_bios(pool);
@ -1996,10 +2002,6 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
/* fall through */ /* fall through */
case -EWOULDBLOCK: 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); thin_defer_bio(tc, bio);
cell_defer_no_holder_no_free(tc, &cell1); cell_defer_no_holder_no_free(tc, &cell1);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;