OSDN Git Service

staging: android: lowmemorykiller: Add config option to support oom_adj values
authorArve Hjønnevåg <arve@android.com>
Wed, 26 Sep 2012 00:37:14 +0000 (17:37 -0700)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Mon, 13 Apr 2015 16:42:58 +0000 (00:42 +0800)
The conversion to use oom_score_adj instead of the deprecated oom_adj
values breaks existing user-space code. Add a config option to convert
oom_adj values written to oom_score_adj values if they appear to be
valid oom_adj values.

Change-Id: I68308125059b802ee2991feefb07e9703bc48549
Signed-off-by: Arve Hjønnevåg <arve@android.com>
drivers/staging/android/Kconfig
drivers/staging/android/lowmemorykiller.c

index 8feb904..898bf85 100644 (file)
@@ -28,6 +28,15 @@ config ANDROID_LOW_MEMORY_KILLER
        ---help---
          Registers processes to be killed when memory is low
 
+config ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES
+       bool "Android Low Memory Killer: detect oom_adj values"
+       depends on ANDROID_LOW_MEMORY_KILLER
+       default y
+       ---help---
+         Detect oom_adj values written to
+         /sys/module/lowmemorykiller/parameters/adj and convert them
+         to oom_score_adj values.
+
 config SYNC
        bool "Synchronization framework"
        default n
index 047fcaa..15e64e5 100644 (file)
@@ -192,9 +192,92 @@ static void __exit lowmem_exit(void)
        unregister_shrinker(&lowmem_shrinker);
 }
 
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES
+static short lowmem_oom_adj_to_oom_score_adj(short oom_adj)
+{
+       if (oom_adj == OOM_ADJUST_MAX)
+               return OOM_SCORE_ADJ_MAX;
+       else
+               return (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
+}
+
+static void lowmem_autodetect_oom_adj_values(void)
+{
+       int i;
+       short oom_adj;
+       short oom_score_adj;
+       int array_size = ARRAY_SIZE(lowmem_adj);
+
+       if (lowmem_adj_size < array_size)
+               array_size = lowmem_adj_size;
+
+       if (array_size <= 0)
+               return;
+
+       oom_adj = lowmem_adj[array_size - 1];
+       if (oom_adj > OOM_ADJUST_MAX)
+               return;
+
+       oom_score_adj = lowmem_oom_adj_to_oom_score_adj(oom_adj);
+       if (oom_score_adj <= OOM_ADJUST_MAX)
+               return;
+
+       lowmem_print(1, "lowmem_shrink: convert oom_adj to oom_score_adj:\n");
+       for (i = 0; i < array_size; i++) {
+               oom_adj = lowmem_adj[i];
+               oom_score_adj = lowmem_oom_adj_to_oom_score_adj(oom_adj);
+               lowmem_adj[i] = oom_score_adj;
+               lowmem_print(1, "oom_adj %d => oom_score_adj %d\n",
+                            oom_adj, oom_score_adj);
+       }
+}
+
+static int lowmem_adj_array_set(const char *val, const struct kernel_param *kp)
+{
+       int ret;
+
+       ret = param_array_ops.set(val, kp);
+
+       /* HACK: Autodetect oom_adj values in lowmem_adj array */
+       lowmem_autodetect_oom_adj_values();
+
+       return ret;
+}
+
+static int lowmem_adj_array_get(char *buffer, const struct kernel_param *kp)
+{
+       return param_array_ops.get(buffer, kp);
+}
+
+static void lowmem_adj_array_free(void *arg)
+{
+       param_array_ops.free(arg);
+}
+
+static struct kernel_param_ops lowmem_adj_array_ops = {
+       .set = lowmem_adj_array_set,
+       .get = lowmem_adj_array_get,
+       .free = lowmem_adj_array_free,
+};
+
+static const struct kparam_array __param_arr_adj = {
+       .max = ARRAY_SIZE(lowmem_adj),
+       .num = &lowmem_adj_size,
+       .ops = &param_ops_short,
+       .elemsize = sizeof(lowmem_adj[0]),
+       .elem = lowmem_adj,
+};
+#endif
+
 module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES
+module_param_cb(adj, &lowmem_adj_array_ops, .arr = &__param_arr_adj,
+                        S_IRUGO | S_IWUSR);
+__MODULE_PARM_TYPE(adj, "array of short");
+#else
 module_param_array_named(adj, lowmem_adj, short, &lowmem_adj_size,
                         S_IRUGO | S_IWUSR);
+#endif
 module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
                         S_IRUGO | S_IWUSR);
 module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);