dm cache: make the 'mq' policy an alias for 'smq'

smq seems to be performing better than the old mq policy in all
situations, as well as using a quarter of the memory.

Make 'mq' an alias for 'smq' when choosing a cache policy.  The tunables
that were present for the old mq are faked, and have no effect.  mq
should be considered deprecated now.

Signed-off-by: Joe Thornber <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
This commit is contained in:
Joe Thornber 2016-02-10 10:18:10 +00:00 • committed by Mike Snitzer
commit 9ed84698fd
5 changed files with 87 additions and 1529 deletions

View file

@ -304,16 +304,6 @@ config DM_CACHE
algorithms used to select which blocks are promoted, demoted,
cleaned etc. It supports writeback and writethrough modes.
config DM_CACHE_MQ
tristate "MQ Cache Policy (EXPERIMENTAL)"
depends on DM_CACHE
default y
---help---
A cache policy that uses a multiqueue ordered by recent hit
count to select which blocks should be promoted and demoted.
This is meant to be a general purpose policy. It prioritises
reads over writes.
config DM_CACHE_SMQ
tristate "Stochastic MQ Cache Policy (EXPERIMENTAL)"
depends on DM_CACHE

View file

@ -12,7 +12,6 @@ dm-log-userspace-y \
+= dm-log-userspace-base.o dm-log-userspace-transfer.o
dm-thin-pool-y += dm-thin.o dm-thin-metadata.o
dm-cache-y += dm-cache-target.o dm-cache-metadata.o dm-cache-policy.o
dm-cache-mq-y += dm-cache-policy-mq.o
dm-cache-smq-y += dm-cache-policy-smq.o
dm-cache-cleaner-y += dm-cache-policy-cleaner.o
dm-era-y += dm-era-target.o
@ -55,7 +54,6 @@ obj-$(CONFIG_DM_RAID) += dm-raid.o
obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o
obj-$(CONFIG_DM_VERITY) += dm-verity.o
obj-$(CONFIG_DM_CACHE) += dm-cache.o
obj-$(CONFIG_DM_CACHE_MQ) += dm-cache-mq.o
obj-$(CONFIG_DM_CACHE_SMQ) += dm-cache-smq.o
obj-$(CONFIG_DM_CACHE_CLEANER) += dm-cache-cleaner.o
obj-$(CONFIG_DM_ERA) += dm-era.o

File diff suppressed because it is too large Load diff

View file

@ -1567,8 +1567,48 @@ static void smq_tick(struct dm_cache_policy *p, bool can_block)
spin_unlock_irqrestore(&mq->lock, flags);
}
/*
* smq has no config values, but the old mq policy did. To avoid breaking
* software we continue to accept these configurables for the mq policy,
* but they have no effect.
*/
static int mq_set_config_value(struct dm_cache_policy *p,
const char *key, const char *value)
{
unsigned long tmp;
if (kstrtoul(value, 10, &tmp))
return -EINVAL;
if (!strcasecmp(key, "random_threshold") ||
!strcasecmp(key, "sequential_threshold") ||
!strcasecmp(key, "discard_promote_adjustment") ||
!strcasecmp(key, "read_promote_adjustment") ||
!strcasecmp(key, "write_promote_adjustment")) {
DMWARN("tunable '%s' no longer has any effect, mq policy is now an alias for smq", key);
return 0;
}
return -EINVAL;
}
static int mq_emit_config_values(struct dm_cache_policy *p, char *result,
unsigned maxlen, ssize_t *sz_ptr)
{
ssize_t sz = *sz_ptr;
DMEMIT("10 random_threshold 0 "
"sequential_threshold 0 "
"discard_promote_adjustment 0 "
"read_promote_adjustment 0 "
"write_promote_adjustment 0 ");
*sz_ptr = sz;
return 0;
}
/* Init the policy plugin interface function pointers. */
static void init_policy_functions(struct smq_policy *mq)
static void init_policy_functions(struct smq_policy *mq, bool mimic_mq)
{
mq->policy.destroy = smq_destroy;
mq->policy.map = smq_map;
@ -1583,6 +1623,11 @@ static void init_policy_functions(struct smq_policy *mq)
mq->policy.force_mapping = smq_force_mapping;
mq->policy.residency = smq_residency;
mq->policy.tick = smq_tick;
if (mimic_mq) {
mq->policy.set_config_value = mq_set_config_value;
mq->policy.emit_config_values = mq_emit_config_values;
}
}
static bool too_many_hotspot_blocks(sector_t origin_size,
@ -1606,9 +1651,10 @@ static void calc_hotspot_params(sector_t origin_size,
*hotspot_block_size /= 2u;
}
static struct dm_cache_policy *smq_create(dm_cblock_t cache_size,
sector_t origin_size,
sector_t cache_block_size)
static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size,
sector_t origin_size,
sector_t cache_block_size,
bool mimic_mq)
{
unsigned i;
unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS;
@ -1618,7 +1664,7 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size,
if (!mq)
return NULL;
init_policy_functions(mq);
init_policy_functions(mq, mimic_mq);
mq->cache_size = cache_size;
mq->cache_block_size = cache_block_size;
@ -1706,19 +1752,41 @@ bad_pool_init:
return NULL;
}
static struct dm_cache_policy *smq_create(dm_cblock_t cache_size,
sector_t origin_size,
sector_t cache_block_size)
{
return __smq_create(cache_size, origin_size, cache_block_size, false);
}
static struct dm_cache_policy *mq_create(dm_cblock_t cache_size,
sector_t origin_size,
sector_t cache_block_size)
{
return __smq_create(cache_size, origin_size, cache_block_size, true);
}
/*----------------------------------------------------------------*/
static struct dm_cache_policy_type smq_policy_type = {
.name = "smq",
.version = {1, 0, 0},
.version = {1, 5, 0},
.hint_size = 4,
.owner = THIS_MODULE,
.create = smq_create
};
static struct dm_cache_policy_type mq_policy_type = {
.name = "mq",
.version = {1, 5, 0},
.hint_size = 4,
.owner = THIS_MODULE,
.create = mq_create,
};
static struct dm_cache_policy_type default_policy_type = {
.name = "default",
.version = {1, 4, 0},
.version = {1, 5, 0},
.hint_size = 4,
.owner = THIS_MODULE,
.create = smq_create,
@ -1735,9 +1803,17 @@ static int __init smq_init(void)
return -ENOMEM;
}
r = dm_cache_policy_register(&mq_policy_type);
if (r) {
DMERR("register failed %d", r);
dm_cache_policy_unregister(&smq_policy_type);
return -ENOMEM;
}
r = dm_cache_policy_register(&default_policy_type);
if (r) {
DMERR("register failed (as default) %d", r);
dm_cache_policy_unregister(&mq_policy_type);
dm_cache_policy_unregister(&smq_policy_type);
return -ENOMEM;
}
@ -1748,6 +1824,7 @@ static int __init smq_init(void)
static void __exit smq_exit(void)
{
dm_cache_policy_unregister(&smq_policy_type);
dm_cache_policy_unregister(&mq_policy_type);
dm_cache_policy_unregister(&default_policy_type);
}
@ -1759,3 +1836,4 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("smq cache policy");
MODULE_ALIAS("dm-cache-default");
MODULE_ALIAS("dm-cache-mq");