Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 177627
b: refs/heads/master
c: 31d3d34
h: refs/heads/master
i:
  177625: cac2a11
  177623: 2ec5357
v: v3
  • Loading branch information
Wu Fengguang authored and Andi Kleen committed Dec 16, 2009
1 parent 4a3367a commit 76fef14
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7c116f2b0dbac4a1dd051c7a5e8cef37701cafd4
refs/heads/master: 31d3d3484f9bd263925ecaa341500ac2df3a5d9b
3 changes: 2 additions & 1 deletion trunk/Documentation/vm/hwpoison.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ hwpoison-inject module through debugfs

corrupt-pfn

Inject hwpoison fault at PFN echoed into this file.
Inject hwpoison fault at PFN echoed into this file. This does
some early filtering to avoid corrupted unintended pages in test suites.

unpoison-pfn

Expand Down
41 changes: 39 additions & 2 deletions trunk/mm/hwpoison-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,53 @@
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/pagemap.h>
#include "internal.h"

static struct dentry *hwpoison_dir;

static int hwpoison_inject(void *data, u64 val)
{
unsigned long pfn = val;
struct page *p;
int err;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
printk(KERN_INFO "Injecting memory failure at pfn %Lx\n", val);
return __memory_failure(val, 18, 0);

if (!pfn_valid(pfn))
return -ENXIO;

p = pfn_to_page(pfn);
/*
* This implies unable to support free buddy pages.
*/
if (!get_page_unless_zero(p))
return 0;

if (!PageLRU(p))
shake_page(p);
/*
* This implies unable to support non-LRU pages.
*/
if (!PageLRU(p))
return 0;

/*
* do a racy check with elevated page count, to make sure PG_hwpoison
* will only be set for the targeted owner (or on a free page).
* We temporarily take page lock for try_get_mem_cgroup_from_page().
* __memory_failure() will redo the check reliably inside page lock.
*/
lock_page(p);
err = hwpoison_filter(p);
unlock_page(p);
if (err)
return 0;

printk(KERN_INFO "Injecting memory failure at pfn %lx\n", pfn);
return __memory_failure(pfn, 18, MF_COUNT_INCREASED);
}

static int hwpoison_unpoison(void *data, u64 val)
Expand Down
2 changes: 2 additions & 0 deletions trunk/mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,5 +251,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
#define ZONE_RECLAIM_SUCCESS 1
#endif

extern int hwpoison_filter(struct page *p);

extern u32 hwpoison_filter_dev_major;
extern u32 hwpoison_filter_dev_minor;

0 comments on commit 76fef14

Please sign in to comment.