locking.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2008 Oracle. All rights reserved.
  4. */
  5. #include <linux/sched.h>
  6. #include <linux/pagemap.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/page-flags.h>
  9. #include <asm/bug.h>
  10. #include "misc.h"
  11. #include "ctree.h"
  12. #include "extent_io.h"
  13. #include "locking.h"
  14. #ifdef CONFIG_BTRFS_DEBUG
  15. static void btrfs_assert_spinning_writers_get(struct extent_buffer *eb)
  16. {
  17. WARN_ON(eb->spinning_writers);
  18. eb->spinning_writers++;
  19. }
  20. static void btrfs_assert_spinning_writers_put(struct extent_buffer *eb)
  21. {
  22. WARN_ON(eb->spinning_writers != 1);
  23. eb->spinning_writers--;
  24. }
  25. static void btrfs_assert_no_spinning_writers(struct extent_buffer *eb)
  26. {
  27. WARN_ON(eb->spinning_writers);
  28. }
  29. static void btrfs_assert_spinning_readers_get(struct extent_buffer *eb)
  30. {
  31. atomic_inc(&eb->spinning_readers);
  32. }
  33. static void btrfs_assert_spinning_readers_put(struct extent_buffer *eb)
  34. {
  35. WARN_ON(atomic_read(&eb->spinning_readers) == 0);
  36. atomic_dec(&eb->spinning_readers);
  37. }
  38. static void btrfs_assert_tree_read_locks_get(struct extent_buffer *eb)
  39. {
  40. atomic_inc(&eb->read_locks);
  41. }
  42. static void btrfs_assert_tree_read_locks_put(struct extent_buffer *eb)
  43. {
  44. atomic_dec(&eb->read_locks);
  45. }
  46. static void btrfs_assert_tree_read_locked(struct extent_buffer *eb)
  47. {
  48. BUG_ON(!atomic_read(&eb->read_locks));
  49. }
  50. static void btrfs_assert_tree_write_locks_get(struct extent_buffer *eb)
  51. {
  52. eb->write_locks++;
  53. }
  54. static void btrfs_assert_tree_write_locks_put(struct extent_buffer *eb)
  55. {
  56. eb->write_locks--;
  57. }
  58. void btrfs_assert_tree_locked(struct extent_buffer *eb)
  59. {
  60. BUG_ON(!eb->write_locks);
  61. }
  62. #else
  63. static void btrfs_assert_spinning_writers_get(struct extent_buffer *eb) { }
  64. static void btrfs_assert_spinning_writers_put(struct extent_buffer *eb) { }
  65. static void btrfs_assert_no_spinning_writers(struct extent_buffer *eb) { }
  66. static void btrfs_assert_spinning_readers_put(struct extent_buffer *eb) { }
  67. static void btrfs_assert_spinning_readers_get(struct extent_buffer *eb) { }
  68. static void btrfs_assert_tree_read_locked(struct extent_buffer *eb) { }
  69. static void btrfs_assert_tree_read_locks_get(struct extent_buffer *eb) { }
  70. static void btrfs_assert_tree_read_locks_put(struct extent_buffer *eb) { }
  71. void btrfs_assert_tree_locked(struct extent_buffer *eb) { }
  72. static void btrfs_assert_tree_write_locks_get(struct extent_buffer *eb) { }
  73. static void btrfs_assert_tree_write_locks_put(struct extent_buffer *eb) { }
  74. #endif
  75. void btrfs_set_lock_blocking_read(struct extent_buffer *eb)
  76. {
  77. trace_btrfs_set_lock_blocking_read(eb);
  78. /*
  79. * No lock is required. The lock owner may change if we have a read
  80. * lock, but it won't change to or away from us. If we have the write
  81. * lock, we are the owner and it'll never change.
  82. */
  83. if (eb->lock_nested && current->pid == eb->lock_owner)
  84. return;
  85. btrfs_assert_tree_read_locked(eb);
  86. atomic_inc(&eb->blocking_readers);
  87. btrfs_assert_spinning_readers_put(eb);
  88. read_unlock(&eb->lock);
  89. }
  90. void btrfs_set_lock_blocking_write(struct extent_buffer *eb)
  91. {
  92. trace_btrfs_set_lock_blocking_write(eb);
  93. /*
  94. * No lock is required. The lock owner may change if we have a read
  95. * lock, but it won't change to or away from us. If we have the write
  96. * lock, we are the owner and it'll never change.
  97. */
  98. if (eb->lock_nested && current->pid == eb->lock_owner)
  99. return;
  100. if (eb->blocking_writers == 0) {
  101. btrfs_assert_spinning_writers_put(eb);
  102. btrfs_assert_tree_locked(eb);
  103. eb->blocking_writers++;
  104. write_unlock(&eb->lock);
  105. }
  106. }
  107. /*
  108. * take a spinning read lock. This will wait for any blocking
  109. * writers
  110. */
  111. void btrfs_tree_read_lock(struct extent_buffer *eb)
  112. {
  113. u64 start_ns = 0;
  114. if (trace_btrfs_tree_read_lock_enabled())
  115. start_ns = ktime_get_ns();
  116. again:
  117. read_lock(&eb->lock);
  118. BUG_ON(eb->blocking_writers == 0 &&
  119. current->pid == eb->lock_owner);
  120. if (eb->blocking_writers && current->pid == eb->lock_owner) {
  121. /*
  122. * This extent is already write-locked by our thread. We allow
  123. * an additional read lock to be added because it's for the same
  124. * thread. btrfs_find_all_roots() depends on this as it may be
  125. * called on a partly (write-)locked tree.
  126. */
  127. BUG_ON(eb->lock_nested);
  128. eb->lock_nested = true;
  129. read_unlock(&eb->lock);
  130. trace_btrfs_tree_read_lock(eb, start_ns);
  131. return;
  132. }
  133. if (eb->blocking_writers) {
  134. read_unlock(&eb->lock);
  135. wait_event(eb->write_lock_wq,
  136. eb->blocking_writers == 0);
  137. goto again;
  138. }
  139. btrfs_assert_tree_read_locks_get(eb);
  140. btrfs_assert_spinning_readers_get(eb);
  141. trace_btrfs_tree_read_lock(eb, start_ns);
  142. }
  143. /*
  144. * take a spinning read lock.
  145. * returns 1 if we get the read lock and 0 if we don't
  146. * this won't wait for blocking writers
  147. */
  148. int btrfs_tree_read_lock_atomic(struct extent_buffer *eb)
  149. {
  150. if (eb->blocking_writers)
  151. return 0;
  152. read_lock(&eb->lock);
  153. if (eb->blocking_writers) {
  154. read_unlock(&eb->lock);
  155. return 0;
  156. }
  157. btrfs_assert_tree_read_locks_get(eb);
  158. btrfs_assert_spinning_readers_get(eb);
  159. trace_btrfs_tree_read_lock_atomic(eb);
  160. return 1;
  161. }
  162. /*
  163. * returns 1 if we get the read lock and 0 if we don't
  164. * this won't wait for blocking writers
  165. */
  166. int btrfs_try_tree_read_lock(struct extent_buffer *eb)
  167. {
  168. if (eb->blocking_writers)
  169. return 0;
  170. if (!read_trylock(&eb->lock))
  171. return 0;
  172. if (eb->blocking_writers) {
  173. read_unlock(&eb->lock);
  174. return 0;
  175. }
  176. btrfs_assert_tree_read_locks_get(eb);
  177. btrfs_assert_spinning_readers_get(eb);
  178. trace_btrfs_try_tree_read_lock(eb);
  179. return 1;
  180. }
  181. /*
  182. * returns 1 if we get the read lock and 0 if we don't
  183. * this won't wait for blocking writers or readers
  184. */
  185. int btrfs_try_tree_write_lock(struct extent_buffer *eb)
  186. {
  187. if (eb->blocking_writers || atomic_read(&eb->blocking_readers))
  188. return 0;
  189. write_lock(&eb->lock);
  190. if (eb->blocking_writers || atomic_read(&eb->blocking_readers)) {
  191. write_unlock(&eb->lock);
  192. return 0;
  193. }
  194. btrfs_assert_tree_write_locks_get(eb);
  195. btrfs_assert_spinning_writers_get(eb);
  196. eb->lock_owner = current->pid;
  197. trace_btrfs_try_tree_write_lock(eb);
  198. return 1;
  199. }
  200. /*
  201. * drop a spinning read lock
  202. */
  203. void btrfs_tree_read_unlock(struct extent_buffer *eb)
  204. {
  205. trace_btrfs_tree_read_unlock(eb);
  206. /*
  207. * if we're nested, we have the write lock. No new locking
  208. * is needed as long as we are the lock owner.
  209. * The write unlock will do a barrier for us, and the lock_nested
  210. * field only matters to the lock owner.
  211. */
  212. if (eb->lock_nested && current->pid == eb->lock_owner) {
  213. eb->lock_nested = false;
  214. return;
  215. }
  216. btrfs_assert_tree_read_locked(eb);
  217. btrfs_assert_spinning_readers_put(eb);
  218. btrfs_assert_tree_read_locks_put(eb);
  219. read_unlock(&eb->lock);
  220. }
  221. /*
  222. * drop a blocking read lock
  223. */
  224. void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
  225. {
  226. trace_btrfs_tree_read_unlock_blocking(eb);
  227. /*
  228. * if we're nested, we have the write lock. No new locking
  229. * is needed as long as we are the lock owner.
  230. * The write unlock will do a barrier for us, and the lock_nested
  231. * field only matters to the lock owner.
  232. */
  233. if (eb->lock_nested && current->pid == eb->lock_owner) {
  234. eb->lock_nested = false;
  235. return;
  236. }
  237. btrfs_assert_tree_read_locked(eb);
  238. WARN_ON(atomic_read(&eb->blocking_readers) == 0);
  239. /* atomic_dec_and_test implies a barrier */
  240. if (atomic_dec_and_test(&eb->blocking_readers))
  241. cond_wake_up_nomb(&eb->read_lock_wq);
  242. btrfs_assert_tree_read_locks_put(eb);
  243. }
  244. /*
  245. * take a spinning write lock. This will wait for both
  246. * blocking readers or writers
  247. */
  248. void btrfs_tree_lock(struct extent_buffer *eb)
  249. {
  250. u64 start_ns = 0;
  251. if (trace_btrfs_tree_lock_enabled())
  252. start_ns = ktime_get_ns();
  253. WARN_ON(eb->lock_owner == current->pid);
  254. again:
  255. wait_event(eb->read_lock_wq, atomic_read(&eb->blocking_readers) == 0);
  256. wait_event(eb->write_lock_wq, eb->blocking_writers == 0);
  257. write_lock(&eb->lock);
  258. if (atomic_read(&eb->blocking_readers) || eb->blocking_writers) {
  259. write_unlock(&eb->lock);
  260. goto again;
  261. }
  262. btrfs_assert_spinning_writers_get(eb);
  263. btrfs_assert_tree_write_locks_get(eb);
  264. eb->lock_owner = current->pid;
  265. trace_btrfs_tree_lock(eb, start_ns);
  266. }
  267. /*
  268. * drop a spinning or a blocking write lock.
  269. */
  270. void btrfs_tree_unlock(struct extent_buffer *eb)
  271. {
  272. int blockers = eb->blocking_writers;
  273. BUG_ON(blockers > 1);
  274. btrfs_assert_tree_locked(eb);
  275. trace_btrfs_tree_unlock(eb);
  276. eb->lock_owner = 0;
  277. btrfs_assert_tree_write_locks_put(eb);
  278. if (blockers) {
  279. btrfs_assert_no_spinning_writers(eb);
  280. eb->blocking_writers--;
  281. /*
  282. * We need to order modifying blocking_writers above with
  283. * actually waking up the sleepers to ensure they see the
  284. * updated value of blocking_writers
  285. */
  286. cond_wake_up(&eb->write_lock_wq);
  287. } else {
  288. btrfs_assert_spinning_writers_put(eb);
  289. write_unlock(&eb->lock);
  290. }
  291. }