diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2012-07-27 10:08:03 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 10:08:03 -0400 |
commit | f9a8e0cd261fc05820539b0ea613686a32795406 (patch) | |
tree | 0edf941f787dd10dd674111cfefbde5004348ef4 /drivers/md | |
parent | 4929630901100fdbfa19186ecf5ea2706f57719b (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.c | 23 |
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 | ||
697 | static void remap_to_origin(struct thin_c *tc, struct bio *bio) | 705 | 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 | */ | 944 | */ |
937 | static int io_overlaps_block(struct pool *pool, struct bio *bio) | 945 | static 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 | ||
945 | static int io_overwrites_block(struct pool *pool, struct bio *bio) | 950 | 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 | 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); |