|
Mel Gorman |
91b69d |
From ef355ceff0a14dae65451f9e0f5cbb9408c69977 Mon Sep 17 00:00:00 2001
|
|
Mel Gorman |
91b69d |
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Mel Gorman |
91b69d |
Date: Sat, 13 Nov 2021 12:03:03 -0800
|
|
Mel Gorman |
91b69d |
Subject: [PATCH] Revert "mm: shmem: don't truncate page if memory failure
|
|
Mel Gorman |
91b69d |
happens"
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
References: git fixes (mm/shmem)
|
|
Mel Gorman |
91b69d |
Patch-mainline: v5.16
|
|
Mel Gorman |
91b69d |
Git-commit: d0b51bfb23a21de771be3fd9c32ab072c2138dbd
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
This reverts commit b9d02f1bdd98f38e6e5ecacc9786a8f58f3f8b2c.
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
The error handling of that patch was fundamentally broken, and it needs
|
|
Mel Gorman |
91b69d |
to be entirely re-done.
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
For example, in shmem_write_begin() it would call shmem_getpage(), then
|
|
Mel Gorman |
91b69d |
ignore the error return from that, and look at the page pointer contents
|
|
Mel Gorman |
91b69d |
instead.
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
And in shmem_read_mapping_page_gfp(), the patch tested PageHWPoison() on
|
|
Mel Gorman |
91b69d |
a page pointer that two lines earlier had potentially been set as an
|
|
Mel Gorman |
91b69d |
error pointer.
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
These issues could be individually fixed, but when it has this many
|
|
Mel Gorman |
91b69d |
issues, I'm just reverting it instead of waiting for fixes.
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
Link: https://lore.kernel.org/linux-mm/20211111084617.6746-1-ajaygargnsit@gmail.com/
|
|
Mel Gorman |
91b69d |
Reported-by: Ajay Garg <ajaygargnsit@gmail.com>
|
|
Mel Gorman |
91b69d |
Reported-by: Jens Axboe <axboe@kernel.dk>
|
|
Mel Gorman |
91b69d |
Cc: Yang Shi <shy828301@gmail.com>
|
|
Mel Gorman |
91b69d |
Cc: Arnd Bergmann <arnd@arndb.de>
|
|
Mel Gorman |
91b69d |
Cc: Andrew Morton <akpm@linux-foundation.org>
|
|
Mel Gorman |
91b69d |
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Mel Gorman |
91b69d |
Signed-off-by: Mel Gorman <mgorman@suse.de>
|
|
Mel Gorman |
91b69d |
---
|
|
Mel Gorman |
91b69d |
mm/memory-failure.c | 14 +++-----------
|
|
Mel Gorman |
91b69d |
mm/shmem.c | 38 +++-----------------------------------
|
|
Mel Gorman |
91b69d |
mm/userfaultfd.c | 5 -----
|
|
Mel Gorman |
91b69d |
3 files changed, 6 insertions(+), 51 deletions(-)
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
|
|
Mel Gorman |
91b69d |
index 1db0d390175a..05ba4b23ff52 100644
|
|
Mel Gorman |
91b69d |
--- a/mm/memory-failure.c
|
|
Mel Gorman |
91b69d |
+++ b/mm/memory-failure.c
|
|
Mel Gorman |
91b69d |
@@ -57,7 +57,6 @@
|
|
Mel Gorman |
91b69d |
#include <linux/ratelimit.h>
|
|
Mel Gorman |
91b69d |
#include <linux/page-isolation.h>
|
|
Mel Gorman |
91b69d |
#include <linux/pagewalk.h>
|
|
Mel Gorman |
91b69d |
-#include <linux/shmem_fs.h>
|
|
Mel Gorman |
91b69d |
#include "internal.h"
|
|
Mel Gorman |
91b69d |
#include "ras/ras_event.h"
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
@@ -868,7 +867,6 @@ static int me_pagecache_clean(struct page_state *ps, struct page *p)
|
|
Mel Gorman |
91b69d |
{
|
|
Mel Gorman |
91b69d |
int ret;
|
|
Mel Gorman |
91b69d |
struct address_space *mapping;
|
|
Mel Gorman |
91b69d |
- bool extra_pins;
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
delete_from_lru_cache(p);
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
@@ -897,24 +895,18 @@ static int me_pagecache_clean(struct page_state *ps, struct page *p)
|
|
Mel Gorman |
91b69d |
goto out;
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
- /*
|
|
Mel Gorman |
91b69d |
- * The shmem page is kept in page cache instead of truncating
|
|
Mel Gorman |
91b69d |
- * so is expected to have an extra refcount after error-handling.
|
|
Mel Gorman |
91b69d |
- */
|
|
Mel Gorman |
91b69d |
- extra_pins = shmem_mapping(mapping);
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
/*
|
|
Mel Gorman |
91b69d |
* Truncation is a bit tricky. Enable it per file system for now.
|
|
Mel Gorman |
91b69d |
*
|
|
Mel Gorman |
91b69d |
* Open: to take i_rwsem or not for this? Right now we don't.
|
|
Mel Gorman |
91b69d |
*/
|
|
Mel Gorman |
91b69d |
ret = truncate_error_page(p, page_to_pfn(p), mapping);
|
|
Mel Gorman |
91b69d |
- if (has_extra_refcount(ps, p, extra_pins))
|
|
Mel Gorman |
91b69d |
- ret = MF_FAILED;
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
out:
|
|
Mel Gorman |
91b69d |
unlock_page(p);
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
+ if (has_extra_refcount(ps, p, false))
|
|
Mel Gorman |
91b69d |
+ ret = MF_FAILED;
|
|
Mel Gorman |
91b69d |
+
|
|
Mel Gorman |
91b69d |
return ret;
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
diff --git a/mm/shmem.c b/mm/shmem.c
|
|
Mel Gorman |
91b69d |
index 89062ce85db8..b5860f4a2738 100644
|
|
Mel Gorman |
91b69d |
--- a/mm/shmem.c
|
|
Mel Gorman |
91b69d |
+++ b/mm/shmem.c
|
|
Mel Gorman |
91b69d |
@@ -2456,7 +2456,6 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
|
|
Mel Gorman |
91b69d |
struct inode *inode = mapping->host;
|
|
Mel Gorman |
91b69d |
struct shmem_inode_info *info = SHMEM_I(inode);
|
|
Mel Gorman |
91b69d |
pgoff_t index = pos >> PAGE_SHIFT;
|
|
Mel Gorman |
91b69d |
- int ret = 0;
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
/* i_rwsem is held by caller */
|
|
Mel Gorman |
91b69d |
if (unlikely(info->seals & (F_SEAL_GROW |
|
|
Mel Gorman |
91b69d |
@@ -2467,15 +2466,7 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
|
|
Mel Gorman |
91b69d |
return -EPERM;
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
- ret = shmem_getpage(inode, index, pagep, SGP_WRITE);
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
- if (*pagep && PageHWPoison(*pagep)) {
|
|
Mel Gorman |
91b69d |
- unlock_page(*pagep);
|
|
Mel Gorman |
91b69d |
- put_page(*pagep);
|
|
Mel Gorman |
91b69d |
- ret = -EIO;
|
|
Mel Gorman |
91b69d |
- }
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
- return ret;
|
|
Mel Gorman |
91b69d |
+ return shmem_getpage(inode, index, pagep, SGP_WRITE);
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
static int
|
|
Mel Gorman |
91b69d |
@@ -2562,12 +2553,6 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
|
Mel Gorman |
91b69d |
if (sgp == SGP_CACHE)
|
|
Mel Gorman |
91b69d |
set_page_dirty(page);
|
|
Mel Gorman |
91b69d |
unlock_page(page);
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
- if (PageHWPoison(page)) {
|
|
Mel Gorman |
91b69d |
- put_page(page);
|
|
Mel Gorman |
91b69d |
- error = -EIO;
|
|
Mel Gorman |
91b69d |
- break;
|
|
Mel Gorman |
91b69d |
- }
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
/*
|
|
Mel Gorman |
91b69d |
@@ -3129,8 +3114,7 @@ static const char *shmem_get_link(struct dentry *dentry,
|
|
Mel Gorman |
91b69d |
page = find_get_page(inode->i_mapping, 0);
|
|
Mel Gorman |
91b69d |
if (!page)
|
|
Mel Gorman |
91b69d |
return ERR_PTR(-ECHILD);
|
|
Mel Gorman |
91b69d |
- if (PageHWPoison(page) ||
|
|
Mel Gorman |
91b69d |
- !PageUptodate(page)) {
|
|
Mel Gorman |
91b69d |
+ if (!PageUptodate(page)) {
|
|
Mel Gorman |
91b69d |
put_page(page);
|
|
Mel Gorman |
91b69d |
return ERR_PTR(-ECHILD);
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
@@ -3138,11 +3122,6 @@ static const char *shmem_get_link(struct dentry *dentry,
|
|
Mel Gorman |
91b69d |
error = shmem_getpage(inode, 0, &page, SGP_READ);
|
|
Mel Gorman |
91b69d |
if (error)
|
|
Mel Gorman |
91b69d |
return ERR_PTR(error);
|
|
Mel Gorman |
91b69d |
- if (page && PageHWPoison(page)) {
|
|
Mel Gorman |
91b69d |
- unlock_page(page);
|
|
Mel Gorman |
91b69d |
- put_page(page);
|
|
Mel Gorman |
91b69d |
- return ERR_PTR(-ECHILD);
|
|
Mel Gorman |
91b69d |
- }
|
|
Mel Gorman |
91b69d |
unlock_page(page);
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
set_delayed_call(done, shmem_put_link, page);
|
|
Mel Gorman |
91b69d |
@@ -3793,13 +3772,6 @@ static void shmem_destroy_inodecache(void)
|
|
Mel Gorman |
91b69d |
kmem_cache_destroy(shmem_inode_cachep);
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
-/* Keep the page in page cache instead of truncating it */
|
|
Mel Gorman |
91b69d |
-static int shmem_error_remove_page(struct address_space *mapping,
|
|
Mel Gorman |
91b69d |
- struct page *page)
|
|
Mel Gorman |
91b69d |
-{
|
|
Mel Gorman |
91b69d |
- return 0;
|
|
Mel Gorman |
91b69d |
-}
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
const struct address_space_operations shmem_aops = {
|
|
Mel Gorman |
91b69d |
.writepage = shmem_writepage,
|
|
Mel Gorman |
91b69d |
.set_page_dirty = __set_page_dirty_no_writeback,
|
|
Mel Gorman |
91b69d |
@@ -3810,7 +3782,7 @@ const struct address_space_operations shmem_aops = {
|
|
Mel Gorman |
91b69d |
#ifdef CONFIG_MIGRATION
|
|
Mel Gorman |
91b69d |
.migratepage = migrate_page,
|
|
Mel Gorman |
91b69d |
#endif
|
|
Mel Gorman |
91b69d |
- .error_remove_page = shmem_error_remove_page,
|
|
Mel Gorman |
91b69d |
+ .error_remove_page = generic_error_remove_page,
|
|
Mel Gorman |
91b69d |
};
|
|
Mel Gorman |
91b69d |
EXPORT_SYMBOL(shmem_aops);
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
@@ -4221,10 +4193,6 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
|
|
Mel Gorman |
91b69d |
page = ERR_PTR(error);
|
|
Mel Gorman |
91b69d |
else
|
|
Mel Gorman |
91b69d |
unlock_page(page);
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
- if (PageHWPoison(page))
|
|
Mel Gorman |
91b69d |
- page = ERR_PTR(-EIO);
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
return page;
|
|
Mel Gorman |
91b69d |
#else
|
|
Mel Gorman |
91b69d |
/*
|
|
Mel Gorman |
91b69d |
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
|
|
Mel Gorman |
91b69d |
index 5dc996bafbba..0e2132834bc7 100644
|
|
Mel Gorman |
91b69d |
--- a/mm/userfaultfd.c
|
|
Mel Gorman |
91b69d |
+++ b/mm/userfaultfd.c
|
|
Mel Gorman |
91b69d |
@@ -233,11 +233,6 @@ static int mcontinue_atomic_pte(struct mm_struct *dst_mm,
|
|
Mel Gorman |
91b69d |
goto out;
|
|
Mel Gorman |
91b69d |
}
|
|
Mel Gorman |
91b69d |
|
|
Mel Gorman |
91b69d |
- if (PageHWPoison(page)) {
|
|
Mel Gorman |
91b69d |
- ret = -EIO;
|
|
Mel Gorman |
91b69d |
- goto out_release;
|
|
Mel Gorman |
91b69d |
- }
|
|
Mel Gorman |
91b69d |
-
|
|
Mel Gorman |
91b69d |
ret = mfill_atomic_install_pte(dst_mm, dst_pmd, dst_vma, dst_addr,
|
|
Mel Gorman |
91b69d |
page, false, wp_copy);
|
|
Mel Gorman |
91b69d |
if (ret)
|