1717/*----------------------------------------------------------------*/
1818
1919#define NR_LOCKS 64
20- #define LOCK_MASK (NR_LOCKS - 1)
2120#define MIN_CELLS 1024
2221
2322struct prison_region {
@@ -26,8 +25,9 @@ struct prison_region {
2625} ____cacheline_aligned_in_smp ;
2726
2827struct dm_bio_prison {
29- struct prison_region regions [NR_LOCKS ];
3028 mempool_t cell_pool ;
29+ unsigned int num_locks ;
30+ struct prison_region regions [NR_LOCKS ];
3131};
3232
3333static struct kmem_cache * _cell_cache ;
@@ -46,8 +46,9 @@ struct dm_bio_prison *dm_bio_prison_create(void)
4646
4747 if (!prison )
4848 return NULL ;
49+ prison -> num_locks = NR_LOCKS ;
4950
50- for (i = 0 ; i < NR_LOCKS ; i ++ ) {
51+ for (i = 0 ; i < prison -> num_locks ; i ++ ) {
5152 spin_lock_init (& prison -> regions [i ].lock );
5253 prison -> regions [i ].cell = RB_ROOT ;
5354 }
@@ -115,9 +116,9 @@ static int cmp_keys(struct dm_cell_key *lhs,
115116 return 0 ;
116117}
117118
118- static unsigned lock_nr (struct dm_cell_key * key )
119+ static unsigned lock_nr (struct dm_cell_key * key , unsigned int num_locks )
119120{
120- return (key -> block_begin >> BIO_PRISON_MAX_RANGE_SHIFT ) & LOCK_MASK ;
121+ return (key -> block_begin >> BIO_PRISON_MAX_RANGE_SHIFT ) & ( num_locks - 1 ) ;
121122}
122123
123124bool dm_cell_key_has_valid_range (struct dm_cell_key * key )
@@ -176,7 +177,7 @@ static int bio_detain(struct dm_bio_prison *prison,
176177 struct dm_bio_prison_cell * * cell_result )
177178{
178179 int r ;
179- unsigned l = lock_nr (key );
180+ unsigned l = lock_nr (key , prison -> num_locks );
180181
181182 spin_lock_irq (& prison -> regions [l ].lock );
182183 r = __bio_detain (& prison -> regions [l ].cell , key , inmate , cell_prealloc , cell_result );
@@ -224,7 +225,7 @@ void dm_cell_release(struct dm_bio_prison *prison,
224225 struct dm_bio_prison_cell * cell ,
225226 struct bio_list * bios )
226227{
227- unsigned l = lock_nr (& cell -> key );
228+ unsigned l = lock_nr (& cell -> key , prison -> num_locks );
228229
229230 spin_lock_irq (& prison -> regions [l ].lock );
230231 __cell_release (& prison -> regions [l ].cell , cell , bios );
@@ -247,7 +248,7 @@ void dm_cell_release_no_holder(struct dm_bio_prison *prison,
247248 struct dm_bio_prison_cell * cell ,
248249 struct bio_list * inmates )
249250{
250- unsigned l = lock_nr (& cell -> key );
251+ unsigned l = lock_nr (& cell -> key , prison -> num_locks );
251252 unsigned long flags ;
252253
253254 spin_lock_irqsave (& prison -> regions [l ].lock , flags );
@@ -277,7 +278,7 @@ void dm_cell_visit_release(struct dm_bio_prison *prison,
277278 void * context ,
278279 struct dm_bio_prison_cell * cell )
279280{
280- unsigned l = lock_nr (& cell -> key );
281+ unsigned l = lock_nr (& cell -> key , prison -> num_locks );
281282 spin_lock_irq (& prison -> regions [l ].lock );
282283 visit_fn (context , cell );
283284 rb_erase (& cell -> node , & prison -> regions [l ].cell );
@@ -301,7 +302,7 @@ int dm_cell_promote_or_release(struct dm_bio_prison *prison,
301302 struct dm_bio_prison_cell * cell )
302303{
303304 int r ;
304- unsigned l = lock_nr (& cell -> key );
305+ unsigned l = lock_nr (& cell -> key , prison -> num_locks );
305306
306307 spin_lock_irq (& prison -> regions [l ].lock );
307308 r = __promote_or_release (& prison -> regions [l ].cell , cell );
0 commit comments