On Thu, 28 Dec 2017, James Bottomley wrote: > On Thu, 2017-12-28 at 09:41 -0800, James Bottomley wrote: > > I'd guess that since they're both in io_schedule, the problem is that > > the io_scheduler is taking far too long servicing the requests due to > > some priority issue you've introduced. > > OK, so after some analysis, that turned out to be incorrect. The > problem seems to be that we're exiting do_swap_page() with locked pages > that have been read in from swap. > > Your changelogs are entirely unclear on why you changed the swapcache > setting logic in this patch: > > commit 0bcac06f27d7528591c27ac2b093ccd71c5d0168 > Author: Minchan Kim <minchan@xxxxxxxxxx> > Date: Wed Nov 15 17:33:07 2017 -0800 > > mm, swap: skip swapcache for swapin of synchronous device > > But I think you're using swapcache == NULL as a signal the page came > from a synchronous device. In which case the bug is that you've > forgotten we may already have picked up a page in > swap_readahead_detect() which you're wrongly keeping swapcache == NULL > for and the fix is this (it works on my system, although I'm still > getting an unaccountable shutdown delay). > > I still think we should revert this series, because this may not be the > only bug lurking in the code, so it should go through a lot more > rigorous testing than it has. Andrew, neither the fix below (works for me, though I have seen other swap funniness, most probably unrelated), nor the reversion preferred by James and Minchan (later in this linux-mm thread), was in 4.15-rc8: the sands of time are running out... Hugh > > James > > --- > > diff --git a/mm/memory.c b/mm/memory.c > index ca5674cbaff2..31f9845c340e 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2847,7 +2847,7 @@ EXPORT_SYMBOL(unmap_mapping_range); > int do_swap_page(struct vm_fault *vmf) > { > struct vm_area_struct *vma = vmf->vma; > - struct page *page = NULL, *swapcache = NULL; > + struct page *page = NULL, *swapcache; > struct mem_cgroup *memcg; > struct vma_swap_readahead swap_ra; > swp_entry_t entry; > @@ -2892,6 +2892,7 @@ int do_swap_page(struct vm_fault *vmf) > if (!page) > page = lookup_swap_cache(entry, vma_readahead ? vma : NULL, > vmf->address); > + swapcache = page; > if (!page) { > struct swap_info_struct *si = swp_swap_info(entry); >