diff options
author | Andi Kleen <andi@firstfloor.org> | 2009-09-16 05:50:15 -0400 |
---|---|---|
committer | Andi Kleen <ak@linux.intel.com> | 2009-09-16 05:50:15 -0400 |
commit | 6a46079cf57a7f7758e8b926980a4f852f89b34d (patch) | |
tree | efd72e830201370d6273bd436dda5a3c4cd6ed9b /kernel | |
parent | 4db96cf077aa938b11fe7ac79ecc9b29ec00fbab (diff) |
HWPOISON: The high level memory error handler in the VM v7
Add the high level memory handler that poisons pages
that got corrupted by hardware (typically by a two bit flip in a DIMM
or a cache) on the Linux level. The goal is to prevent everyone
from accessing these pages in the future.
This done at the VM level by marking a page hwpoisoned
and doing the appropriate action based on the type of page
it is.
The code that does this is portable and lives in mm/memory-failure.c
To quote the overview comment:
High level machine check handler. Handles pages reported by the
hardware as being corrupted usually due to a 2bit ECC memory or cache
failure.
This focuses on pages detected as corrupted in the background.
When the current CPU tries to consume corruption the currently
running process can just be killed directly instead. This implies
that if the error cannot be handled for some reason it's safe to
just ignore it because no corruption has been consumed yet. Instead
when that happens another machine check will happen.
Handles page cache pages in various states. The tricky part
here is that we can access any page asynchronous to other VM
users, because memory failures could happen anytime and anywhere,
possibly violating some of their assumptions. This is why this code
has to be extremely careful. Generally it tries to use normal locking
rules, as in get the standard locks, even if that means the
error handling takes potentially a long time.
Some of the operations here are somewhat inefficient and have non
linear algorithmic complexity, because the data structures have not
been optimized for this case. This is in particular the case
for the mapping from a vma to a process. Since this case is expected
to be rare we hope we can get away with this.
There are in principle two strategies to kill processes on poison:
- just unmap the data and wait for an actual reference before
killing
- kill as soon as corruption is detected.
Both have advantages and disadvantages and should be used
in different situations. Right now both are implemented and can
be switched with a new sysctl vm.memory_failure_early_kill
The default is early kill.
The patch does some rmap data structure walking on its own to collect
processes to kill. This is unusual because normally all rmap data structure
knowledge is in rmap.c only. I put it here for now to keep
everything together and rmap knowledge has been seeping out anyways
Includes contributions from Johannes Weiner, Chris Mason, Fengguang Wu,
Nick Piggin (who did a lot of great work) and others.
Cc: npiggin@suse.de
Cc: riel@redhat.com
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Rik van Riel <riel@redhat.com>
Reviewed-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sysctl.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 6bb59f707402..eacae77ac9fc 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1372,6 +1372,31 @@ static struct ctl_table vm_table[] = { | |||
1372 | .mode = 0644, | 1372 | .mode = 0644, |
1373 | .proc_handler = &scan_unevictable_handler, | 1373 | .proc_handler = &scan_unevictable_handler, |
1374 | }, | 1374 | }, |
1375 | #ifdef CONFIG_MEMORY_FAILURE | ||
1376 | { | ||
1377 | .ctl_name = CTL_UNNUMBERED, | ||
1378 | .procname = "memory_failure_early_kill", | ||
1379 | .data = &sysctl_memory_failure_early_kill, | ||
1380 | .maxlen = sizeof(sysctl_memory_failure_early_kill), | ||
1381 | .mode = 0644, | ||
1382 | .proc_handler = &proc_dointvec_minmax, | ||
1383 | .strategy = &sysctl_intvec, | ||
1384 | .extra1 = &zero, | ||
1385 | .extra2 = &one, | ||
1386 | }, | ||
1387 | { | ||
1388 | .ctl_name = CTL_UNNUMBERED, | ||
1389 | .procname = "memory_failure_recovery", | ||
1390 | .data = &sysctl_memory_failure_recovery, | ||
1391 | .maxlen = sizeof(sysctl_memory_failure_recovery), | ||
1392 | .mode = 0644, | ||
1393 | .proc_handler = &proc_dointvec_minmax, | ||
1394 | .strategy = &sysctl_intvec, | ||
1395 | .extra1 = &zero, | ||
1396 | .extra2 = &one, | ||
1397 | }, | ||
1398 | #endif | ||
1399 | |||
1375 | /* | 1400 | /* |
1376 | * NOTE: do not add new entries to this table unless you have read | 1401 | * NOTE: do not add new entries to this table unless you have read |
1377 | * Documentation/sysctl/ctl_unnumbered.txt | 1402 | * Documentation/sysctl/ctl_unnumbered.txt |