diff options
author | Hong-Mei Li <a21834@motorola.com> | 2013-06-28 19:26:38 +0800 |
---|---|---|
committer | Simon Shields <keepcalm444@gmail.com> | 2016-06-13 14:47:39 +1000 |
commit | 6f04da23b1e3aa60626bfef868ee89a77cebd637 (patch) | |
tree | 965631521a4d3b9831846da116efda37ddeae69b /drivers | |
parent | 8f5f33a7fd66e85d8d8502b5ee9c1c731ff0aeb5 (diff) | |
download | kernel_samsung_smdk4412-6f04da23b1e3aa60626bfef868ee89a77cebd637.tar.gz kernel_samsung_smdk4412-6f04da23b1e3aa60626bfef868ee89a77cebd637.tar.bz2 kernel_samsung_smdk4412-6f04da23b1e3aa60626bfef868ee89a77cebd637.zip |
staging: android: lowmemorykiller: implement task's adj rbtree
Based on the current LMK implementation, LMK has to scan all processes to
select the correct task to kill during low memory.
The basic idea for the optimization is to :
queue all tasks with oom_score_adj priority, and then LMK just selects the
proper task from the queue(rbtree) to kill.
performance improvement:
the current implementation: average time to find a task to kill : 1004us
the optimized implementation: average time to find a task to kill: 43us
Change-Id: I4dbbdd5673314dbbdabb71c3eff0dc229ce4ea91
Signed-off-by: Hong-Mei Li <a21834@motorola.com>
Reviewed-on: http://gerrit.pcs.mot.com/548917
SLT-Approved: Slta Waiver <sltawvr@motorola.com>
Tested-by: Jira Key <jirakey@motorola.com>
Reviewed-by: Yi-Wei Zhao <gbjc64@motorola.com>
Submit-Approved: Jira Key <jirakey@motorola.com>
Signed-off-by: D. Andrei Măceș <dmaces@nd.edu>
Conflicts:
drivers/staging/android/Kconfig
drivers/staging/android/lowmemorykiller.c
fs/proc/base.c
mm/oom_kill.c
Conflicts:
drivers/staging/android/lowmemorykiller.c
mm/oom_kill.c
Conflicts:
mm/oom_kill.c
Conflicts:
drivers/staging/android/lowmemorykiller.c
mm/oom_kill.c
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/android/Kconfig | 8 | ||||
-rw-r--r-- | drivers/staging/android/lowmemorykiller.c | 100 |
2 files changed, 108 insertions, 0 deletions
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 4aa14949902..30ad4d24bd1 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -99,6 +99,14 @@ config ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES /sys/module/lowmemorykiller/parameters/adj and convert them to oom_score_adj values. +config ANDROID_LMK_ADJ_RBTREE + bool "Use RBTREE for Android Low Memory Killer" + depends on ANDROID_LOW_MEMORY_KILLER + default y + ---help--- + Use oom_score_adj rbtree to select the best proecss to kill + when system in low memory status. + endif # if ANDROID endmenu diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 5645e2939e5..754057c4079 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -101,6 +101,12 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) return NOTIFY_OK; } +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE +static struct task_struct *pick_next_from_adj_tree(struct task_struct *task); +static struct task_struct *pick_first_task(void); +static struct task_struct *pick_last_task(void); +#endif + static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; @@ -184,7 +190,14 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) selected_oom_score_adj = min_score_adj; #endif rcu_read_lock(); + +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE + for (tsk = pick_first_task(); + tsk != pick_last_task(); + tsk = pick_next_from_adj_tree(tsk)) { +#else for_each_process(tsk) { +#endif struct task_struct *p; int oom_score_adj; #ifdef ENHANCED_LMK_ROUTINE @@ -200,7 +213,11 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE + break; +#else continue; +#endif } tasksize = get_mm_rss(p->mm); task_unlock(p); @@ -246,7 +263,11 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) #else if (selected) { if (oom_score_adj < selected_oom_score_adj) +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE + break; +#else continue; +#endif if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; @@ -391,6 +412,85 @@ static const struct kparam_array __param_arr_adj = { }; #endif +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE +DEFINE_SPINLOCK(lmk_lock); +struct rb_root tasks_scoreadj = RB_ROOT; +void add_2_adj_tree(struct task_struct *task) +{ + struct rb_node **link = &tasks_scoreadj.rb_node; + struct rb_node *parent = NULL; + struct task_struct *task_entry; + s64 key = task->signal->oom_score_adj; + /* + * Find the right place in the rbtree: + */ + spin_lock(&lmk_lock); + while (*link) { + parent = *link; + task_entry = rb_entry(parent, struct task_struct, adj_node); + + if (key < task_entry->signal->oom_score_adj) + link = &parent->rb_right; + else + link = &parent->rb_left; + } + + rb_link_node(&task->adj_node, parent, link); + rb_insert_color(&task->adj_node, &tasks_scoreadj); + spin_unlock(&lmk_lock); +} + +void delete_from_adj_tree(struct task_struct *task) +{ + spin_lock(&lmk_lock); + rb_erase(&task->adj_node, &tasks_scoreadj); + spin_unlock(&lmk_lock); +} + + +static struct task_struct *pick_next_from_adj_tree(struct task_struct *task) +{ + struct rb_node *next; + + spin_lock(&lmk_lock); + next = rb_next(&task->adj_node); + spin_unlock(&lmk_lock); + + if (!next) + return NULL; + + return rb_entry(next, struct task_struct, adj_node); +} + +static struct task_struct *pick_first_task(void) +{ + struct rb_node *left; + + spin_lock(&lmk_lock); + left = rb_first(&tasks_scoreadj); + spin_unlock(&lmk_lock); + + if (!left) + return NULL; + + return rb_entry(left, struct task_struct, adj_node); +} + +static struct task_struct *pick_last_task(void) +{ + struct rb_node *right; + + spin_lock(&lmk_lock); + right = rb_last(&tasks_scoreadj); + spin_unlock(&lmk_lock); + + if (!right) + return NULL; + + return rb_entry(right, struct task_struct, adj_node); +} +#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_call(MODULE_PARAM_PREFIX, adj, |