diff options
author | Joe Thornber <ejt@redhat.com> | 2016-09-15 09:36:24 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-09-22 11:15:03 -0400 |
commit | 9d1b404cbc3f990a4035dcf7ddd37adac2a99b3f (patch) | |
tree | e3afe884a02e400cf69d8e10f809b218d772b564 /drivers/md/dm-cache-policy-smq.c | |
parent | 4e781b498ee5008ede91362d91404a362e7a46b3 (diff) | |
download | linux-stable-9d1b404cbc3f990a4035dcf7ddd37adac2a99b3f.tar.gz linux-stable-9d1b404cbc3f990a4035dcf7ddd37adac2a99b3f.tar.bz2 linux-stable-9d1b404cbc3f990a4035dcf7ddd37adac2a99b3f.zip |
dm cache policy smq: distribute entries to random levels when switching to smq
For smq the 32 bit 'hint' stores the multiqueue level that the entry
should be stored in. If a different policy has been used previously,
and then switched to smq, the hints will be invalid. In which case we
used to put all entries in the bottom level of the multiqueue, and then
redistribute. Redistribution is faster if we put entries with invalid
hints in random levels initially.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-cache-policy-smq.c')
-rw-r--r-- | drivers/md/dm-cache-policy-smq.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c index f3cec4e6333c..c33f4a6e1d7d 100644 --- a/drivers/md/dm-cache-policy-smq.c +++ b/drivers/md/dm-cache-policy-smq.c @@ -1359,6 +1359,11 @@ static void smq_clear_dirty(struct dm_cache_policy *p, dm_oblock_t oblock) spin_unlock_irqrestore(&mq->lock, flags); } +static unsigned random_level(dm_cblock_t cblock) +{ + return hash_32_generic(from_cblock(cblock), 9) & (NR_CACHE_LEVELS - 1); +} + static int smq_load_mapping(struct dm_cache_policy *p, dm_oblock_t oblock, dm_cblock_t cblock, uint32_t hint, bool hint_valid) @@ -1369,7 +1374,7 @@ static int smq_load_mapping(struct dm_cache_policy *p, e = alloc_particular_entry(&mq->cache_alloc, from_cblock(cblock)); e->oblock = oblock; e->dirty = false; /* this gets corrected in a minute */ - e->level = hint_valid ? min(hint, NR_CACHE_LEVELS - 1) : 1; + e->level = hint_valid ? min(hint, NR_CACHE_LEVELS - 1) : random_level(cblock); push(mq, e); return 0; |