If swap-out is using filesystem operations (SWP_FS_OPS), then it is not safe to enter the FS for reclaim. So only down-grade the requirement for swap pages to __GFP_IO after checking that SWP_FS_OPS are not being used. Signed-off-by: NeilBrown <neilb@xxxxxxx> --- mm/vmscan.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index fb9584641ac7..049ff4494081 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1513,8 +1513,14 @@ static unsigned int shrink_page_list(struct list_head *page_list, if (!sc->may_unmap && page_mapped(page)) goto keep_locked; + /* ->flags can be updated non-atomicially (scan_swap_map_slots), + * but that will never affect SWP_FS_OPS, so the data_race + * is safe. + */ may_enter_fs = (sc->gfp_mask & __GFP_FS) || - (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); + (PageSwapCache(page) && + !data_race(page_swap_info(page)->flags & SWP_FS_OPS) && + (sc->gfp_mask & __GFP_IO)); /* * The number of dirty pages determines if a node is marked @@ -1682,7 +1688,9 @@ static unsigned int shrink_page_list(struct list_head *page_list, goto activate_locked_split; } - may_enter_fs = true; + if ((sc->gfp_mask & __GFP_FS) || + !data_race(page_swap_info(page)->flags & SWP_FS_OPS)) + may_enter_fs = true; /* Adding to swap updated mapping */ mapping = page_mapping(page);