All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs: Do not free xfs_extent_busy from inside a spinlock
@ 2019-07-23 15:00 Carlos Maiolino
  2019-07-23 15:11 ` Darrick J. Wong
  2019-07-23 15:13 ` Carlos Maiolino
  0 siblings, 2 replies; 9+ messages in thread
From: Carlos Maiolino @ 2019-07-23 15:00 UTC (permalink / raw)
  To: linux-xfs

xfs_extent_busy_clear_one() calls kmem_free() with the pag spinlock
locked.

Fix this by adding a new temporary list, and, make
xfs_extent_busy_clear_one() to move the extent_busy items to this new
list, instead of freeing them.

Free the objects in the temporary list after we drop the pagb_lock

Reported-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
 fs/xfs/xfs_extent_busy.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c
index 0ed68379e551..0a7dcf03340b 100644
--- a/fs/xfs/xfs_extent_busy.c
+++ b/fs/xfs/xfs_extent_busy.c
@@ -523,7 +523,8 @@ STATIC void
 xfs_extent_busy_clear_one(
 	struct xfs_mount	*mp,
 	struct xfs_perag	*pag,
-	struct xfs_extent_busy	*busyp)
+	struct xfs_extent_busy	*busyp,
+	struct list_head	*list)
 {
 	if (busyp->length) {
 		trace_xfs_extent_busy_clear(mp, busyp->agno, busyp->bno,
@@ -531,8 +532,7 @@ xfs_extent_busy_clear_one(
 		rb_erase(&busyp->rb_node, &pag->pagb_tree);
 	}
 
-	list_del_init(&busyp->list);
-	kmem_free(busyp);
+	list_move(&busyp->list, list);
 }
 
 static void
@@ -565,6 +565,7 @@ xfs_extent_busy_clear(
 	struct xfs_perag	*pag = NULL;
 	xfs_agnumber_t		agno = NULLAGNUMBER;
 	bool			wakeup = false;
+	LIST_HEAD(busy_list);
 
 	list_for_each_entry_safe(busyp, n, list, list) {
 		if (busyp->agno != agno) {
@@ -580,13 +581,18 @@ xfs_extent_busy_clear(
 		    !(busyp->flags & XFS_EXTENT_BUSY_SKIP_DISCARD)) {
 			busyp->flags = XFS_EXTENT_BUSY_DISCARDED;
 		} else {
-			xfs_extent_busy_clear_one(mp, pag, busyp);
+			xfs_extent_busy_clear_one(mp, pag, busyp, &busy_list);
 			wakeup = true;
 		}
 	}
 
 	if (pag)
 		xfs_extent_busy_put_pag(pag, wakeup);
+
+	list_for_each_entry_safe(busyp, n, &busy_list, list) {
+		list_del_init(&busyp->list);
+		kmem_free(busyp);
+	}
 }
 
 /*
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-07-23 17:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-23 15:00 [PATCH] xfs: Do not free xfs_extent_busy from inside a spinlock Carlos Maiolino
2019-07-23 15:11 ` Darrick J. Wong
2019-07-23 15:31   ` Carlos Maiolino
2019-07-23 15:51     ` Christoph Hellwig
2019-07-23 17:07       ` Jeff Layton
2019-07-23 17:08         ` Christoph Hellwig
2019-07-23 17:38           ` Jeff Layton
2019-07-23 17:41             ` Christoph Hellwig
2019-07-23 15:13 ` Carlos Maiolino

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.