Commit 2455881c0b52f87be539c4c7deab1afff4d8a560

Authored by Dave Chinner
Committed by Ben Myers
1 parent a00416844b

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>

Showing 5 changed files with 13 additions and 3 deletions Side-by-side Diff

... ... @@ -2447,7 +2447,7 @@
2447 2447 {
2448 2448 DECLARE_COMPLETION_ONSTACK(done);
2449 2449  
2450   - if (!args->userdata)
  2450 + if (!args->stack_switch)
2451 2451 return __xfs_alloc_vextent(args);
2452 2452  
2453 2453  
... ... @@ -123,6 +123,7 @@
123 123 struct completion *done;
124 124 struct work_struct work;
125 125 int result;
  126 + char stack_switch;
126 127 } xfs_alloc_arg_t;
127 128  
128 129 /*
... ... @@ -2441,6 +2441,7 @@
2441 2441 args.tp = ap->tp;
2442 2442 args.mp = mp;
2443 2443 args.fsbno = ap->blkno;
  2444 + args.stack_switch = ap->stack_switch;
2444 2445  
2445 2446 /* Trim the allocation back to the maximum an AG can fit. */
2446 2447 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp));
... ... @@ -4674,6 +4675,9 @@
4674 4675 if (error)
4675 4676 return error;
4676 4677 }
  4678 +
  4679 + if (flags & XFS_BMAPI_STACK_SWITCH)
  4680 + bma->stack_switch = 1;
4677 4681  
4678 4682 error = xfs_bmap_alloc(bma);
4679 4683 if (error)
... ... @@ -77,6 +77,7 @@
77 77 * from written to unwritten, otherwise convert from unwritten to written.
78 78 */
79 79 #define XFS_BMAPI_CONVERT 0x040
  80 +#define XFS_BMAPI_STACK_SWITCH 0x080
80 81  
81 82 #define XFS_BMAPI_FLAGS \
82 83 { XFS_BMAPI_ENTIRE, "ENTIRE" }, \
... ... @@ -85,7 +86,8 @@
85 86 { XFS_BMAPI_PREALLOC, "PREALLOC" }, \
86 87 { XFS_BMAPI_IGSTATE, "IGSTATE" }, \
87 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  
91 93 static inline int xfs_bmapi_aflag(int w)
... ... @@ -133,6 +135,7 @@
133 135 char userdata;/* set if is user data */
134 136 char aeof; /* allocated space at eof */
135 137 char conv; /* overwriting unwritten extents */
  138 + char stack_switch;
136 139 } xfs_bmalloca_t;
137 140  
138 141 /*
... ... @@ -575,7 +575,9 @@
575 575 * pointer that the caller gave to us.
576 576 */
577 577 error = xfs_bmapi_write(tp, ip, map_start_fsb,
578   - count_fsb, 0, &first_block, 1,
  578 + count_fsb,
  579 + XFS_BMAPI_STACK_SWITCH,
  580 + &first_block, 1,
579 581 imap, &nimaps, &free_list);
580 582 if (error)
581 583 goto trans_cancel;