Skip to content

Commit 363b7fd

Browse files
jthornberMike Snitzer
authored andcommitted
dm: improve hash_locks sizing and hash function
Both bufio and bio-prison-v1 use the identical model for splitting their respective locks and rbtrees. Improve dm_num_hash_locks() to distribute across more rbtrees to improve overall performance -- but the maximum number of locks/rbtrees is still 64. Also factor out a common hash function named dm_hash_locks_index(), the magic numbers used were determined to be best using this program: https://gist.github.com/jthornber/e05c47daa7b500c56dc339269c5467fc Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
1 parent b6279f8 commit 363b7fd

3 files changed

Lines changed: 17 additions & 4 deletions

File tree

drivers/md/dm-bio-prison-v1.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,10 @@ static int cmp_keys(struct dm_cell_key *lhs,
117117
return 0;
118118
}
119119

120-
static unsigned lock_nr(struct dm_cell_key *key, unsigned int num_locks)
120+
static inline unsigned int lock_nr(struct dm_cell_key *key, unsigned int num_locks)
121121
{
122-
return (key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT) & (num_locks - 1);
122+
return dm_hash_locks_index((key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT),
123+
num_locks);
123124
}
124125

125126
bool dm_cell_key_has_valid_range(struct dm_cell_key *key)

drivers/md/dm-bufio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ struct dm_buffer_cache {
398398

399399
static inline unsigned int cache_index(sector_t block, unsigned int num_locks)
400400
{
401-
return block & (num_locks - 1);
401+
return dm_hash_locks_index(block, num_locks);
402402
}
403403

404404
static inline void cache_read_lock(struct dm_buffer_cache *bc, sector_t block)

drivers/md/dm.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,21 @@ unsigned int dm_get_reserved_bio_based_ios(void);
233233

234234
static inline unsigned int dm_num_hash_locks(void)
235235
{
236-
unsigned int num_locks = roundup_pow_of_two(num_online_cpus());
236+
unsigned int num_locks = roundup_pow_of_two(num_online_cpus()) << 1;
237237

238238
return min_t(unsigned int, num_locks, DM_HASH_LOCKS_MAX);
239239
}
240240

241+
#define DM_HASH_LOCKS_MULT 4294967291ULL
242+
#define DM_HASH_LOCKS_SHIFT 6
243+
244+
static inline unsigned int dm_hash_locks_index(sector_t block,
245+
unsigned int num_locks)
246+
{
247+
sector_t h1 = (block * DM_HASH_LOCKS_MULT) >> DM_HASH_LOCKS_SHIFT;
248+
sector_t h2 = h1 >> DM_HASH_LOCKS_SHIFT;
249+
250+
return (h1 ^ h2) & (num_locks - 1);
251+
}
252+
241253
#endif

0 commit comments

Comments
 (0)