diff options
author | Hong-Mei Li <a21834@motorola.com> | 2015-06-03 14:33:43 -0700 |
---|---|---|
committer | Simon Shields <keepcalm444@gmail.com> | 2016-06-13 14:47:41 +1000 |
commit | 9b0e84ac672845689861120bbb58b33788f7f6a3 (patch) | |
tree | 6eba6ca8a433f7645c76149a375bf4f161161881 /drivers/staging | |
parent | f8be24cb48429f5d532876b57d5083dd4e178159 (diff) | |
download | kernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.zip kernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.tar.gz kernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.tar.bz2 |
lowmemorykiller: maintain LMK rbtree with signal->adj_node
Currently, we maintain LMK rbtree with task->adj_node. However, when
handling oom_score_adj change case, we may del/add a non-leader task
to the RB tree, which is not as expected.
This patch we maintain the LMK rbtree with task->signal->adj_node.
Since signal_struct is shared between main task and threads, we can
avoid non-leader thread adding to tree.
Change-Id: I3ba9e740e03ab04c25497a1cc2c870f051bd5b07
Signed-off-by: Hong-Mei Li <a21834@motorola.com>
Reviewed-on: http://gerrit.mot.com/754225
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver <sltawvr@motorola.com>
Tested-by: Jira Key <jirakey@motorola.com>
Reviewed-by: Zhi-Ming Yuan <a14194@motorola.com>
Reviewed-by: Yi-Wei Zhao <gbjc64@motorola.com>
Submit-Approved: Jira Key <jirakey@motorola.com>
(cherry picked from commit b40634023f9152c6232de9acb80108e0af7e4075)
Signed-off-by: Abdul Salam <salamab@motorola.com>
Reviewed-on: http://gerrit.mot.com/766107
Reviewed-by: Sudharsan Yettapu <sudharsan.yettapu@motorola.com>
Reviewed-by: Ravikumar Vembu <raviv@motorola.com>
(cherry picked from commit f3abd37ce3b4d36ae05cfc1c5cd10e5a3f584e7f)
Reviewed-on: http://gerrit.mot.com/768302
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/android/lowmemorykiller.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index c6ee61c..f68459a 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -420,11 +420,14 @@ static const struct kparam_array __param_arr_adj = { #ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE DEFINE_SPINLOCK(lmk_lock); struct rb_root tasks_scoreadj = RB_ROOT; +/* + * Makesure to invoke the function with holding sighand->siglock + */ void add_2_adj_tree(struct task_struct *task) { struct rb_node **link; struct rb_node *parent = NULL; - struct task_struct *task_entry; + struct signal_struct *sig_entry; s64 key = task->signal->oom_score_adj; /* @@ -434,25 +437,28 @@ void add_2_adj_tree(struct task_struct *task) link = &tasks_scoreadj.rb_node; while (*link) { parent = *link; - task_entry = rb_entry(parent, struct task_struct, adj_node); + sig_entry = rb_entry(parent, struct signal_struct, adj_node); - if (key < task_entry->signal->oom_score_adj) + if (key < sig_entry->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); + rb_link_node(&task->signal->adj_node, parent, link); + rb_insert_color(&task->signal->adj_node, &tasks_scoreadj); spin_unlock(&lmk_lock); } +/* + * Makesure to invoke the function with holding sighand->siglock + */ void delete_from_adj_tree(struct task_struct *task) { spin_lock(&lmk_lock); - if (!RB_EMPTY_NODE(&task->adj_node)) { - rb_erase(&task->adj_node, &tasks_scoreadj); - RB_CLEAR_NODE(&task->adj_node); + if (!RB_EMPTY_NODE(&task->signal->adj_node)) { + rb_erase(&task->signal->adj_node, &tasks_scoreadj); + RB_CLEAR_NODE(&task->signal->adj_node); } spin_unlock(&lmk_lock); } @@ -461,20 +467,23 @@ void delete_from_adj_tree(struct task_struct *task) static struct task_struct *pick_next_from_adj_tree(struct task_struct *task) { struct rb_node *next; + struct signal_struct *next_tsk_sig; spin_lock(&lmk_lock); - next = rb_next(&task->adj_node); + next = rb_next(&task->signal->adj_node); spin_unlock(&lmk_lock); if (!next) return NULL; - return rb_entry(next, struct task_struct, adj_node); + next_tsk_sig = rb_entry(next, struct signal_struct, adj_node); + return next_tsk_sig->curr_target->group_leader; } static struct task_struct *pick_first_task(void) { struct rb_node *left; + struct signal_struct *first_tsk_sig; spin_lock(&lmk_lock); left = rb_first(&tasks_scoreadj); @@ -483,12 +492,14 @@ static struct task_struct *pick_first_task(void) if (!left) return NULL; - return rb_entry(left, struct task_struct, adj_node); + first_tsk_sig = rb_entry(left, struct signal_struct, adj_node); + return first_tsk_sig->curr_target->group_leader; } static struct task_struct *pick_last_task(void) { struct rb_node *right; + struct signal_struct *last_tsk_sig; spin_lock(&lmk_lock); right = rb_last(&tasks_scoreadj); @@ -497,7 +508,8 @@ static struct task_struct *pick_last_task(void) if (!right) return NULL; - return rb_entry(right, struct task_struct, adj_node); + last_tsk_sig = rb_entry(right, struct signal_struct, adj_node); + return last_tsk_sig->curr_target->group_leader; } #endif |