diff options
author | Kevin Hilman <khilman@linaro.org> | 2015-08-12 19:19:09 +0900 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2016-12-14 13:42:03 +0900 |
commit | 107135bdd14704801c8135eb913a1a6874e5c711 (patch) | |
tree | e83b41c793589ff1f050458d2a6e6cc4fe1a0ca9 /kernel | |
parent | 3884488a27857f148ccacfa364ecfb5338d0d9e1 (diff) |
sched: hmp: fix spinlock recursion in active migration
[original commit message]
Commit cd5c2cc93d3d (hmp: Remove potential for task_struct access
race) introduced a put_task_struct() to prevent races, but in
doing so introduced potential spinlock recursion. (This change was further
onsolidated in commit 0baa5811bacf -- sched: hmp: unify active migration code.)
Unfortunately, the put_task_struct() is done while the runqueue
spinlock is held, but put_task_struct() can also cause a reschedule
causing the runqueue lock to be acquired recursively.
To fix, move the put_task_struct() outside the runqueue spinlock.
[additional commit message by Chanwoo Choi]
We did not apply hmp patch[1] because patch[1] clean the code by sharing the
same code. When I applied hmp patch[1], scheduling problem issue occured.
[1] commit 0baa5811bacf -- sched: hmp: unify active migration code.)
So, this patch move the put_task_struct() just outside the runqueue spinlock.
Reported-by: Victor Lixin <victor.lixin@hisilicon.com>
Cc: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Cc: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Kevin Hilman <khilman@linaro.org>
Reviewed-by: Jon Medhurst <tixy@linaro.org>
Reviewed-by: Alex Shi <alex.shi@linaro.org>
Reviewed-by: Chris Redpath <chris.redpath@arm.com>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
[cw00.choi: Fix the merge conflict]
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/fair.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5900db7e1fba..55b42fc00294 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -9160,9 +9160,9 @@ static int hmp_active_task_migration_cpu_stop(void *data) rcu_read_unlock(); double_unlock_balance(busiest_rq, target_rq); out_unlock: - put_task_struct(p); busiest_rq->active_balance = 0; raw_spin_unlock_irq(&busiest_rq->lock); + put_task_struct(p); return 0; } @@ -9234,9 +9234,9 @@ static int hmp_idle_pull_cpu_stop(void *data) rcu_read_unlock(); double_unlock_balance(busiest_rq, target_rq); out_unlock: - put_task_struct(p); busiest_rq->active_balance = 0; raw_spin_unlock_irq(&busiest_rq->lock); + put_task_struct(p); return 0; } |