Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/mm: add memory failure clean pagecache test

This patch adds a new testcase to validate memory failure handling for
clean pagecache. This test performs similar operations as anonymous pages
except allocating memory using mmap() with a file fd.

This test helps ensure that memory failure handling for clean pagecache
works correctly, including unchanged page content, page isolation, and
recovery paths.

Link: https://lkml.kernel.org/r/20260206031639.2707102-3-linmiaohe@huawei.com
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202601221142.mDWA1ucw-lkp@intel.com/
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Miaohe Lin and committed by
Andrew Morton
12e8a2fa ff4ef2fb

+66
+66
tools/testing/selftests/mm/memory-failure.c
··· 10 10 #include <sys/mman.h> 11 11 #include <linux/mman.h> 12 12 #include <linux/string.h> 13 + #include <unistd.h> 13 14 #include <signal.h> 14 15 #include <setjmp.h> 15 16 #include <unistd.h> 16 17 #include <fcntl.h> 18 + #include <sys/vfs.h> 19 + #include <linux/magic.h> 20 + #include <errno.h> 17 21 18 22 #include "vm_util.h" 19 23 ··· 28 24 29 25 enum result_type { 30 26 MADV_HARD_ANON, 27 + MADV_HARD_CLEAN_PAGECACHE, 31 28 MADV_SOFT_ANON, 29 + MADV_SOFT_CLEAN_PAGECACHE, 32 30 }; 33 31 34 32 static jmp_buf signal_jmp_buf; ··· 160 154 161 155 switch (type) { 162 156 case MADV_SOFT_ANON: 157 + case MADV_HARD_CLEAN_PAGECACHE: 158 + case MADV_SOFT_CLEAN_PAGECACHE: 163 159 /* It is not expected to receive a SIGBUS signal. */ 164 160 ASSERT_EQ(setjmp, 0); 165 161 ··· 242 234 cleanup(_metadata, self, addr); 243 235 244 236 ASSERT_EQ(munmap(addr, self->page_size), 0); 237 + } 238 + 239 + /* Borrowed from mm/gup_longterm.c. */ 240 + static int get_fs_type(int fd) 241 + { 242 + struct statfs fs; 243 + int ret; 244 + 245 + do { 246 + ret = fstatfs(fd, &fs); 247 + } while (ret && errno == EINTR); 248 + 249 + return ret ? 0 : (int)fs.f_type; 250 + } 251 + 252 + TEST_F(memory_failure, clean_pagecache) 253 + { 254 + const char *fname = "./clean-page-cache-test-file"; 255 + int fd; 256 + char *addr; 257 + int ret; 258 + int fs_type; 259 + 260 + fd = open(fname, O_RDWR | O_CREAT, 0664); 261 + if (fd < 0) 262 + SKIP(return, "failed to open test file.\n"); 263 + unlink(fname); 264 + ftruncate(fd, self->page_size); 265 + fs_type = get_fs_type(fd); 266 + if (!fs_type || fs_type == TMPFS_MAGIC) 267 + SKIP(return, "unsupported filesystem :%x\n", fs_type); 268 + 269 + addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE, 270 + MAP_SHARED, fd, 0); 271 + if (addr == MAP_FAILED) 272 + SKIP(return, "mmap failed, not enough memory.\n"); 273 + memset(addr, 0xce, self->page_size); 274 + fsync(fd); 275 + 276 + prepare(_metadata, self, addr); 277 + 278 + ret = sigsetjmp(signal_jmp_buf, 1); 279 + if (!self->triggered) { 280 + self->triggered = true; 281 + ASSERT_EQ(variant->inject(self, addr), 0); 282 + FORCE_READ(*addr); 283 + } 284 + 285 + if (variant->type == MADV_HARD) 286 + check(_metadata, self, addr, MADV_HARD_CLEAN_PAGECACHE, ret); 287 + else 288 + check(_metadata, self, addr, MADV_SOFT_CLEAN_PAGECACHE, ret); 289 + 290 + cleanup(_metadata, self, addr); 291 + 292 + ASSERT_EQ(munmap(addr, self->page_size), 0); 293 + 294 + ASSERT_EQ(close(fd), 0); 245 295 } 246 296 247 297 TEST_HARNESS_MAIN