dm-bio-prison.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. * Copyright (C) 2012 Red Hat, Inc.
  3. *
  4. * This file is released under the GPL.
  5. */
  6. #include "dm.h"
  7. #include "dm-bio-prison.h"
  8. #include <linux/spinlock.h>
  9. #include <linux/mempool.h>
  10. #include <linux/module.h>
  11. #include <linux/slab.h>
  12. /*----------------------------------------------------------------*/
  13. struct dm_bio_prison_cell {
  14. struct hlist_node list;
  15. struct dm_bio_prison *prison;
  16. struct dm_cell_key key;
  17. struct bio *holder;
  18. struct bio_list bios;
  19. };
  20. struct dm_bio_prison {
  21. spinlock_t lock;
  22. mempool_t *cell_pool;
  23. unsigned nr_buckets;
  24. unsigned hash_mask;
  25. struct hlist_head *cells;
  26. };
  27. /*----------------------------------------------------------------*/
  28. static uint32_t calc_nr_buckets(unsigned nr_cells)
  29. {
  30. uint32_t n = 128;
  31. nr_cells /= 4;
  32. nr_cells = min(nr_cells, 8192u);
  33. while (n < nr_cells)
  34. n <<= 1;
  35. return n;
  36. }
  37. static struct kmem_cache *_cell_cache;
  38. /*
  39. * @nr_cells should be the number of cells you want in use _concurrently_.
  40. * Don't confuse it with the number of distinct keys.
  41. */
  42. struct dm_bio_prison *dm_bio_prison_create(unsigned nr_cells)
  43. {
  44. unsigned i;
  45. uint32_t nr_buckets = calc_nr_buckets(nr_cells);
  46. size_t len = sizeof(struct dm_bio_prison) +
  47. (sizeof(struct hlist_head) * nr_buckets);
  48. struct dm_bio_prison *prison = kmalloc(len, GFP_KERNEL);
  49. if (!prison)
  50. return NULL;
  51. spin_lock_init(&prison->lock);
  52. prison->cell_pool = mempool_create_slab_pool(nr_cells, _cell_cache);
  53. if (!prison->cell_pool) {
  54. kfree(prison);
  55. return NULL;
  56. }
  57. prison->nr_buckets = nr_buckets;
  58. prison->hash_mask = nr_buckets - 1;
  59. prison->cells = (struct hlist_head *) (prison + 1);
  60. for (i = 0; i < nr_buckets; i++)
  61. INIT_HLIST_HEAD(prison->cells + i);
  62. return prison;
  63. }
  64. EXPORT_SYMBOL_GPL(dm_bio_prison_create);
  65. void dm_bio_prison_destroy(struct dm_bio_prison *prison)
  66. {
  67. mempool_destroy(prison->cell_pool);
  68. kfree(prison);
  69. }
  70. EXPORT_SYMBOL_GPL(dm_bio_prison_destroy);
  71. static uint32_t hash_key(struct dm_bio_prison *prison, struct dm_cell_key *key)
  72. {
  73. const unsigned long BIG_PRIME = 4294967291UL;
  74. uint64_t hash = key->block * BIG_PRIME;
  75. return (uint32_t) (hash & prison->hash_mask);
  76. }
  77. static int keys_equal(struct dm_cell_key *lhs, struct dm_cell_key *rhs)
  78. {
  79. return (lhs->virtual == rhs->virtual) &&
  80. (lhs->dev == rhs->dev) &&
  81. (lhs->block == rhs->block);
  82. }
  83. static struct dm_bio_prison_cell *__search_bucket(struct hlist_head *bucket,
  84. struct dm_cell_key *key)
  85. {
  86. struct dm_bio_prison_cell *cell;
  87. struct hlist_node *tmp;
  88. hlist_for_each_entry(cell, tmp, bucket, list)
  89. if (keys_equal(&cell->key, key))
  90. return cell;
  91. return NULL;
  92. }
  93. /*
  94. * This may block if a new cell needs allocating. You must ensure that
  95. * cells will be unlocked even if the calling thread is blocked.
  96. *
  97. * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
  98. */
  99. int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
  100. struct bio *inmate, struct dm_bio_prison_cell **ref)
  101. {
  102. int r = 1;
  103. unsigned long flags;
  104. uint32_t hash = hash_key(prison, key);
  105. struct dm_bio_prison_cell *cell, *cell2;
  106. BUG_ON(hash > prison->nr_buckets);
  107. spin_lock_irqsave(&prison->lock, flags);
  108. cell = __search_bucket(prison->cells + hash, key);
  109. if (cell) {
  110. bio_list_add(&cell->bios, inmate);
  111. goto out;
  112. }
  113. /*
  114. * Allocate a new cell
  115. */
  116. spin_unlock_irqrestore(&prison->lock, flags);
  117. cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
  118. spin_lock_irqsave(&prison->lock, flags);
  119. /*
  120. * We've been unlocked, so we have to double check that
  121. * nobody else has inserted this cell in the meantime.
  122. */
  123. cell = __search_bucket(prison->cells + hash, key);
  124. if (cell) {
  125. mempool_free(cell2, prison->cell_pool);
  126. bio_list_add(&cell->bios, inmate);
  127. goto out;
  128. }
  129. /*
  130. * Use new cell.
  131. */
  132. cell = cell2;
  133. cell->prison = prison;
  134. memcpy(&cell->key, key, sizeof(cell->key));
  135. cell->holder = inmate;
  136. bio_list_init(&cell->bios);
  137. hlist_add_head(&cell->list, prison->cells + hash);
  138. r = 0;
  139. out:
  140. spin_unlock_irqrestore(&prison->lock, flags);
  141. *ref = cell;
  142. return r;
  143. }
  144. EXPORT_SYMBOL_GPL(dm_bio_detain);
  145. /*
  146. * @inmates must have been initialised prior to this call
  147. */
  148. static void __cell_release(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  149. {
  150. struct dm_bio_prison *prison = cell->prison;
  151. hlist_del(&cell->list);
  152. if (inmates) {
  153. bio_list_add(inmates, cell->holder);
  154. bio_list_merge(inmates, &cell->bios);
  155. }
  156. mempool_free(cell, prison->cell_pool);
  157. }
  158. void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios)
  159. {
  160. unsigned long flags;
  161. struct dm_bio_prison *prison = cell->prison;
  162. spin_lock_irqsave(&prison->lock, flags);
  163. __cell_release(cell, bios);
  164. spin_unlock_irqrestore(&prison->lock, flags);
  165. }
  166. EXPORT_SYMBOL_GPL(dm_cell_release);
  167. /*
  168. * There are a couple of places where we put a bio into a cell briefly
  169. * before taking it out again. In these situations we know that no other
  170. * bio may be in the cell. This function releases the cell, and also does
  171. * a sanity check.
  172. */
  173. static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
  174. {
  175. BUG_ON(cell->holder != bio);
  176. BUG_ON(!bio_list_empty(&cell->bios));
  177. __cell_release(cell, NULL);
  178. }
  179. void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
  180. {
  181. unsigned long flags;
  182. struct dm_bio_prison *prison = cell->prison;
  183. spin_lock_irqsave(&prison->lock, flags);
  184. __cell_release_singleton(cell, bio);
  185. spin_unlock_irqrestore(&prison->lock, flags);
  186. }
  187. EXPORT_SYMBOL_GPL(dm_cell_release_singleton);
  188. /*
  189. * Sometimes we don't want the holder, just the additional bios.
  190. */
  191. static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  192. {
  193. struct dm_bio_prison *prison = cell->prison;
  194. hlist_del(&cell->list);
  195. bio_list_merge(inmates, &cell->bios);
  196. mempool_free(cell, prison->cell_pool);
  197. }
  198. void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
  199. {
  200. unsigned long flags;
  201. struct dm_bio_prison *prison = cell->prison;
  202. spin_lock_irqsave(&prison->lock, flags);
  203. __cell_release_no_holder(cell, inmates);
  204. spin_unlock_irqrestore(&prison->lock, flags);
  205. }
  206. EXPORT_SYMBOL_GPL(dm_cell_release_no_holder);
  207. void dm_cell_error(struct dm_bio_prison_cell *cell)
  208. {
  209. struct dm_bio_prison *prison = cell->prison;
  210. struct bio_list bios;
  211. struct bio *bio;
  212. unsigned long flags;
  213. bio_list_init(&bios);
  214. spin_lock_irqsave(&prison->lock, flags);
  215. __cell_release(cell, &bios);
  216. spin_unlock_irqrestore(&prison->lock, flags);
  217. while ((bio = bio_list_pop(&bios)))
  218. bio_io_error(bio);
  219. }
  220. EXPORT_SYMBOL_GPL(dm_cell_error);
  221. /*----------------------------------------------------------------*/
  222. #define DEFERRED_SET_SIZE 64
  223. struct dm_deferred_entry {
  224. struct dm_deferred_set *ds;
  225. unsigned count;
  226. struct list_head work_items;
  227. };
  228. struct dm_deferred_set {
  229. spinlock_t lock;
  230. unsigned current_entry;
  231. unsigned sweeper;
  232. struct dm_deferred_entry entries[DEFERRED_SET_SIZE];
  233. };
  234. struct dm_deferred_set *dm_deferred_set_create(void)
  235. {
  236. int i;
  237. struct dm_deferred_set *ds;
  238. ds = kmalloc(sizeof(*ds), GFP_KERNEL);
  239. if (!ds)
  240. return NULL;
  241. spin_lock_init(&ds->lock);
  242. ds->current_entry = 0;
  243. ds->sweeper = 0;
  244. for (i = 0; i < DEFERRED_SET_SIZE; i++) {
  245. ds->entries[i].ds = ds;
  246. ds->entries[i].count = 0;
  247. INIT_LIST_HEAD(&ds->entries[i].work_items);
  248. }
  249. return ds;
  250. }
  251. EXPORT_SYMBOL_GPL(dm_deferred_set_create);
  252. void dm_deferred_set_destroy(struct dm_deferred_set *ds)
  253. {
  254. kfree(ds);
  255. }
  256. EXPORT_SYMBOL_GPL(dm_deferred_set_destroy);
  257. struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds)
  258. {
  259. unsigned long flags;
  260. struct dm_deferred_entry *entry;
  261. spin_lock_irqsave(&ds->lock, flags);
  262. entry = ds->entries + ds->current_entry;
  263. entry->count++;
  264. spin_unlock_irqrestore(&ds->lock, flags);
  265. return entry;
  266. }
  267. EXPORT_SYMBOL_GPL(dm_deferred_entry_inc);
  268. static unsigned ds_next(unsigned index)
  269. {
  270. return (index + 1) % DEFERRED_SET_SIZE;
  271. }
  272. static void __sweep(struct dm_deferred_set *ds, struct list_head *head)
  273. {
  274. while ((ds->sweeper != ds->current_entry) &&
  275. !ds->entries[ds->sweeper].count) {
  276. list_splice_init(&ds->entries[ds->sweeper].work_items, head);
  277. ds->sweeper = ds_next(ds->sweeper);
  278. }
  279. if ((ds->sweeper == ds->current_entry) && !ds->entries[ds->sweeper].count)
  280. list_splice_init(&ds->entries[ds->sweeper].work_items, head);
  281. }
  282. void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head)
  283. {
  284. unsigned long flags;
  285. spin_lock_irqsave(&entry->ds->lock, flags);
  286. BUG_ON(!entry->count);
  287. --entry->count;
  288. __sweep(entry->ds, head);
  289. spin_unlock_irqrestore(&entry->ds->lock, flags);
  290. }
  291. EXPORT_SYMBOL_GPL(dm_deferred_entry_dec);
  292. /*
  293. * Returns 1 if deferred or 0 if no pending items to delay job.
  294. */
  295. int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work)
  296. {
  297. int r = 1;
  298. unsigned long flags;
  299. unsigned next_entry;
  300. spin_lock_irqsave(&ds->lock, flags);
  301. if ((ds->sweeper == ds->current_entry) &&
  302. !ds->entries[ds->current_entry].count)
  303. r = 0;
  304. else {
  305. list_add(work, &ds->entries[ds->current_entry].work_items);
  306. next_entry = ds_next(ds->current_entry);
  307. if (!ds->entries[next_entry].count)
  308. ds->current_entry = next_entry;
  309. }
  310. spin_unlock_irqrestore(&ds->lock, flags);
  311. return r;
  312. }
  313. EXPORT_SYMBOL_GPL(dm_deferred_set_add_work);
  314. /*----------------------------------------------------------------*/
  315. static int __init dm_bio_prison_init(void)
  316. {
  317. _cell_cache = KMEM_CACHE(dm_bio_prison_cell, 0);
  318. if (!_cell_cache)
  319. return -ENOMEM;
  320. return 0;
  321. }
  322. static void __exit dm_bio_prison_exit(void)
  323. {
  324. kmem_cache_destroy(_cell_cache);
  325. _cell_cache = NULL;
  326. }
  327. /*
  328. * module hooks
  329. */
  330. module_init(dm_bio_prison_init);
  331. module_exit(dm_bio_prison_exit);
  332. MODULE_DESCRIPTION(DM_NAME " bio prison");
  333. MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
  334. MODULE_LICENSE("GPL");