aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf.c
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-12-04 09:43:17 +1100
committerDave Chinner <david@fromorbit.com>2014-12-04 09:43:17 +1100
commitb29c70f59870dad0945b0e0b3fe3758ad528e268 (patch)
tree8b78cac19312a4619b68f826eb6f124c62a36a10 /fs/xfs/xfs_buf.c
parentxfs: fix set-but-unused warnings (diff)
downloadlinux-dev-b29c70f59870dad0945b0e0b3fe3758ad528e268.tar.xz
linux-dev-b29c70f59870dad0945b0e0b3fe3758ad528e268.zip
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/xfs/xfs_buf.c')
-rw-r--r--fs/xfs/xfs_buf.c13
1 files changed, 10 insertions, 3 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(
struct work_struct *work)
{
struct xfs_buf *bp =
- container_of(work, xfs_buf_t, b_iodone_work);
+ container_of(work, xfs_buf_t, b_ioend_work);
xfs_buf_ioend(bp);
}
@@ -1050,8 +1050,8 @@ void
xfs_buf_ioend_async(
struct xfs_buf *bp)
{
- INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work);
- queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work);
+ INIT_WORK(&bp->b_ioend_work, xfs_buf_ioend_work);
+ queue_work(bp->b_ioend_wq, &bp->b_ioend_work);
}
void
@@ -1220,6 +1220,13 @@ _xfs_buf_ioapply(
*/
bp->b_error = 0;
+ /*
+ * Initialize the I/O completion workqueue if we haven't yet or the
+ * submitter has not opted to specify a custom one.
+ */
+ if (!bp->b_ioend_wq)
+ bp->b_ioend_wq = bp->b_target->bt_mount->m_buf_workqueue;
+
if (bp->b_flags & XBF_WRITE) {
if (bp->b_flags & XBF_SYNCIO)
rw = WRITE_SYNC;