dm writecache: add optional "metadata_only" parameter
authorMikulas Patocka <mpatocka@redhat.com>
Mon, 21 Jun 2021 09:22:21 +0000 (05:22 -0400)
committerMike Snitzer <snitzer@redhat.com>
Fri, 25 Jun 2021 19:25:21 +0000 (15:25 -0400)
Add a "metadata_only" parameter that when present: only metadata is
promoted to the cache. This option improves performance for heavier
REQ_META workloads (e.g. device-mapper-test-suite's "git clone and
checkout" benchmark improves from 341s to 312s).

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Documentation/admin-guide/device-mapper/writecache.rst
drivers/md/dm-writecache.c

index c181f26af7693a5d8205c4769fd86b25f3b618eb..977f82b5a811834d434a830ec1bf6f06593d86e1 100644 (file)
@@ -68,6 +68,9 @@ Constructor parameters:
                specifies the maximum age of a block in milliseconds. If
                a block is stored in the cache for too long, it will be
                written to the underlying device and cleaned up.
+       metadata_only
+               only metadata is promoted to the cache. This option
+               improves performance for heavier REQ_META workloads.
 
 Status:
 1. error indicator - 0 if there was no error, otherwise error number
index 558d39764e6dac3df5e6fd731fad8ff3f84adf10..2eb7d7bcdfb1814ac7ba66fb00795fb3934f90a4 100644 (file)
@@ -171,6 +171,7 @@ struct dm_writecache {
        bool flush_on_suspend:1;
        bool cleaner:1;
        bool cleaner_set:1;
+       bool metadata_only:1;
 
        unsigned high_wm_percent_value;
        unsigned low_wm_percent_value;
@@ -1301,7 +1302,7 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
                        writecache_flush(wc);
                        if (writecache_has_error(wc))
                                goto unlock_error;
-                       if (unlikely(wc->cleaner))
+                       if (unlikely(wc->cleaner) || unlikely(wc->metadata_only))
                                goto unlock_remap_origin;
                        goto unlock_submit;
                } else {
@@ -1380,7 +1381,8 @@ read_next_block:
                                }
                                found_entry = true;
                        } else {
-                               if (unlikely(wc->cleaner))
+                               if (unlikely(wc->cleaner) ||
+                                   (wc->metadata_only && !(bio->bi_opf & REQ_META)))
                                        goto direct_write;
                        }
                        e = writecache_pop_from_freelist(wc, (sector_t)-1);
@@ -2094,7 +2096,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
        struct wc_memory_superblock s;
 
        static struct dm_arg _args[] = {
-               {0, 16, "Invalid number of feature args"},
+               {0, 17, "Invalid number of feature args"},
        };
 
        as.argc = argc;
@@ -2321,6 +2323,8 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
                                wc->writeback_fua = false;
                                wc->writeback_fua_set = true;
                        } else goto invalid_optional;
+               } else if (!strcasecmp(string, "metadata_only")) {
+                       wc->metadata_only = true;
                } else {
 invalid_optional:
                        r = -EINVAL;
@@ -2544,6 +2548,8 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
                        extra_args++;
                if (wc->writeback_fua_set)
                        extra_args++;
+               if (wc->metadata_only)
+                       extra_args++;
 
                DMEMIT("%u", extra_args);
                if (wc->start_sector_set)
@@ -2564,13 +2570,15 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
                        DMEMIT(" cleaner");
                if (wc->writeback_fua_set)
                        DMEMIT(" %sfua", wc->writeback_fua ? "" : "no");
+               if (wc->metadata_only)
+                       DMEMIT(" metadata_only");
                break;
        }
 }
 
 static struct target_type writecache_target = {
        .name                   = "writecache",
-       .version                = {1, 4, 0},
+       .version                = {1, 5, 0},
        .module                 = THIS_MODULE,
        .ctr                    = writecache_ctr,
        .dtr                    = writecache_dtr,