On Thu, Mar 10, 2022 at 11:47 AM David Howells <dhowells@xxxxxxxxxx> wrote: > > In afs_writepages_region(), if the dirty page we find is undergoing > writeback or write to cache, but the sync_mode is WB_SYNC_NONE, we go round > the loop trying the same page again and again with no pausing or waiting > unless and until another thread manages to clear the writeback and fscache > flags. > > Fix this with three measures: > > (1) Advance the start to after the page we found. > > (2) Break out of the loop and return if rescheduling is requested. > > (3) Arbitrarily give up after a maximum of 5 skips. > > Fixes: 31143d5d515e ("AFS: implement basic file write support") > Reported-by: Marc Dionne <marc.dionne@xxxxxxxxxxxx> > Signed-off-by: David Howells <dhowells@xxxxxxxxxx> > --- > > fs/afs/write.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/fs/afs/write.c b/fs/afs/write.c > index 85c9056ba9fb..bd0201f4939a 100644 > --- a/fs/afs/write.c > +++ b/fs/afs/write.c > @@ -701,7 +701,7 @@ static int afs_writepages_region(struct address_space *mapping, > struct folio *folio; > struct page *head_page; > ssize_t ret; > - int n; > + int n, skips = 0; > > _enter("%llx,%llx,", start, end); > > @@ -752,8 +752,15 @@ static int afs_writepages_region(struct address_space *mapping, > #ifdef CONFIG_AFS_FSCACHE > folio_wait_fscache(folio); > #endif > + } else { > + start += folio_size(folio); > } > folio_put(folio); > + if (wbc->sync_mode == WB_SYNC_NONE) { > + if (skips >= 5 || need_resched()) > + break; > + skips++; > + } > continue; > } Looks good in testing, the problem would show up in xfstests generic/285. Tested-by: Marc Dionne <marc.dionne@xxxxxxxxxxxx> Acked-by: Marc Dionne <marc.dionne@xxxxxxxxxxxx> Marc