dm thin: prefetch missing metadata pages
authorJoe Thornber <ejt@redhat.com>
Mon, 6 Oct 2014 14:28:30 +0000 (15:28 +0100)
committerMike Snitzer <snitzer@redhat.com>
Mon, 10 Nov 2014 20:25:27 +0000 (15:25 -0500)
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>
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c

index ee42d1c52387577644c57021d26dbeaab87071d0..43adbb863f5a9e5426dc0641f8c12ba696b09e10 100644 (file)
@@ -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);
+}
index efedd5a4cd8f0e271ba7b92c45a1fc68c768d6ca..921d15ee56a0c687bd09e54846d90f2bbb082c86 100644 (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);
 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
index eecfe74952328965080788794650300bd609ef1c..97a7eb4d041249365ffccbf454cc10d40cad9ebd 100644 (file)
@@ -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;