Received: by 2002:a05:7412:40d:b0:e2:908c:2ebd with SMTP id 13csp1179112rdf; Wed, 22 Nov 2023 07:35:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IF1XNUcfRtLCD5c61F2Kw1vnC86DE4466XI1Fnqkd36KfAanUtcjZLNh3GlPZjEpHTiehnl X-Received: by 2002:a05:6a00:6ca2:b0:6be:334c:6fd1 with SMTP id jc34-20020a056a006ca200b006be334c6fd1mr3673650pfb.26.1700667320314; Wed, 22 Nov 2023 07:35:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700667320; cv=none; d=google.com; s=arc-20160816; b=cw8uK9TloOJopjQ+f0BgRrq6IewRZD3jUlhTbBJbpJs93HmUsAPI9Aj4pQaP1jAeGH ZdulFeQmv+7zTAzgdhS2/Fue7QWCUFcfl/C1DiFYBftRwqbglwrN/ttWfAodUHQNPfuY gpZKN/VbAFIw3Q5/i2R78dlsJ4yC3Wfgssds5fKPXCF0f8AoPtUA9yNaqJY898SZin9r BJTNQ7zFW8nw4korhGWDd7kHMVsExfSXyrhiXIv+re6AJ8P0Vu5KKwx1EoQ7PE35Ip8k D8xymlYSTsV7nJKHVN2aN5AfbxjsEHyu9VF4L4BhfaZbp9kP+qObJ9XMI1zOl9e7dArv BsNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=UMPwMLugHPkj8PTa4jtOAQ0VacfCz2RH7OhR+i5k8ac=; fh=XZ0uwZE0paIV2j00M5UPyZjQ8Mltj2gjM9nA995WUzQ=; b=AtjFKDLNLzdxgYqrwCgjdc6cNAv9qZmtkH4IfvaDMX/CLgPDOqYhhCbffPmGvPiSjN nFAYXDgeb4phL87c4LGaK9OMy+fghY7pL178H1Yqg2EwVP1KIg/7cp9Q/O8Ff7iDcpkM PLh5R2FjJwNOBjh/LD2kUazfjK3bd0Om3mjiKL1LlQLsNEdXJmnaUjAg/xF/7Ldt/YAk KSniVl0Qei7eNdlXGKpjmoC94ayeG1hiRZpLeQoKhiPKftzZk8BjaZiggR6yS1b/3ZFo tiTVxZIi8RwdZD5gEk0reNJeSrYtldKOIntz+No3vLbyWGGM5PuC0TISXEUijddSgsWZ GN/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QkQm27iV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id q9-20020a056a00084900b006cb8980fce1si7561867pfk.356.2023.11.22.07.35.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 07:35:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QkQm27iV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 0D5AE8213F21; Wed, 22 Nov 2023 07:35:08 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229634AbjKVPe5 (ORCPT + 99 others); Wed, 22 Nov 2023 10:34:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235345AbjKVPeb (ORCPT ); Wed, 22 Nov 2023 10:34:31 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE57E211B; Wed, 22 Nov 2023 07:33:50 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C99EC43395; Wed, 22 Nov 2023 15:33:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700667230; bh=9TjfYzEketco56JT7Gl5XlhikKQhgIw6GK/3EvG5mK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QkQm27iV3qqPQox1yz608ICAKo+xyfs27gm7GxcPKVPghm7Qrn3sAPv/BuC4gMBez Oo/fFo8p/jo4CFuMke8LaQOt4zpGyG4/UVYbqiQX5ZqfFGLmEQYSSZuOjv8LCvlklU y8F2R5a/n3nDTFImP8WLGqQOPMzLd4E4/wi8Mf2Op5rrYlRgMSv0abnvDdKajWZY1K bwW/lJhhPKI1rVceExXOkCDUP1wRdqseih+Y0o1BSBYKweYT0AkGBvGtsiBvpc0Ykn A6sZBqX131Nd5lzH2uJ1wBfSuw6ttAEMMNUgn+a3wJ6uit4roOgCWECSN1GeeN3KGH NxBXFuAXZ/g3g== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Thomas Gleixner , Yu Liao , Liu Tie , Sasha Levin , peterz@infradead.org Subject: [PATCH AUTOSEL 6.5 03/15] hrtimers: Push pending hrtimers away from outgoing CPU earlier Date: Wed, 22 Nov 2023 10:33:05 -0500 Message-ID: <20231122153340.852434-3-sashal@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231122153340.852434-1-sashal@kernel.org> References: <20231122153340.852434-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.5.12 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Wed, 22 Nov 2023 07:35:08 -0800 (PST) From: Thomas Gleixner [ Upstream commit 5c0930ccaad5a74d74e8b18b648c5eb21ed2fe94 ] 2b8272ff4a70 ("cpu/hotplug: Prevent self deadlock on CPU hot-unplug") solved the straight forward CPU hotplug deadlock vs. the scheduler bandwidth timer. Yu discovered a more involved variant where a task which has a bandwidth timer started on the outgoing CPU holds a lock and then gets throttled. If the lock required by one of the CPU hotplug callbacks the hotplug operation deadlocks because the unthrottling timer event is not handled on the dying CPU and can only be recovered once the control CPU reaches the hotplug state which pulls the pending hrtimers from the dead CPU. Solve this by pushing the hrtimers away from the dying CPU in the dying callbacks. Nothing can queue a hrtimer on the dying CPU at that point because all other CPUs spin in stop_machine() with interrupts disabled and once the operation is finished the CPU is marked offline. Reported-by: Yu Liao Signed-off-by: Thomas Gleixner Tested-by: Liu Tie Link: https://lore.kernel.org/r/87a5rphara.ffs@tglx Signed-off-by: Sasha Levin --- include/linux/cpuhotplug.h | 1 + include/linux/hrtimer.h | 4 ++-- kernel/cpu.c | 8 +++++++- kernel/time/hrtimer.c | 33 ++++++++++++--------------------- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index f0231cc66746e..294e58ce035ce 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -195,6 +195,7 @@ enum cpuhp_state { CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, CPUHP_AP_ARM64_ISNDEP_STARTING, CPUHP_AP_SMPCFD_DYING, + CPUHP_AP_HRTIMERS_DYING, CPUHP_AP_X86_TBOOT_DYING, CPUHP_AP_ARM_CACHE_B15_RAC_DYING, CPUHP_AP_ONLINE, diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 0ee140176f102..f2044d5a652b5 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -531,9 +531,9 @@ extern void sysrq_timer_list_show(void); int hrtimers_prepare_cpu(unsigned int cpu); #ifdef CONFIG_HOTPLUG_CPU -int hrtimers_dead_cpu(unsigned int cpu); +int hrtimers_cpu_dying(unsigned int cpu); #else -#define hrtimers_dead_cpu NULL +#define hrtimers_cpu_dying NULL #endif #endif diff --git a/kernel/cpu.c b/kernel/cpu.c index 26119d2154102..491c0a7e7c25c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -2086,7 +2086,7 @@ static struct cpuhp_step cpuhp_hp_states[] = { [CPUHP_HRTIMERS_PREPARE] = { .name = "hrtimers:prepare", .startup.single = hrtimers_prepare_cpu, - .teardown.single = hrtimers_dead_cpu, + .teardown.single = NULL, }, [CPUHP_SMPCFD_PREPARE] = { .name = "smpcfd:prepare", @@ -2178,6 +2178,12 @@ static struct cpuhp_step cpuhp_hp_states[] = { .startup.single = NULL, .teardown.single = smpcfd_dying_cpu, }, + [CPUHP_AP_HRTIMERS_DYING] = { + .name = "hrtimers:dying", + .startup.single = NULL, + .teardown.single = hrtimers_cpu_dying, + }, + /* Entry state on starting. Interrupts enabled from here on. Transient * state for synchronsization */ [CPUHP_AP_ONLINE] = { diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 238262e4aba7e..760793998cdd7 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2219,29 +2219,22 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, } } -int hrtimers_dead_cpu(unsigned int scpu) +int hrtimers_cpu_dying(unsigned int dying_cpu) { struct hrtimer_cpu_base *old_base, *new_base; - int i; + int i, ncpu = cpumask_first(cpu_active_mask); - BUG_ON(cpu_online(scpu)); - tick_cancel_sched_timer(scpu); + tick_cancel_sched_timer(dying_cpu); + + old_base = this_cpu_ptr(&hrtimer_bases); + new_base = &per_cpu(hrtimer_bases, ncpu); - /* - * this BH disable ensures that raise_softirq_irqoff() does - * not wakeup ksoftirqd (and acquire the pi-lock) while - * holding the cpu_base lock - */ - local_bh_disable(); - local_irq_disable(); - old_base = &per_cpu(hrtimer_bases, scpu); - new_base = this_cpu_ptr(&hrtimer_bases); /* * The caller is globally serialized and nobody else * takes two locks at once, deadlock is not possible. */ - raw_spin_lock(&new_base->lock); - raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock(&old_base->lock); + raw_spin_lock_nested(&new_base->lock, SINGLE_DEPTH_NESTING); for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { migrate_hrtimer_list(&old_base->clock_base[i], @@ -2252,15 +2245,13 @@ int hrtimers_dead_cpu(unsigned int scpu) * The migration might have changed the first expiring softirq * timer on this CPU. Update it. */ - hrtimer_update_softirq_timer(new_base, false); + __hrtimer_get_next_event(new_base, HRTIMER_ACTIVE_SOFT); + /* Tell the other CPU to retrigger the next event */ + smp_call_function_single(ncpu, retrigger_next_event, NULL, 0); - raw_spin_unlock(&old_base->lock); raw_spin_unlock(&new_base->lock); + raw_spin_unlock(&old_base->lock); - /* Check, if we got expired work to do */ - __hrtimer_peek_ahead_timers(); - local_irq_enable(); - local_bh_enable(); return 0; } -- 2.42.0