[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH] dm-stripe: Optimize chunk_size divisions and modulos



Hi

This patch optimizes dm-stripe if chunk_size is a power of two. It should 
be applied after "dm-stripe-support-for-non-power-of-2-chunksize.patch".

Mikulas

---

dm-stripe: Optimize chunk_size divisions and modulos

dm-stripe is usually used with a chunk size that is a power of two.
Previous code used slow divide and modulo operations with a power-of-two
chunk size. This patch changes it to use faster shifts and bit masks.

stripe_width is already optimized in a similar way.

Signed-off-by: Mikulas Patocka <mpatocka redhat com>

---
 drivers/md/dm-stripe.c |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

Index: linux-3.4.2-fast/drivers/md/dm-stripe.c
===================================================================
--- linux-3.4.2-fast.orig/drivers/md/dm-stripe.c	2012-06-18 11:39:36.000000000 +0200
+++ linux-3.4.2-fast/drivers/md/dm-stripe.c	2012-06-18 12:52:40.000000000 +0200
@@ -32,6 +32,7 @@ struct stripe_c {
 	sector_t stripe_width;
 
 	uint32_t chunk_size;
+	int chunk_size_shift;
 
 	/* Needed for handling events */
 	struct dm_target *ti;
@@ -170,6 +171,10 @@ static int stripe_ctr(struct dm_target *
 	ti->num_discard_requests = stripes;
 
 	sc->chunk_size = chunk_size;
+	if (chunk_size & (chunk_size - 1))
+		sc->chunk_size_shift = -1;
+	else
+		sc->chunk_size_shift = __ffs(chunk_size);
 
 	/*
 	 * Get the stripe destinations.
@@ -209,7 +214,14 @@ static void stripe_map_sector(struct str
 			      uint32_t *stripe, sector_t *result)
 {
 	sector_t chunk = dm_target_offset(sc->ti, sector);
-	sector_t chunk_offset = sector_div(chunk, sc->chunk_size);
+	sector_t chunk_offset;
+
+	if (sc->chunk_size_shift < 0)
+		chunk_offset = sector_div(chunk, sc->chunk_size);
+	else {
+		chunk_offset = chunk & (sc->chunk_size - 1);
+		chunk >>= sc->chunk_size_shift;
+	}
 
 	if (sc->stripes_shift < 0)
 		*stripe = sector_div(chunk, sc->stripes);
@@ -218,7 +230,12 @@ static void stripe_map_sector(struct str
 		chunk >>= sc->stripes_shift;
 	}
 
-	*result = (chunk * sc->chunk_size) + chunk_offset;
+	if (sc->chunk_size_shift < 0)
+		chunk *= sc->chunk_size;
+	else
+		chunk <<= sc->chunk_size_shift;
+
+	*result = chunk + chunk_offset;
 }
 
 static void stripe_map_range_sector(struct stripe_c *sc, sector_t sector,
@@ -232,7 +249,10 @@ static void stripe_map_range_sector(stru
 
 	/* round down */
 	sector = *result;
-	*result -= sector_div(sector, sc->chunk_size);
+	if (sc->chunk_size_shift < 0)
+		*result -= sector_div(sector, sc->chunk_size);
+	else
+		*result = sector & ~(sector_t)(sc->chunk_size - 1);
 
 	if (target_stripe < stripe)
 		*result += sc->chunk_size;		/* next chunk */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]