aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSan Mehat <san@android.com>2008-12-20 03:48:38 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:45 -0500
commit08b88cc7844bf984e2e474134c207bb2c46c007d (patch)
tree7733a71c85aabea72410253ca8f37a9c5d076f95 /drivers
parent1fa7026ff026012f3a819b49d44dd6267997f379 (diff)
Staging: android: add lowmemorykiller driver
From: San Mehat <san@android.com> Cc: Brian Swetland <swetland@google.com> Cc: Robert Love <rlove@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/android/Kconfig6
-rw-r--r--drivers/staging/android/Makefile1
-rw-r--r--drivers/staging/android/lowmemorykiller.c119
3 files changed, 126 insertions, 0 deletions
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 502c283eedcc..934f6f2019b3 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -77,4 +77,10 @@ config ANDROID_TIMED_GPIO
77 depends on GENERIC_GPIO 77 depends on GENERIC_GPIO
78 default n 78 default n
79 79
80config ANDROID_LOW_MEMORY_KILLER
81 bool "Android Low Memory Killer"
82 default N
83 ---help---
84 Register processes to be killed when memory is low
85
80endmenu 86endmenu
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 7ea6fbe92f4b..95209d6273a1 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o
2obj-$(CONFIG_ANDROID_LOGGER) += logger.o 2obj-$(CONFIG_ANDROID_LOGGER) += logger.o
3obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o 3obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o
4obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o 4obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
5obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
new file mode 100644
index 000000000000..3715d56ca96b
--- /dev/null
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -0,0 +1,119 @@
1/* drivers/misc/lowmemorykiller.c
2 *
3 * Copyright (C) 2007-2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/oom.h>
20#include <linux/sched.h>
21
22static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask);
23
24static struct shrinker lowmem_shrinker = {
25 .shrink = lowmem_shrink,
26 .seeks = DEFAULT_SEEKS * 16
27};
28static uint32_t lowmem_debug_level = 2;
29static int lowmem_adj[6] = {
30 0,
31 1,
32 6,
33 12,
34};
35static int lowmem_adj_size = 4;
36static size_t lowmem_minfree[6] = {
37 3*512, // 6MB
38 2*1024, // 8MB
39 4*1024, // 16MB
40 16*1024, // 64MB
41};
42static int lowmem_minfree_size = 4;
43
44#define lowmem_print(level, x...) do { if(lowmem_debug_level >= (level)) printk(x); } while(0)
45
46module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
47module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, S_IRUGO | S_IWUSR);
48module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, S_IRUGO | S_IWUSR);
49module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
50
51static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
52{
53 struct task_struct *p;
54 struct task_struct *selected = NULL;
55 int rem = 0;
56 int tasksize;
57 int i;
58 int min_adj = OOM_ADJUST_MAX + 1;
59 int selected_tasksize = 0;
60 int array_size = ARRAY_SIZE(lowmem_adj);
61 int other_free = global_page_state(NR_FREE_PAGES) + global_page_state(NR_FILE_PAGES);
62 if(lowmem_adj_size < array_size)
63 array_size = lowmem_adj_size;
64 if(lowmem_minfree_size < array_size)
65 array_size = lowmem_minfree_size;
66 for(i = 0; i < array_size; i++) {
67 if(other_free < lowmem_minfree[i]) {
68 min_adj = lowmem_adj[i];
69 break;
70 }
71 }
72 if(nr_to_scan > 0)
73 lowmem_print(3, "lowmem_shrink %d, %x, ofree %d, ma %d\n", nr_to_scan, gfp_mask, other_free, min_adj);
74 read_lock(&tasklist_lock);
75 for_each_process(p) {
76 if(p->oomkilladj >= 0 && p->mm) {
77 tasksize = get_mm_rss(p->mm);
78 if(nr_to_scan > 0 && tasksize > 0 && p->oomkilladj >= min_adj) {
79 if(selected == NULL ||
80 p->oomkilladj > selected->oomkilladj ||
81 (p->oomkilladj == selected->oomkilladj &&
82 tasksize > selected_tasksize)) {
83 selected = p;
84 selected_tasksize = tasksize;
85 lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
86 p->pid, p->comm, p->oomkilladj, tasksize);
87 }
88 }
89 rem += tasksize;
90 }
91 }
92 if(selected != NULL) {
93 lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
94 selected->pid, selected->comm,
95 selected->oomkilladj, selected_tasksize);
96 force_sig(SIGKILL, selected);
97 rem -= selected_tasksize;
98 }
99 lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", nr_to_scan, gfp_mask, rem);
100 read_unlock(&tasklist_lock);
101 return rem;
102}
103
104static int __init lowmem_init(void)
105{
106 register_shrinker(&lowmem_shrinker);
107 return 0;
108}
109
110static void __exit lowmem_exit(void)
111{
112 unregister_shrinker(&lowmem_shrinker);
113}
114
115module_init(lowmem_init);
116module_exit(lowmem_exit);
117
118MODULE_LICENSE("GPL");
119