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