summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.h
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-10-05 11:06:59 +1000
committerBen Myers <bpm@sgi.com>2012-11-08 11:08:46 -0600
commit1f3c785c3adb7d2b109ec7c8f10081d1294b03d3 (patch)
tree7af47beb69f6ccdecffde2363c4f6b16cd353c2e /fs/xfs/xfs_bmap.h
parent326c03555b914ff153ba5b40df87fd6e28e7e367 (diff)
downloadlinux-1f3c785c3adb7d2b109ec7c8f10081d1294b03d3.tar.bz2
xfs: move allocation stack switch up to xfs_bmapi_allocate
Switching stacks are xfs_alloc_vextent can cause deadlocks when we run out of worker threads on the allocation workqueue. This can occur because xfs_bmap_btalloc can make multiple calls to xfs_alloc_vextent() and even if xfs_alloc_vextent() fails it can return with the AGF locked in the current allocation transaction. If we then need to make another allocation, and all the allocation worker contexts are exhausted because the are blocked waiting for the AGF lock, holder of the AGF cannot get it's xfs-alloc_vextent work completed to release the AGF. Hence allocation effectively deadlocks. To avoid this, move the stack switch one layer up to xfs_bmapi_allocate() so that all of the allocation attempts in a single switched stack transaction occur in a single worker context. This avoids the problem of an allocation being blocked waiting for a worker thread whilst holding the AGF. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap.h')
-rw-r--r--fs/xfs/xfs_bmap.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index b68c598034c1..5f469c3516eb 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -136,6 +136,10 @@ typedef struct xfs_bmalloca {
char aeof; /* allocated space at eof */
char conv; /* overwriting unwritten extents */
char stack_switch;
+ int flags;
+ struct completion *done;
+ struct work_struct work;
+ int result;
} xfs_bmalloca_t;
/*