aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-10-04 21:06:58 -0400
committerBen Myers <bpm@sgi.com>2012-11-08 12:08:27 -0500
commit326c03555b914ff153ba5b40df87fd6e28e7e367 (patch)
tree65354bb8abe5c9ab63ce0a6d36cf9b957f9a1353 /fs
parent408cc4e97a3ccd172d2d676e4b585badf439271b (diff)
xfs: introduce XFS_BMAPI_STACK_SWITCH
Certain allocation paths through xfs_bmapi_write() are in situations where we have limited stack available. These are almost always in the buffered IO writeback path when convertion delayed allocation extents to real extents. The current stack switch occurs for userdata allocations, which means we also do stack switches for preallocation, direct IO and unwritten extent conversion, even those these call chains have never been implicated in a stack overrun. Hence, let's target just the single stack overun offended for stack switches. To do that, introduce a XFS_BMAPI_STACK_SWITCH flag that the caller can pass xfs_bmapi_write() to indicate it should switch stacks if it needs to do allocation. 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')
-rw-r--r--fs/xfs/xfs_alloc.c2
-rw-r--r--fs/xfs/xfs_alloc.h1
-rw-r--r--fs/xfs/xfs_bmap.c4
-rw-r--r--fs/xfs/xfs_bmap.h5
-rw-r--r--fs/xfs/xfs_iomap.c4
5 files changed, 13 insertions, 3 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 0287f3b1b503..43f791bcd8b1 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -2447,7 +2447,7 @@ xfs_alloc_vextent(
2447{ 2447{
2448 DECLARE_COMPLETION_ONSTACK(done); 2448 DECLARE_COMPLETION_ONSTACK(done);
2449 2449
2450 if (!args->userdata) 2450 if (!args->stack_switch)
2451 return __xfs_alloc_vextent(args); 2451 return __xfs_alloc_vextent(args);
2452 2452
2453 2453
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 93be4a667ca1..ef7d4885dc2d 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -123,6 +123,7 @@ typedef struct xfs_alloc_arg {
123 struct completion *done; 123 struct completion *done;
124 struct work_struct work; 124 struct work_struct work;
125 int result; 125 int result;
126 char stack_switch;
126} xfs_alloc_arg_t; 127} xfs_alloc_arg_t;
127 128
128/* 129/*
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index e1545ec2f7d2..91259554df8b 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2441,6 +2441,7 @@ xfs_bmap_btalloc(
2441 args.tp = ap->tp; 2441 args.tp = ap->tp;
2442 args.mp = mp; 2442 args.mp = mp;
2443 args.fsbno = ap->blkno; 2443 args.fsbno = ap->blkno;
2444 args.stack_switch = ap->stack_switch;
2444 2445
2445 /* Trim the allocation back to the maximum an AG can fit. */ 2446 /* Trim the allocation back to the maximum an AG can fit. */
2446 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp)); 2447 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp));
@@ -4675,6 +4676,9 @@ xfs_bmapi_allocate(
4675 return error; 4676 return error;
4676 } 4677 }
4677 4678
4679 if (flags & XFS_BMAPI_STACK_SWITCH)
4680 bma->stack_switch = 1;
4681
4678 error = xfs_bmap_alloc(bma); 4682 error = xfs_bmap_alloc(bma);
4679 if (error) 4683 if (error)
4680 return error; 4684 return error;
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 803b56d7ce16..b68c598034c1 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -77,6 +77,7 @@ typedef struct xfs_bmap_free
77 * from written to unwritten, otherwise convert from unwritten to written. 77 * from written to unwritten, otherwise convert from unwritten to written.
78 */ 78 */
79#define XFS_BMAPI_CONVERT 0x040 79#define XFS_BMAPI_CONVERT 0x040
80#define XFS_BMAPI_STACK_SWITCH 0x080
80 81
81#define XFS_BMAPI_FLAGS \ 82#define XFS_BMAPI_FLAGS \
82 { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ 83 { XFS_BMAPI_ENTIRE, "ENTIRE" }, \
@@ -85,7 +86,8 @@ typedef struct xfs_bmap_free
85 { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ 86 { XFS_BMAPI_PREALLOC, "PREALLOC" }, \
86 { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ 87 { XFS_BMAPI_IGSTATE, "IGSTATE" }, \
87 { XFS_BMAPI_CONTIG, "CONTIG" }, \ 88 { XFS_BMAPI_CONTIG, "CONTIG" }, \
88 { XFS_BMAPI_CONVERT, "CONVERT" } 89 { XFS_BMAPI_CONVERT, "CONVERT" }, \
90 { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" }
89 91
90 92
91static inline int xfs_bmapi_aflag(int w) 93static inline int xfs_bmapi_aflag(int w)
@@ -133,6 +135,7 @@ typedef struct xfs_bmalloca {
133 char userdata;/* set if is user data */ 135 char userdata;/* set if is user data */
134 char aeof; /* allocated space at eof */ 136 char aeof; /* allocated space at eof */
135 char conv; /* overwriting unwritten extents */ 137 char conv; /* overwriting unwritten extents */
138 char stack_switch;
136} xfs_bmalloca_t; 139} xfs_bmalloca_t;
137 140
138/* 141/*
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 973dff6ad935..7f537663365b 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -584,7 +584,9 @@ xfs_iomap_write_allocate(
584 * pointer that the caller gave to us. 584 * pointer that the caller gave to us.
585 */ 585 */
586 error = xfs_bmapi_write(tp, ip, map_start_fsb, 586 error = xfs_bmapi_write(tp, ip, map_start_fsb,
587 count_fsb, 0, &first_block, 1, 587 count_fsb,
588 XFS_BMAPI_STACK_SWITCH,
589 &first_block, 1,
588 imap, &nimaps, &free_list); 590 imap, &nimaps, &free_list);
589 if (error) 591 if (error)
590 goto trans_cancel; 592 goto trans_cancel;