Messages in this thread Patch in this message | | | Date | Sat, 1 Aug 2009 12:10:42 +0800 | From | Wu Fengguang <> | Subject | Re: Bug in kernel 2.6.31, Slow wb_kupdate writeout |
| |
On Fri, Jul 31, 2009 at 04:33:09AM +0800, Martin Bligh wrote: > (BTW: background ... I'm not picking through this code for fun, I'm > trying to debug writeback problems introduced in our new kernel > that are affecting Google production workloads ;-)) > > >> Well, I see two problems. One is that we set more_io based on > >> whether s_more_io is empty or not before we finish the loop. > >> I can't see how this can be correct, especially as there can be > >> other concurrent writers. So somehow we need to check when > >> we exit the loop, not during it. > > > > It is correct inside the loop, however with some overheads. > > > > We put it inside the loop because sometimes the whole filesystem is > > skipped and we shall not set more_io on them whether or not s_more_io > > is empty. > > My point was that you're setting more_io based on a condition > at a point in time that isn't when you return to the caller. > > By the time you return to the caller (after several more loops > iterations), that condition may no longer be true. > > One other way to address that would to be only to set if if we're > about to fall off the end of the loop, ie change it to: > > if (!list_empty(&sb->s_more_io) && list_empty(&sb->s_io)) > wbc->more_io = 1;
Ah I see it (as the below patch), looks reasonable to me.
Thanks, Fengguang
--- fs/fs-writeback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- sound-2.6.orig/fs/fs-writeback.c +++ sound-2.6/fs/fs-writeback.c @@ -544,9 +544,9 @@ void generic_sync_sb_inodes(struct super wbc->more_io = 1; break; } - if (!list_empty(&sb->s_more_io)) - wbc->more_io = 1; } + if (!list_empty(&sb->s_more_io) && list_empty(&sb->s_io)) + wbc->more_io = 1; if (sync) { struct inode *inode, *old_inode = NULL;
| |