Commit 6beca5eb6e801aea810da6cbc4990d96e6c1c0bc

Authored by Joe Thornber
Committed by Alasdair G Kergon
1 parent 4e7f1f9089

dm bio prison: pass cell memory in

Change the dm_bio_prison interface so that instead of allocating memory
internally, dm_bio_detain is supplied with a pre-allocated cell each
time it is called.

This enables a subsequent patch to move the allocation of the struct
dm_bio_prison_cell outside the thin target's mapping function so it can
no longer block there.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

Showing 3 changed files with 176 additions and 101 deletions Side-by-side Diff

drivers/md/dm-bio-prison.c
... ... @@ -16,7 +16,6 @@
16 16  
17 17 struct dm_bio_prison_cell {
18 18 struct hlist_node list;
19   - struct dm_bio_prison *prison;
20 19 struct dm_cell_key key;
21 20 struct bio *holder;
22 21 struct bio_list bios;
... ... @@ -87,6 +86,19 @@
87 86 }
88 87 EXPORT_SYMBOL_GPL(dm_bio_prison_destroy);
89 88  
  89 +struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison, gfp_t gfp)
  90 +{
  91 + return mempool_alloc(prison->cell_pool, gfp);
  92 +}
  93 +EXPORT_SYMBOL_GPL(dm_bio_prison_alloc_cell);
  94 +
  95 +void dm_bio_prison_free_cell(struct dm_bio_prison *prison,
  96 + struct dm_bio_prison_cell *cell)
  97 +{
  98 + mempool_free(cell, prison->cell_pool);
  99 +}
  100 +EXPORT_SYMBOL_GPL(dm_bio_prison_free_cell);
  101 +
90 102 static uint32_t hash_key(struct dm_bio_prison *prison, struct dm_cell_key *key)
91 103 {
92 104 const unsigned long BIG_PRIME = 4294967291UL;
93 105  
94 106  
95 107  
96 108  
97 109  
98 110  
99 111  
100 112  
101 113  
102 114  
103 115  
104 116  
105 117  
106 118  
107 119  
... ... @@ -114,91 +126,86 @@
114 126 return NULL;
115 127 }
116 128  
117   -/*
118   - * This may block if a new cell needs allocating. You must ensure that
119   - * cells will be unlocked even if the calling thread is blocked.
120   - *
121   - * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
122   - */
123   -int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
124   - struct bio *inmate, struct dm_bio_prison_cell **ref)
  129 +static void __setup_new_cell(struct dm_bio_prison *prison,
  130 + struct dm_cell_key *key,
  131 + struct bio *holder,
  132 + uint32_t hash,
  133 + struct dm_bio_prison_cell *cell)
125 134 {
126   - int r = 1;
127   - unsigned long flags;
  135 + memcpy(&cell->key, key, sizeof(cell->key));
  136 + cell->holder = holder;
  137 + bio_list_init(&cell->bios);
  138 + hlist_add_head(&cell->list, prison->cells + hash);
  139 +}
  140 +
  141 +static int __bio_detain(struct dm_bio_prison *prison,
  142 + struct dm_cell_key *key,
  143 + struct bio *inmate,
  144 + struct dm_bio_prison_cell *cell_prealloc,
  145 + struct dm_bio_prison_cell **cell_result)
  146 +{
128 147 uint32_t hash = hash_key(prison, key);
129   - struct dm_bio_prison_cell *cell, *cell2;
  148 + struct dm_bio_prison_cell *cell;
130 149  
131   - BUG_ON(hash > prison->nr_buckets);
132   -
133   - spin_lock_irqsave(&prison->lock, flags);
134   -
135 150 cell = __search_bucket(prison->cells + hash, key);
136 151 if (cell) {
137   - bio_list_add(&cell->bios, inmate);
138   - goto out;
  152 + if (inmate)
  153 + bio_list_add(&cell->bios, inmate);
  154 + *cell_result = cell;
  155 + return 1;
139 156 }
140 157  
141   - /*
142   - * Allocate a new cell
143   - */
144   - spin_unlock_irqrestore(&prison->lock, flags);
145   - cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
146   - spin_lock_irqsave(&prison->lock, flags);
  158 + __setup_new_cell(prison, key, inmate, hash, cell_prealloc);
  159 + *cell_result = cell_prealloc;
  160 + return 0;
  161 +}
147 162  
148   - /*
149   - * We've been unlocked, so we have to double check that
150   - * nobody else has inserted this cell in the meantime.
151   - */
152   - cell = __search_bucket(prison->cells + hash, key);
153   - if (cell) {
154   - mempool_free(cell2, prison->cell_pool);
155   - bio_list_add(&cell->bios, inmate);
156   - goto out;
157   - }
  163 +static int bio_detain(struct dm_bio_prison *prison,
  164 + struct dm_cell_key *key,
  165 + struct bio *inmate,
  166 + struct dm_bio_prison_cell *cell_prealloc,
  167 + struct dm_bio_prison_cell **cell_result)
  168 +{
  169 + int r;
  170 + unsigned long flags;
158 171  
159   - /*
160   - * Use new cell.
161   - */
162   - cell = cell2;
163   -
164   - cell->prison = prison;
165   - memcpy(&cell->key, key, sizeof(cell->key));
166   - cell->holder = inmate;
167   - bio_list_init(&cell->bios);
168   - hlist_add_head(&cell->list, prison->cells + hash);
169   -
170   - r = 0;
171   -
172   -out:
  172 + spin_lock_irqsave(&prison->lock, flags);
  173 + r = __bio_detain(prison, key, inmate, cell_prealloc, cell_result);
173 174 spin_unlock_irqrestore(&prison->lock, flags);
174 175  
175   - *ref = cell;
176   -
177 176 return r;
178 177 }
  178 +
  179 +int dm_bio_detain(struct dm_bio_prison *prison,
  180 + struct dm_cell_key *key,
  181 + struct bio *inmate,
  182 + struct dm_bio_prison_cell *cell_prealloc,
  183 + struct dm_bio_prison_cell **cell_result)
  184 +{
  185 + return bio_detain(prison, key, inmate, cell_prealloc, cell_result);
  186 +}
179 187 EXPORT_SYMBOL_GPL(dm_bio_detain);
180 188  
181 189 /*
182 190 * @inmates must have been initialised prior to this call
183 191 */
184   -static void __cell_release(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  192 +static void __cell_release(struct dm_bio_prison_cell *cell,
  193 + struct bio_list *inmates)
185 194 {
186   - struct dm_bio_prison *prison = cell->prison;
187   -
188 195 hlist_del(&cell->list);
189 196  
190 197 if (inmates) {
191   - bio_list_add(inmates, cell->holder);
  198 + if (cell->holder)
  199 + bio_list_add(inmates, cell->holder);
192 200 bio_list_merge(inmates, &cell->bios);
193 201 }
194   -
195   - mempool_free(cell, prison->cell_pool);
196 202 }
197 203  
198   -void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios)
  204 +void dm_cell_release(struct dm_bio_prison *prison,
  205 + struct dm_bio_prison_cell *cell,
  206 + struct bio_list *bios)
199 207 {
200 208 unsigned long flags;
201   - struct dm_bio_prison *prison = cell->prison;
202 209  
203 210 spin_lock_irqsave(&prison->lock, flags);
204 211 __cell_release(cell, bios);
205 212  
206 213  
207 214  
208 215  
... ... @@ -209,20 +216,18 @@
209 216 /*
210 217 * Sometimes we don't want the holder, just the additional bios.
211 218 */
212   -static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  219 +static void __cell_release_no_holder(struct dm_bio_prison_cell *cell,
  220 + struct bio_list *inmates)
213 221 {
214   - struct dm_bio_prison *prison = cell->prison;
215   -
216 222 hlist_del(&cell->list);
217 223 bio_list_merge(inmates, &cell->bios);
218   -
219   - mempool_free(cell, prison->cell_pool);
220 224 }
221 225  
222   -void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  226 +void dm_cell_release_no_holder(struct dm_bio_prison *prison,
  227 + struct dm_bio_prison_cell *cell,
  228 + struct bio_list *inmates)
223 229 {
224 230 unsigned long flags;
225   - struct dm_bio_prison *prison = cell->prison;
226 231  
227 232 spin_lock_irqsave(&prison->lock, flags);
228 233 __cell_release_no_holder(cell, inmates);
229 234  
... ... @@ -230,9 +235,9 @@
230 235 }
231 236 EXPORT_SYMBOL_GPL(dm_cell_release_no_holder);
232 237  
233   -void dm_cell_error(struct dm_bio_prison_cell *cell)
  238 +void dm_cell_error(struct dm_bio_prison *prison,
  239 + struct dm_bio_prison_cell *cell)
234 240 {
235   - struct dm_bio_prison *prison = cell->prison;
236 241 struct bio_list bios;
237 242 struct bio *bio;
238 243 unsigned long flags;
drivers/md/dm-bio-prison.h
... ... @@ -35,17 +35,36 @@
35 35 void dm_bio_prison_destroy(struct dm_bio_prison *prison);
36 36  
37 37 /*
38   - * This may block if a new cell needs allocating. You must ensure that
39   - * cells will be unlocked even if the calling thread is blocked.
  38 + * These two functions just wrap a mempool. This is a transitory step:
  39 + * Eventually all bio prison clients should manage their own cell memory.
40 40 *
  41 + * Like mempool_alloc(), dm_bio_prison_alloc_cell() can only fail if called
  42 + * in interrupt context or passed GFP_NOWAIT.
  43 + */
  44 +struct dm_bio_prison_cell *dm_bio_prison_alloc_cell(struct dm_bio_prison *prison,
  45 + gfp_t gfp);
  46 +void dm_bio_prison_free_cell(struct dm_bio_prison *prison,
  47 + struct dm_bio_prison_cell *cell);
  48 +
  49 +/*
  50 + * An atomic op that combines retrieving a cell, and adding a bio to it.
  51 + *
41 52 * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
42 53 */
43   -int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
44   - struct bio *inmate, struct dm_bio_prison_cell **ref);
  54 +int dm_bio_detain(struct dm_bio_prison *prison,
  55 + struct dm_cell_key *key,
  56 + struct bio *inmate,
  57 + struct dm_bio_prison_cell *cell_prealloc,
  58 + struct dm_bio_prison_cell **cell_result);
45 59  
46   -void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios);
47   -void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates);
48   -void dm_cell_error(struct dm_bio_prison_cell *cell);
  60 +void dm_cell_release(struct dm_bio_prison *prison,
  61 + struct dm_bio_prison_cell *cell,
  62 + struct bio_list *bios);
  63 +void dm_cell_release_no_holder(struct dm_bio_prison *prison,
  64 + struct dm_bio_prison_cell *cell,
  65 + struct bio_list *inmates);
  66 +void dm_cell_error(struct dm_bio_prison *prison,
  67 + struct dm_bio_prison_cell *cell);
49 68  
50 69 /*----------------------------------------------------------------*/
51 70  
drivers/md/dm-thin.c
... ... @@ -229,6 +229,54 @@
229 229  
230 230 /*----------------------------------------------------------------*/
231 231  
  232 +static int bio_detain(struct pool *pool, struct dm_cell_key *key, struct bio *bio,
  233 + struct dm_bio_prison_cell **cell_result)
  234 +{
  235 + int r;
  236 + struct dm_bio_prison_cell *cell_prealloc;
  237 +
  238 + /*
  239 + * Allocate a cell from the prison's mempool.
  240 + * This might block but it can't fail.
  241 + */
  242 + cell_prealloc = dm_bio_prison_alloc_cell(pool->prison, GFP_NOIO);
  243 +
  244 + r = dm_bio_detain(pool->prison, key, bio, cell_prealloc, cell_result);
  245 + if (r)
  246 + /*
  247 + * We reused an old cell; we can get rid of
  248 + * the new one.
  249 + */
  250 + dm_bio_prison_free_cell(pool->prison, cell_prealloc);
  251 +
  252 + return r;
  253 +}
  254 +
  255 +static void cell_release(struct pool *pool,
  256 + struct dm_bio_prison_cell *cell,
  257 + struct bio_list *bios)
  258 +{
  259 + dm_cell_release(pool->prison, cell, bios);
  260 + dm_bio_prison_free_cell(pool->prison, cell);
  261 +}
  262 +
  263 +static void cell_release_no_holder(struct pool *pool,
  264 + struct dm_bio_prison_cell *cell,
  265 + struct bio_list *bios)
  266 +{
  267 + dm_cell_release_no_holder(pool->prison, cell, bios);
  268 + dm_bio_prison_free_cell(pool->prison, cell);
  269 +}
  270 +
  271 +static void cell_error(struct pool *pool,
  272 + struct dm_bio_prison_cell *cell)
  273 +{
  274 + dm_cell_error(pool->prison, cell);
  275 + dm_bio_prison_free_cell(pool->prison, cell);
  276 +}
  277 +
  278 +/*----------------------------------------------------------------*/
  279 +
232 280 /*
233 281 * A global list of pools that uses a struct mapped_device as a key.
234 282 */
235 283  
... ... @@ -524,14 +572,14 @@
524 572 unsigned long flags;
525 573  
526 574 spin_lock_irqsave(&pool->lock, flags);
527   - dm_cell_release(cell, &pool->deferred_bios);
  575 + cell_release(pool, cell, &pool->deferred_bios);
528 576 spin_unlock_irqrestore(&tc->pool->lock, flags);
529 577  
530 578 wake_worker(pool);
531 579 }
532 580  
533 581 /*
534   - * Same as cell_defer except it omits the original holder of the cell.
  582 + * Same as cell_defer above, except it omits the original holder of the cell.
535 583 */
536 584 static void cell_defer_no_holder(struct thin_c *tc, struct dm_bio_prison_cell *cell)
537 585 {
... ... @@ -539,7 +587,7 @@
539 587 unsigned long flags;
540 588  
541 589 spin_lock_irqsave(&pool->lock, flags);
542   - dm_cell_release_no_holder(cell, &pool->deferred_bios);
  590 + cell_release_no_holder(pool, cell, &pool->deferred_bios);
543 591 spin_unlock_irqrestore(&pool->lock, flags);
544 592  
545 593 wake_worker(pool);
546 594  
... ... @@ -549,13 +597,14 @@
549 597 {
550 598 if (m->bio)
551 599 m->bio->bi_end_io = m->saved_bi_end_io;
552   - dm_cell_error(m->cell);
  600 + cell_error(m->tc->pool, m->cell);
553 601 list_del(&m->list);
554 602 mempool_free(m, m->tc->pool->mapping_pool);
555 603 }
556 604 static void process_prepared_mapping(struct dm_thin_new_mapping *m)
557 605 {
558 606 struct thin_c *tc = m->tc;
  607 + struct pool *pool = tc->pool;
559 608 struct bio *bio;
560 609 int r;
561 610  
... ... @@ -564,7 +613,7 @@
564 613 bio->bi_end_io = m->saved_bi_end_io;
565 614  
566 615 if (m->err) {
567   - dm_cell_error(m->cell);
  616 + cell_error(pool, m->cell);
568 617 goto out;
569 618 }
570 619  
... ... @@ -576,7 +625,7 @@
576 625 r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block);
577 626 if (r) {
578 627 DMERR_LIMIT("dm_thin_insert_block() failed");
579   - dm_cell_error(m->cell);
  628 + cell_error(pool, m->cell);
580 629 goto out;
581 630 }
582 631  
... ... @@ -594,7 +643,7 @@
594 643  
595 644 out:
596 645 list_del(&m->list);
597   - mempool_free(m, tc->pool->mapping_pool);
  646 + mempool_free(m, pool->mapping_pool);
598 647 }
599 648  
600 649 static void process_prepared_discard_fail(struct dm_thin_new_mapping *m)
... ... @@ -745,7 +794,7 @@
745 794 if (r < 0) {
746 795 mempool_free(m, pool->mapping_pool);
747 796 DMERR_LIMIT("dm_kcopyd_copy() failed");
748   - dm_cell_error(cell);
  797 + cell_error(pool, cell);
749 798 }
750 799 }
751 800 }
... ... @@ -811,7 +860,7 @@
811 860 if (r < 0) {
812 861 mempool_free(m, pool->mapping_pool);
813 862 DMERR_LIMIT("dm_kcopyd_zero() failed");
814   - dm_cell_error(cell);
  863 + cell_error(pool, cell);
815 864 }
816 865 }
817 866 }
818 867  
... ... @@ -917,13 +966,13 @@
917 966 spin_unlock_irqrestore(&pool->lock, flags);
918 967 }
919 968  
920   -static void no_space(struct dm_bio_prison_cell *cell)
  969 +static void no_space(struct pool *pool, struct dm_bio_prison_cell *cell)
921 970 {
922 971 struct bio *bio;
923 972 struct bio_list bios;
924 973  
925 974 bio_list_init(&bios);
926   - dm_cell_release(cell, &bios);
  975 + cell_release(pool, cell, &bios);
927 976  
928 977 while ((bio = bio_list_pop(&bios)))
929 978 retry_on_resume(bio);
... ... @@ -941,7 +990,7 @@
941 990 struct dm_thin_new_mapping *m;
942 991  
943 992 build_virtual_key(tc->td, block, &key);
944   - if (dm_bio_detain(tc->pool->prison, &key, bio, &cell))
  993 + if (bio_detain(tc->pool, &key, bio, &cell))
945 994 return;
946 995  
947 996 r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
... ... @@ -953,7 +1002,7 @@
953 1002 * on this block.
954 1003 */
955 1004 build_data_key(tc->td, lookup_result.block, &key2);
956   - if (dm_bio_detain(tc->pool->prison, &key2, bio, &cell2)) {
  1005 + if (bio_detain(tc->pool, &key2, bio, &cell2)) {
957 1006 cell_defer_no_holder(tc, cell);
958 1007 break;
959 1008 }
960 1009  
... ... @@ -1029,13 +1078,13 @@
1029 1078 break;
1030 1079  
1031 1080 case -ENOSPC:
1032   - no_space(cell);
  1081 + no_space(tc->pool, cell);
1033 1082 break;
1034 1083  
1035 1084 default:
1036 1085 DMERR_LIMIT("%s: alloc_data_block() failed: error = %d",
1037 1086 __func__, r);
1038   - dm_cell_error(cell);
  1087 + cell_error(tc->pool, cell);
1039 1088 break;
1040 1089 }
1041 1090 }
... ... @@ -1053,7 +1102,7 @@
1053 1102 * of being broken so we have nothing further to do here.
1054 1103 */
1055 1104 build_data_key(tc->td, lookup_result->block, &key);
1056   - if (dm_bio_detain(pool->prison, &key, bio, &cell))
  1105 + if (bio_detain(pool, &key, bio, &cell))
1057 1106 return;
1058 1107  
1059 1108 if (bio_data_dir(bio) == WRITE && bio->bi_size)
1060 1109  
... ... @@ -1074,12 +1123,13 @@
1074 1123 {
1075 1124 int r;
1076 1125 dm_block_t data_block;
  1126 + struct pool *pool = tc->pool;
1077 1127  
1078 1128 /*
1079 1129 * Remap empty bios (flushes) immediately, without provisioning.
1080 1130 */
1081 1131 if (!bio->bi_size) {
1082   - inc_all_io_entry(tc->pool, bio);
  1132 + inc_all_io_entry(pool, bio);
1083 1133 cell_defer_no_holder(tc, cell);
1084 1134  
1085 1135 remap_and_issue(tc, bio, 0);
1086 1136  
... ... @@ -1106,14 +1156,14 @@
1106 1156 break;
1107 1157  
1108 1158 case -ENOSPC:
1109   - no_space(cell);
  1159 + no_space(pool, cell);
1110 1160 break;
1111 1161  
1112 1162 default:
1113 1163 DMERR_LIMIT("%s: alloc_data_block() failed: error = %d",
1114 1164 __func__, r);
1115   - set_pool_mode(tc->pool, PM_READ_ONLY);
1116   - dm_cell_error(cell);
  1165 + set_pool_mode(pool, PM_READ_ONLY);
  1166 + cell_error(pool, cell);
1117 1167 break;
1118 1168 }
1119 1169 }
... ... @@ -1121,6 +1171,7 @@
1121 1171 static void process_bio(struct thin_c *tc, struct bio *bio)
1122 1172 {
1123 1173 int r;
  1174 + struct pool *pool = tc->pool;
1124 1175 dm_block_t block = get_bio_block(tc, bio);
1125 1176 struct dm_bio_prison_cell *cell;
1126 1177 struct dm_cell_key key;
... ... @@ -1131,7 +1182,7 @@
1131 1182 * being provisioned so we have nothing further to do here.
1132 1183 */
1133 1184 build_virtual_key(tc->td, block, &key);
1134   - if (dm_bio_detain(tc->pool->prison, &key, bio, &cell))
  1185 + if (bio_detain(pool, &key, bio, &cell))
1135 1186 return;
1136 1187  
1137 1188 r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
1138 1189  
... ... @@ -1139,9 +1190,9 @@
1139 1190 case 0:
1140 1191 if (lookup_result.shared) {
1141 1192 process_shared_bio(tc, bio, block, &lookup_result);
1142   - cell_defer_no_holder(tc, cell);
  1193 + cell_defer_no_holder(tc, cell); /* FIXME: pass this cell into process_shared? */
1143 1194 } else {
1144   - inc_all_io_entry(tc->pool, bio);
  1195 + inc_all_io_entry(pool, bio);
1145 1196 cell_defer_no_holder(tc, cell);
1146 1197  
1147 1198 remap_and_issue(tc, bio, lookup_result.block);
... ... @@ -1150,7 +1201,7 @@
1150 1201  
1151 1202 case -ENODATA:
1152 1203 if (bio_data_dir(bio) == READ && tc->origin_dev) {
1153   - inc_all_io_entry(tc->pool, bio);
  1204 + inc_all_io_entry(pool, bio);
1154 1205 cell_defer_no_holder(tc, cell);
1155 1206  
1156 1207 remap_to_origin_and_issue(tc, bio);
1157 1208  
... ... @@ -1429,11 +1480,11 @@
1429 1480 }
1430 1481  
1431 1482 build_virtual_key(tc->td, block, &key);
1432   - if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1))
  1483 + if (bio_detain(tc->pool, &key, bio, &cell1))
1433 1484 return DM_MAPIO_SUBMITTED;
1434 1485  
1435 1486 build_data_key(tc->td, result.block, &key);
1436   - if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2)) {
  1487 + if (bio_detain(tc->pool, &key, bio, &cell2)) {
1437 1488 cell_defer_no_holder(tc, cell1);
1438 1489 return DM_MAPIO_SUBMITTED;
1439 1490 }