aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-12-03 17:43:17 -0500
committerDave Chinner <david@fromorbit.com>2014-12-03 17:43:17 -0500
commitb29c70f59870dad0945b0e0b3fe3758ad528e268 (patch)
tree8b78cac19312a4619b68f826eb6f124c62a36a10 /fs
parent32296f865e8d41ff8c337ce6f0b97eeda08988a3 (diff)
xfs: split metadata and log buffer completion to separate workqueues
XFS traditionally sends all buffer I/O completion work to a single workqueue. This includes metadata buffer completion and log buffer completion. The log buffer completion requires a high priority queue to prevent stalls due to log forces getting stuck behind other queued work. Rather than continue to prioritize all buffer I/O completion due to the needs of log completion, split log buffer completion off to m_log_workqueue and move the high priority flag from m_buf_workqueue to m_log_workqueue. Add a b_ioend_wq wq pointer to xfs_buf to allow completion workqueue customization on a per-buffer basis. Initialize b_ioend_wq to m_buf_workqueue by default in the generic buffer I/O submission path. Finally, override the default wq with the high priority m_log_workqueue in the log buffer I/O submission path. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_buf.c13
-rw-r--r--fs/xfs/xfs_buf.h3
-rw-r--r--fs/xfs/xfs_log.c4
-rw-r--r--fs/xfs/xfs_super.c5
4 files changed, 18 insertions, 7 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index d083889535a2..945bea924e48 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1041,7 +1041,7 @@ xfs_buf_ioend_work(
1041 struct work_struct *work) 1041 struct work_struct *work)
1042{ 1042{
1043 struct xfs_buf *bp = 1043 struct xfs_buf *bp =
1044 container_of(work, xfs_buf_t, b_iodone_work); 1044 container_of(work, xfs_buf_t, b_ioend_work);
1045 1045
1046 xfs_buf_ioend(bp); 1046 xfs_buf_ioend(bp);
1047} 1047}
@@ -1050,8 +1050,8 @@ void
1050xfs_buf_ioend_async( 1050xfs_buf_ioend_async(
1051 struct xfs_buf *bp) 1051 struct xfs_buf *bp)
1052{ 1052{
1053 INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work); 1053 INIT_WORK(&bp->b_ioend_work, xfs_buf_ioend_work);
1054 queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work); 1054 queue_work(bp->b_ioend_wq, &bp->b_ioend_work);
1055} 1055}
1056 1056
1057void 1057void
@@ -1220,6 +1220,13 @@ _xfs_buf_ioapply(
1220 */ 1220 */
1221 bp->b_error = 0; 1221 bp->b_error = 0;
1222 1222
1223 /*
1224 * Initialize the I/O completion workqueue if we haven't yet or the
1225 * submitter has not opted to specify a custom one.
1226 */
1227 if (!bp->b_ioend_wq)
1228 bp->b_ioend_wq = bp->b_target->bt_mount->m_buf_workqueue;
1229
1223 if (bp->b_flags & XBF_WRITE) { 1230 if (bp->b_flags & XBF_WRITE) {
1224 if (bp->b_flags & XBF_SYNCIO) 1231 if (bp->b_flags & XBF_SYNCIO)
1225 rw = WRITE_SYNC; 1232 rw = WRITE_SYNC;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 82002c00af90..75ff5d5a7d2e 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -164,7 +164,8 @@ typedef struct xfs_buf {
164 struct xfs_perag *b_pag; /* contains rbtree root */ 164 struct xfs_perag *b_pag; /* contains rbtree root */
165 xfs_buftarg_t *b_target; /* buffer target (device) */ 165 xfs_buftarg_t *b_target; /* buffer target (device) */
166 void *b_addr; /* virtual address of buffer */ 166 void *b_addr; /* virtual address of buffer */
167 struct work_struct b_iodone_work; 167 struct work_struct b_ioend_work;
168 struct workqueue_struct *b_ioend_wq; /* I/O completion wq */
168 xfs_buf_iodone_t b_iodone; /* I/O completion function */ 169 xfs_buf_iodone_t b_iodone; /* I/O completion function */
169 struct completion b_iowait; /* queue for I/O waiters */ 170 struct completion b_iowait; /* queue for I/O waiters */
170 void *b_fspriv; 171 void *b_fspriv;
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index e810e9df91b7..d508a654e198 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1808,6 +1808,8 @@ xlog_sync(
1808 XFS_BUF_ZEROFLAGS(bp); 1808 XFS_BUF_ZEROFLAGS(bp);
1809 XFS_BUF_ASYNC(bp); 1809 XFS_BUF_ASYNC(bp);
1810 bp->b_flags |= XBF_SYNCIO; 1810 bp->b_flags |= XBF_SYNCIO;
1811 /* use high priority completion wq */
1812 bp->b_ioend_wq = log->l_mp->m_log_workqueue;
1811 1813
1812 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { 1814 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
1813 bp->b_flags |= XBF_FUA; 1815 bp->b_flags |= XBF_FUA;
@@ -1856,6 +1858,8 @@ xlog_sync(
1856 bp->b_flags |= XBF_SYNCIO; 1858 bp->b_flags |= XBF_SYNCIO;
1857 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) 1859 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1858 bp->b_flags |= XBF_FUA; 1860 bp->b_flags |= XBF_FUA;
1861 /* use high priority completion wq */
1862 bp->b_ioend_wq = log->l_mp->m_log_workqueue;
1859 1863
1860 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); 1864 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1861 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); 1865 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 45fa5b570eb5..b5aacfc462af 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -842,8 +842,7 @@ xfs_init_mount_workqueues(
842 struct xfs_mount *mp) 842 struct xfs_mount *mp)
843{ 843{
844 mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s", 844 mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
845 WQ_MEM_RECLAIM|WQ_HIGHPRI|WQ_FREEZABLE, 1, 845 WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_fsname);
846 mp->m_fsname);
847 if (!mp->m_buf_workqueue) 846 if (!mp->m_buf_workqueue)
848 goto out; 847 goto out;
849 848
@@ -868,7 +867,7 @@ xfs_init_mount_workqueues(
868 goto out_destroy_cil; 867 goto out_destroy_cil;
869 868
870 mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", 869 mp->m_log_workqueue = alloc_workqueue("xfs-log/%s",
871 WQ_FREEZABLE, 0, mp->m_fsname); 870 WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname);
872 if (!mp->m_log_workqueue) 871 if (!mp->m_log_workqueue)
873 goto out_destroy_reclaim; 872 goto out_destroy_reclaim;
874 873