Lines Matching +full:1 +full:- +full:cell
1 // SPDX-License-Identifier: GPL-2.0-only
9 #include "dm-bio-prison-v1.h"
10 #include "dm-bio-prison-v2.h"
17 /*----------------------------------------------------------------*/
23 struct rb_root cell; member
34 /*----------------------------------------------------------------*/
50 prison->num_locks = num_locks; in dm_bio_prison_create()
52 for (i = 0; i < prison->num_locks; i++) { in dm_bio_prison_create()
53 spin_lock_init(&prison->regions[i].lock); in dm_bio_prison_create()
54 prison->regions[i].cell = RB_ROOT; in dm_bio_prison_create()
57 ret = mempool_init_slab_pool(&prison->cell_pool, MIN_CELLS, _cell_cache); in dm_bio_prison_create()
69 mempool_exit(&prison->cell_pool); in dm_bio_prison_destroy()
76 return mempool_alloc(&prison->cell_pool, gfp); in dm_bio_prison_alloc_cell()
81 struct dm_bio_prison_cell *cell) in dm_bio_prison_free_cell() argument
83 mempool_free(cell, &prison->cell_pool); in dm_bio_prison_free_cell()
89 struct dm_bio_prison_cell *cell) in __setup_new_cell() argument
91 memcpy(&cell->key, key, sizeof(cell->key)); in __setup_new_cell()
92 cell->holder = holder; in __setup_new_cell()
93 bio_list_init(&cell->bios); in __setup_new_cell()
99 if (lhs->virtual < rhs->virtual) in cmp_keys()
100 return -1; in cmp_keys()
102 if (lhs->virtual > rhs->virtual) in cmp_keys()
103 return 1; in cmp_keys()
105 if (lhs->dev < rhs->dev) in cmp_keys()
106 return -1; in cmp_keys()
108 if (lhs->dev > rhs->dev) in cmp_keys()
109 return 1; in cmp_keys()
111 if (lhs->block_end <= rhs->block_begin) in cmp_keys()
112 return -1; in cmp_keys()
114 if (lhs->block_begin >= rhs->block_end) in cmp_keys()
115 return 1; in cmp_keys()
122 return dm_hash_locks_index((key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT), in lock_nr()
128 if (WARN_ON_ONCE(key->block_end - key->block_begin > BIO_PRISON_MAX_RANGE)) in dm_cell_key_has_valid_range()
130 if (WARN_ON_ONCE((key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT) != in dm_cell_key_has_valid_range()
131 (key->block_end - 1) >> BIO_PRISON_MAX_RANGE_SHIFT)) in dm_cell_key_has_valid_range()
145 struct rb_node **new = &root->rb_node, *parent = NULL; in __bio_detain()
148 struct dm_bio_prison_cell *cell = in __bio_detain() local
151 r = cmp_keys(key, &cell->key); in __bio_detain()
155 new = &((*new)->rb_left); in __bio_detain()
157 new = &((*new)->rb_right); in __bio_detain()
160 bio_list_add(&cell->bios, inmate); in __bio_detain()
161 *cell_result = cell; in __bio_detain()
162 return 1; in __bio_detain()
169 rb_link_node(&cell_prealloc->node, parent, new); in __bio_detain()
170 rb_insert_color(&cell_prealloc->node, root); in __bio_detain()
182 unsigned l = lock_nr(key, prison->num_locks); in bio_detain()
184 spin_lock_irq(&prison->regions[l].lock); in bio_detain()
185 r = __bio_detain(&prison->regions[l].cell, key, inmate, cell_prealloc, cell_result); in bio_detain()
186 spin_unlock_irq(&prison->regions[l].lock); in bio_detain()
214 struct dm_bio_prison_cell *cell, in __cell_release() argument
217 rb_erase(&cell->node, root); in __cell_release()
220 if (cell->holder) in __cell_release()
221 bio_list_add(inmates, cell->holder); in __cell_release()
222 bio_list_merge(inmates, &cell->bios); in __cell_release()
227 struct dm_bio_prison_cell *cell, in dm_cell_release() argument
230 unsigned l = lock_nr(&cell->key, prison->num_locks); in dm_cell_release()
232 spin_lock_irq(&prison->regions[l].lock); in dm_cell_release()
233 __cell_release(&prison->regions[l].cell, cell, bios); in dm_cell_release()
234 spin_unlock_irq(&prison->regions[l].lock); in dm_cell_release()
242 struct dm_bio_prison_cell *cell, in __cell_release_no_holder() argument
245 rb_erase(&cell->node, root); in __cell_release_no_holder()
246 bio_list_merge(inmates, &cell->bios); in __cell_release_no_holder()
250 struct dm_bio_prison_cell *cell, in dm_cell_release_no_holder() argument
253 unsigned l = lock_nr(&cell->key, prison->num_locks); in dm_cell_release_no_holder()
256 spin_lock_irqsave(&prison->regions[l].lock, flags); in dm_cell_release_no_holder()
257 __cell_release_no_holder(&prison->regions[l].cell, cell, inmates); in dm_cell_release_no_holder()
258 spin_unlock_irqrestore(&prison->regions[l].lock, flags); in dm_cell_release_no_holder()
263 struct dm_bio_prison_cell *cell, blk_status_t error) in dm_cell_error() argument
269 dm_cell_release(prison, cell, &bios); in dm_cell_error()
272 bio->bi_status = error; in dm_cell_error()
281 struct dm_bio_prison_cell *cell) in dm_cell_visit_release() argument
283 unsigned l = lock_nr(&cell->key, prison->num_locks); in dm_cell_visit_release()
284 spin_lock_irq(&prison->regions[l].lock); in dm_cell_visit_release()
285 visit_fn(context, cell); in dm_cell_visit_release()
286 rb_erase(&cell->node, &prison->regions[l].cell); in dm_cell_visit_release()
287 spin_unlock_irq(&prison->regions[l].lock); in dm_cell_visit_release()
292 struct dm_bio_prison_cell *cell) in __promote_or_release() argument
294 if (bio_list_empty(&cell->bios)) { in __promote_or_release()
295 rb_erase(&cell->node, root); in __promote_or_release()
296 return 1; in __promote_or_release()
299 cell->holder = bio_list_pop(&cell->bios); in __promote_or_release()
304 struct dm_bio_prison_cell *cell) in dm_cell_promote_or_release() argument
307 unsigned l = lock_nr(&cell->key, prison->num_locks); in dm_cell_promote_or_release()
309 spin_lock_irq(&prison->regions[l].lock); in dm_cell_promote_or_release()
310 r = __promote_or_release(&prison->regions[l].cell, cell); in dm_cell_promote_or_release()
311 spin_unlock_irq(&prison->regions[l].lock); in dm_cell_promote_or_release()
317 /*----------------------------------------------------------------*/
343 spin_lock_init(&ds->lock); in dm_deferred_set_create()
344 ds->current_entry = 0; in dm_deferred_set_create()
345 ds->sweeper = 0; in dm_deferred_set_create()
347 ds->entries[i].ds = ds; in dm_deferred_set_create()
348 ds->entries[i].count = 0; in dm_deferred_set_create()
349 INIT_LIST_HEAD(&ds->entries[i].work_items); in dm_deferred_set_create()
367 spin_lock_irqsave(&ds->lock, flags); in dm_deferred_entry_inc()
368 entry = ds->entries + ds->current_entry; in dm_deferred_entry_inc()
369 entry->count++; in dm_deferred_entry_inc()
370 spin_unlock_irqrestore(&ds->lock, flags); in dm_deferred_entry_inc()
378 return (index + 1) % DEFERRED_SET_SIZE; in ds_next()
383 while ((ds->sweeper != ds->current_entry) && in __sweep()
384 !ds->entries[ds->sweeper].count) { in __sweep()
385 list_splice_init(&ds->entries[ds->sweeper].work_items, head); in __sweep()
386 ds->sweeper = ds_next(ds->sweeper); in __sweep()
389 if ((ds->sweeper == ds->current_entry) && !ds->entries[ds->sweeper].count) in __sweep()
390 list_splice_init(&ds->entries[ds->sweeper].work_items, head); in __sweep()
397 spin_lock_irqsave(&entry->ds->lock, flags); in dm_deferred_entry_dec()
398 BUG_ON(!entry->count); in dm_deferred_entry_dec()
399 --entry->count; in dm_deferred_entry_dec()
400 __sweep(entry->ds, head); in dm_deferred_entry_dec()
401 spin_unlock_irqrestore(&entry->ds->lock, flags); in dm_deferred_entry_dec()
406 * Returns 1 if deferred or 0 if no pending items to delay job.
410 int r = 1; in dm_deferred_set_add_work()
413 spin_lock_irq(&ds->lock); in dm_deferred_set_add_work()
414 if ((ds->sweeper == ds->current_entry) && in dm_deferred_set_add_work()
415 !ds->entries[ds->current_entry].count) in dm_deferred_set_add_work()
418 list_add(work, &ds->entries[ds->current_entry].work_items); in dm_deferred_set_add_work()
419 next_entry = ds_next(ds->current_entry); in dm_deferred_set_add_work()
420 if (!ds->entries[next_entry].count) in dm_deferred_set_add_work()
421 ds->current_entry = next_entry; in dm_deferred_set_add_work()
423 spin_unlock_irq(&ds->lock); in dm_deferred_set_add_work()
429 /*----------------------------------------------------------------*/
435 return -ENOMEM; in dm_bio_prison_init_v1()
471 while (i--) in dm_bio_prison_init()
481 while (i--) in dm_bio_prison_exit()
492 MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");