mm/memory-failure.c
Source file repositories/reference/linux-study-clean/mm/memory-failure.c
File Facts
- System
- Linux kernel
- Corpus path
mm/memory-failure.c- Extension
.c- Size
- 80516 bytes
- Lines
- 2961
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/mm.hlinux/memory-failure.hlinux/page-flags.hlinux/sched/signal.hlinux/sched/task.hlinux/dax.hlinux/ksm.hlinux/rmap.hlinux/export.hlinux/pagemap.hlinux/swap.hlinux/backing-dev.hlinux/migrate.hlinux/slab.hlinux/leafops.hlinux/hugetlb.hlinux/memory_hotplug.hlinux/mm_inline.hlinux/memremap.hlinux/kfifo.hlinux/ratelimit.hlinux/pagewalk.hlinux/shmem_fs.hlinux/sysctl.htrace/events/memory-failure.hswap.hinternal.h
Detected Declarations
struct to_killstruct hwpoison_walkstruct page_statestruct raw_hwp_pagestruct memory_failure_entrystruct memory_failure_cpufunction num_poisoned_pages_incfunction num_poisoned_pages_subfunction __page_handle_poisonfunction page_handle_poisonfunction hwpoison_filter_registerfunction hwpoison_filter_unregisterfunction hwpoison_filterfunction kill_procfunction shake_foliofunction shake_pagefunction dev_pagemap_mapping_shiftfunction __add_to_killfunction add_to_kill_anon_filefunction task_in_to_kill_listfunction list_for_each_entry_safefunction add_to_kill_ksmfunction listfunction list_for_each_entry_safefunction SIGBUSfunction for_each_threadfunction threadfunction collect_procs_anonfunction anon_vma_interval_tree_foreachfunction collect_procs_filefunction vma_interval_tree_foreachfunction add_to_kill_fsdaxfunction collect_procs_fsdaxfunction vma_interval_tree_foreachfunction collect_procsfunction set_to_killfunction check_hwpoisoned_entryfunction check_hwpoisoned_pmd_entryfunction check_hwpoisoned_pmd_entryfunction hwpoison_pte_rangefunction hwpoison_hugetlb_rangefunction hwpoison_test_walkfunction memory_failurefunction delete_from_lru_cachefunction truncate_error_foliofunction has_extra_refcountfunction me_kernelfunction me_unknown
Annotated Snippet
core_initcall(memory_failure_init);
#undef pr_fmt
#define pr_fmt(fmt) "Unpoison: " fmt
#define unpoison_pr_info(fmt, pfn, rs) \
({ \
if (__ratelimit(rs)) \
pr_info(fmt, pfn); \
})
/**
* unpoison_memory - Unpoison a previously poisoned page
* @pfn: Page number of the to be unpoisoned page
*
* Software-unpoison a page that has been poisoned by
* memory_failure() earlier.
*
* This is only done on the software-level, so it only works
* for linux injected failures, not real hardware failures
*
* Returns 0 for success, otherwise -errno.
*/
int unpoison_memory(unsigned long pfn)
{
struct folio *folio;
struct page *p;
int ret = -EBUSY, ghp;
unsigned long count;
bool huge = false;
static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
p = pfn_to_online_page(pfn);
if (!p)
return -EIO;
folio = page_folio(p);
mutex_lock(&mf_mutex);
if (hw_memory_failure) {
unpoison_pr_info("%#lx: disabled after HW memory failure\n",
pfn, &unpoison_rs);
ret = -EOPNOTSUPP;
goto unlock_mutex;
}
if (is_huge_zero_folio(folio)) {
unpoison_pr_info("%#lx: huge zero page is not supported\n",
pfn, &unpoison_rs);
ret = -EOPNOTSUPP;
goto unlock_mutex;
}
if (!PageHWPoison(p)) {
unpoison_pr_info("%#lx: page was already unpoisoned\n",
pfn, &unpoison_rs);
goto unlock_mutex;
}
if (folio_ref_count(folio) > 1) {
unpoison_pr_info("%#lx: someone grabs the hwpoison page\n",
pfn, &unpoison_rs);
goto unlock_mutex;
}
if (folio_test_slab(folio) || folio_test_pgtable(folio) ||
folio_test_reserved(folio) || folio_test_offline(folio))
goto unlock_mutex;
if (folio_mapped(folio)) {
unpoison_pr_info("%#lx: someone maps the hwpoison page\n",
pfn, &unpoison_rs);
goto unlock_mutex;
}
if (folio_mapping(folio)) {
unpoison_pr_info("%#lx: the hwpoison page has non-NULL mapping\n",
pfn, &unpoison_rs);
goto unlock_mutex;
}
ghp = get_hwpoison_page(p, MF_UNPOISON);
if (!ghp) {
if (folio_test_hugetlb(folio)) {
huge = true;
count = folio_free_raw_hwp(folio, false);
if (count == 0)
goto unlock_mutex;
}
ret = folio_test_clear_hwpoison(folio) ? 0 : -EBUSY;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/mm.h`, `linux/memory-failure.h`, `linux/page-flags.h`, `linux/sched/signal.h`, `linux/sched/task.h`, `linux/dax.h`, `linux/ksm.h`.
- Detected declarations: `struct to_kill`, `struct hwpoison_walk`, `struct page_state`, `struct raw_hwp_page`, `struct memory_failure_entry`, `struct memory_failure_cpu`, `function num_poisoned_pages_inc`, `function num_poisoned_pages_sub`, `function __page_handle_poison`, `function page_handle_poison`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.