klist.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * klist.c - Routines for manipulating klists.
  3. *
  4. *
  5. * This klist interface provides a couple of structures that wrap around
  6. * struct list_head to provide explicit list "head" (struct klist) and
  7. * list "node" (struct klist_node) objects. For struct klist, a spinlock
  8. * is included that protects access to the actual list itself. struct
  9. * klist_node provides a pointer to the klist that owns it and a kref
  10. * reference count that indicates the number of current users of that node
  11. * in the list.
  12. *
  13. * The entire point is to provide an interface for iterating over a list
  14. * that is safe and allows for modification of the list during the
  15. * iteration (e.g. insertion and removal), including modification of the
  16. * current node on the list.
  17. *
  18. * It works using a 3rd object type - struct klist_iter - that is declared
  19. * and initialized before an iteration. klist_next() is used to acquire the
  20. * next element in the list. It returns NULL if there are no more items.
  21. * Internally, that routine takes the klist's lock, decrements the reference
  22. * count of the previous klist_node and increments the count of the next
  23. * klist_node. It then drops the lock and returns.
  24. *
  25. * There are primitives for adding and removing nodes to/from a klist.
  26. * When deleting, klist_del() will simply decrement the reference count.
  27. * Only when the count goes to 0 is the node removed from the list.
  28. * klist_remove() will try to delete the node from the list and block
  29. * until it is actually removed. This is useful for objects (like devices)
  30. * that have been removed from the system and must be freed (but must wait
  31. * until all accessors have finished).
  32. *
  33. * Copyright (C) 2005 Patrick Mochel
  34. *
  35. * This file is released under the GPL v2.
  36. */
  37. #include <linux/klist.h>
  38. #include <linux/module.h>
  39. /**
  40. * klist_init - Initialize a klist structure.
  41. * @k: The klist we're initializing.
  42. */
  43. void klist_init(struct klist * k)
  44. {
  45. INIT_LIST_HEAD(&k->k_list);
  46. spin_lock_init(&k->k_lock);
  47. }
  48. EXPORT_SYMBOL_GPL(klist_init);
  49. static void add_head(struct klist * k, struct klist_node * n)
  50. {
  51. spin_lock(&k->k_lock);
  52. list_add(&n->n_node, &k->k_list);
  53. spin_unlock(&k->k_lock);
  54. }
  55. static void add_tail(struct klist * k, struct klist_node * n)
  56. {
  57. spin_lock(&k->k_lock);
  58. list_add_tail(&n->n_node, &k->k_list);
  59. spin_unlock(&k->k_lock);
  60. }
  61. static void klist_node_init(struct klist * k, struct klist_node * n)
  62. {
  63. INIT_LIST_HEAD(&n->n_node);
  64. init_completion(&n->n_removed);
  65. kref_init(&n->n_ref);
  66. n->n_klist = k;
  67. }
  68. /**
  69. * klist_add_head - Initialize a klist_node and add it to front.
  70. * @k: klist it's going on.
  71. * @n: node we're adding.
  72. */
  73. void klist_add_head(struct klist * k, struct klist_node * n)
  74. {
  75. klist_node_init(k, n);
  76. add_head(k, n);
  77. }
  78. EXPORT_SYMBOL_GPL(klist_add_head);
  79. /**
  80. * klist_add_tail - Initialize a klist_node and add it to back.
  81. * @k: klist it's going on.
  82. * @n: node we're adding.
  83. */
  84. void klist_add_tail(struct klist * k, struct klist_node * n)
  85. {
  86. klist_node_init(k, n);
  87. add_tail(k, n);
  88. }
  89. EXPORT_SYMBOL_GPL(klist_add_tail);
  90. static void klist_release(struct kref * kref)
  91. {
  92. struct klist_node * n = container_of(kref, struct klist_node, n_ref);
  93. list_del(&n->n_node);
  94. complete(&n->n_removed);
  95. }
  96. static int klist_dec_and_del(struct klist_node * n)
  97. {
  98. return kref_put(&n->n_ref, klist_release);
  99. }
  100. /**
  101. * klist_del - Decrement the reference count of node and try to remove.
  102. * @n: node we're deleting.
  103. */
  104. void klist_del(struct klist_node * n)
  105. {
  106. struct klist * k = n->n_klist;
  107. spin_lock(&k->k_lock);
  108. klist_dec_and_del(n);
  109. spin_unlock(&k->k_lock);
  110. }
  111. EXPORT_SYMBOL_GPL(klist_del);
  112. /**
  113. * klist_remove - Decrement the refcount of node and wait for it to go away.
  114. * @n: node we're removing.
  115. */
  116. void klist_remove(struct klist_node * n)
  117. {
  118. spin_lock(&n->n_klist->k_lock);
  119. klist_dec_and_del(n);
  120. spin_unlock(&n->n_klist->k_lock);
  121. wait_for_completion(&n->n_removed);
  122. }
  123. EXPORT_SYMBOL_GPL(klist_remove);
  124. /**
  125. * klist_iter_init_node - Initialize a klist_iter structure.
  126. * @k: klist we're iterating.
  127. * @i: klist_iter we're filling.
  128. * @n: node to start with.
  129. *
  130. * Similar to klist_iter_init(), but starts the action off with @n,
  131. * instead of with the list head.
  132. */
  133. void klist_iter_init_node(struct klist * k, struct klist_iter * i, struct klist_node * n)
  134. {
  135. i->i_klist = k;
  136. i->i_head = &k->k_list;
  137. i->i_cur = n;
  138. }
  139. EXPORT_SYMBOL_GPL(klist_iter_init_node);
  140. /**
  141. * klist_iter_init - Iniitalize a klist_iter structure.
  142. * @k: klist we're iterating.
  143. * @i: klist_iter structure we're filling.
  144. *
  145. * Similar to klist_iter_init_node(), but start with the list head.
  146. */
  147. void klist_iter_init(struct klist * k, struct klist_iter * i)
  148. {
  149. klist_iter_init_node(k, i, NULL);
  150. }
  151. EXPORT_SYMBOL_GPL(klist_iter_init);
  152. /**
  153. * klist_iter_exit - Finish a list iteration.
  154. * @i: Iterator structure.
  155. *
  156. * Must be called when done iterating over list, as it decrements the
  157. * refcount of the current node. Necessary in case iteration exited before
  158. * the end of the list was reached, and always good form.
  159. */
  160. void klist_iter_exit(struct klist_iter * i)
  161. {
  162. if (i->i_cur) {
  163. klist_del(i->i_cur);
  164. i->i_cur = NULL;
  165. }
  166. }
  167. EXPORT_SYMBOL_GPL(klist_iter_exit);
  168. static struct klist_node * to_klist_node(struct list_head * n)
  169. {
  170. return container_of(n, struct klist_node, n_node);
  171. }
  172. /**
  173. * klist_next - Ante up next node in list.
  174. * @i: Iterator structure.
  175. *
  176. * First grab list lock. Decrement the reference count of the previous
  177. * node, if there was one. Grab the next node, increment its reference
  178. * count, drop the lock, and return that next node.
  179. */
  180. struct klist_node * klist_next(struct klist_iter * i)
  181. {
  182. struct list_head * next;
  183. struct klist_node * knode = NULL;
  184. spin_lock(&i->i_klist->k_lock);
  185. if (i->i_cur) {
  186. next = i->i_cur->n_node.next;
  187. klist_dec_and_del(i->i_cur);
  188. } else
  189. next = i->i_head->next;
  190. if (next != i->i_head) {
  191. knode = to_klist_node(next);
  192. kref_get(&knode->n_ref);
  193. }
  194. i->i_cur = knode;
  195. spin_unlock(&i->i_klist->k_lock);
  196. return knode;
  197. }
  198. EXPORT_SYMBOL_GPL(klist_next);