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

HWPOISON: Add a madvise() injector for soft page offlining

Process based injection is much easier to handle for test programs,
who can first bring a page into a specific state and then test.
So add a new MADV_SOFT_OFFLINE to soft offline a page, similar
to the existing hard offline injector.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

authored by

Andi Kleen and committed by
Andi Kleen
afcf938e facb6011

+13 -3
+1
include/asm-generic/mman-common.h
··· 40 40 #define MADV_DONTFORK 10 /* don't inherit across fork */ 41 41 #define MADV_DOFORK 11 /* do inherit across fork */ 42 42 #define MADV_HWPOISON 100 /* poison a page for testing */ 43 + #define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ 43 44 44 45 #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ 45 46 #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
+12 -3
mm/madvise.c
··· 9 9 #include <linux/pagemap.h> 10 10 #include <linux/syscalls.h> 11 11 #include <linux/mempolicy.h> 12 + #include <linux/page-isolation.h> 12 13 #include <linux/hugetlb.h> 13 14 #include <linux/sched.h> 14 15 #include <linux/ksm.h> ··· 223 222 /* 224 223 * Error injection support for memory error handling. 225 224 */ 226 - static int madvise_hwpoison(unsigned long start, unsigned long end) 225 + static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end) 227 226 { 228 227 int ret = 0; 229 228 ··· 234 233 int ret = get_user_pages_fast(start, 1, 0, &p); 235 234 if (ret != 1) 236 235 return ret; 236 + if (bhv == MADV_SOFT_OFFLINE) { 237 + printk(KERN_INFO "Soft offlining page %lx at %lx\n", 238 + page_to_pfn(p), start); 239 + ret = soft_offline_page(p, MF_COUNT_INCREASED); 240 + if (ret) 241 + break; 242 + continue; 243 + } 237 244 printk(KERN_INFO "Injecting memory failure for page %lx at %lx\n", 238 245 page_to_pfn(p), start); 239 246 /* Ignore return value for now */ ··· 342 333 size_t len; 343 334 344 335 #ifdef CONFIG_MEMORY_FAILURE 345 - if (behavior == MADV_HWPOISON) 346 - return madvise_hwpoison(start, start+len_in); 336 + if (behavior == MADV_HWPOISON || behavior == MADV_SOFT_OFFLINE) 337 + return madvise_hwpoison(behavior, start, start+len_in); 347 338 #endif 348 339 if (!madvise_behavior_valid(behavior)) 349 340 return error;