Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2018-06-20 10:45:54 +0200
committerVlastimil Babka <vbabka@suse.cz>2018-06-20 10:45:54 +0200
commit329f6908877e80c43142d143edca3c7d6967bdc1 (patch)
tree20010b74b29e4fb80b6562f9808865dded097899
parent18461bb563ad4005345a2703e59f2eef3c46539c (diff)
mm, swap: fix false error message in __swp_swapcount()
(VM Functionality, bsc#1098043).
-rw-r--r--patches.fixes/mm-swap-fix-false-error-message-in-_swp_swapcount.patch89
-rw-r--r--series.conf1
2 files changed, 90 insertions, 0 deletions
diff --git a/patches.fixes/mm-swap-fix-false-error-message-in-_swp_swapcount.patch b/patches.fixes/mm-swap-fix-false-error-message-in-_swp_swapcount.patch
new file mode 100644
index 0000000000..7e1819b9eb
--- /dev/null
+++ b/patches.fixes/mm-swap-fix-false-error-message-in-_swp_swapcount.patch
@@ -0,0 +1,89 @@
+From: Huang Ying <huang.ying.caritas@gmail.com>
+Date: Wed, 15 Nov 2017 17:33:15 -0800
+Subject: mm, swap: fix false error message in __swp_swapcount()
+Git-commit: e9a6effa500526e2a19d5ad042cb758b55b1ef93
+Patch-mainline: v4.15-rc1
+References: VM Functionality, bsc#1098043
+
+[ Backport contains parts of 0bcac06f27d7528591c27ac2b093ccd71c5d0168 that
+ introduce swp_swap_info() ]
+
+When a page fault occurs for a swap entry, the physical swap readahead
+(not the VMA base swap readahead) may readahead several swap entries
+after the fault swap entry. The readahead algorithm calculates some of
+the swap entries to readahead via increasing the offset of the fault
+swap entry without checking whether they are beyond the end of the swap
+device and it relys on the __swp_swapcount() and swapcache_prepare() to
+check it. Although __swp_swapcount() checks for the swap entry passed
+in, it will complain with the error message as follow for the expected
+invalid swap entry. This may make the end users confused.
+
+ swap_info_get: Bad swap offset entry 0200f8a7
+
+To fix the false error message, the swap entry checking is added in
+swapin_readahead() to avoid to pass the out-of-bound swap entries and
+the swap entry reserved for the swap header to __swp_swapcount() and
+swapcache_prepare().
+
+Link: http://lkml.kernel.org/r/20171102054225.22897-1-ying.huang@intel.com
+Fixes: e8c26ab60598 ("mm/swap: skip readahead for unreferenced swap slots")
+Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
+Reported-by: Christian Kujau <lists@nerdbynature.de>
+Acked-by: Minchan Kim <minchan@kernel.org>
+Suggested-by: Minchan Kim <minchan@kernel.org>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: <stable@vger.kernel.org> [4.11+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+---
+ include/linux/swap.h | 1 +
+ mm/swap_state.c | 3 +++
+ mm/swapfile.c | 5 +++++
+ 3 files changed, 9 insertions(+)
+
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -427,6 +427,7 @@ extern int page_swapcount(struct page *)
+ extern int __swp_swapcount(swp_entry_t entry);
+ extern int swp_swapcount(swp_entry_t entry);
+ extern struct swap_info_struct *page_swap_info(struct page *);
++extern struct swap_info_struct *swp_swap_info(swp_entry_t entry);
+ extern bool reuse_swap_page(struct page *, int *);
+ extern int try_to_free_swap(struct page *);
+ struct backing_dev_info;
+--- a/mm/swap_state.c
++++ b/mm/swap_state.c
+@@ -500,6 +500,7 @@ struct page *swapin_readahead(swp_entry_
+ unsigned long offset = entry_offset;
+ unsigned long start_offset, end_offset;
+ unsigned long mask;
++ struct swap_info_struct *si = swp_swap_info(entry);
+ struct blk_plug plug;
+
+ mask = swapin_nr_pages(offset) - 1;
+@@ -511,6 +512,8 @@ struct page *swapin_readahead(swp_entry_
+ end_offset = offset | mask;
+ if (!start_offset) /* First page is swap header. */
+ start_offset++;
++ if (end_offset >= si->max)
++ end_offset = si->max - 1;
+
+ blk_start_plug(&plug);
+ for (offset = start_offset; offset <= end_offset ; offset++) {
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -3065,6 +3065,11 @@ int swapcache_prepare(swp_entry_t entry)
+ return __swap_duplicate(entry, SWAP_HAS_CACHE);
+ }
+
++struct swap_info_struct *swp_swap_info(swp_entry_t entry)
++{
++ return swap_info[swp_type(entry)];
++}
++
+ struct swap_info_struct *page_swap_info(struct page *page)
+ {
+ swp_entry_t swap = { .val = page_private(page) };
diff --git a/series.conf b/series.conf
index b7e262f81f..4b3874fa09 100644
--- a/series.conf
+++ b/series.conf
@@ -8366,6 +8366,7 @@
patches.fixes/ocfs2-fix-cluster-hang-after-a-node-dies.patch
patches.fixes/ocfs2-should-wait-dio-before-inode-lock-in-ocfs2_set.patch
patches.fixes/ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_bloc.patch
+ patches.fixes/mm-swap-fix-false-error-message-in-_swp_swapcount.patch
patches.fixes/mm-page-writeback.c-remove-unused-parameter-from-bal.patch
patches.fixes/0001-mm-drop-migrate-type-checks-from-has_unmovable_pages.patch
patches.fixes/0001-mm-distinguish-CMA-and-MOVABLE-isolation-in-has_unmo.patch