Commit 611c3e16 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Mike Snitzer

dm writecache: add optional "metadata_only" parameter

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