From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Tue, 10 Oct 2000 18:11:48 +0200 From: Ingo Oeser Subject: Re: [PATCH] OOM killer API (was: [PATCH] VM fix for 2.4.0-test9 & OOM handler) Message-ID: <20001010181148.D784@nightmaster.csn.tu-chemnitz.de> References: <20001010170708.C784@nightmaster.csn.tu-chemnitz.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: ; from riel@conectiva.com.br on Tue, Oct 10, 2000 at 12:32:50PM -0300 Sender: owner-linux-mm@kvack.org Return-Path: To: Rik van Riel Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org List-ID: On Tue, Oct 10, 2000 at 12:32:50PM -0300, Rik van Riel wrote: > > So now you can stop arguing about the one and only OOM killer, > > implement it, provide it as module and get back to the important > > stuff ;-) > > This is definately a cool toy for people who have doubts > that my OOM killer will do the wrong thing in their > workloads. Thanks ;-) But I forgot to include my changes to the mm/Makefile (to export the API for modules). Here is a _working_ one: --- linux-2.4.0-test10-pre1/mm/oom_kill.c Tue Oct 10 16:31:08 2000 +++ linux-2.4.0-test10-pre1-ioe/mm/oom_kill.c Tue Oct 10 16:59:27 2000 @@ -13,6 +13,8 @@ * 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. + * + * Added oom_killer API for special needs - Ingo Oeser */ #include @@ -136,7 +138,7 @@ } /** - * oom_kill - kill the "best" process when we run out of memory + * oom_kill_rik - 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) @@ -147,7 +149,9 @@ * 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(void) + + +static void oom_kill_rik(void) { struct task_struct *p = select_bad_process(); @@ -207,4 +211,63 @@ /* Else... */ return 1; +} + +/* Protects oom_killer against resetting during its execution */ +static rwlock_t oom_kill_lock = RW_LOCK_UNLOCKED; + +static oom_killer_t oom_killer = oom_kill_rik; + +/** + * oom_kill - the oom_kill wrapper for installable OOM killers + * + * Wraper around the OOM killers, that can be installed via + * install_oom_killer and reset_default_oom_killer. + * + * This gets called from kswapd() in linux/mm/vmscan.c when we + * really run out of memory. + */ +void oom_kill(void) { + read_lock(&oom_kill_lock); + oom_killer(); + read_unlock(&oom_kill_lock); +} + +/** + * install_oom_killer - install alternate OOM killer + * @new_oom_kill: the alternate OOM killer provided by the caller + * + * Since the default OOM killer (oom_kill_rik) is not suitable + * for everyone, we provide an interface to install custom OOM killers. + * + * You can take the most appropriate action for your application if the + * kernel goes OOM. + * + * Providing an NULL argument just returns the current OOM killer. + * + * Returns: The OOM killer, which has been installed so far. + * + * NOTE: We don't do refcounting on OOM killers, so be careful with + * modules + */ +oom_killer_t install_oom_killer(oom_killer_t new_oom_kill) { + oom_killer_t tmp; + write_lock(&oom_kill_lock); + tmp=oom_killer; + if (new_oom_kill) + oom_killer=new_oom_kill; + write_unlock(&oom_kill_lock); + return tmp; +} + +/** + * reset_default_oom_killer - reset back to default OOM killer + * + * If you are going to unload the module which provided + * your OOM killer, you can install the default one by this. + * + * Returns: The OOM killer, which has been installed so far. + */ +oom_killer_t reset_default_oom_killer(void) { + return install_oom_killer(&oom_kill_rik); } --- linux-2.4.0-test10-pre1/include/linux/swap.h Tue Oct 10 16:31:08 2000 +++ linux-2.4.0-test10-pre1-ioe/include/linux/swap.h Tue Oct 10 16:44:22 2000 @@ -127,8 +127,14 @@ #define read_swap_cache(entry) read_swap_cache_async(entry, 1); /* linux/mm/oom_kill.c */ +typedef void (*oom_killer_t)(void); + extern int out_of_memory(void); extern void oom_kill(void); + +oom_killer_t install_oom_killer(oom_killer_t new_oom_kill); +oom_killer_t reset_default_oom_killer(void); + /* * Make these inline later once they are working properly. --- linux-2.4.0-test10-pre1/mm/Makefile Tue Oct 10 16:31:08 2000 +++ linux-2.4.0-test10-pre1-ioe/mm/Makefile Tue Oct 10 16:34:06 2000 @@ -10,7 +10,8 @@ O_TARGET := mm.o O_OBJS := 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 + page_alloc.o swap_state.o swapfile.o numa.o +OX_OBJS := oom_kill.o ifeq ($(CONFIG_HIGHMEM),y) O_OBJS += highmem.o Regards Ingo Oeser -- Feel the power of the penguin - run linux@your.pc :x -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux.eu.org/Linux-MM/