Skip to content

Commit

Permalink
xfs: introduce XFS_BMAPI_STACK_SWITCH
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Mark Tinguely <[email protected]>
Signed-off-by: Ben Myers <[email protected]>
  • Loading branch information
Dave Chinner authored and Ben Myers committed Nov 8, 2012
1 parent 408cc4e commit 326c035
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 3 deletions.
2 changes: 1 addition & 1 deletion fs/xfs/xfs_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2447,7 +2447,7 @@ xfs_alloc_vextent(
{
DECLARE_COMPLETION_ONSTACK(done);

if (!args->userdata)
if (!args->stack_switch)
return __xfs_alloc_vextent(args);


Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ typedef struct xfs_alloc_arg {
struct completion *done;
struct work_struct work;
int result;
char stack_switch;
} xfs_alloc_arg_t;

/*
Expand Down
4 changes: 4 additions & 0 deletions fs/xfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,7 @@ xfs_bmap_btalloc(
args.tp = ap->tp;
args.mp = mp;
args.fsbno = ap->blkno;
args.stack_switch = ap->stack_switch;

/* Trim the allocation back to the maximum an AG can fit. */
args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp));
Expand Down Expand Up @@ -4675,6 +4676,9 @@ xfs_bmapi_allocate(
return error;
}

if (flags & XFS_BMAPI_STACK_SWITCH)
bma->stack_switch = 1;

error = xfs_bmap_alloc(bma);
if (error)
return error;
Expand Down
5 changes: 4 additions & 1 deletion fs/xfs/xfs_bmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ typedef struct xfs_bmap_free
* from written to unwritten, otherwise convert from unwritten to written.
*/
#define XFS_BMAPI_CONVERT 0x040
#define XFS_BMAPI_STACK_SWITCH 0x080

#define XFS_BMAPI_FLAGS \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
Expand All @@ -85,7 +86,8 @@ typedef struct xfs_bmap_free
{ XFS_BMAPI_PREALLOC, "PREALLOC" }, \
{ XFS_BMAPI_IGSTATE, "IGSTATE" }, \
{ XFS_BMAPI_CONTIG, "CONTIG" }, \
{ XFS_BMAPI_CONVERT, "CONVERT" }
{ XFS_BMAPI_CONVERT, "CONVERT" }, \
{ XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" }


static inline int xfs_bmapi_aflag(int w)
Expand Down Expand Up @@ -133,6 +135,7 @@ typedef struct xfs_bmalloca {
char userdata;/* set if is user data */
char aeof; /* allocated space at eof */
char conv; /* overwriting unwritten extents */
char stack_switch;
} xfs_bmalloca_t;

/*
Expand Down
4 changes: 3 additions & 1 deletion fs/xfs/xfs_iomap.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,9 @@ xfs_iomap_write_allocate(
* pointer that the caller gave to us.
*/
error = xfs_bmapi_write(tp, ip, map_start_fsb,
count_fsb, 0, &first_block, 1,
count_fsb,
XFS_BMAPI_STACK_SWITCH,
&first_block, 1,
imap, &nimaps, &free_list);
if (error)
goto trans_cancel;
Expand Down

0 comments on commit 326c035

Please sign in to comment.