aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-26 02:31:20 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:47 -0400
commit8bc719d3cab8414938f9ea6e33b58d8810d18068 (patch)
tree1afd4ce7865466bf9578ca746c63c1d351f07cdc /mm
parent19655d3487001d7df0e10e9cbfc27c758b77c2b5 (diff)
[PATCH] out of memory notifier
Add a notifer chain to the out of memory killer. If one of the registered callbacks could release some memory, do not kill the process but return and retry the allocation that forced the oom killer to run. The purpose of the notifier is to add a safety net in the presence of memory ballooners. If the resource manager inflated the balloon to a size where memory allocations can not be satisfied anymore, it is better to deflate the balloon a bit instead of killing processes. The implementation for the s390 ballooner is included. [akpm@osdl.org: cleanups] Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/oom_kill.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index b9af136e5cfa..7d056843fa2d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -21,6 +21,8 @@
21#include <linux/timex.h> 21#include <linux/timex.h>
22#include <linux/jiffies.h> 22#include <linux/jiffies.h>
23#include <linux/cpuset.h> 23#include <linux/cpuset.h>
24#include <linux/module.h>
25#include <linux/notifier.h>
24 26
25int sysctl_panic_on_oom; 27int sysctl_panic_on_oom;
26/* #define DEBUG */ 28/* #define DEBUG */
@@ -306,6 +308,20 @@ static int oom_kill_process(struct task_struct *p, unsigned long points,
306 return oom_kill_task(p, message); 308 return oom_kill_task(p, message);
307} 309}
308 310
311static BLOCKING_NOTIFIER_HEAD(oom_notify_list);
312
313int register_oom_notifier(struct notifier_block *nb)
314{
315 return blocking_notifier_chain_register(&oom_notify_list, nb);
316}
317EXPORT_SYMBOL_GPL(register_oom_notifier);
318
319int unregister_oom_notifier(struct notifier_block *nb)
320{
321 return blocking_notifier_chain_unregister(&oom_notify_list, nb);
322}
323EXPORT_SYMBOL_GPL(unregister_oom_notifier);
324
309/** 325/**
310 * out_of_memory - kill the "best" process when we run out of memory 326 * out_of_memory - kill the "best" process when we run out of memory
311 * 327 *
@@ -318,6 +334,12 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
318{ 334{
319 struct task_struct *p; 335 struct task_struct *p;
320 unsigned long points = 0; 336 unsigned long points = 0;
337 unsigned long freed = 0;
338
339 blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
340 if (freed > 0)
341 /* Got some memory back in the last second. */
342 return;
321 343
322 if (printk_ratelimit()) { 344 if (printk_ratelimit()) {
323 printk("oom-killer: gfp_mask=0x%x, order=%d\n", 345 printk("oom-killer: gfp_mask=0x%x, order=%d\n",