staging: android/lowmemorykiller: Better mm handling

LMK should not directly check for task->mm. The reason is that the
process' threads may exit or detach its mm via use_mm(), but other
threads may still have a valid mm. To catch this we use
find_lock_task_mm(), which walks up all threads and returns an
appropriate task (with lock held).

Suggested-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Anton Vorontsov 2012-02-06 20:29:47 +04:00 committed by Greg Kroah-Hartman
parent 294b27119f
commit 9567000118

View file

@ -82,7 +82,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data)
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *p;
struct task_struct *tsk;
struct task_struct *selected = NULL;
int rem = 0;
int tasksize;
@ -134,15 +134,17 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
selected_oom_adj = min_adj;
rcu_read_lock();
for_each_process(p) {
struct mm_struct *mm;
for_each_process(tsk) {
struct task_struct *p;
struct signal_struct *sig;
int oom_adj;
task_lock(p);
mm = p->mm;
p = find_lock_task_mm(tsk);
if (!p)
continue;
sig = p->signal;
if (!mm || !sig) {
if (!sig) {
task_unlock(p);
continue;
}
@ -151,7 +153,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
task_unlock(p);
continue;
}
tasksize = get_mm_rss(mm);
tasksize = get_mm_rss(p->mm);
task_unlock(p);
if (tasksize <= 0)
continue;