xref: /linux-6.15/fs/btrfs/locking.c (revision 196d59ab)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2008 Oracle.  All rights reserved.
4  */
5 
6 #include <linux/sched.h>
7 #include <linux/pagemap.h>
8 #include <linux/spinlock.h>
9 #include <linux/page-flags.h>
10 #include <asm/bug.h>
11 #include "misc.h"
12 #include "ctree.h"
13 #include "extent_io.h"
14 #include "locking.h"
15 
16 /*
17  * Extent buffer locking
18  * =====================
19  *
20  * We use a rw_semaphore for tree locking, and the semantics are exactly the
21  * same:
22  *
23  * - reader/writer exclusion
24  * - writer/writer exclusion
25  * - reader/reader sharing
26  * - try-lock semantics for readers and writers
27  *
28  * Additionally we need one level nesting recursion, see below. The rwsem
29  * implementation does opportunistic spinning which reduces number of times the
30  * locking task needs to sleep.
31  *
32  *
33  * Lock recursion
34  * --------------
35  *
36  * A write operation on a tree might indirectly start a look up on the same
37  * tree.  This can happen when btrfs_cow_block locks the tree and needs to
38  * lookup free extents.
39  *
40  * btrfs_cow_block
41  *   ..
42  *   alloc_tree_block_no_bg_flush
43  *     btrfs_alloc_tree_block
44  *       btrfs_reserve_extent
45  *         ..
46  *         load_free_space_cache
47  *           ..
48  *           btrfs_lookup_file_extent
49  *             btrfs_search_slot
50  *
51  */
52 
53 /*
54  * Mark already held read lock as blocking. Can be nested in write lock by the
55  * same thread.
56  *
57  * Use when there are potentially long operations ahead so other thread waiting
58  * on the lock will not actively spin but sleep instead.
59  *
60  * The rwlock is released and blocking reader counter is increased.
61  */
62 void btrfs_set_lock_blocking_read(struct extent_buffer *eb)
63 {
64 }
65 
66 /*
67  * Mark already held write lock as blocking.
68  *
69  * Use when there are potentially long operations ahead so other threads
70  * waiting on the lock will not actively spin but sleep instead.
71  *
72  * The rwlock is released and blocking writers is set.
73  */
74 void btrfs_set_lock_blocking_write(struct extent_buffer *eb)
75 {
76 }
77 
78 /*
79  * __btrfs_tree_read_lock - lock extent buffer for read
80  * @eb:		the eb to be locked
81  * @nest:	the nesting level to be used for lockdep
82  * @recurse:	if this lock is able to be recursed
83  *
84  * This takes the read lock on the extent buffer, using the specified nesting
85  * level for lockdep purposes.
86  *
87  * If you specify recurse = true, then we will allow this to be taken if we
88  * currently own the lock already.  This should only be used in specific
89  * usecases, and the subsequent unlock will not change the state of the lock.
90  */
91 void __btrfs_tree_read_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest,
92 			    bool recurse)
93 {
94 	u64 start_ns = 0;
95 
96 	if (trace_btrfs_tree_read_lock_enabled())
97 		start_ns = ktime_get_ns();
98 
99 	if (unlikely(recurse)) {
100 		/* First see if we can grab the lock outright */
101 		if (down_read_trylock(&eb->lock))
102 			goto out;
103 
104 		/*
105 		 * Ok still doesn't necessarily mean we are already holding the
106 		 * lock, check the owner.
107 		 */
108 		if (eb->lock_owner != current->pid) {
109 			down_read_nested(&eb->lock, nest);
110 			goto out;
111 		}
112 
113 		/*
114 		 * Ok we have actually recursed, but we should only be recursing
115 		 * once, so blow up if we're already recursed, otherwise set
116 		 * ->lock_recursed and carry on.
117 		 */
118 		BUG_ON(eb->lock_recursed);
119 		eb->lock_recursed = true;
120 		goto out;
121 	}
122 	down_read_nested(&eb->lock, nest);
123 out:
124 	eb->lock_owner = current->pid;
125 	trace_btrfs_tree_read_lock(eb, start_ns);
126 }
127 
128 void btrfs_tree_read_lock(struct extent_buffer *eb)
129 {
130 	__btrfs_tree_read_lock(eb, BTRFS_NESTING_NORMAL, false);
131 }
132 
133 /*
134  * Lock extent buffer for read, optimistically expecting that there are no
135  * contending blocking writers. If there are, don't wait.
136  *
137  * Return 1 if the rwlock has been taken, 0 otherwise
138  */
139 int btrfs_tree_read_lock_atomic(struct extent_buffer *eb)
140 {
141 	return btrfs_try_tree_read_lock(eb);
142 }
143 
144 /*
145  * Try-lock for read.
146  *
147  * Retrun 1 if the rwlock has been taken, 0 otherwise
148  */
149 int btrfs_try_tree_read_lock(struct extent_buffer *eb)
150 {
151 	if (down_read_trylock(&eb->lock)) {
152 		eb->lock_owner = current->pid;
153 		trace_btrfs_try_tree_read_lock(eb);
154 		return 1;
155 	}
156 	return 0;
157 }
158 
159 /*
160  * Try-lock for write.
161  *
162  * Retrun 1 if the rwlock has been taken, 0 otherwise
163  */
164 int btrfs_try_tree_write_lock(struct extent_buffer *eb)
165 {
166 	if (down_write_trylock(&eb->lock)) {
167 		eb->lock_owner = current->pid;
168 		trace_btrfs_try_tree_write_lock(eb);
169 		return 1;
170 	}
171 	return 0;
172 }
173 
174 /*
175  * Release read lock.  If the read lock was recursed then the lock stays in the
176  * original state that it was before it was recursively locked.
177  */
178 void btrfs_tree_read_unlock(struct extent_buffer *eb)
179 {
180 	trace_btrfs_tree_read_unlock(eb);
181 	/*
182 	 * if we're nested, we have the write lock.  No new locking
183 	 * is needed as long as we are the lock owner.
184 	 * The write unlock will do a barrier for us, and the lock_recursed
185 	 * field only matters to the lock owner.
186 	 */
187 	if (eb->lock_recursed && current->pid == eb->lock_owner) {
188 		eb->lock_recursed = false;
189 		return;
190 	}
191 	eb->lock_owner = 0;
192 	up_read(&eb->lock);
193 }
194 
195 /*
196  * Release read lock, previously set to blocking by a pairing call to
197  * btrfs_set_lock_blocking_read(). Can be nested in write lock by the same
198  * thread.
199  *
200  * State of rwlock is unchanged, last reader wakes waiting threads.
201  */
202 void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
203 {
204 	btrfs_tree_read_unlock(eb);
205 }
206 
207 /*
208  * __btrfs_tree_lock - lock eb for write
209  * @eb:		the eb to lock
210  * @nest:	the nesting to use for the lock
211  *
212  * Returns with the eb->lock write locked.
213  */
214 void __btrfs_tree_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest)
215 	__acquires(&eb->lock)
216 {
217 	u64 start_ns = 0;
218 
219 	if (trace_btrfs_tree_lock_enabled())
220 		start_ns = ktime_get_ns();
221 
222 	down_write_nested(&eb->lock, nest);
223 	eb->lock_owner = current->pid;
224 	trace_btrfs_tree_lock(eb, start_ns);
225 }
226 
227 void btrfs_tree_lock(struct extent_buffer *eb)
228 {
229 	__btrfs_tree_lock(eb, BTRFS_NESTING_NORMAL);
230 }
231 
232 /*
233  * Release the write lock.
234  */
235 void btrfs_tree_unlock(struct extent_buffer *eb)
236 {
237 	trace_btrfs_tree_unlock(eb);
238 	eb->lock_owner = 0;
239 	up_write(&eb->lock);
240 }
241 
242 /*
243  * Set all locked nodes in the path to blocking locks.  This should be done
244  * before scheduling
245  */
246 void btrfs_set_path_blocking(struct btrfs_path *p)
247 {
248 	int i;
249 
250 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
251 		if (!p->nodes[i] || !p->locks[i])
252 			continue;
253 		/*
254 		 * If we currently have a spinning reader or writer lock this
255 		 * will bump the count of blocking holders and drop the
256 		 * spinlock.
257 		 */
258 		if (p->locks[i] == BTRFS_READ_LOCK) {
259 			btrfs_set_lock_blocking_read(p->nodes[i]);
260 			p->locks[i] = BTRFS_READ_LOCK_BLOCKING;
261 		} else if (p->locks[i] == BTRFS_WRITE_LOCK) {
262 			btrfs_set_lock_blocking_write(p->nodes[i]);
263 			p->locks[i] = BTRFS_WRITE_LOCK_BLOCKING;
264 		}
265 	}
266 }
267 
268 /*
269  * This releases any locks held in the path starting at level and going all the
270  * way up to the root.
271  *
272  * btrfs_search_slot will keep the lock held on higher nodes in a few corner
273  * cases, such as COW of the block at slot zero in the node.  This ignores
274  * those rules, and it should only be called when there are no more updates to
275  * be done higher up in the tree.
276  */
277 void btrfs_unlock_up_safe(struct btrfs_path *path, int level)
278 {
279 	int i;
280 
281 	if (path->keep_locks)
282 		return;
283 
284 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
285 		if (!path->nodes[i])
286 			continue;
287 		if (!path->locks[i])
288 			continue;
289 		btrfs_tree_unlock_rw(path->nodes[i], path->locks[i]);
290 		path->locks[i] = 0;
291 	}
292 }
293 
294 /*
295  * Loop around taking references on and locking the root node of the tree until
296  * we end up with a lock on the root node.
297  *
298  * Return: root extent buffer with write lock held
299  */
300 struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
301 {
302 	struct extent_buffer *eb;
303 
304 	while (1) {
305 		eb = btrfs_root_node(root);
306 		btrfs_tree_lock(eb);
307 		if (eb == root->node)
308 			break;
309 		btrfs_tree_unlock(eb);
310 		free_extent_buffer(eb);
311 	}
312 	return eb;
313 }
314 
315 /*
316  * Loop around taking references on and locking the root node of the tree until
317  * we end up with a lock on the root node.
318  *
319  * Return: root extent buffer with read lock held
320  */
321 struct extent_buffer *__btrfs_read_lock_root_node(struct btrfs_root *root,
322 						  bool recurse)
323 {
324 	struct extent_buffer *eb;
325 
326 	while (1) {
327 		eb = btrfs_root_node(root);
328 		__btrfs_tree_read_lock(eb, BTRFS_NESTING_NORMAL, recurse);
329 		if (eb == root->node)
330 			break;
331 		btrfs_tree_read_unlock(eb);
332 		free_extent_buffer(eb);
333 	}
334 	return eb;
335 }
336 
337 /*
338  * DREW locks
339  * ==========
340  *
341  * DREW stands for double-reader-writer-exclusion lock. It's used in situation
342  * where you want to provide A-B exclusion but not AA or BB.
343  *
344  * Currently implementation gives more priority to reader. If a reader and a
345  * writer both race to acquire their respective sides of the lock the writer
346  * would yield its lock as soon as it detects a concurrent reader. Additionally
347  * if there are pending readers no new writers would be allowed to come in and
348  * acquire the lock.
349  */
350 
351 int btrfs_drew_lock_init(struct btrfs_drew_lock *lock)
352 {
353 	int ret;
354 
355 	ret = percpu_counter_init(&lock->writers, 0, GFP_KERNEL);
356 	if (ret)
357 		return ret;
358 
359 	atomic_set(&lock->readers, 0);
360 	init_waitqueue_head(&lock->pending_readers);
361 	init_waitqueue_head(&lock->pending_writers);
362 
363 	return 0;
364 }
365 
366 void btrfs_drew_lock_destroy(struct btrfs_drew_lock *lock)
367 {
368 	percpu_counter_destroy(&lock->writers);
369 }
370 
371 /* Return true if acquisition is successful, false otherwise */
372 bool btrfs_drew_try_write_lock(struct btrfs_drew_lock *lock)
373 {
374 	if (atomic_read(&lock->readers))
375 		return false;
376 
377 	percpu_counter_inc(&lock->writers);
378 
379 	/* Ensure writers count is updated before we check for pending readers */
380 	smp_mb();
381 	if (atomic_read(&lock->readers)) {
382 		btrfs_drew_write_unlock(lock);
383 		return false;
384 	}
385 
386 	return true;
387 }
388 
389 void btrfs_drew_write_lock(struct btrfs_drew_lock *lock)
390 {
391 	while (true) {
392 		if (btrfs_drew_try_write_lock(lock))
393 			return;
394 		wait_event(lock->pending_writers, !atomic_read(&lock->readers));
395 	}
396 }
397 
398 void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock)
399 {
400 	percpu_counter_dec(&lock->writers);
401 	cond_wake_up(&lock->pending_readers);
402 }
403 
404 void btrfs_drew_read_lock(struct btrfs_drew_lock *lock)
405 {
406 	atomic_inc(&lock->readers);
407 
408 	/*
409 	 * Ensure the pending reader count is perceieved BEFORE this reader
410 	 * goes to sleep in case of active writers. This guarantees new writers
411 	 * won't be allowed and that the current reader will be woken up when
412 	 * the last active writer finishes its jobs.
413 	 */
414 	smp_mb__after_atomic();
415 
416 	wait_event(lock->pending_readers,
417 		   percpu_counter_sum(&lock->writers) == 0);
418 }
419 
420 void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock)
421 {
422 	/*
423 	 * atomic_dec_and_test implies a full barrier, so woken up writers
424 	 * are guaranteed to see the decrement
425 	 */
426 	if (atomic_dec_and_test(&lock->readers))
427 		wake_up(&lock->pending_writers);
428 }
429