Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23b5d9f8 authored by Vinayak Menon's avatar Vinayak Menon
Browse files

mm: process_reclaim: do not iterate over stale task structs



swap_fn iterates through the threads of selected tasks after
a rcu_read_unlock which is wrong. But we can't extend the
rcu_read_lock since it will result in severe performance
issues. So better avoid iterating over the threads. Just
lock the group leader and use it further.

Change-Id: I36269b1b6619315f33f6f3b49ec73571a66796f2
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent a9ee5f7d
Loading
Loading
Loading
Loading
+12 −19
Original line number Diff line number Diff line
@@ -88,14 +88,17 @@ static int test_task_flag(struct task_struct *p, int flag)
{
	struct task_struct *t = p;

	do {
	rcu_read_lock();
	for_each_thread(p, t) {
		task_lock(t);
		if (test_tsk_thread_flag(t, flag)) {
			task_unlock(t);
			rcu_read_unlock();
			return 1;
		}
		task_unlock(t);
	} while_each_thread(p, t);
	}
	rcu_read_unlock();

	return 0;
}
@@ -125,10 +128,6 @@ static void swap_fn(struct work_struct *work)
		if (tsk->flags & PF_KTHREAD)
			continue;

		/* if task no longer has any memory ignore it */
		if (test_task_flag(tsk, TIF_MM_RELEASED))
			continue;

		if (test_task_flag(tsk, TIF_MEMDIE))
			continue;

@@ -165,20 +164,20 @@ static void swap_fn(struct work_struct *work)
		}
	}

	for (i = 0; i < si; i++) {
		get_task_struct(selected[i].p);
	for (i = 0; i < si; i++)
		total_sz += selected[i].tasksize;
	}

	rcu_read_unlock();

	/* Skip reclaim if total size is too less */
	if (total_sz < SWAP_CLUSTER_MAX) {
		for (i = 0; i < si; i++)
			put_task_struct(selected[i].p);
		rcu_read_unlock();
		return;
	}

	for (i = 0; i < si; i++)
		get_task_struct(selected[i].p);

	rcu_read_unlock();

	while (si--) {
		nr_to_reclaim =
			(selected[si].tasksize * per_swap_size) / total_sz;
@@ -186,12 +185,6 @@ static void swap_fn(struct work_struct *work)
		if (!nr_to_reclaim)
			nr_to_reclaim = 1;

		if ((test_task_flag(selected[si].p, TIF_MM_RELEASED))
			|| (test_task_flag(selected[si].p, TIF_MEMDIE))) {
			put_task_struct(selected[si].p);
			continue;
		}

		rp = reclaim_task_anon(selected[si].p, nr_to_reclaim);

		trace_process_reclaim(selected[si].tasksize,