aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-03-22 01:15:07 -0400
committerBen Myers <bpm@sgi.com>2012-03-22 17:12:24 -0400
commitc999a223c2f0d31c64ef7379814cea1378b2b800 (patch)
treeed699c3c98075bbfc4aed0ab22bd174e65e575a8 /fs/xfs/xfs_super.c
parent1a1d772433d42aaff7315b3468fef5951604f5c6 (diff)
xfs: introduce an allocation workqueue
We currently have significant issues with the amount of stack that allocation in XFS uses, especially in the writeback path. We can easily consume 4k of stack between mapping the page, manipulating the bmap btree and allocating blocks from the free list. Not to mention btree block readahead and other functionality that issues IO in the allocation path. As a result, we can no longer fit allocation in the writeback path in the stack space provided on x86_64. To alleviate this problem, introduce an allocation workqueue and move all allocations to a seperate context. This can be easily added as an interposing layer into xfs_alloc_vextent(), which takes a single argument structure and does not return until the allocation is complete or has failed. To do this, add a work structure and a completion to the allocation args structure. This allows xfs_alloc_vextent to queue the args onto the workqueue and wait for it to be completed by the worker. This can be done completely transparently to the caller. The worker function needs to ensure that it sets and clears the PF_TRANS flag appropriately as it is being run in an active transaction context. Work can also be queued in a memory reclaim context, so a rescuer is needed for the workqueue. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r--fs/xfs/xfs_super.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 06d23b976f4c..5484888d39c4 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1607,12 +1607,28 @@ xfs_init_workqueues(void)
1607 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0); 1607 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0);
1608 if (!xfs_syncd_wq) 1608 if (!xfs_syncd_wq)
1609 return -ENOMEM; 1609 return -ENOMEM;
1610
1611 /*
1612 * The allocation workqueue can be used in memory reclaim situations
1613 * (writepage path), and parallelism is only limited by the number of
1614 * AGs in all the filesystems mounted. Hence use the default large
1615 * max_active value for this workqueue.
1616 */
1617 xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0);
1618 if (!xfs_alloc_wq)
1619 goto out_destroy_syncd;
1620
1610 return 0; 1621 return 0;
1622
1623out_destroy_syncd:
1624 destroy_workqueue(xfs_syncd_wq);
1625 return -ENOMEM;
1611} 1626}
1612 1627
1613STATIC void 1628STATIC void
1614xfs_destroy_workqueues(void) 1629xfs_destroy_workqueues(void)
1615{ 1630{
1631 destroy_workqueue(xfs_alloc_wq);
1616 destroy_workqueue(xfs_syncd_wq); 1632 destroy_workqueue(xfs_syncd_wq);
1617} 1633}
1618 1634