Commit f9a8e0cd authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Alasdair G Kergon

dm thin: optimize power of two block size

dm-thin will be most likely used with a block size that is a power of
two. So it should be optimized for this case.

This patch changes division and modulo operations to shifts and bit
masks if block size is a power of two.

A test that bi_sector is divisible by a block size is removed from
io_overlaps_block. Device mapper never sends bios that span a block
boundary. Consequently, if we tested that bi_size is equivalent to block
size, bi_sector must already be on a block boundary.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 49296309
...@@ -512,6 +512,7 @@ struct pool { ...@@ -512,6 +512,7 @@ struct pool {
dm_block_t low_water_blocks; dm_block_t low_water_blocks;
uint32_t sectors_per_block; uint32_t sectors_per_block;
int sectors_per_block_shift;
struct pool_features pf; struct pool_features pf;
unsigned low_water_triggered:1; /* A dm event has been sent */ unsigned low_water_triggered:1; /* A dm event has been sent */
...@@ -679,7 +680,10 @@ static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio) ...@@ -679,7 +680,10 @@ static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio)
{ {
sector_t block_nr = bio->bi_sector; sector_t block_nr = bio->bi_sector;
(void) sector_div(block_nr, tc->pool->sectors_per_block); if (tc->pool->sectors_per_block_shift < 0)
(void) sector_div(block_nr, tc->pool->sectors_per_block);
else
block_nr >>= tc->pool->sectors_per_block_shift;
return block_nr; return block_nr;
} }
...@@ -690,8 +694,12 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block) ...@@ -690,8 +694,12 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
sector_t bi_sector = bio->bi_sector; sector_t bi_sector = bio->bi_sector;
bio->bi_bdev = tc->pool_dev->bdev; bio->bi_bdev = tc->pool_dev->bdev;
bio->bi_sector = (block * pool->sectors_per_block) + if (tc->pool->sectors_per_block_shift < 0)
sector_div(bi_sector, pool->sectors_per_block); bio->bi_sector = (block * pool->sectors_per_block) +
sector_div(bi_sector, pool->sectors_per_block);
else
bio->bi_sector = (block << pool->sectors_per_block_shift) |
(bi_sector & (pool->sectors_per_block - 1));
} }
static void remap_to_origin(struct thin_c *tc, struct bio *bio) static void remap_to_origin(struct thin_c *tc, struct bio *bio)
...@@ -936,10 +944,7 @@ static void process_prepared(struct pool *pool, struct list_head *head, ...@@ -936,10 +944,7 @@ static void process_prepared(struct pool *pool, struct list_head *head,
*/ */
static int io_overlaps_block(struct pool *pool, struct bio *bio) static int io_overlaps_block(struct pool *pool, struct bio *bio)
{ {
sector_t bi_sector = bio->bi_sector; return bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT);
return !sector_div(bi_sector, pool->sectors_per_block) &&
(bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT));
} }
static int io_overwrites_block(struct pool *pool, struct bio *bio) static int io_overwrites_block(struct pool *pool, struct bio *bio)
...@@ -1721,6 +1726,10 @@ static struct pool *pool_create(struct mapped_device *pool_md, ...@@ -1721,6 +1726,10 @@ static struct pool *pool_create(struct mapped_device *pool_md,
pool->pmd = pmd; pool->pmd = pmd;
pool->sectors_per_block = block_size; pool->sectors_per_block = block_size;
if (block_size & (block_size - 1))
pool->sectors_per_block_shift = -1;
else
pool->sectors_per_block_shift = __ffs(block_size);
pool->low_water_blocks = 0; pool->low_water_blocks = 0;
pool_features_init(&pool->pf); pool_features_init(&pool->pf);
pool->prison = prison_create(PRISON_CELLS); pool->prison = prison_create(PRISON_CELLS);
......
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