aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2012-04-23 03:54:32 -0400
committerBen Myers <bpm@sgi.com>2012-05-14 17:20:34 -0400
commit4c2d542f2e786537db33b613d5199dc6d69a96da (patch)
treeeeca27ca63e519981e8d4f2ab1bcf8230f5e598e /fs/xfs/xfs_super.c
parent04913fdd91f342e537005ef1233f98068b925a7f (diff)
xfs: Do background CIL flushes via a workqueue
Doing background CIL flushes adds significant latency to whatever async transaction that triggers it. To avoid blocking async transactions on things like waiting for log buffer IO to complete, move the CIL push off into a workqueue. By moving the push work into a workqueue, we remove all the latency that the commit adds from the foreground transaction commit path. This also means that single threaded workloads won't do the CIL push procssing, leaving them more CPU to do more async transactions. To do this, we need to keep track of the sequence number we have pushed work for. This avoids having many transaction commits attempting to schedule work for the same sequence, and ensures that we only ever have one push (background or forced) in progress at a time. It also means that we don't need to take the CIL lock in write mode to check for potential background push races, which reduces lock contention. To avoid potential issues with "smart" IO schedulers, don't use the workqueue for log force triggered flushes. Instead, do them directly so that the log IO is done directly by the process issuing the log force and so doesn't get stuck on IO elevator queue idling incorrectly delaying the log IO from the workqueue. 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_super.c')
-rw-r--r--fs/xfs/xfs_super.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index fa07b7731cf2..49197e24d8db 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -773,8 +773,14 @@ xfs_init_mount_workqueues(
773 if (!mp->m_unwritten_workqueue) 773 if (!mp->m_unwritten_workqueue)
774 goto out_destroy_data_iodone_queue; 774 goto out_destroy_data_iodone_queue;
775 775
776 mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s",
777 WQ_MEM_RECLAIM, 0, mp->m_fsname);
778 if (!mp->m_cil_workqueue)
779 goto out_destroy_unwritten;
776 return 0; 780 return 0;
777 781
782out_destroy_unwritten:
783 destroy_workqueue(mp->m_unwritten_workqueue);
778out_destroy_data_iodone_queue: 784out_destroy_data_iodone_queue:
779 destroy_workqueue(mp->m_data_workqueue); 785 destroy_workqueue(mp->m_data_workqueue);
780out: 786out:
@@ -785,6 +791,7 @@ STATIC void
785xfs_destroy_mount_workqueues( 791xfs_destroy_mount_workqueues(
786 struct xfs_mount *mp) 792 struct xfs_mount *mp)
787{ 793{
794 destroy_workqueue(mp->m_cil_workqueue);
788 destroy_workqueue(mp->m_data_workqueue); 795 destroy_workqueue(mp->m_data_workqueue);
789 destroy_workqueue(mp->m_unwritten_workqueue); 796 destroy_workqueue(mp->m_unwritten_workqueue);
790} 797}