diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 15:36:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 15:36:49 -0500 |
commit | d4220f987cf473c65a342ca69e3eb13dea919a49 (patch) | |
tree | dbb004a9c805d6de3f6e3955398fee1084a29f16 /drivers/base | |
parent | 61cf693159d6a968a7014e24905143f71ed8ddcf (diff) | |
parent | f2c03debdfb387fa2e35cac6382779072b8b9209 (diff) |
Merge branch 'hwpoison' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6
* 'hwpoison' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6: (34 commits)
HWPOISON: Remove stray phrase in a comment
HWPOISON: Try to allocate migration page on the same node
HWPOISON: Don't do early filtering if filter is disabled
HWPOISON: Add a madvise() injector for soft page offlining
HWPOISON: Add soft page offline support
HWPOISON: Undefine short-hand macros after use to avoid namespace conflict
HWPOISON: Use new shake_page in memory_failure
HWPOISON: Use correct name for MADV_HWPOISON in documentation
HWPOISON: mention HWPoison in Kconfig entry
HWPOISON: Use get_user_page_fast in hwpoison madvise
HWPOISON: add an interface to switch off/on all the page filters
HWPOISON: add memory cgroup filter
memcg: add accessor to mem_cgroup.css
memcg: rename and export try_get_mem_cgroup_from_page()
HWPOISON: add page flags filter
mm: export stable page flags
HWPOISON: limit hwpoison injector to known page types
HWPOISON: add fs/device filters
HWPOISON: return 0 to indicate success reliably
HWPOISON: make semantics of IGNORED/DELAYED clear
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/memory.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 989429cfed88..c4c8f2e1dd15 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -341,6 +341,64 @@ static inline int memory_probe_init(void) | |||
341 | } | 341 | } |
342 | #endif | 342 | #endif |
343 | 343 | ||
344 | #ifdef CONFIG_MEMORY_FAILURE | ||
345 | /* | ||
346 | * Support for offlining pages of memory | ||
347 | */ | ||
348 | |||
349 | /* Soft offline a page */ | ||
350 | static ssize_t | ||
351 | store_soft_offline_page(struct class *class, const char *buf, size_t count) | ||
352 | { | ||
353 | int ret; | ||
354 | u64 pfn; | ||
355 | if (!capable(CAP_SYS_ADMIN)) | ||
356 | return -EPERM; | ||
357 | if (strict_strtoull(buf, 0, &pfn) < 0) | ||
358 | return -EINVAL; | ||
359 | pfn >>= PAGE_SHIFT; | ||
360 | if (!pfn_valid(pfn)) | ||
361 | return -ENXIO; | ||
362 | ret = soft_offline_page(pfn_to_page(pfn), 0); | ||
363 | return ret == 0 ? count : ret; | ||
364 | } | ||
365 | |||
366 | /* Forcibly offline a page, including killing processes. */ | ||
367 | static ssize_t | ||
368 | store_hard_offline_page(struct class *class, const char *buf, size_t count) | ||
369 | { | ||
370 | int ret; | ||
371 | u64 pfn; | ||
372 | if (!capable(CAP_SYS_ADMIN)) | ||
373 | return -EPERM; | ||
374 | if (strict_strtoull(buf, 0, &pfn) < 0) | ||
375 | return -EINVAL; | ||
376 | pfn >>= PAGE_SHIFT; | ||
377 | ret = __memory_failure(pfn, 0, 0); | ||
378 | return ret ? ret : count; | ||
379 | } | ||
380 | |||
381 | static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page); | ||
382 | static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page); | ||
383 | |||
384 | static __init int memory_fail_init(void) | ||
385 | { | ||
386 | int err; | ||
387 | |||
388 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, | ||
389 | &class_attr_soft_offline_page.attr); | ||
390 | if (!err) | ||
391 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, | ||
392 | &class_attr_hard_offline_page.attr); | ||
393 | return err; | ||
394 | } | ||
395 | #else | ||
396 | static inline int memory_fail_init(void) | ||
397 | { | ||
398 | return 0; | ||
399 | } | ||
400 | #endif | ||
401 | |||
344 | /* | 402 | /* |
345 | * Note that phys_device is optional. It is here to allow for | 403 | * Note that phys_device is optional. It is here to allow for |
346 | * differentiation between which *physical* devices each | 404 | * differentiation between which *physical* devices each |
@@ -473,6 +531,9 @@ int __init memory_dev_init(void) | |||
473 | err = memory_probe_init(); | 531 | err = memory_probe_init(); |
474 | if (!ret) | 532 | if (!ret) |
475 | ret = err; | 533 | ret = err; |
534 | err = memory_fail_init(); | ||
535 | if (!ret) | ||
536 | ret = err; | ||
476 | err = block_size_init(); | 537 | err = block_size_init(); |
477 | if (!ret) | 538 | if (!ret) |
478 | ret = err; | 539 | ret = err; |