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 <pkondeti@codeaurora.org>
This commit is contained in:
Pavankumar Kondeti
2018-01-10 15:15:41 +05:30
parent 5a580c0a4d
commit 4d09122c18
2 changed files with 6 additions and 2 deletions

View File

@@ -9622,11 +9622,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, &rf);
free_task_load_ptrs(p);
}
#endif /* CONFIG_SCHED_WALT */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1965,6 +1965,10 @@ void init_new_task_load(struct task_struct *p, bool idle_task)
p->misfit = false;
}
/*
* 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);