sched/walt: Fix use after free in trace_sched_update_task_ravg()
commit 4d09122c1868 ("sched: Fix spinlock recursion in sched_exit()") moved freeing of task's current and previous window arrays outside the rq->lock. These arrays can be accessed from another CPU in parallel and end up using freed memory. For example, CPU#0 CPU#1 ---------------------------------- ------------------------------- sched_exit() try_to_wake_up()--> The task wakes up on CPU#0 task_rq_lock() set_task_cpu() fixup_busy_time() --> waiting for CPU#0's rq->lock task_rq_unlock() fixup_busy_time()-->lock acquired free_task_load_ptrs() kfree(p->ravg.curr_window_cpu) update_task_ravg()-->called on current of CPU#0 trace_sched_update_task_ravg() --> access freed memory p->ravg.curr_window_cpu = NULL; To fix this issue, window array pointers must be set to NULL before freeing the memory. Since this happens outside the lock, memory barriers are needed on write and read paths. A much simpler alternative would be skipping update_task_ravg() trace point for tasks that are marked as dead. The window stats of dead tasks are not updated any ways. While at it, skip this trace point for newly created tasks for which also window stats are not updated. Change-Id: I4d7cb8a3cf7cf84270b09721140d35205643b7ab Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org> [spathi@codeaurora.org: moved changes to hmp.c since EAS is not supported] Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
This commit is contained in:
parent
cb0e8e7c96
commit
c6a5b958e6
1 changed files with 6 additions and 2 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-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
|
||||
|
@ -2881,11 +2881,15 @@ void update_task_ravg(struct task_struct *p, struct rq *rq, int event,
|
|||
update_task_burst(p, rq, event, runtime);
|
||||
update_cpu_busy_time(p, rq, event, wallclock, irqtime);
|
||||
update_task_pred_demand(rq, p, event);
|
||||
done:
|
||||
|
||||
if (exiting_task(p))
|
||||
goto done;
|
||||
|
||||
trace_sched_update_task_ravg(p, rq, event, wallclock, irqtime,
|
||||
rq->cc.cycles, rq->cc.time,
|
||||
p->grp ? &rq->grp_time : NULL);
|
||||
|
||||
done:
|
||||
p->ravg.mark_start = wallclock;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue