public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Xiongfeng Wang <wangxiongfeng2@huawei.com>,
	vschneid@redhat.com, Phil Auld <pauld@redhat.com>,
	vdonnefort@google.com,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Wei Li <liwei391@huawei.com>, "liaoyu (E)" <liaoyu15@huawei.com>,
	zhangqiao22@huawei.com, Peter Zijlstra <peterz@infradead.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Ingo Molnar <mingo@kernel.org>
Subject: Re: [Question] report a race condition between CPU hotplug state machine and hrtimer 'sched_cfs_period_timer' for cfs bandwidth throttling
Date: Wed, 23 Aug 2023 12:14:37 +0200	[thread overview]
Message-ID: <87h6oqdq0i.ffs@tglx> (raw)
In-Reply-To: <CAKfTPtBSx7h1caR9g8wEK5GG2JMfSBRqSzLgjRUjrnp1Zc-ssg@mail.gmail.com>

On Thu, Jun 29 2023 at 10:30, Vincent Guittot wrote:
> On Thu, 29 Jun 2023 at 00:01, Thomas Gleixner <tglx@linutronix.de> wrote:
>>  int cpu_device_down(struct device *dev)
>>  {
>> -       return cpu_down(dev->id, CPUHP_OFFLINE);
>> +       unsigned int cpu = cpumask_any_but(cpu_online_mask, dev->id);
>> +
>> +       if (cpu >= nr_cpu_ids)
>> +               return -EBUSY;
>> +
>> +       return work_on_cpu(cpu, __cpu_device_down, dev);
>
> The comment for work_on_cpu :
>
>  * It is up to the caller to ensure that the cpu doesn't go offline.
>  * The caller must not hold any locks which would prevent @fn from completing.
>
> make me wonder if this should be done only once the hotplug lock is
> taken so the selected cpu will not go offline

That makes sense. Updated and again untested patch below.

Thanks,

        tglx
---
Subject: cpu/hotplug: Prevent self deadlock on CPU hot-unplug
From: Thomas Gleixner <tglx@linutronix.de>
Date: Wed, 23 Aug 2023 10:47:02 +0200

Xiongfeng reported and debugged a self deadlock of the task which initiates
and controls a CPU hot-unplug operation vs. the CFS bandwidth timer.

    CPU1      			                 	 CPU2

T1 sets cfs_quota
   starts hrtimer cfs_bandwidth 'period_timer'
T1 is migrated to CPU2				
						T1 initiates offlining of CPU1
Hotplug operation starts
  ...
'period_timer' expires and is re-enqueued on CPU1
  ...
take_cpu_down()
  CPU1 shuts down and does not handle timers
  anymore. They have to be migrated in the
  post dead hotplug steps by the control task.

						T1 runs the post dead offline operation
					      	T1 is scheduled out
						T1 waits for 'period_timer' to expire

T1 waits there forever if it is scheduled out before it can execute the hrtimer
offline callback hrtimers_dead_cpu().

Cure this by delegating the hotplug control operation to a worker thread on
an online CPU. This takes the initiating user space task, which might be
affected by the bandwidth timer, completely out of the picture.

Reported-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/lkml/8e785777-03aa-99e1-d20e-e956f5685be6@huawei.com
---
 kernel/cpu.c |   24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1467,8 +1467,22 @@ static int __ref _cpu_down(unsigned int
 	return ret;
 }
 
+struct cpu_down_work {
+	unsigned int		cpu;
+	enum cpuhp_state	target;
+};
+
+static long __cpu_down_maps_locked(void *arg)
+{
+	struct cpu_down_work *work = arg;
+
+	return _cpu_down(work->cpu, 0, work->target);
+}
+
 static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
 {
+	struct cpu_down_work work = { .cpu = cpu, .target = target, };
+
 	/*
 	 * If the platform does not support hotplug, report it explicitly to
 	 * differentiate it from a transient offlining failure.
@@ -1477,7 +1491,15 @@ static int cpu_down_maps_locked(unsigned
 		return -EOPNOTSUPP;
 	if (cpu_hotplug_disabled)
 		return -EBUSY;
-	return _cpu_down(cpu, 0, target);
+
+	/*
+	 * Ensure that the control task does not run on the to be offlined
+	 * CPU to prevent a deadlock against cfs_b->period_timer.
+	 */
+	cpu = cpumask_any_but(cpu_online_mask, cpu);
+	if (cpu >= nr_cpu_ids)
+		return -EBUSY;
+	return work_on_cpu(cpu, __cpu_down_maps_locked, &work);
 }
 
 static int cpu_down(unsigned int cpu, enum cpuhp_state target)

  parent reply	other threads:[~2023-08-23 10:15 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-09 11:24 [Question] report a race condition between CPU hotplug state machine and hrtimer 'sched_cfs_period_timer' for cfs bandwidth throttling Xiongfeng Wang
2023-06-09 14:55 ` Thomas Gleixner
2023-06-12 12:49   ` Xiongfeng Wang
2023-06-26  8:23     ` Xiongfeng Wang
2023-06-27 16:46       ` Vincent Guittot
2023-06-28 12:03         ` Thomas Gleixner
2023-06-28 12:35           ` Vincent Guittot
2023-06-28 22:01             ` Thomas Gleixner
2023-06-29  1:41               ` Xiongfeng Wang
2023-06-29  8:30               ` Vincent Guittot
2023-08-22  8:58                 ` Xiongfeng Wang
2023-08-23 10:14                 ` Thomas Gleixner [this message]
2023-08-24  7:25                   ` Yu Liao
2023-08-29  7:18                   ` Vincent Guittot
2023-06-28 13:30         ` Vincent Guittot
2023-06-28 21:09           ` Thomas Gleixner
2023-06-29  1:26         ` Xiongfeng Wang
2023-06-29  8:33           ` Vincent Guittot
2023-08-30 10:29 ` [tip: smp/urgent] cpu/hotplug: Prevent self deadlock on CPU hot-unplug tip-bot2 for Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87h6oqdq0i.ffs@tglx \
    --to=tglx@linutronix.de \
    --cc=dietmar.eggemann@arm.com \
    --cc=liaoyu15@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liwei391@huawei.com \
    --cc=mingo@kernel.org \
    --cc=pauld@redhat.com \
    --cc=peterz@infradead.org \
    --cc=vdonnefort@google.com \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=wangxiongfeng2@huawei.com \
    --cc=zhangqiao22@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox