From f7983488cb4c691cb58e9d4c81bdc64af3c6c857 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 26 Apr 2010 15:11:04 -0700 Subject: lowmemorykiller: Don't try to kill the same pid over and over Under certain circumstances, a process can take awhile to handle a sig-kill (especially if it's in a scheduler group with a very low share ratio). When this occurs, lowmemkiller returns to vmscan indicating the process memory has been freed - even though the process is still waiting to die. Since the memory hasn't actually freed, lowmemkiller is called again shortly after, and picks the same process to die; regardless of the fact that it has already been 'scheduled' to die and the memory has already been reported to vmscan as having been freed. Solution is to check fatal_signal_pending() on the selected task, and if it's already pending destruction return; indicating to vmscan that no resources were freed on this pass. Signed-off-by: San Mehat --- drivers/staging/android/lowmemorykiller.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/staging/android/lowmemorykiller.c') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 2d8d2b79610..f4960dd3b26 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -168,6 +168,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) p->pid, p->comm, oom_adj, tasksize); } if (selected) { + if (fatal_signal_pending(selected)) { + pr_warning("process %d is suffering a slow death\n", + selected->pid); + read_unlock(&tasklist_lock); + return rem; + } lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_adj, selected_tasksize); -- cgit v1.2.3 From af0240f095a704f75f032bbcc01f670c65c163ba Mon Sep 17 00:00:00 2001 From: San Mehat Date: Thu, 6 May 2010 15:40:07 -0700 Subject: staging: android: lowmemorykiller: Fix task_struct leak As it turns out, the CONFIG_PROFILING interfaces leak a task struct if the notifier chain returns NOTIFY_OK.. doh. This patch reworks lowmemkiller to use the new generic task free notifier chain. Signed-off-by: San Mehat --- drivers/staging/android/lowmemorykiller.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers/staging/android/lowmemorykiller.c') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index f4960dd3b26..cae9212d909 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -34,7 +34,6 @@ #include #include #include -#include #include static uint32_t lowmem_debug_level = 2; @@ -74,7 +73,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) struct task_struct *task = data; if (task == lowmem_deathpending) { lowmem_deathpending = NULL; - task_handoff_unregister(&task_nb); + task_free_unregister(&task_nb); } return NOTIFY_OK; } @@ -100,8 +99,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) * that we have nothing further to offer on * this pass. * - * Note: Currently you need CONFIG_PROFILING - * for this to work correctly. */ if (lowmem_deathpending) return 0; @@ -177,15 +174,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_adj, selected_tasksize); - /* - * If CONFIG_PROFILING is off, then task_handoff_register() - * is a nop. In that case we don't want to stall the killer - * by setting lowmem_deathpending. - */ -#ifdef CONFIG_PROFILING lowmem_deathpending = selected; - task_handoff_register(&task_nb); -#endif + task_free_register(&task_nb); force_sig(SIGKILL, selected); rem -= selected_tasksize; } -- cgit v1.2.3 From 730c51b8da40df4d6b27faea011849107eddb765 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Thu, 6 May 2010 15:43:46 -0700 Subject: staging: android: lowmemorykiller: Remove bitrotted codepath Now that we're murder-synchronous, this code path will never be called (and if it does, it doesn't tell us anything useful other than we killed a task that was already being killed by somebody else but hadn't gotten its' signal yet) Signed-off-by: San Mehat --- drivers/staging/android/lowmemorykiller.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/staging/android/lowmemorykiller.c') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index cae9212d909..cd4d3fdb2e7 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -165,12 +165,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) p->pid, p->comm, oom_adj, tasksize); } if (selected) { - if (fatal_signal_pending(selected)) { - pr_warning("process %d is suffering a slow death\n", - selected->pid); - read_unlock(&tasklist_lock); - return rem; - } lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_adj, selected_tasksize); -- cgit v1.2.3 From 84a7bd81bc301b7a25151dac04a7c39048df33be Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 9 Sep 2010 10:48:21 +0530 Subject: lowmemorykiller: don't unregister notifier from atomic context The lowmemorykiller registers an atomic notifier for notfication of when the task is freed. From this atomic notifier callback, it removes the atomic notifier via task_free_unregister(). This is incorrect because atomic_notifier_chain_unregister() calls syncronize_rcu(), which can sleep, which shouldn't be done from an atomic notifier. Fix this by registering the notifier during init, and only unregister it if the lowmemorykiller is unloaded. Change-Id: I1577b04e617bc2b2e39dcb490fcfc9ce660eb7ec Signed-off-by: Rabin Vincent Signed-off-by: Christian Bejram --- drivers/staging/android/lowmemorykiller.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/staging/android/lowmemorykiller.c') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index cd4d3fdb2e7..0111497550d 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -71,10 +71,10 @@ static int task_notify_func(struct notifier_block *self, unsigned long val, void *data) { struct task_struct *task = data; - if (task == lowmem_deathpending) { + + if (task == lowmem_deathpending) lowmem_deathpending = NULL; - task_free_unregister(&task_nb); - } + return NOTIFY_OK; } @@ -169,7 +169,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) selected->pid, selected->comm, selected_oom_adj, selected_tasksize); lowmem_deathpending = selected; - task_free_register(&task_nb); force_sig(SIGKILL, selected); rem -= selected_tasksize; } @@ -186,6 +185,7 @@ static struct shrinker lowmem_shrinker = { static int __init lowmem_init(void) { + task_free_register(&task_nb); register_shrinker(&lowmem_shrinker); return 0; } @@ -193,6 +193,7 @@ static int __init lowmem_init(void) static void __exit lowmem_exit(void) { unregister_shrinker(&lowmem_shrinker); + task_free_unregister(&task_nb); } module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -- cgit v1.2.3 From f1724765f84dffeaa3bbb09115f55efa79382f17 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Tue, 23 Nov 2010 18:20:28 -0800 Subject: staging: android: lowmemorykiller: Don't wait more than one second for a process to die MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a process forked and the child process was killed by the lowmemorykiller, the lowmemory killer would be disabled until the parent process reaped the child or it died itself. Change-Id: I709b1a4e1b1a1970e51d26a39fcbee57977bbc7f Signed-off-by: Arve Hjønnevåg --- drivers/staging/android/lowmemorykiller.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/staging/android/lowmemorykiller.c') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 0111497550d..95ff01b4bc1 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -53,6 +53,7 @@ static size_t lowmem_minfree[6] = { static int lowmem_minfree_size = 4; static struct task_struct *lowmem_deathpending; +static unsigned long lowmem_deathpending_timeout; #define lowmem_print(level, x...) \ do { \ @@ -100,7 +101,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) * this pass. * */ - if (lowmem_deathpending) + if (lowmem_deathpending && + time_before_eq(jiffies, lowmem_deathpending_timeout)) return 0; if (lowmem_adj_size < array_size) @@ -169,6 +171,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) selected->pid, selected->comm, selected_oom_adj, selected_tasksize); lowmem_deathpending = selected; + lowmem_deathpending_timeout = jiffies + HZ; force_sig(SIGKILL, selected); rem -= selected_tasksize; } -- cgit v1.2.3