aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2012-07-27 10:08:03 -0400
committerAlasdair G Kergon <agk@redhat.com>2012-07-27 10:08:03 -0400
commitf9a8e0cd261fc05820539b0ea613686a32795406 (patch)
tree0edf941f787dd10dd674111cfefbde5004348ef4 /drivers/md
parent4929630901100fdbfa19186ecf5ea2706f57719b (diff)
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: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-thin.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 828649256902..93e3e542cff9 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -512,6 +512,7 @@ struct pool {
512 512
513 dm_block_t low_water_blocks; 513 dm_block_t low_water_blocks;
514 uint32_t sectors_per_block; 514 uint32_t sectors_per_block;
515 int sectors_per_block_shift;
515 516
516 struct pool_features pf; 517 struct pool_features pf;
517 unsigned low_water_triggered:1; /* A dm event has been sent */ 518 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{ 680{
680 sector_t block_nr = bio->bi_sector; 681 sector_t block_nr = bio->bi_sector;
681 682
682 (void) sector_div(block_nr, tc->pool->sectors_per_block); 683 if (tc->pool->sectors_per_block_shift < 0)
684 (void) sector_div(block_nr, tc->pool->sectors_per_block);
685 else
686 block_nr >>= tc->pool->sectors_per_block_shift;
683 687
684 return block_nr; 688 return block_nr;
685} 689}
@@ -690,8 +694,12 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
690 sector_t bi_sector = bio->bi_sector; 694 sector_t bi_sector = bio->bi_sector;
691 695
692 bio->bi_bdev = tc->pool_dev->bdev; 696 bio->bi_bdev = tc->pool_dev->bdev;
693 bio->bi_sector = (block * pool->sectors_per_block) + 697 if (tc->pool->sectors_per_block_shift < 0)
694 sector_div(bi_sector, pool->sectors_per_block); 698 bio->bi_sector = (block * pool->sectors_per_block) +
699 sector_div(bi_sector, pool->sectors_per_block);
700 else
701 bio->bi_sector = (block << pool->sectors_per_block_shift) |
702 (bi_sector & (pool->sectors_per_block - 1));
695} 703}
696 704
697static void remap_to_origin(struct thin_c *tc, struct bio *bio) 705static 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 */ 944 */
937static int io_overlaps_block(struct pool *pool, struct bio *bio) 945static int io_overlaps_block(struct pool *pool, struct bio *bio)
938{ 946{
939 sector_t bi_sector = bio->bi_sector; 947 return bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT);
940
941 return !sector_div(bi_sector, pool->sectors_per_block) &&
942 (bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT));
943} 948}
944 949
945static int io_overwrites_block(struct pool *pool, struct bio *bio) 950static 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 1726
1722 pool->pmd = pmd; 1727 pool->pmd = pmd;
1723 pool->sectors_per_block = block_size; 1728 pool->sectors_per_block = block_size;
1729 if (block_size & (block_size - 1))
1730 pool->sectors_per_block_shift = -1;
1731 else
1732 pool->sectors_per_block_shift = __ffs(block_size);
1724 pool->low_water_blocks = 0; 1733 pool->low_water_blocks = 0;
1725 pool_features_init(&pool->pf); 1734 pool_features_init(&pool->pf);
1726 pool->prison = prison_create(PRISON_CELLS); 1735 pool->prison = prison_create(PRISON_CELLS);