]>
Commit | Line | Data |
---|---|---|
c5830388 GKH |
1 | From 7af7a8e19f0c5425ff639b0f0d2d244c2a647724 Mon Sep 17 00:00:00 2001 |
2 | From: Huang Ying <ying.huang@intel.com> | |
3 | Date: Fri, 28 Dec 2018 00:39:53 -0800 | |
4 | Subject: mm, swap: fix swapoff with KSM pages | |
5 | ||
6 | From: Huang Ying <ying.huang@intel.com> | |
7 | ||
8 | commit 7af7a8e19f0c5425ff639b0f0d2d244c2a647724 upstream. | |
9 | ||
10 | KSM pages may be mapped to the multiple VMAs that cannot be reached from | |
11 | one anon_vma. So during swapin, a new copy of the page need to be | |
12 | generated if a different anon_vma is needed, please refer to comments of | |
13 | ksm_might_need_to_copy() for details. | |
14 | ||
15 | During swapoff, unuse_vma() uses anon_vma (if available) to locate VMA and | |
16 | virtual address mapped to the page, so not all mappings to a swapped out | |
17 | KSM page could be found. So in try_to_unuse(), even if the swap count of | |
18 | a swap entry isn't zero, the page needs to be deleted from swap cache, so | |
19 | that, in the next round a new page could be allocated and swapin for the | |
20 | other mappings of the swapped out KSM page. | |
21 | ||
22 | But this contradicts with the THP swap support. Where the THP could be | |
23 | deleted from swap cache only after the swap count of every swap entry in | |
24 | the huge swap cluster backing the THP has reach 0. So try_to_unuse() is | |
25 | changed in commit e07098294adf ("mm, THP, swap: support to reclaim swap | |
26 | space for THP swapped out") to check that before delete a page from swap | |
27 | cache, but this has broken KSM swapoff too. | |
28 | ||
29 | Fortunately, KSM is for the normal pages only, so the original behavior | |
30 | for KSM pages could be restored easily via checking PageTransCompound(). | |
31 | That is how this patch works. | |
32 | ||
33 | The bug is introduced by e07098294adf ("mm, THP, swap: support to reclaim | |
34 | swap space for THP swapped out"), which is merged by v4.14-rc1. So I | |
35 | think we should backport the fix to from 4.14 on. But Hugh thinks it may | |
36 | be rare for the KSM pages being in the swap device when swapoff, so nobody | |
37 | reports the bug so far. | |
38 | ||
39 | Link: http://lkml.kernel.org/r/20181226051522.28442-1-ying.huang@intel.com | |
40 | Fixes: e07098294adf ("mm, THP, swap: support to reclaim swap space for THP swapped out") | |
41 | Signed-off-by: "Huang, Ying" <ying.huang@intel.com> | |
42 | Reported-by: Hugh Dickins <hughd@google.com> | |
43 | Tested-by: Hugh Dickins <hughd@google.com> | |
44 | Acked-by: Hugh Dickins <hughd@google.com> | |
45 | Cc: Rik van Riel <riel@redhat.com> | |
46 | Cc: Johannes Weiner <hannes@cmpxchg.org> | |
47 | Cc: Minchan Kim <minchan@kernel.org> | |
48 | Cc: Shaohua Li <shli@kernel.org> | |
49 | Cc: Daniel Jordan <daniel.m.jordan@oracle.com> | |
50 | Cc: <stable@vger.kernel.org> | |
51 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
52 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
53 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
54 | ||
55 | --- | |
56 | mm/swapfile.c | 3 ++- | |
57 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
58 | ||
59 | --- a/mm/swapfile.c | |
60 | +++ b/mm/swapfile.c | |
61 | @@ -2218,7 +2218,8 @@ int try_to_unuse(unsigned int type, bool | |
62 | */ | |
63 | if (PageSwapCache(page) && | |
64 | likely(page_private(page) == entry.val) && | |
65 | - !page_swapped(page)) | |
66 | + (!PageTransCompound(page) || | |
67 | + !swap_page_trans_huge_swapped(si, entry))) | |
68 | delete_from_swap_cache(compound_head(page)); | |
69 | ||
70 | /* |