stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Josef Bacik <josef@toxicpanda.com>,
	David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.10 116/138] btrfs: switch extent buffer tree lock to rw_semaphore
Date: Mon,  6 Jan 2025 16:17:20 +0100	[thread overview]
Message-ID: <20250106151137.620921688@linuxfoundation.org> (raw)
In-Reply-To: <20250106151133.209718681@linuxfoundation.org>

5.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Josef Bacik <josef@toxicpanda.com>

[ Upstream commit 196d59ab9ccc975d8d29292845d227cdf4423ef8 ]

Historically we've implemented our own locking because we wanted to be
able to selectively spin or sleep based on what we were doing in the
tree.  For instance, if all of our nodes were in cache then there's
rarely a reason to need to sleep waiting for node locks, as they'll
likely become available soon.  At the time this code was written the
rw_semaphore didn't do adaptive spinning, and thus was orders of
magnitude slower than our home grown locking.

However now the opposite is the case.  There are a few problems with how
we implement blocking locks, namely that we use a normal waitqueue and
simply wake everybody up in reverse sleep order.  This leads to some
suboptimal performance behavior, and a lot of context switches in highly
contended cases.  The rw_semaphores actually do this properly, and also
have adaptive spinning that works relatively well.

The locking code is also a bit of a bear to understand, and we lose the
benefit of lockdep for the most part because the blocking states of the
lock are simply ad-hoc and not mapped into lockdep.

So rework the locking code to drop all of this custom locking stuff, and
simply use a rw_semaphore for everything.  This makes the locking much
simpler for everything, as we can now drop a lot of cruft and blocking
transitions.  The performance numbers vary depending on the workload,
because generally speaking there doesn't tend to be a lot of contention
on the btree.  However, on my test system which is an 80 core single
socket system with 256GiB of RAM and a 2TiB NVMe drive I get the
following results (with all debug options off):

  dbench 200 baseline
  Throughput 216.056 MB/sec  200 clients  200 procs  max_latency=1471.197 ms

  dbench 200 with patch
  Throughput 737.188 MB/sec  200 clients  200 procs  max_latency=714.346 ms

Previously we also used fs_mark to test this sort of contention, and
those results are far less impressive, mostly because there's not enough
tasks to really stress the locking

  fs_mark -d /d[0-15] -S 0 -L 20 -n 100000 -s 0 -t 16

  baseline
    Average Files/sec:     160166.7
    p50 Files/sec:         165832
    p90 Files/sec:         123886
    p99 Files/sec:         123495

    real    3m26.527s
    user    2m19.223s
    sys     48m21.856s

  patched
    Average Files/sec:     164135.7
    p50 Files/sec:         171095
    p90 Files/sec:         122889
    p99 Files/sec:         113819

    real    3m29.660s
    user    2m19.990s
    sys     44m12.259s

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 44f52bbe96df ("btrfs: fix use-after-free when COWing tree bock and tracing is enabled")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/btrfs/extent_io.c  |  13 +-
 fs/btrfs/extent_io.h  |  21 +--
 fs/btrfs/locking.c    | 374 ++++++++----------------------------------
 fs/btrfs/locking.h    |   2 +-
 fs/btrfs/print-tree.c |  11 +-
 5 files changed, 70 insertions(+), 351 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 685a375bb6af..9cef930c4ecf 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4960,12 +4960,8 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
 	eb->len = len;
 	eb->fs_info = fs_info;
 	eb->bflags = 0;
-	rwlock_init(&eb->lock);
-	atomic_set(&eb->blocking_readers, 0);
-	eb->blocking_writers = 0;
+	init_rwsem(&eb->lock);
 	eb->lock_recursed = false;
-	init_waitqueue_head(&eb->write_lock_wq);
-	init_waitqueue_head(&eb->read_lock_wq);
 
 	btrfs_leak_debug_add(&fs_info->eb_leak_lock, &eb->leak_list,
 			     &fs_info->allocated_ebs);
@@ -4981,13 +4977,6 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
 		> MAX_INLINE_EXTENT_BUFFER_SIZE);
 	BUG_ON(len > MAX_INLINE_EXTENT_BUFFER_SIZE);
 
-#ifdef CONFIG_BTRFS_DEBUG
-	eb->spinning_writers = 0;
-	atomic_set(&eb->spinning_readers, 0);
-	atomic_set(&eb->read_locks, 0);
-	eb->write_locks = 0;
-#endif
-
 	return eb;
 }
 
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 16f44bc481ab..e8ab48e5f282 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -87,31 +87,14 @@ struct extent_buffer {
 	int read_mirror;
 	struct rcu_head rcu_head;
 	pid_t lock_owner;
-
-	int blocking_writers;
-	atomic_t blocking_readers;
 	bool lock_recursed;
+	struct rw_semaphore lock;
+
 	/* >= 0 if eb belongs to a log tree, -1 otherwise */
 	short log_index;
 
-	/* protects write locks */
-	rwlock_t lock;
-
-	/* readers use lock_wq while they wait for the write
-	 * lock holders to unlock
-	 */
-	wait_queue_head_t write_lock_wq;
-
-	/* writers use read_lock_wq while they wait for readers
-	 * to unlock
-	 */
-	wait_queue_head_t read_lock_wq;
 	struct page *pages[INLINE_EXTENT_BUFFER_PAGES];
 #ifdef CONFIG_BTRFS_DEBUG
-	int spinning_writers;
-	atomic_t spinning_readers;
-	atomic_t read_locks;
-	int write_locks;
 	struct list_head leak_list;
 #endif
 };
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 66e02ebdd340..60e0f00b9b8f 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -17,44 +17,17 @@
  * Extent buffer locking
  * =====================
  *
- * The locks use a custom scheme that allows to do more operations than are
- * available fromt current locking primitives. The building blocks are still
- * rwlock and wait queues.
- *
- * Required semantics:
+ * We use a rw_semaphore for tree locking, and the semantics are exactly the
+ * same:
  *
  * - reader/writer exclusion
  * - writer/writer exclusion
  * - reader/reader sharing
- * - spinning lock semantics
- * - blocking lock semantics
  * - try-lock semantics for readers and writers
- * - one level nesting, allowing read lock to be taken by the same thread that
- *   already has write lock
- *
- * The extent buffer locks (also called tree locks) manage access to eb data
- * related to the storage in the b-tree (keys, items, but not the individual
- * members of eb).
- * We want concurrency of many readers and safe updates. The underlying locking
- * is done by read-write spinlock and the blocking part is implemented using
- * counters and wait queues.
- *
- * spinning semantics - the low-level rwlock is held so all other threads that
- *                      want to take it are spinning on it.
- *
- * blocking semantics - the low-level rwlock is not held but the counter
- *                      denotes how many times the blocking lock was held;
- *                      sleeping is possible
- *
- * Write lock always allows only one thread to access the data.
- *
  *
- * Debugging
- * ---------
- *
- * There are additional state counters that are asserted in various contexts,
- * removed from non-debug build to reduce extent_buffer size and for
- * performance reasons.
+ * Additionally we need one level nesting recursion, see below. The rwsem
+ * implementation does opportunistic spinning which reduces number of times the
+ * locking task needs to sleep.
  *
  *
  * Lock recursion
@@ -75,115 +48,8 @@
  *           btrfs_lookup_file_extent
  *             btrfs_search_slot
  *
- *
- * Locking pattern - spinning
- * --------------------------
- *
- * The simple locking scenario, the +--+ denotes the spinning section.
- *
- * +- btrfs_tree_lock
- * | - extent_buffer::rwlock is held
- * | - no heavy operations should happen, eg. IO, memory allocations, large
- * |   structure traversals
- * +- btrfs_tree_unock
-*
-*
- * Locking pattern - blocking
- * --------------------------
- *
- * The blocking write uses the following scheme.  The +--+ denotes the spinning
- * section.
- *
- * +- btrfs_tree_lock
- * |
- * +- btrfs_set_lock_blocking_write
- *
- *   - allowed: IO, memory allocations, etc.
- *
- * -- btrfs_tree_unlock - note, no explicit unblocking necessary
- *
- *
- * Blocking read is similar.
- *
- * +- btrfs_tree_read_lock
- * |
- * +- btrfs_set_lock_blocking_read
- *
- *  - heavy operations allowed
- *
- * +- btrfs_tree_read_unlock_blocking
- * |
- * +- btrfs_tree_read_unlock
- *
  */
 
-#ifdef CONFIG_BTRFS_DEBUG
-static inline void btrfs_assert_spinning_writers_get(struct extent_buffer *eb)
-{
-	WARN_ON(eb->spinning_writers);
-	eb->spinning_writers++;
-}
-
-static inline void btrfs_assert_spinning_writers_put(struct extent_buffer *eb)
-{
-	WARN_ON(eb->spinning_writers != 1);
-	eb->spinning_writers--;
-}
-
-static inline void btrfs_assert_no_spinning_writers(struct extent_buffer *eb)
-{
-	WARN_ON(eb->spinning_writers);
-}
-
-static inline void btrfs_assert_spinning_readers_get(struct extent_buffer *eb)
-{
-	atomic_inc(&eb->spinning_readers);
-}
-
-static inline void btrfs_assert_spinning_readers_put(struct extent_buffer *eb)
-{
-	WARN_ON(atomic_read(&eb->spinning_readers) == 0);
-	atomic_dec(&eb->spinning_readers);
-}
-
-static inline void btrfs_assert_tree_read_locks_get(struct extent_buffer *eb)
-{
-	atomic_inc(&eb->read_locks);
-}
-
-static inline void btrfs_assert_tree_read_locks_put(struct extent_buffer *eb)
-{
-	atomic_dec(&eb->read_locks);
-}
-
-static inline void btrfs_assert_tree_read_locked(struct extent_buffer *eb)
-{
-	BUG_ON(!atomic_read(&eb->read_locks));
-}
-
-static inline void btrfs_assert_tree_write_locks_get(struct extent_buffer *eb)
-{
-	eb->write_locks++;
-}
-
-static inline void btrfs_assert_tree_write_locks_put(struct extent_buffer *eb)
-{
-	eb->write_locks--;
-}
-
-#else
-static void btrfs_assert_spinning_writers_get(struct extent_buffer *eb) { }
-static void btrfs_assert_spinning_writers_put(struct extent_buffer *eb) { }
-static void btrfs_assert_no_spinning_writers(struct extent_buffer *eb) { }
-static void btrfs_assert_spinning_readers_put(struct extent_buffer *eb) { }
-static void btrfs_assert_spinning_readers_get(struct extent_buffer *eb) { }
-static void btrfs_assert_tree_read_locked(struct extent_buffer *eb) { }
-static void btrfs_assert_tree_read_locks_get(struct extent_buffer *eb) { }
-static void btrfs_assert_tree_read_locks_put(struct extent_buffer *eb) { }
-static void btrfs_assert_tree_write_locks_get(struct extent_buffer *eb) { }
-static void btrfs_assert_tree_write_locks_put(struct extent_buffer *eb) { }
-#endif
-
 /*
  * Mark already held read lock as blocking. Can be nested in write lock by the
  * same thread.
@@ -195,18 +61,6 @@ static void btrfs_assert_tree_write_locks_put(struct extent_buffer *eb) { }
  */
 void btrfs_set_lock_blocking_read(struct extent_buffer *eb)
 {
-	trace_btrfs_set_lock_blocking_read(eb);
-	/*
-	 * No lock is required.  The lock owner may change if we have a read
-	 * lock, but it won't change to or away from us.  If we have the write
-	 * lock, we are the owner and it'll never change.
-	 */
-	if (eb->lock_recursed && current->pid == eb->lock_owner)
-		return;
-	btrfs_assert_tree_read_locked(eb);
-	atomic_inc(&eb->blocking_readers);
-	btrfs_assert_spinning_readers_put(eb);
-	read_unlock(&eb->lock);
 }
 
 /*
@@ -219,30 +73,20 @@ void btrfs_set_lock_blocking_read(struct extent_buffer *eb)
  */
 void btrfs_set_lock_blocking_write(struct extent_buffer *eb)
 {
-	trace_btrfs_set_lock_blocking_write(eb);
-	/*
-	 * No lock is required.  The lock owner may change if we have a read
-	 * lock, but it won't change to or away from us.  If we have the write
-	 * lock, we are the owner and it'll never change.
-	 */
-	if (eb->lock_recursed && current->pid == eb->lock_owner)
-		return;
-	if (eb->blocking_writers == 0) {
-		btrfs_assert_spinning_writers_put(eb);
-		btrfs_assert_tree_locked(eb);
-		WRITE_ONCE(eb->blocking_writers, 1);
-		write_unlock(&eb->lock);
-	}
 }
 
 /*
- * Lock the extent buffer for read. Wait for any writers (spinning or blocking).
- * Can be nested in write lock by the same thread.
+ * __btrfs_tree_read_lock - lock extent buffer for read
+ * @eb:		the eb to be locked
+ * @nest:	the nesting level to be used for lockdep
+ * @recurse:	if this lock is able to be recursed
  *
- * Use when the locked section does only lightweight actions and busy waiting
- * would be cheaper than making other threads do the wait/wake loop.
+ * This takes the read lock on the extent buffer, using the specified nesting
+ * level for lockdep purposes.
  *
- * The rwlock is held upon exit.
+ * If you specify recurse = true, then we will allow this to be taken if we
+ * currently own the lock already.  This should only be used in specific
+ * usecases, and the subsequent unlock will not change the state of the lock.
  */
 void __btrfs_tree_read_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest,
 			    bool recurse)
@@ -251,33 +95,33 @@ void __btrfs_tree_read_lock(struct extent_buffer *eb, enum btrfs_lock_nesting ne
 
 	if (trace_btrfs_tree_read_lock_enabled())
 		start_ns = ktime_get_ns();
-again:
-	read_lock(&eb->lock);
-	BUG_ON(eb->blocking_writers == 0 &&
-	       current->pid == eb->lock_owner);
-	if (eb->blocking_writers) {
-		if (current->pid == eb->lock_owner) {
-			/*
-			 * This extent is already write-locked by our thread.
-			 * We allow an additional read lock to be added because
-			 * it's for the same thread. btrfs_find_all_roots()
-			 * depends on this as it may be called on a partly
-			 * (write-)locked tree.
-			 */
-			WARN_ON(!recurse);
-			BUG_ON(eb->lock_recursed);
-			eb->lock_recursed = true;
-			read_unlock(&eb->lock);
-			trace_btrfs_tree_read_lock(eb, start_ns);
-			return;
+
+	if (unlikely(recurse)) {
+		/* First see if we can grab the lock outright */
+		if (down_read_trylock(&eb->lock))
+			goto out;
+
+		/*
+		 * Ok still doesn't necessarily mean we are already holding the
+		 * lock, check the owner.
+		 */
+		if (eb->lock_owner != current->pid) {
+			down_read_nested(&eb->lock, nest);
+			goto out;
 		}
-		read_unlock(&eb->lock);
-		wait_event(eb->write_lock_wq,
-			   READ_ONCE(eb->blocking_writers) == 0);
-		goto again;
+
+		/*
+		 * Ok we have actually recursed, but we should only be recursing
+		 * once, so blow up if we're already recursed, otherwise set
+		 * ->lock_recursed and carry on.
+		 */
+		BUG_ON(eb->lock_recursed);
+		eb->lock_recursed = true;
+		goto out;
 	}
-	btrfs_assert_tree_read_locks_get(eb);
-	btrfs_assert_spinning_readers_get(eb);
+	down_read_nested(&eb->lock, nest);
+out:
+	eb->lock_owner = current->pid;
 	trace_btrfs_tree_read_lock(eb, start_ns);
 }
 
@@ -294,74 +138,42 @@ void btrfs_tree_read_lock(struct extent_buffer *eb)
  */
 int btrfs_tree_read_lock_atomic(struct extent_buffer *eb)
 {
-	if (READ_ONCE(eb->blocking_writers))
-		return 0;
-
-	read_lock(&eb->lock);
-	/* Refetch value after lock */
-	if (READ_ONCE(eb->blocking_writers)) {
-		read_unlock(&eb->lock);
-		return 0;
-	}
-	btrfs_assert_tree_read_locks_get(eb);
-	btrfs_assert_spinning_readers_get(eb);
-	trace_btrfs_tree_read_lock_atomic(eb);
-	return 1;
+	return btrfs_try_tree_read_lock(eb);
 }
 
 /*
- * Try-lock for read. Don't block or wait for contending writers.
+ * Try-lock for read.
  *
  * Retrun 1 if the rwlock has been taken, 0 otherwise
  */
 int btrfs_try_tree_read_lock(struct extent_buffer *eb)
 {
-	if (READ_ONCE(eb->blocking_writers))
-		return 0;
-
-	if (!read_trylock(&eb->lock))
-		return 0;
-
-	/* Refetch value after lock */
-	if (READ_ONCE(eb->blocking_writers)) {
-		read_unlock(&eb->lock);
-		return 0;
+	if (down_read_trylock(&eb->lock)) {
+		eb->lock_owner = current->pid;
+		trace_btrfs_try_tree_read_lock(eb);
+		return 1;
 	}
-	btrfs_assert_tree_read_locks_get(eb);
-	btrfs_assert_spinning_readers_get(eb);
-	trace_btrfs_try_tree_read_lock(eb);
-	return 1;
+	return 0;
 }
 
 /*
- * Try-lock for write. May block until the lock is uncontended, but does not
- * wait until it is free.
+ * Try-lock for write.
  *
  * Retrun 1 if the rwlock has been taken, 0 otherwise
  */
 int btrfs_try_tree_write_lock(struct extent_buffer *eb)
 {
-	if (READ_ONCE(eb->blocking_writers) || atomic_read(&eb->blocking_readers))
-		return 0;
-
-	write_lock(&eb->lock);
-	/* Refetch value after lock */
-	if (READ_ONCE(eb->blocking_writers) || atomic_read(&eb->blocking_readers)) {
-		write_unlock(&eb->lock);
-		return 0;
+	if (down_write_trylock(&eb->lock)) {
+		eb->lock_owner = current->pid;
+		trace_btrfs_try_tree_write_lock(eb);
+		return 1;
 	}
-	btrfs_assert_tree_write_locks_get(eb);
-	btrfs_assert_spinning_writers_get(eb);
-	eb->lock_owner = current->pid;
-	trace_btrfs_try_tree_write_lock(eb);
-	return 1;
+	return 0;
 }
 
 /*
- * Release read lock. Must be used only if the lock is in spinning mode.  If
- * the read lock is nested, must pair with read lock before the write unlock.
- *
- * The rwlock is not held upon exit.
+ * Release read lock.  If the read lock was recursed then the lock stays in the
+ * original state that it was before it was recursively locked.
  */
 void btrfs_tree_read_unlock(struct extent_buffer *eb)
 {
@@ -376,10 +188,8 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb)
 		eb->lock_recursed = false;
 		return;
 	}
-	btrfs_assert_tree_read_locked(eb);
-	btrfs_assert_spinning_readers_put(eb);
-	btrfs_assert_tree_read_locks_put(eb);
-	read_unlock(&eb->lock);
+	eb->lock_owner = 0;
+	up_read(&eb->lock);
 }
 
 /*
@@ -391,30 +201,15 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb)
  */
 void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
 {
-	trace_btrfs_tree_read_unlock_blocking(eb);
-	/*
-	 * if we're nested, we have the write lock.  No new locking
-	 * is needed as long as we are the lock owner.
-	 * The write unlock will do a barrier for us, and the lock_recursed
-	 * field only matters to the lock owner.
-	 */
-	if (eb->lock_recursed && current->pid == eb->lock_owner) {
-		eb->lock_recursed = false;
-		return;
-	}
-	btrfs_assert_tree_read_locked(eb);
-	WARN_ON(atomic_read(&eb->blocking_readers) == 0);
-	/* atomic_dec_and_test implies a barrier */
-	if (atomic_dec_and_test(&eb->blocking_readers))
-		cond_wake_up_nomb(&eb->read_lock_wq);
-	btrfs_assert_tree_read_locks_put(eb);
+	btrfs_tree_read_unlock(eb);
 }
 
 /*
- * Lock for write. Wait for all blocking and spinning readers and writers. This
- * starts context where reader lock could be nested by the same thread.
+ * __btrfs_tree_lock - lock eb for write
+ * @eb:		the eb to lock
+ * @nest:	the nesting to use for the lock
  *
- * The rwlock is held for write upon exit.
+ * Returns with the eb->lock write locked.
  */
 void __btrfs_tree_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest)
 	__acquires(&eb->lock)
@@ -424,19 +219,7 @@ void __btrfs_tree_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest)
 	if (trace_btrfs_tree_lock_enabled())
 		start_ns = ktime_get_ns();
 
-	WARN_ON(eb->lock_owner == current->pid);
-again:
-	wait_event(eb->read_lock_wq, atomic_read(&eb->blocking_readers) == 0);
-	wait_event(eb->write_lock_wq, READ_ONCE(eb->blocking_writers) == 0);
-	write_lock(&eb->lock);
-	/* Refetch value after lock */
-	if (atomic_read(&eb->blocking_readers) ||
-	    READ_ONCE(eb->blocking_writers)) {
-		write_unlock(&eb->lock);
-		goto again;
-	}
-	btrfs_assert_spinning_writers_get(eb);
-	btrfs_assert_tree_write_locks_get(eb);
+	down_write_nested(&eb->lock, nest);
 	eb->lock_owner = current->pid;
 	trace_btrfs_tree_lock(eb, start_ns);
 }
@@ -447,42 +230,13 @@ void btrfs_tree_lock(struct extent_buffer *eb)
 }
 
 /*
- * Release the write lock, either blocking or spinning (ie. there's no need
- * for an explicit blocking unlock, like btrfs_tree_read_unlock_blocking).
- * This also ends the context for nesting, the read lock must have been
- * released already.
- *
- * Tasks blocked and waiting are woken, rwlock is not held upon exit.
+ * Release the write lock.
  */
 void btrfs_tree_unlock(struct extent_buffer *eb)
 {
-	/*
-	 * This is read both locked and unlocked but always by the same thread
-	 * that already owns the lock so we don't need to use READ_ONCE
-	 */
-	int blockers = eb->blocking_writers;
-
-	BUG_ON(blockers > 1);
-
-	btrfs_assert_tree_locked(eb);
 	trace_btrfs_tree_unlock(eb);
 	eb->lock_owner = 0;
-	btrfs_assert_tree_write_locks_put(eb);
-
-	if (blockers) {
-		btrfs_assert_no_spinning_writers(eb);
-		/* Unlocked write */
-		WRITE_ONCE(eb->blocking_writers, 0);
-		/*
-		 * We need to order modifying blocking_writers above with
-		 * actually waking up the sleepers to ensure they see the
-		 * updated value of blocking_writers
-		 */
-		cond_wake_up(&eb->write_lock_wq);
-	} else {
-		btrfs_assert_spinning_writers_put(eb);
-		write_unlock(&eb->lock);
-	}
+	up_write(&eb->lock);
 }
 
 /*
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h
index 3ea81ed3320b..7c27f142f7d2 100644
--- a/fs/btrfs/locking.h
+++ b/fs/btrfs/locking.h
@@ -110,7 +110,7 @@ static inline struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root
 
 #ifdef CONFIG_BTRFS_DEBUG
 static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) {
-	BUG_ON(!eb->write_locks);
+	lockdep_assert_held(&eb->lock);
 }
 #else
 static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { }
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index e98ba4e091b3..70feac4bdf3c 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -191,15 +191,8 @@ static void print_uuid_item(struct extent_buffer *l, unsigned long offset,
 static void print_eb_refs_lock(struct extent_buffer *eb)
 {
 #ifdef CONFIG_BTRFS_DEBUG
-	btrfs_info(eb->fs_info,
-"refs %u lock (w:%d r:%d bw:%d br:%d sw:%d sr:%d) lock_owner %u current %u",
-		   atomic_read(&eb->refs), eb->write_locks,
-		   atomic_read(&eb->read_locks),
-		   eb->blocking_writers,
-		   atomic_read(&eb->blocking_readers),
-		   eb->spinning_writers,
-		   atomic_read(&eb->spinning_readers),
-		   eb->lock_owner, current->pid);
+	btrfs_info(eb->fs_info, "refs %u lock_owner %u current %u",
+		   atomic_read(&eb->refs), eb->lock_owner, current->pid);
 #endif
 }
 
-- 
2.39.5




  parent reply	other threads:[~2025-01-06 15:47 UTC|newest]

Thread overview: 156+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-06 15:15 [PATCH 5.10 000/138] 5.10.233-rc1 review Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 001/138] net: sched: fix ordering of qlen adjustment Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 002/138] PCI/AER: Disable AER service on suspend Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 003/138] PCI: Use preserve_config in place of pci_flags Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 004/138] MIPS: Loongson64: DTS: Fix msi node for ls7a Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 005/138] ALSA: usb: Fix UBSAN warning in parse_audio_unit() Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 006/138] PCI: Add ACS quirk for Broadcom BCM5760X NIC Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 007/138] usb: cdns3: Add quirk flag to enable suspend residency Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 008/138] usb: dwc2: gadget: Dont write invalid mapped sg entries into dma_desc with iommu enabled Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 009/138] i2c: pnx: Fix timeout in wait functions Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 010/138] erofs: fix order >= MAX_ORDER warning due to crafted negative i_size Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 011/138] erofs: fix incorrect symlink detection in fast symlink Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 012/138] net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 013/138] net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal msg Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 014/138] net/smc: check return value of sock_recvmsg when draining clc data Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 015/138] netdevsim: switch to memdup_user_nul() Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 016/138] netdevsim: prevent bad user input in nsim_dev_health_break_write() Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 017/138] ionic: use ee->offset when returning sprom data Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 018/138] net: hinic: Fix cleanup in create_rxqs/txqs() Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 019/138] net: ethernet: bgmac-platform: fix an OF node reference leak Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 020/138] netfilter: ipset: Fix for recursive locking warning Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 021/138] mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 022/138] chelsio/chtls: prevent potential integer overflow on 32bit Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 023/138] i2c: riic: Always round-up when calculating bus period Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 024/138] efivarfs: Fix error on non-existent file Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 025/138] USB: serial: option: add TCL IK512 MBIM & ECM Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 026/138] USB: serial: option: add MeiG Smart SLM770A Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 027/138] USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 028/138] USB: serial: option: add MediaTek T7XX compositions Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 029/138] USB: serial: option: add Telit FE910C04 rmnet compositions Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 030/138] drm/modes: Avoid divide by zero harder in drm_mode_vrefresh() Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 031/138] hwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit Registers Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 032/138] sh: clk: Fix clk_enable() to return 0 on NULL clk Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 033/138] zram: refuse to use zero sized block device as backing device Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 034/138] btrfs: tree-checker: reject inline extent items with 0 ref count Greg Kroah-Hartman
2025-01-06 15:15 ` [PATCH 5.10 035/138] Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 036/138] NFS/pnfs: Fix a live lock between recalled layouts and layoutget Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 037/138] of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 038/138] nilfs2: prevent use of deleted inode Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 039/138] udmabuf: also check for F_SEAL_FUTURE_WRITE Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 040/138] of: Fix error path in of_parse_phandle_with_args_map() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 041/138] of: Fix refcount leakage for OF node returned by __of_get_dma_parent() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 042/138] ceph: validate snapdirname option length when mounting Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 043/138] epoll: Add synchronous wakeup support for ep_poll_callback Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 044/138] media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 045/138] mm/vmstat: fix a W=1 clang compiler warning Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 046/138] tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 047/138] bpf: Check negative offsets in __bpf_skb_min_len() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 048/138] nfsd: restore callback functionality for NFSv4.0 Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 049/138] mtd: diskonchip: Cast an operand to prevent potential overflow Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 050/138] phy: core: Fix an OF node refcount leakage in _of_phy_get() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 051/138] phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 052/138] phy: core: Fix that API devm_phy_put() fails to release the phy Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 053/138] phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 054/138] phy: core: Fix that API devm_phy_destroy() fails to destroy the phy Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 055/138] dmaengine: mv_xor: fix child node refcount handling in early exit Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 056/138] dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 057/138] mtd: rawnand: fix double free in atmel_pmecc_create_user() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 058/138] tracing/kprobe: Make trace_kprobes module callback called after jump_label update Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 059/138] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 060/138] scsi: qla1280: Fix hw revision numbering for ISP1020/1040 Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 061/138] scsi: megaraid_sas: Fix for a potential deadlock Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 062/138] ALSA: hda/conexant: fix Z60MR100 startup pop issue Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 063/138] regmap: Use correct format specifier for logging range errors Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 064/138] platform/x86: asus-nb-wmi: Ignore unknown event 0xCF Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 065/138] scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load time Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 066/138] scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN as an error Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 067/138] virtio-blk: dont keep queue frozen during system suspend Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 068/138] MIPS: Probe toolchain support of -msym32 Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 069/138] skbuff: introduce skb_expand_head() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 070/138] ipv6: use skb_expand_head in ip6_finish_output2 Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 071/138] ipv6: use skb_expand_head in ip6_xmit Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 072/138] ipv6: fix possible UAF in ip6_finish_output2() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 073/138] bpf: Check validity of link->type in bpf_link_show_fdinfo() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 074/138] bpf: fix recursive lock when verdict program return SK_PASS Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 075/138] drm/dp_mst: Fix MST sideband message body length check Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 076/138] arm64: mm: Rename asid2idx() to ctxid2asid() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 077/138] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 078/138] tracing: Constify string literal data member in struct trace_event_call Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 079/138] power: supply: gpio-charger: Fix set charge current limits Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 080/138] btrfs: avoid monopolizing a core when activating a swap file Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 081/138] nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 082/138] skb_expand_head() adjust skb->truesize incorrectly Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 083/138] ipv6: prevent possible UAF in ip6_xmit() Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 084/138] x86/hyperv: Fix hv tsc page based sched_clock for hibernation Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 085/138] selinux: ignore unknown extended permissions Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 086/138] thunderbolt: Add support for Intel Alder Lake Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 087/138] thunderbolt: Add support for Intel Raptor Lake Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 088/138] thunderbolt: Add support for Intel Meteor Lake Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 089/138] thunderbolt: Add Intel Barlow Ridge PCI ID Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 090/138] thunderbolt: Add support for Intel Lunar Lake Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 091/138] thunderbolt: Add support for Intel Panther Lake-M/P Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 092/138] loop: let set_capacity_revalidate_and_notify update the bdev size Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 093/138] nvme: " Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 094/138] sd: update the bdev size in sd_revalidate_disk Greg Kroah-Hartman
2025-01-06 15:16 ` [PATCH 5.10 095/138] block: remove the update_bdev parameter to set_capacity_revalidate_and_notify Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 096/138] zram: use set_capacity_and_notify Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 097/138] drivers/block/zram/zram_drv.c: do not keep dangling zcomp pointer after zram reset Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 098/138] zram: fix uninitialized ZRAM not releasing backing device Greg Kroah-Hartman
2025-01-07  2:40   ` Dominique Martinet
2025-01-07  4:28     ` Dominique Martinet
2025-01-07  7:16       ` [PATCH 5.10 5.15 6.1] zram: check comp is non-NULL before calling comp_destroy Dominique Martinet
2025-01-07  7:16         ` kernel test robot
2025-01-09 10:09         ` Greg Kroah-Hartman
2025-01-09 10:09           ` Greg Kroah-Hartman
2025-01-10  2:23             ` Dominique Martinet
2025-01-10  5:57               ` Greg Kroah-Hartman
2025-01-08  3:55   ` [PATCH 5.10 098/138] zram: fix uninitialized ZRAM not releasing backing device Sergey Senozhatsky
2025-01-06 15:17 ` [PATCH 5.10 099/138] net/mlx5: Make API mlx5_core_is_ecpf accept const pointer Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 100/138] RDMA/mlx5: Enforce same type port association for multiport RoCE Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 101/138] RDMA/bnxt_re: Add check for path mtu in modify_qp Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 102/138] RDMA/bnxt_re: Fix reporting hw_ver in query_device Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 103/138] RDMA/bnxt_re: Fix max_qp_wrs reported Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 104/138] RDMA/bnxt_re: Fix the locking while accessing the QP table Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 105/138] drm/bridge: adv7511_audio: Update Audio InfoFrame properly Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 106/138] netrom: check buffer length before accessing it Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 107/138] netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 108/138] net: llc: reset skb->transport_header Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 109/138] ALSA: usb-audio: US16x08: Initialize array before use Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 110/138] eth: bcmsysport: fix call balance of priv->clk handling routines Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 111/138] RDMA/rtrs: Ensure ib_sge list is accessible Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 112/138] af_packet: fix vlan_get_tci() vs MSG_PEEK Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 113/138] af_packet: fix vlan_get_protocol_dgram() " Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 114/138] ila: serialize calls to nf_register_net_hooks() Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 115/138] dmaengine: dw: Select only supported masters for ACPI devices Greg Kroah-Hartman
2025-01-06 15:17 ` Greg Kroah-Hartman [this message]
2025-01-06 15:17 ` [PATCH 5.10 117/138] btrfs: locking: remove all the blocking helpers Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 118/138] btrfs: rename and export __btrfs_cow_block() Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 119/138] btrfs: fix use-after-free when COWing tree bock and tracing is enabled Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 120/138] kernel: Initialize cpumask before parsing Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 121/138] tracing: Prevent bad count for tracing_cpumask_write Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 122/138] wifi: mac80211: wake the queues in case of failure in resume Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 123/138] btrfs: flush delalloc workers queue before stopping cleaner kthread during unmount Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 124/138] sound: usb: format: dont warn that raw DSD is unsupported Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 125/138] bpf: fix potential error return Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 126/138] net: usb: qmi_wwan: add Telit FE910C04 compositions Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 127/138] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 128/138] ARC: build: Try to guess GCC variant of cross compiler Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 129/138] btrfs: locking: remove the recursion handling code Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 130/138] btrfs: dont set lock_owner when locking extent buffer for reading Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 131/138] modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 132/138] modpost: fix the missed iteration for the max bit in do_input() Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 133/138] RDMA/uverbs: Prevent integer overflow issue Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 134/138] pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 135/138] sky2: Add device ID 11ab:4373 for Marvell 88E8075 Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 136/138] net/sctp: Prevent autoclose integer overflow in sctp_association_init() Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 137/138] drm: adv7511: Drop dsi single lane support Greg Kroah-Hartman
2025-01-06 15:17 ` [PATCH 5.10 138/138] mm: vmscan: account for free pages to prevent infinite Loop in throttle_direct_reclaim() Greg Kroah-Hartman
2025-01-06 18:23 ` [PATCH 5.10 000/138] 5.10.233-rc1 review Pavel Machek
2025-01-06 19:11 ` Florian Fainelli
2025-01-07  5:48 ` Dominique Martinet
2025-01-07  9:12 ` Naresh Kamboju
2025-01-09 10:34   ` Greg Kroah-Hartman
2025-01-07 12:36 ` Mark Brown
2025-01-07 12:44 ` Jon Hunter
2025-01-08 12:47 ` Muhammad Usama Anjum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250106151137.620921688@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dsterba@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).