Skip to content

Commit d0b51bf

Browse files
committed
Revert "mm: shmem: don't truncate page if memory failure happens"
This reverts commit b9d02f1. The error handling of that patch was fundamentally broken, and it needs to be entirely re-done. For example, in shmem_write_begin() it would call shmem_getpage(), then ignore the error return from that, and look at the page pointer contents instead. And in shmem_read_mapping_page_gfp(), the patch tested PageHWPoison() on a page pointer that two lines earlier had potentially been set as an error pointer. These issues could be individually fixed, but when it has this many issues, I'm just reverting it instead of waiting for fixes. Link: https://lore.kernel.org/linux-mm/[email protected]/ Reported-by: Ajay Garg <[email protected]> Reported-by: Jens Axboe <[email protected]> Cc: Yang Shi <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a613224 commit d0b51bf

File tree

3 files changed

+6
-51
lines changed

3 files changed

+6
-51
lines changed

mm/memory-failure.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
#include <linux/ratelimit.h>
5959
#include <linux/page-isolation.h>
6060
#include <linux/pagewalk.h>
61-
#include <linux/shmem_fs.h>
6261
#include "internal.h"
6362
#include "ras/ras_event.h"
6463

@@ -868,7 +867,6 @@ static int me_pagecache_clean(struct page_state *ps, struct page *p)
868867
{
869868
int ret;
870869
struct address_space *mapping;
871-
bool extra_pins;
872870

873871
delete_from_lru_cache(p);
874872

@@ -897,24 +895,18 @@ static int me_pagecache_clean(struct page_state *ps, struct page *p)
897895
goto out;
898896
}
899897

900-
/*
901-
* The shmem page is kept in page cache instead of truncating
902-
* so is expected to have an extra refcount after error-handling.
903-
*/
904-
extra_pins = shmem_mapping(mapping);
905-
906898
/*
907899
* Truncation is a bit tricky. Enable it per file system for now.
908900
*
909901
* Open: to take i_rwsem or not for this? Right now we don't.
910902
*/
911903
ret = truncate_error_page(p, page_to_pfn(p), mapping);
912-
if (has_extra_refcount(ps, p, extra_pins))
913-
ret = MF_FAILED;
914-
915904
out:
916905
unlock_page(p);
917906

907+
if (has_extra_refcount(ps, p, false))
908+
ret = MF_FAILED;
909+
918910
return ret;
919911
}
920912

mm/shmem.c

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,7 +2456,6 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
24562456
struct inode *inode = mapping->host;
24572457
struct shmem_inode_info *info = SHMEM_I(inode);
24582458
pgoff_t index = pos >> PAGE_SHIFT;
2459-
int ret = 0;
24602459

24612460
/* i_rwsem is held by caller */
24622461
if (unlikely(info->seals & (F_SEAL_GROW |
@@ -2467,15 +2466,7 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
24672466
return -EPERM;
24682467
}
24692468

2470-
ret = shmem_getpage(inode, index, pagep, SGP_WRITE);
2471-
2472-
if (*pagep && PageHWPoison(*pagep)) {
2473-
unlock_page(*pagep);
2474-
put_page(*pagep);
2475-
ret = -EIO;
2476-
}
2477-
2478-
return ret;
2469+
return shmem_getpage(inode, index, pagep, SGP_WRITE);
24792470
}
24802471

24812472
static int
@@ -2562,12 +2553,6 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
25622553
if (sgp == SGP_CACHE)
25632554
set_page_dirty(page);
25642555
unlock_page(page);
2565-
2566-
if (PageHWPoison(page)) {
2567-
put_page(page);
2568-
error = -EIO;
2569-
break;
2570-
}
25712556
}
25722557

25732558
/*
@@ -3107,20 +3092,14 @@ static const char *shmem_get_link(struct dentry *dentry,
31073092
page = find_get_page(inode->i_mapping, 0);
31083093
if (!page)
31093094
return ERR_PTR(-ECHILD);
3110-
if (PageHWPoison(page) ||
3111-
!PageUptodate(page)) {
3095+
if (!PageUptodate(page)) {
31123096
put_page(page);
31133097
return ERR_PTR(-ECHILD);
31143098
}
31153099
} else {
31163100
error = shmem_getpage(inode, 0, &page, SGP_READ);
31173101
if (error)
31183102
return ERR_PTR(error);
3119-
if (page && PageHWPoison(page)) {
3120-
unlock_page(page);
3121-
put_page(page);
3122-
return ERR_PTR(-ECHILD);
3123-
}
31243103
unlock_page(page);
31253104
}
31263105
set_delayed_call(done, shmem_put_link, page);
@@ -3771,13 +3750,6 @@ static void shmem_destroy_inodecache(void)
37713750
kmem_cache_destroy(shmem_inode_cachep);
37723751
}
37733752

3774-
/* Keep the page in page cache instead of truncating it */
3775-
static int shmem_error_remove_page(struct address_space *mapping,
3776-
struct page *page)
3777-
{
3778-
return 0;
3779-
}
3780-
37813753
const struct address_space_operations shmem_aops = {
37823754
.writepage = shmem_writepage,
37833755
.set_page_dirty = __set_page_dirty_no_writeback,
@@ -3788,7 +3760,7 @@ const struct address_space_operations shmem_aops = {
37883760
#ifdef CONFIG_MIGRATION
37893761
.migratepage = migrate_page,
37903762
#endif
3791-
.error_remove_page = shmem_error_remove_page,
3763+
.error_remove_page = generic_error_remove_page,
37923764
};
37933765
EXPORT_SYMBOL(shmem_aops);
37943766

@@ -4199,10 +4171,6 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
41994171
page = ERR_PTR(error);
42004172
else
42014173
unlock_page(page);
4202-
4203-
if (PageHWPoison(page))
4204-
page = ERR_PTR(-EIO);
4205-
42064174
return page;
42074175
#else
42084176
/*

mm/userfaultfd.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,6 @@ static int mcontinue_atomic_pte(struct mm_struct *dst_mm,
232232
goto out;
233233
}
234234

235-
if (PageHWPoison(page)) {
236-
ret = -EIO;
237-
goto out_release;
238-
}
239-
240235
ret = mfill_atomic_install_pte(dst_mm, dst_pmd, dst_vma, dst_addr,
241236
page, false, wp_copy);
242237
if (ret)

0 commit comments

Comments
 (0)