aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHong-Mei Li <a21834@motorola.com>2015-06-03 14:33:43 -0700
committerSimon Shields <keepcalm444@gmail.com>2016-06-13 14:47:41 +1000
commit9b0e84ac672845689861120bbb58b33788f7f6a3 (patch)
tree6eba6ca8a433f7645c76149a375bf4f161161881 /drivers
parentf8be24cb48429f5d532876b57d5083dd4e178159 (diff)
downloadkernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.tar.gz
kernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.tar.bz2
kernel_samsung_smdk4412-9b0e84ac672845689861120bbb58b33788f7f6a3.zip
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')
-rw-r--r--drivers/staging/android/lowmemorykiller.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index c6ee61ca4a6..f68459a36db 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