aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-stripe.c
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2010-08-11 23:14:21 -0400
committerAlasdair G Kergon <agk@redhat.com>2010-08-11 23:14:21 -0400
commitc96053b767d494d7c30e2be68097ac9defa9403f (patch)
treeb66f185ffd58538f6107f3acf3af38b8aecd7f8a /drivers/md/dm-stripe.c
parent65988525abde0b0a5833c4e20f32967184a5dcf0 (diff)
dm stripe: optimize sector division
Optimize sector division: If the number of stripes is a power of two, we can do shift and mask instead of division. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-stripe.c')
-rw-r--r--drivers/md/dm-stripe.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index e2ad1ae5268d..1559fdfd2073 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -25,6 +25,8 @@ struct stripe {
25 25
26struct stripe_c { 26struct stripe_c {
27 uint32_t stripes; 27 uint32_t stripes;
28 int stripes_shift;
29 sector_t stripes_mask;
28 30
29 /* The size of this target / num. stripes */ 31 /* The size of this target / num. stripes */
30 sector_t stripe_width; 32 sector_t stripe_width;
@@ -162,16 +164,21 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
162 164
163 /* Set pointer to dm target; used in trigger_event */ 165 /* Set pointer to dm target; used in trigger_event */
164 sc->ti = ti; 166 sc->ti = ti;
165
166 sc->stripes = stripes; 167 sc->stripes = stripes;
167 sc->stripe_width = width; 168 sc->stripe_width = width;
169
170 if (stripes & (stripes - 1))
171 sc->stripes_shift = -1;
172 else {
173 sc->stripes_shift = ffs(stripes) - 1;
174 sc->stripes_mask = ((sector_t) stripes) - 1;
175 }
176
168 ti->split_io = chunk_size; 177 ti->split_io = chunk_size;
169 ti->num_flush_requests = stripes; 178 ti->num_flush_requests = stripes;
170 179
180 sc->chunk_shift = ffs(chunk_size) - 1;
171 sc->chunk_mask = ((sector_t) chunk_size) - 1; 181 sc->chunk_mask = ((sector_t) chunk_size) - 1;
172 for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++)
173 chunk_size >>= 1;
174 sc->chunk_shift--;
175 182
176 /* 183 /*
177 * Get the stripe destinations. 184 * Get the stripe destinations.
@@ -213,7 +220,13 @@ static void stripe_map_sector(struct stripe_c *sc, sector_t sector,
213 sector_t offset = dm_target_offset(sc->ti, sector); 220 sector_t offset = dm_target_offset(sc->ti, sector);
214 sector_t chunk = offset >> sc->chunk_shift; 221 sector_t chunk = offset >> sc->chunk_shift;
215 222
216 *stripe = sector_div(chunk, sc->stripes); 223 if (sc->stripes_shift < 0)
224 *stripe = sector_div(chunk, sc->stripes);
225 else {
226 *stripe = chunk & sc->stripes_mask;
227 chunk >>= sc->stripes_shift;
228 }
229
217 *result = (chunk << sc->chunk_shift) | (offset & sc->chunk_mask); 230 *result = (chunk << sc->chunk_shift) | (offset & sc->chunk_mask);
218} 231}
219 232