From 9c933388d8783e46d50c1fd049bd2be68f3d32f5 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Sat, 30 Dec 2017 11:16:45 +0530 Subject: sched: Fix spinlock recursion in sched_exit() The exiting task's prev_window and curr_window arrays are freed with rq->lock acquired. The kfree() may wakeup kswapd and if kswapd wakeup needs the same rq->lock, we hit a deadlock. Fix this issue by freeing these arrays after releasing the lock. Since the task is already marked as exiting under lock, delaying the freeing of the current and window arrays will not have any side effect. Change-Id: I3282d91ba715765e38177b9d66be32aaed989303 Signed-off-by: Pavankumar Kondeti --- kernel/sched/core.c | 2 +- kernel/sched/hmp.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 9dd9640bfe82..acd6fd8393fb 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2325,11 +2325,11 @@ void sched_exit(struct task_struct *p) reset_task_stats(p); p->ravg.mark_start = wallclock; p->ravg.sum_history[0] = EXITING_TASK_MARKER; - free_task_load_ptrs(p); enqueue_task(rq, p, 0); clear_ed_task(p, rq); task_rq_unlock(rq, p, &flags); + free_task_load_ptrs(p); } #endif /* CONFIG_SCHED_HMP */ diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index ae6876e62c0f..70a556f0dd06 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -1526,6 +1526,10 @@ unsigned int cpu_temp(int cpu) return 0; } +/* + * kfree() may wakeup kswapd. So this function should NOT be called + * with any CPU's rq->lock acquired. + */ void free_task_load_ptrs(struct task_struct *p) { kfree(p->ravg.curr_window_cpu); -- cgit v1.2.3