On Tue, Apr 16, 2019 at 03:45:14PM +0200, Laurent Dufour wrote: > Vinayak Menon faced a panic because one thread was page faulting a page in > swap, while another one was mprotecting a part of the VMA leading to a VMA > split. > This raise a panic in swap_vma_readahead() because the VMA's boundaries > were not more matching the faulting address. > > To avoid this, if the page is not found in the swap, the speculative page > fault is aborted to retry a regular page fault. > > Reported-by: Vinayak Menon <vinmenon@xxxxxxxxxxxxxx> > Signed-off-by: Laurent Dufour <ldufour@xxxxxxxxxxxxx> Reviewed-by: Jérôme Glisse <jglisse@xxxxxxxxxx> Note that you should also skip non swap entry in do_swap_page() when doing speculative page fault at very least you need to is_device_private_entry() case. But this should either be part of patch 22 or another patch to fix swap case. > --- > mm/memory.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/mm/memory.c b/mm/memory.c > index 6e6bf61c0e5c..1991da97e2db 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2900,6 +2900,17 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) > lru_cache_add_anon(page); > swap_readpage(page, true); > } > + } else if (vmf->flags & FAULT_FLAG_SPECULATIVE) { > + /* > + * Don't try readahead during a speculative page fault > + * as the VMA's boundaries may change in our back. > + * If the page is not in the swap cache and synchronous > + * read is disabled, fall back to the regular page > + * fault mechanism. > + */ > + delayacct_clear_flag(DELAYACCT_PF_SWAPIN); > + ret = VM_FAULT_RETRY; > + goto out; > } else { > page = swapin_readahead(entry, GFP_HIGHUSER_MOVABLE, > vmf); > -- > 2.21.0 >