From 4e81d3a3f5c1c55ec6c063be1d6e778c918183a9 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 19 Apr 2012 00:26:36 -0400 Subject: [PATCH 2/3] dm thin: optimize power of 2 division to be the fast path Slower divison will only ever be used if a thin-pool with a non-power-of-2 block_size is created. FIXME: insert benchmark data that shows perf improvement Signed-off-by: Mike Snitzer --- drivers/md/dm-thin.c | 30 ++++++++++++++++++++++++------ 1 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index bdd0344..2a0958d 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -13,6 +13,7 @@ #include #include #include +#include #define DM_MSG_PREFIX "thin" @@ -673,6 +674,8 @@ static void requeue_io(struct thin_c *tc) * target. */ +static struct static_key_deferred non_pow2_division_enabled; /* defaults to false */ + /* * do_div variants for power-of-2 and non-power-of-2 pool block_size */ @@ -691,10 +694,13 @@ static inline sector_t pool_block_non_pow2_do_div(sector_t a, struct pool *pool) static inline sector_t pool_block_do_div(sector_t a, struct pool *pool) { - if (pool->block_shift) + if (static_key_false(&non_pow2_division_enabled.key)) { + if (pool->block_shift) + return pool_block_pow2_do_div(a, pool); + else + return pool_block_non_pow2_do_div(a, pool); + } else return pool_block_pow2_do_div(a, pool); - else - return pool_block_non_pow2_do_div(a, pool); } /* @@ -719,10 +725,13 @@ static inline sector_t pool_block_non_pow2_do_mod(sector_t a, struct pool *pool) static inline sector_t pool_block_do_mod(sector_t a, struct pool *pool) { - if (pool->block_shift) + if (static_key_false(&non_pow2_division_enabled.key)) { + if (pool->block_shift) + return pool_block_pow2_do_mod(a, pool); + else + return pool_block_non_pow2_do_mod(a, pool); + } else return pool_block_pow2_do_mod(a, pool); - else - return pool_block_non_pow2_do_mod(a, pool); } static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio) @@ -1717,6 +1726,10 @@ static void __pool_destroy(struct pool *pool) mempool_free(pool->next_mapping, pool->mapping_pool); mempool_destroy(pool->mapping_pool); mempool_destroy(pool->endio_hook_pool); + if (!pool->block_shift) { + /* drop reference on need for the slower path for division */ + static_key_slow_dec_deferred(&non_pow2_division_enabled); + } kfree(pool); } @@ -1811,6 +1824,11 @@ static struct pool *pool_create(struct mapped_device *pool_md, pool->md_dev = metadata_dev; __pool_table_insert(pool); + if (!pool->block_shift) { + /* enable the slower path for division */ + static_key_slow_inc(&non_pow2_division_enabled.key); + } + return pool; bad_endio_hook_pool: -- 1.7.1