diff options
author | Dave Chinner <dchinner@redhat.com> | 2016-02-15 17:23:12 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-02-15 17:23:12 +1100 |
commit | e10de3723c53378e7cf441529f563c316fdc0dd3 (patch) | |
tree | a21990a6de7476c768ec5924ed5cb4d40d3efe5f /fs/xfs/xfs_aops.h | |
parent | bfce7d2e2d5ee05e9d465888905c66a70a9c243c (diff) | |
download | linux-e10de3723c53378e7cf441529f563c316fdc0dd3.tar.gz linux-e10de3723c53378e7cf441529f563c316fdc0dd3.tar.bz2 linux-e10de3723c53378e7cf441529f563c316fdc0dd3.zip |
xfs: don't chain ioends during writepage submission
Currently we can build a long ioend chain during ->writepages that
gets attached to the writepage context. IO submission only then
occurs when we finish all the writepage processing. This means we
can have many ioends allocated and pending, and this violates the
mempool guarantees that we need to give about forwards progress.
i.e. we really should only have one ioend being built at a time,
otherwise we may drain the mempool trying to allocate a new ioend
and that blocks submission, completion and freeing of ioends that
are already in progress.
To prevent this situation from happening, we need to submit ioends
for IO as soon as they are ready for dispatch rather than queuing
them for later submission. This means the ioends have bios built
immediately and they get queued on any plug that is current active.
Hence if we schedule away from writeback, the ioends that have been
built will make forwards progress due to the plug flushing on
context switch. This will also prevent context switches from
creating unnecessary IO submission latency.
We can't completely avoid having nested IO allocation - when we have
a block size smaller than a page size, we still need to hold the
ioend submission until after we have marked the current page dirty.
Hence we may need multiple ioends to be held while the current page
is completely mapped and made ready for IO dispatch. We cannot avoid
this problem - the current code already has this ioend chaining
within a page so we can mostly ignore that it occurs.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_aops.h')
-rw-r--r-- | fs/xfs/xfs_aops.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 3c3f1a37a1c7..4e01bd5b6426 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -41,7 +41,7 @@ enum { * It can manage several multi-page bio's at once. */ typedef struct xfs_ioend { - struct xfs_ioend *io_list; /* next ioend in chain */ + struct list_head io_list; /* next ioend in chain */ unsigned int io_type; /* delalloc / unwritten */ int io_error; /* I/O error code */ atomic_t io_remaining; /* hold count */ |