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

Commit 247cd183 authored by Vinayak Menon's avatar Vinayak Menon
Browse files

lowmemorykiller: use for_each_thread instead of buggy while_each_thread

Couple of cases were reported few months ago, where the cpu was blocked
on the following call stack for /seconds/ after which the watchdog fires.

test_task_flag(p = 0xE14ABF00, ?)
lowmem_shrink(?, sc = 0xD7A03C04)
shrink_slab(shrink = 0xD7A03C04, nr_pages_scanned = 0, lru_pages = 120)
try_to_free_pages(zonelist = 0xC1116440, ?, ?, ?)
__alloc_pages_nodemask(?, order = 0, ?, nodemask = 0x0)
__do_page_cache_readahead(mapping = 0xEB819364, filp = 0xCC16DC00, offset =
ra_submit(?, ?, ?)
filemap_fault(vma = 0xC105D240, vmf = 0xD7A03DC8)

There weren't any dumps to analyse the case, but this can be a possible
reason. while_each_thread is known to be buggy and can result in the
function looping forever if the task exits, even when protected with
rcu_read_lock. Use for_each_thread instead.

More details on the problems with while_each_thread can be found
at https://lkml.org/lkml/2013/12/2/320



Change-Id: I5eb6e4b463f81142a2a7824db389201357432ec7
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent dbb67aae
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -182,16 +182,16 @@ static struct notifier_block lmk_vmpr_nb = {

static int test_task_flag(struct task_struct *p, int flag)
{
	struct task_struct *t = p;
	struct task_struct *t;

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

	return 0;
}