Commit f9a8e0cd261fc05820539b0ea613686a32795406

Authored by Mikulas Patocka
Committed by Alasdair G Kergon
1 parent 4929630901

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>

Showing 1 changed file with 16 additions and 7 deletions Side-by-side Diff

drivers/md/dm-thin.c
... ... @@ -512,6 +512,7 @@
512 512  
513 513 dm_block_t low_water_blocks;
514 514 uint32_t sectors_per_block;
  515 + int sectors_per_block_shift;
515 516  
516 517 struct pool_features pf;
517 518 unsigned low_water_triggered:1; /* A dm event has been sent */
... ... @@ -679,7 +680,10 @@
679 680 {
680 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 688 return block_nr;
685 689 }
... ... @@ -690,8 +694,12 @@
690 694 sector_t bi_sector = bio->bi_sector;
691 695  
692 696 bio->bi_bdev = tc->pool_dev->bdev;
693   - bio->bi_sector = (block * pool->sectors_per_block) +
694   - sector_div(bi_sector, pool->sectors_per_block);
  697 + if (tc->pool->sectors_per_block_shift < 0)
  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 705 static void remap_to_origin(struct thin_c *tc, struct bio *bio)
... ... @@ -936,10 +944,7 @@
936 944 */
937 945 static int io_overlaps_block(struct pool *pool, struct bio *bio)
938 946 {
939   - sector_t bi_sector = bio->bi_sector;
940   -
941   - return !sector_div(bi_sector, pool->sectors_per_block) &&
942   - (bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT));
  947 + return bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT);
943 948 }
944 949  
945 950 static int io_overwrites_block(struct pool *pool, struct bio *bio)
... ... @@ -1721,6 +1726,10 @@
1721 1726  
1722 1727 pool->pmd = pmd;
1723 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 1733 pool->low_water_blocks = 0;
1725 1734 pool_features_init(&pool->pf);
1726 1735 pool->prison = prison_create(PRISON_CELLS);