public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: tinguely@sgi.com
To: xfs@oss.sgi.com
Subject: [PATCH 2/3] xfs: move allocate worker
Date: Wed, 19 Sep 2012 11:31:35 -0500	[thread overview]
Message-ID: <20120919163145.485656298@sgi.com> (raw)
In-Reply-To: 20120919163133.097340199@sgi.com

[-- Attachment #1: 2-3-xfs-move_allocate_worker.patch --]
[-- Type: text/plain, Size: 6610 bytes --]

Move the allocation worker call so that any loops on xfs_alloc_vextent()
calls for a particular transaction are contained within a single worker.
This prevents a filesystem hang that can occur because the holder of
AGF buffer lock cannot allocate a worker.

Signed-off-by: Mark Tinguely <tinguely@sgi.com>
---
 fs/xfs/xfs_alloc.c |   53 -------------------------------------------
 fs/xfs/xfs_alloc.h |    3 --
 fs/xfs/xfs_bmap.c  |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/xfs/xfs_bmap.h  |   16 +++++++++++++
 4 files changed, 80 insertions(+), 56 deletions(-)

Index: b/fs/xfs/xfs_alloc.c
===================================================================
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -2207,7 +2207,7 @@ xfs_alloc_read_agf(
  * group or loop over the allocation groups to find the result.
  */
 int				/* error */
-__xfs_alloc_vextent(
+xfs_alloc_vextent(
 	xfs_alloc_arg_t	*args)	/* allocation argument structure */
 {
 	xfs_agblock_t	agsize;	/* allocation group size */
@@ -2417,57 +2417,6 @@ error0:
 	return error;
 }
 
-#if defined(CONFIG_X86_64)
-static void
-xfs_alloc_vextent_worker(
-	struct work_struct	*work)
-{
-	struct xfs_alloc_arg	*args = container_of(work,
-						struct xfs_alloc_arg, work);
-	unsigned long		pflags;
-
-	/* we are in a transaction context here */
-	current_set_flags_nested(&pflags, PF_FSTRANS);
-
-	args->result = __xfs_alloc_vextent(args);
-	complete(args->done);
-
-	current_restore_flags_nested(&pflags, PF_FSTRANS);
-}
-#endif
-
-/*
- * Data allocation requests often come in with little stack to work on. Push
- * them off to a worker thread so there is lots of stack to use. Metadata
- * requests, OTOH, are generally from low stack usage paths, so avoid the
- * context switch overhead here.
- */
-int
-xfs_alloc_vextent(
-	struct xfs_alloc_arg	*args)
-{
-#if defined(CONFIG_X86_64)
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	if (!args->userdata)
-		return __xfs_alloc_vextent(args);
-
-
-	args->done = &done;
-	INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker);
-	queue_work(xfs_alloc_wq, &args->work);
-	wait_for_completion(&done);
-	return args->result;
-#else
-	/* The allocation worker is needed by the i386_64.
-	 * Do not use the worker for other platforms. This will
-	 * allow those platforms avoid the performance hit and
-	 * the potential AGF buffer deadlock issue.
-	 */
-	return __xfs_alloc_vextent(args);
-#endif
-}
-
 /*
  * Free an extent.
  * Just break up the extent address and hand off to xfs_free_ag_extent
Index: b/fs/xfs/xfs_alloc.h
===================================================================
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -120,9 +120,6 @@ typedef struct xfs_alloc_arg {
 	char		isfl;		/* set if is freelist blocks - !acctg */
 	char		userdata;	/* set if this is user data */
 	xfs_fsblock_t	firstblock;	/* io first block allocated */
-	struct completion *done;
-	struct work_struct work;
-	int		result;
 } xfs_alloc_arg_t;
 
 /*
Index: b/fs/xfs/xfs_bmap.c
===================================================================
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -48,7 +48,6 @@
 #include "xfs_vnodeops.h"
 #include "xfs_trace.h"
 
-
 kmem_zone_t		*xfs_bmap_free_item_zone;
 
 /*
@@ -4807,7 +4806,11 @@ xfs_bmapi_convert_unwritten(
  * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
  */
 int
+#if defined(CONFIG_X86_64)
+__xfs_bmapi_write(
+#else
 xfs_bmapi_write(
+#endif
 	struct xfs_trans	*tp,		/* transaction pointer */
 	struct xfs_inode	*ip,		/* incore inode */
 	xfs_fileoff_t		bno,		/* starting file offs. mapped */
@@ -5031,6 +5034,65 @@ error0:
 	return error;
 }
 
+#if defined(CONFIG_X86_64)
+static void
+xfs_bmapi_write_worker(
+	struct work_struct      *work)
+{
+	struct xfs_bmw_wkr	*bw = container_of(work,
+						     struct xfs_bmw_wkr, work);
+	unsigned long		pflags;
+
+	/* we are in a transaction context here */
+	current_set_flags_nested(&pflags, PF_FSTRANS);
+
+	bw->result = __xfs_bmapi_write(bw->tp, bw->ip, bw->bno, bw->len,
+					 bw->flags, bw->firstblock, bw->total,
+					 bw->mval, bw->nmap, bw->flist);
+	complete(bw->done);
+
+	current_restore_flags_nested(&pflags, PF_FSTRANS);
+}
+
+int
+xfs_bmapi_write(
+	struct xfs_trans	*tp,		/* transaction pointer */
+	struct xfs_inode	*ip,		/* incore inode */
+	xfs_fileoff_t		bno,		/* starting file offs. mapped */
+	xfs_filblks_t		len,		/* length to map in file */
+	int			flags,		/* XFS_BMAPI_... */
+	xfs_fsblock_t		*firstblock,	/* first allocated block
+						   controls a.g. for allocs */
+	xfs_extlen_t		total,		/* total blocks needed */
+	struct xfs_bmbt_irec	*mval,		/* output: map values */
+	int			*nmap,		/* i/o: mval size/count */
+	struct xfs_bmap_free	*flist)		/* i/o: list extents to free */
+{
+	struct xfs_bmw_wkr	bw;
+	DECLARE_COMPLETION_ONSTACK(done);
+
+	if (flags & XFS_BMAPI_METADATA)
+		return __xfs_bmapi_write(tp, ip, bno, len, flags, firstblock,
+					 total, mval, nmap, flist);
+	/* initialize the worker argument list structure */
+	bw.tp = tp;
+	bw.ip = ip;
+	bw.bno = bno;
+	bw.len = len;
+	bw.flags = flags;
+	bw.firstblock = firstblock;
+	bw.total = total;
+	bw.mval = mval;
+	bw.nmap = nmap;
+	bw.flist = flist;
+	bw.done = &done;
+	INIT_WORK_ONSTACK(&bw.work, xfs_bmapi_write_worker);
+	queue_work(xfs_alloc_wq, &bw.work);
+	wait_for_completion(&done);
+	return bw.result;
+}
+#endif
+
 /*
  * Unmap (remove) blocks from a file.
  * If nexts is nonzero then the number of extents to remove is limited to
Index: b/fs/xfs/xfs_bmap.h
===================================================================
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -135,6 +135,22 @@ typedef struct xfs_bmalloca {
 	char			conv;	/* overwriting unwritten extents */
 } xfs_bmalloca_t;
 
+struct xfs_bmw_wkr {
+	struct xfs_trans	*tp;		/* transaction pointer */
+	struct xfs_inode	*ip;		/* incore inode */
+	xfs_fileoff_t		bno;		/* starting file offs. mapped */
+	xfs_filblks_t		len;		/* length to map in file */
+	int			flags;		/* XFS_BMAPI_... */
+	xfs_fsblock_t		*firstblock;	/* first allocblock controls */
+	xfs_extlen_t		total;		/* total blocks needed */
+	struct xfs_bmbt_irec	*mval;		/* output: map values */
+	int			*nmap;		/* i/o: mval size/count */
+	struct xfs_bmap_free	*flist;		/* bmap freelist */
+	struct completion	*done;		/* worker completion ptr */
+	struct work_struct	work;		/* worker */
+	int			result;		/* worker function result */
+} ;
+
 /*
  * Flags for xfs_bmap_add_extent*.
  */

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2012-09-19 16:33 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-19 16:31 [PATCH 0/3] xfs: allocation worker causes freelist buffer lock hang tinguely
2012-09-19 16:31 ` [PATCH 1/3] xfs: restrict allocate worker to x86_64 tinguely
2012-09-19 21:54   ` Dave Chinner
2012-09-20 17:37     ` Mark Tinguely
2012-09-24 17:37       ` Ben Myers
2012-09-25  0:14         ` Dave Chinner
2012-09-19 16:31 ` tinguely [this message]
2012-09-19 16:31 ` [PATCH 3/3] xfs: zero allocation_args on the kernel stack tinguely
2012-09-19 23:41   ` Dave Chinner
2012-09-20 18:16   ` [PATCH 3/3 v2] " Mark Tinguely
2012-09-25 20:20     ` Ben Myers
2012-10-18 22:52     ` Ben Myers
2012-09-19 23:34 ` [PATCH 0/3] xfs: allocation worker causes freelist buffer lock hang Dave Chinner
2012-09-20 13:49   ` Mark Tinguely
2012-09-24 13:25   ` Dave Chinner
2012-09-24 17:11 ` Ben Myers
2012-09-24 18:09   ` Mark Tinguely
2012-09-25  0:56     ` Dave Chinner
2012-09-25 15:14       ` Mark Tinguely
2012-09-25 22:01         ` Dave Chinner
2012-09-26 14:14           ` Mark Tinguely
2012-09-26 23:41             ` Dave Chinner
2012-09-27 20:10               ` Mark Tinguely
2012-09-28  3:08         ` Dave Chinner
2012-10-01 22:10           ` [PATCH 0/3] xfs: allocation worker causes freelist buffer lock Mark Tinguely
2012-10-01 23:10             ` Dave Chinner
2012-09-27 22:48     ` [PATCH 0/3] xfs: allocation worker causes freelist buffer lock hang Ben Myers
2012-09-27 23:17       ` Mark Tinguely
2012-09-27 23:27         ` Mark Tinguely

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=20120919163145.485656298@sgi.com \
    --to=tinguely@sgi.com \
    --cc=xfs@oss.sgi.com \
    /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