From: Rusty Lynch <rusty@linux.co.intel.com>
To: "Tvrtko A. Uršulin" <tvrtko@croadria.com>
Cc: linux-kernel@vger.kernel.org,
Marcelo Tosatti <marcelo.tosatti@cyclades.com.br>
Subject: Re: [PATCH] [RFC] Modular OOM killer for 2.4 (or no OOM at all)
Date: 09 Oct 2003 10:59:01 -0700 [thread overview]
Message-ID: <1065722342.26834.7.camel@vmhack> (raw)
In-Reply-To: <200310091008.40836.tvrtko@croadria.com>
On Thu, 2003-10-09 at 01:08, Tvrtko A. Uršulin wrote:
>
> Hello all,
>
> Here is a patch ported from one made by Rusty for 2.6 series. It is also a
> little bit improved (IMHO) so it is completely modular.
>
> There was much flamimg on the subject of OOM killer so I should note one key
> feature first:
>
> - it is completely modular eg. one can choose *not* to compile in any OOM
> killer module
>
> Other features:
>
> - each module can be either compiled in or modularized
> - changing/adding new oom policies without rebooting
>
> Modules present so far are: oom_panic.o (by Rusty Lynch), oom_kill.o (classic
> by Rik van Riel), oom_kill_parent.o (classic one improved)
>
> So people who want it to be removed should be happy with this one. And at the
> same time people who need it can use it.
>
> Any comments (and inclusion :) is welcomed!
>
> Regards,
> Tvrtko A. Ursulin
> ----
>
<snip>
> + define_bool CONFIG_OOM_KILL = m
All of the lines that do this in mm/Config.in will break my "make
?config"
replacing with:
define_bool CONFIG_XXX m
works for me.
Also, I had some feedback that people wanted the default values to make
the kernel oom behavior not change (i.e. doing a "yes ''|make oldconfig"
would end up using the classic oom killer) but I don't recall how to do
that for the 2.4 config system.
--rustyl
> + fi
> + if [ "$CONFIG_OOM_KPPID" = "y" ]; then
> + define_bool CONFIG_OOM_KPPID = m
> + fi
> +fi
> +
> +tristate 'Classic' CONFIG_OOM_KILL
> +if [ "$CONFIG_OOM_KILL" = "y" ]; then
> + if [ "$CONFIG_OOM_PANIC" = "y" ]; then
> + define_bool CONFIG_OOM_PANIC = m
> + fi
> + if [ "$CONFIG_OOM_KPPID" = "y" ]; then
> + define_bool CONFIG_OOM_KPPID = m
> + fi
> +fi
> +
> +tristate 'Kill parents' CONFIG_OOM_KPPID
> +if [ "$CONFIG_OOM_KPPID" = "y" ]; then
> + if [ "$CONFIG_OOM_PANIC" = "y" ]; then
> + define_bool CONFIG_OOM_PANIC = m
> + fi
> + if [ "$CONFIG_OOM_KILL" = "y" ]; then
> + define_bool CONFIG_OOM_KILL = m
> + fi
> +fi
> +
> +endmenu
> diff -Naur linux-2.4.22/mm/Makefile linux-2.4.22-moom/mm/Makefile
> --- linux-2.4.22/mm/Makefile 2002-08-06 09:10:56.000000000 +0200
> +++ linux-2.4.22-moom/mm/Makefile 2003-10-07 20:08:45.000000000 +0200
> @@ -9,13 +9,17 @@
>
> O_TARGET := mm.o
>
> -export-objs := shmem.o filemap.o memory.o page_alloc.o
> +export-objs := shmem.o filemap.o memory.o page_alloc.o oom_notifier.o
>
> obj-y := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
> vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
> - page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o \
> - shmem.o
> + page_alloc.o swap_state.o swapfile.o numa.o \
> + shmem.o oom_notifier.o
>
> obj-$(CONFIG_HIGHMEM) += highmem.o
>
> +obj-$(CONFIG_OOM_PANIC) += oom_panic.o
> +obj-$(CONFIG_OOM_KILL) += oom_kill.o
> +obj-$(CONFIG_OOM_KPPID) += oom_kill_parent.o
> +
> include $(TOPDIR)/Rules.make
> diff -Naur linux-2.4.22/mm/oom_kill.c linux-2.4.22-moom/mm/oom_kill.c
> --- linux-2.4.22/mm/oom_kill.c 2003-10-07 19:37:49.000000000 +0200
> +++ linux-2.4.22-moom/mm/oom_kill.c 2003-10-07 23:23:51.000000000 +0200
> @@ -13,16 +13,28 @@
> * machine) this file will double as a 'coding guide' and a signpost
> * for newbie kernel hackers. It features several pointers to major
> * kernel subsystems and hints as to where to find out what things do.
> + *
> + * Modularized by using notifies by --rustyl <rusty@linux.intel.com>
> + * Final modularization (C) 2003 Tvrtko A. Ursulin (tvrtko.ursulin@zg.htnet.hr)
> */
>
> +#include <linux/kernel.h>
> #include <linux/mm.h>
> #include <linux/sched.h>
> #include <linux/swap.h>
> #include <linux/swapctl.h>
> #include <linux/timex.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/notifier.h>
> +#include <linux/oom_notifier.h>
>
> /* #define DEBUG */
>
> +#ifndef DEBUG
> +#define dbg(format, arg...)
> +#endif
> +
> /**
> * int_sqrt - oom_kill.c internal function, rough approximation to sqrt
> * @x: integer of which to calculate the sqrt
> @@ -105,10 +117,7 @@
> */
> if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
> points /= 4;
> -#ifdef DEBUG
> - printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
> - p->pid, p->comm, points);
> -#endif
> + dbg("Task %d (%s) got %d points", p->pid, p->comm, points);
> return points;
> }
>
> @@ -143,7 +152,7 @@
> */
> void oom_kill_task(struct task_struct *p)
> {
> - printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm);
> + error("Killed process %d (%s).", p->pid, p->comm);
>
> /*
> * We give our sacrificial lamb high priority and access to
> @@ -199,7 +208,7 @@
> /**
> * out_of_memory - is the system out of memory?
> */
> -void out_of_memory(void)
> +void out_of_memory_killer(void)
> {
> static unsigned long first, last, count, lastkill;
> unsigned long now, since;
> @@ -207,7 +216,7 @@
> /*
> * Enough swap space left? Not OOM.
> */
> - if (nr_swap_pages > 0)
> + if ( get_nr_swap_pages() > 0)
> return;
>
> now = jiffies;
> @@ -256,3 +265,36 @@
> first = now;
> count = 0;
> }
> +
> +static int oom_notify(struct notifier_block * s, unsigned long v, void * d)
> +{
> + out_of_memory_killer();
> + return 0;
> +}
> +
> +static struct notifier_block oom_nb = {
> + .notifier_call = oom_notify,
> +};
> +
> +static int __init init_oom_kill(void)
> +{
> + int err;
> +
> + info("Installing oom_kill handler");
> + err = register_oom_notifier(&oom_nb);
> + if (err)
> + error("Error installing oom_kill handler!");
> +
> + return err;
> +}
> +
> +static void __exit exit_oom_kill(void)
> +{
> + unregister_oom_notifier(&oom_nb);
> + info("Unregistered oom_kill handler");
> +}
> +
> +MODULE_LICENSE("GPL");
> +
> +module_init(init_oom_kill);
> +module_exit(exit_oom_kill);
> diff -Naur linux-2.4.22/mm/oom_kill_parent.c linux-2.4.22-moom/mm/oom_kill_parent.c
> --- linux-2.4.22/mm/oom_kill_parent.c 1970-01-01 01:00:00.000000000 +0100
> +++ linux-2.4.22-moom/mm/oom_kill_parent.c 2003-10-07 23:37:07.000000000 +0200
> @@ -0,0 +1,449 @@
> +/*
> + * linux/mm/oom_kill_parent.c
> + *
> + * Copyright (C) 1998,2000 Rik van Riel
> + * Thanks go out to Claus Fischer for some serious inspiration and
> + * for goading me into coding this file...
> + *
> + * The routines in this file are used to kill a process when
> + * we're seriously out of memory. This gets called from kswapd()
> + * in linux/mm/vmscan.c when we really run out of memory.
> + *
> + * Since we won't call these routines often (on a well-configured
> + * machine) this file will double as a 'coding guide' and a signpost
> + * for newbie kernel hackers. It features several pointers to major
> + * kernel subsystems and hints as to where to find out what things do.
> + *
> + * Copyright (C) 2003 Tvrtko A. Ursulin (tvrtko.ursulin@zg.htnet.hr)
> + * Extended to keep per parent process statistics and to kill parent processes
> + * which keep producing bad children.
> + * Modularized by using notifies by --rustyl <rusty@linux.intel.com>
> + * Final modularization (C) 2003 Tvrtko A. Ursulin (tvrtko.ursulin@zg.htnet.hr)
> + *
> +*/
> +
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/sched.h>
> +#include <linux/swap.h>
> +#include <linux/swapctl.h>
> +#include <linux/timex.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/sysctl.h>
> +#include <linux/notifier.h>
> +#include <linux/oom_notifier.h>
> +
> +#define OOM_HISTORY_SIZE 32
> +
> +#define OOM_DEFAULT_VALUE (10)
> +#define OOM_DEFAULT_EXPIRE (5*60)
> +
> +static unsigned int oom_parent_max = OOM_DEFAULT_VALUE;
> +static unsigned int oom_parent_expire = OOM_DEFAULT_EXPIRE;
> +
> +static struct ctl_table_header *oom_root_table_header;
> +
> +static ctl_table oom_table[] = {
> + {1, "oom_parent_max",
> + &oom_parent_max, sizeof(int), 0644, NULL, &proc_dointvec},
> + {2, "oom_parent_expire",
> + &oom_parent_expire, sizeof(int), 0644, NULL, &proc_dointvec},
> + { 0 }
> +};
> +
> +static ctl_table oom_dir_table[] = {
> + {VM_OOM, "oom", NULL, 0, 0555, oom_table},
> + {0}
> +};
> +
> +static ctl_table oom_root_table[] = {
> + {CTL_VM, "vm", NULL, 0, 0555, oom_dir_table},
> + {0}
> +};
> +
> +struct parent_record
> +{
> + pid_t pid;
> + struct task_struct *task;
> + unsigned long last_kill;
> + unsigned long value;
> +};
> +
> +static struct parent_record blacklist[OOM_HISTORY_SIZE];
> +
> +/* #define DEBUG */
> +
> +#ifndef DEBUG
> +#define dbg(format, arg...)
> +#endif
> +
> +void oom_kill_task(struct task_struct *p);
> +
> +static void process_blacklist(void)
> +{
> + struct parent_record *p;
> + struct task_struct *task;
> +
> + unsigned int i;
> +
> + for ( i = 0; i < OOM_HISTORY_SIZE; i++ ) {
> + p = &blacklist[i];
> + if ( p->pid ) {
> + task = find_task_by_pid(p->pid);
> + if ( task != p->task ) {
> + dbg("Parent %d (%p) removed from list - does not exist",p->pid, p->task);
> + p->pid = 0;
> + }
> + else if ( abs(jiffies - p->last_kill) >= (oom_parent_expire*HZ) ) {
> + dbg("Parent %d (%p) removed from list - expired",p->pid, p->task);
> + p->pid = 0;
> + }
> + else if ( p->value >= oom_parent_max ) {
> + error("Will kill parent process %d (%s)",p->pid,p->task->comm);
> + p->pid = 0;
> + oom_kill_task(p->task);
> + }
> + }
> + }
> +}
> +
> +static struct parent_record *find_in_blacklist(struct task_struct *task)
> +{
> + struct parent_record *p = NULL;
> + unsigned int i;
> +
> + if ( !task )
> + return NULL;
> +
> + for ( i = 0; i < OOM_HISTORY_SIZE; i++ ) {
> + p = &blacklist[i];
> + if ( p->pid ) {
> + if ( (task->pid == p->pid) && (task == p->task) )
> + return p;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +static struct parent_record *blacklist_parent(struct task_struct *task)
> +{
> + struct parent_record *p;
> + unsigned int i;
> +
> + if ( !task )
> + return NULL;
> +
> + for ( i = 0; i < OOM_HISTORY_SIZE; i++ ) {
> + p = &blacklist[i];
> + if ( !p->pid )
> + break;
> + }
> +
> + if ( p->pid )
> + return NULL;
> +
> + p->pid= task->pid;
> + p->task = task;
> + p->last_kill = jiffies;
> + p->value = 0;
> +
> + return p;
> +}
> +
> +/**
> + * int_sqrt - oom_kill.c internal function, rough approximation to sqrt
> + * @x: integer of which to calculate the sqrt
> + *
> + * A very rough approximation to the sqrt() function.
> + */
> +static unsigned int int_sqrt(unsigned int x)
> +{
> + unsigned int out = x;
> + while (x & ~(unsigned int)1) x >>=2, out >>=1;
> + if (x) out -= out >> 2;
> + return (out ? out : 1);
> +}
> +
> +/**
> + * oom_badness - calculate a numeric value for how bad this task has been
> + * @p: task struct of which task we should calculate
> + *
> + * The formula used is relatively simple and documented inline in the
> + * function. The main rationale is that we want to select a good task
> + * to kill when we run out of memory.
> + *
> + * Good in this context means that:
> + * 1) we lose the minimum amount of work done
> + * 2) we recover a large amount of memory
> + * 3) we don't kill anything innocent of eating tons of memory
> + * 4) we want to kill the minimum amount of processes (one)
> + * 5) we try to kill the process the user expects us to kill, this
> + * algorithm has been meticulously tuned to meet the priniciple
> + * of least surprise ... (be careful when you change it)
> + */
> +
> +static int badness(struct task_struct *p)
> +{
> + int points, cpu_time, run_time;
> +
> + if (!p->mm)
> + return 0;
> +
> + if (p->flags & PF_MEMDIE)
> + return 0;
> +
> + /*
> + * The memory size of the process is the basis for the badness.
> + */
> + points = p->mm->total_vm;
> +
> + /*
> + * CPU time is in seconds and run time is in minutes. There is no
> + * particular reason for this other than that it turned out to work
> + * very well in practice. This is not safe against jiffie wraps
> + * but we don't care _that_ much...
> + */
> + cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3);
> + run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10);
> +
> + points /= int_sqrt(cpu_time);
> + points /= int_sqrt(int_sqrt(run_time));
> +
> + /*
> + * Niced processes are most likely less important, so double
> + * their badness points.
> + */
> + if (p->nice > 0)
> + points *= 2;
> +
> + /*
> + * Superuser processes are usually more important, so we make it
> + * less likely that we kill those.
> + */
> + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
> + p->uid == 0 || p->euid == 0)
> + points /= 4;
> +
> + /*
> + * We don't want to kill a process with direct hardware access.
> + * Not only could that mess up the hardware, but usually users
> + * tend to only have this flag set on applications they think
> + * of as important.
> + */
> + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
> + points /= 4;
> + dbg("Task %d (%s) got %d points",p->pid, p->comm, points);
> + return points;
> +}
> +
> +/*
> + * Simple selection loop. We chose the process with the highest
> + * number of 'points'. We expect the caller will lock the tasklist.
> + *
> + * (not docbooked, we don't want this one cluttering up the manual)
> + */
> +static struct task_struct * select_bad_process(void)
> +{
> + int maxpoints = 0;
> + struct task_struct *p = NULL;
> + struct task_struct *chosen = NULL;
> +
> + for_each_task(p) {
> + if (p->pid) {
> + int points = badness(p);
> + if (points > maxpoints) {
> + chosen = p;
> + maxpoints = points;
> + }
> + }
> + }
> + return chosen;
> +}
> +
> +/**
> + * We must be careful though to never send SIGKILL a process with
> + * CAP_SYS_RAW_IO set, send SIGTERM instead (but it's unlikely that
> + * we select a process with CAP_SYS_RAW_IO set).
> + */
> +void oom_kill_task(struct task_struct *p)
> +{
> + error("Killed process %d (%s).", p->pid, p->comm);
> +
> + /*
> + * We give our sacrificial lamb high priority and access to
> + * all the memory it needs. That way it should be able to
> + * exit() and clear out its resources quickly...
> + */
> + p->counter = 5 * HZ;
> + p->flags |= PF_MEMALLOC | PF_MEMDIE;
> +
> + /* This process has hardware access, be more careful. */
> + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
> + force_sig(SIGTERM, p);
> + } else {
> + force_sig(SIGKILL, p);
> + }
> +}
> +
> +/**
> + * oom_kill - kill the "best" process when we run out of memory
> + *
> + * If we run out of memory, we have the choice between either
> + * killing a random task (bad), letting the system crash (worse)
> + * OR try to be smart about which process to kill. Note that we
> + * don't have to be perfect here, we just have to be good.
> + */
> +static void oom_kill(void)
> +{
> + struct task_struct *p, *q;
> + struct parent_record *parent;
> +
> + read_lock(&tasklist_lock);
> + p = select_bad_process();
> +
> + /* Found nothing?!?! Either we hang forever, or we panic. */
> + if (p == NULL)
> + panic("Out of memory and no killable processes...\n");
> +
> + /* Add or update statistics for a parent processs */
> + if ( p->p_opptr->pid > 1 ) {
> + parent = find_in_blacklist(p->p_opptr);
> + if ( !parent ) {
> + dbg("Adding parent (%d) to black list because of %d",p->parent->pid, p->pid);
> + parent = blacklist_parent(p->p_opptr);
> + }
> + else {
> + dbg("Parent (%d) black list value increased to %ld",parent->pid, parent->value);
> + parent->value++;
> + parent->last_kill = jiffies;
> + }
> + }
> +
> + /* kill all processes that share the ->mm (i.e. all threads) */
> + for_each_task(q) {
> + if (q->mm == p->mm)
> + oom_kill_task(q);
> + }
> + read_unlock(&tasklist_lock);
> +
> + /*
> + * Make kswapd go out of the way, so "p" has a good chance of
> + * killing itself before someone else gets the chance to ask
> + * for more memory.
> + */
> + yield();
> + return;
> +}
> +
> +/**
> + * out_of_memory - is the system out of memory?
> + */
> +void out_of_memory_killer(void)
> +{
> + static unsigned long first, last, count, lastkill;
> + unsigned long now, since;
> +
> + /*
> + * Process kill history...
> + */
> + process_blacklist();
> +
> + /*
> + * Enough swap space left? Not OOM.
> + */
> + if ( get_nr_swap_pages() > 0)
> + return;
> +
> + now = jiffies;
> + since = now - last;
> + last = now;
> +
> + /*
> + * If it's been a long time since last failure,
> + * we're not oom.
> + */
> + last = now;
> + if (since > 5*HZ)
> + goto reset;
> +
> + /*
> + * If we haven't tried for at least one second,
> + * we're not really oom.
> + */
> + since = now - first;
> + if (since < HZ)
> + return;
> +
> + /*
> + * If we have gotten only a few failures,
> + * we're not really oom.
> + */
> + if (++count < 10)
> + return;
> +
> + /*
> + * If we just killed a process, wait a while
> + * to give that task a chance to exit. This
> + * avoids killing multiple processes needlessly.
> + */
> + since = now - lastkill;
> + if (since < HZ*5)
> + return;
> +
> + /*
> + * Ok, really out of memory. Kill something.
> + */
> + lastkill = now;
> + oom_kill();
> +
> +reset:
> + first = now;
> + count = 0;
> +}
> +
> +static int oom_notify(struct notifier_block * s, unsigned long v, void * d)
> +{
> + out_of_memory_killer();
> + return 0;
> +}
> +
> +static struct notifier_block oom_nb = {
> + .notifier_call = oom_notify,
> +};
> +
> +static int __init init_oom_kill_parent(void)
> +{
> + int err;
> +
> + info("Installing oom_kill_parent handler");
> +
> + err = register_oom_notifier(&oom_nb);
> + if (err)
> + error("Error installing oom_kill_parent handler!");
> +
> + oom_root_table_header = register_sysctl_table(oom_root_table, 1);
> + if (!oom_root_table_header)
> + error("Error installing oom sysctl table!");
> +
> + return err;
> +}
> +
> +static void __exit exit_oom_kill_parent(void)
> +{
> + if (oom_root_table_header)
> + unregister_sysctl_table(oom_root_table_header);
> +
> + unregister_oom_notifier(&oom_nb);
> + info("Unregistered oom_kill_parent handler");
> +}
> +
> +MODULE_LICENSE("GPL");
> +MODULE_PARM(oom_parent_max, "i");
> +MODULE_PARM_DESC(oom_parent_max, "Maximum number of bad childs parent can produce" );
> +MODULE_PARM(oom_parent_expire, "i");
> +MODULE_PARM_DESC(oom_parent_expire, "Time period in seconds after which parents past sins are forgotten" );
> +
> +module_init(init_oom_kill_parent);
> +module_exit(exit_oom_kill_parent);
> diff -Naur linux-2.4.22/mm/oom_notifier.c linux-2.4.22-moom/mm/oom_notifier.c
> --- linux-2.4.22/mm/oom_notifier.c 1970-01-01 01:00:00.000000000 +0100
> +++ linux-2.4.22-moom/mm/oom_notifier.c 2003-10-07 23:16:56.000000000 +0200
> @@ -0,0 +1,44 @@
> +/*
> + * linux/mm/oom_notifier.c
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <asm/semaphore.h>
> +
> +static DECLARE_MUTEX(notify_mutex);
> +static struct notifier_block * oom_notify_list = 0;
> +
> +int register_oom_notifier(struct notifier_block * nb)
> +{
> + int err;
> +
> + down(¬ify_mutex);
> + err = notifier_chain_register(&oom_notify_list, nb);
> + up(¬ify_mutex);
> +
> + return err;
> +}
> +EXPORT_SYMBOL(register_oom_notifier);
> +
> +int unregister_oom_notifier(struct notifier_block * nb)
> +{
> + int err;
> +
> + down(¬ify_mutex);
> + err = notifier_chain_unregister(&oom_notify_list, nb);
> + up(¬ify_mutex);
> +
> + return err;
> +}
> +EXPORT_SYMBOL(unregister_oom_notifier);
> +
> +void out_of_memory(void)
> +{
> + down(¬ify_mutex);
> + notifier_call_chain(&oom_notify_list, OUT_OF_MEMORY, 0);
> + up(¬ify_mutex);
> +}
> +EXPORT_SYMBOL(out_of_memory);
> diff -Naur linux-2.4.22/mm/oom_panic.c linux-2.4.22-moom/mm/oom_panic.c
> --- linux-2.4.22/mm/oom_panic.c 1970-01-01 01:00:00.000000000 +0100
> +++ linux-2.4.22-moom/mm/oom_panic.c 2003-10-07 23:23:33.000000000 +0200
> @@ -0,0 +1,50 @@
> +/*
> + * linux/mm/oom_panic.c
> + *
> + * This is a very simple component that will cause the kernel to
> + * panic on out-of-memory conditions. The behavior of panic can be
> + * further controlled with /proc/sys/kernel/panic.
> + *
> + * --rustyl <rusty@linux.intel.com>
> + *
> + * Final modularization (C) 2003 Tvrtko A. Ursulin (tvrtko.ursulin@zg.htnet.hr)
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/notifier.h>
> +#include <linux/oom_notifier.h>
> +
> +static int oom_notify(struct notifier_block * s, unsigned long v, void * d)
> +{
> + panic("Out-Of-Memory");
> + return 0;
> +}
> +
> +static struct notifier_block oom_nb = {
> + .notifier_call = oom_notify,
> +};
> +
> +static int __init init_oom_panic(void)
> +{
> + int err;
> +
> + info("Installing oom_panic handler");
> + err = register_oom_notifier(&oom_nb);
> + if (err)
> + error("Error installing oom_panic handler!");
> +
> + return err;
> +}
> +
> +static void __exit exit_oom_panic(void)
> +{
> + unregister_oom_notifier(&oom_nb);
> +}
> +
> +MODULE_LICENSE("GPL");
> +
> +module_init(init_oom_panic);
> +module_exit(exit_oom_panic);
> diff -Naur linux-2.4.22/mm/page_alloc.c linux-2.4.22-moom/mm/page_alloc.c
> --- linux-2.4.22/mm/page_alloc.c 2003-10-07 19:35:21.000000000 +0200
> +++ linux-2.4.22-moom/mm/page_alloc.c 2003-10-07 20:14:56.000000000 +0200
> @@ -475,6 +475,15 @@
> }
>
> /*
> + * Total amount of swap pages
> + */
> +int get_nr_swap_pages (void)
> +{
> + return nr_swap_pages;
> +}
> +EXPORT_SYMBOL(get_nr_swap_pages);
> +
> +/*
> * Amount of free RAM allocatable as buffer memory:
> */
> unsigned int nr_free_buffer_pages (void)
next prev parent reply other threads:[~2003-10-09 18:03 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-09 8:08 [PATCH] [RFC] Modular OOM killer for 2.4 (or no OOM at all) Tvrtko A. Uršulin
2003-10-09 17:59 ` Rusty Lynch [this message]
2003-10-10 12:33 ` Tvrtko A. Uršulin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1065722342.26834.7.camel@vmhack \
--to=rusty@linux.co.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo.tosatti@cyclades.com.br \
--cc=tvrtko@croadria.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.