[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220519134706.GH2578@worktop.programming.kicks-ass.net>
Date: Thu, 19 May 2022 15:47:06 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Jing-Ting Wu <jing-ting.wu@...iatek.com>
Cc: Daniel Bristot de Oliveira <bristot@...hat.com>,
Valentin Schneider <vschneid@...hat.com>, tglx@...utronix.de,
wsd_upstream@...iatek.com, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-mediatek@...ts.infradead.org, Jonathan.JMChen@...iatek.com,
"chris.redpath@....com" <chris.redpath@....com>,
Dietmar Eggemann <dietmar.eggemann@....com>,
Vincent Donnefort <vdonnefort@...il.com>,
Ingo Molnar <mingo@...hat.com>,
Juri Lelli <juri.lelli@...hat.com>,
Vincent Guittot <vincent.guittot@...aro.org>,
Steven Rostedt <rostedt@...dmis.org>,
Ben Segall <bsegall@...gle.com>, Mel Gorman <mgorman@...e.de>,
Christian Brauner <brauner@...nel.org>
Subject: Re: [Bug] Race condition between CPU hotplug off flow and
__sched_setscheduler()
On Thu, May 19, 2022 at 08:53:15PM +0800, Jing-Ting Wu wrote:
> Hi all
>
>
> There is a race condition between CPU hotplug off flow and
> __sched_setscheduler(), which will cause hang-up in CPU hotplug off
> flow.
How easy can you reproduce; does the below hack make it better?
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 95bac3b094b3..f18ee22b29bc 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4763,20 +4763,30 @@ struct callback_head balance_push_callback = {
.func = (void (*)(struct callback_head *))balance_push,
};
-static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
+static inline struct callback_head *
+__splice_balance_callbacks(struct rq *rq, bool foo)
{
struct callback_head *head = rq->balance_callback;
lockdep_assert_rq_held(rq);
- if (head)
- rq->balance_callback = NULL;
+ if (head) {
+ if (foo && head == &balance_push_callback)
+ head = NULL;
+ else
+ rq->balance_callback = NULL;
+ }
return head;
}
+static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
+{
+ return __splice_balance_callbacks(rq, true);
+}
+
static void __balance_callbacks(struct rq *rq)
{
- do_balance_callbacks(rq, splice_balance_callbacks(rq));
+ do_balance_callbacks(rq, __splice_balance_callbacks(rq, false));
}
static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
Powered by blists - more mailing lists