From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B56E3EC2E2 for ; Tue, 19 May 2026 22:09:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779228581; cv=none; b=O+PY82ZiGCly4so4ndAbz6OH8j1k3E4mRmmVmN9Kw30PcewVE1udVE2wN6n/6fY9KQtlRZeQ2tEET+WKUqDAnompAt53YuuOMKAHd1lK8JpjZv6SjsGf8+CV1v6F5istusxbqt+Ebj1DInFF/DOuVGL/45fGwS36awCWeftrZNc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779228581; c=relaxed/simple; bh=k3HZ/7aFAxQXr2+oIWEtPPlVR5aO93QOW5mPY53kvCQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l3q9K7KqWrJzuEqvkz8dZ/VN6IdFwaZ3fkAmUfVRKFvoFnxIOH2e9TF5/2eqnwltOzYo0xRn1Ca24YwFm58zoBi7rxgMDa0m/d6m4pkZ6o0Ck5u6I3z+E/c3mZDG9CxQjvXQ0+yL22ka/sXiTnMjaToad7bLcRB1y3bLg2hsz+g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Jc64k7u1; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Jc64k7u1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14DB31F00893; Tue, 19 May 2026 22:09:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779228580; bh=vpXEf9HmqV1e8Sg2c3WGP+ZvBBaP9PnxdTj8TGSirAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Jc64k7u1q8RfgCCWrkMkYyYaTBCBVFNj76A3G/z/meP99alM/DB7yz/gDI8TPuN1N VtzqAiOgqLRbmKKsj/BGNUbYlsOFxqvqZFqoAxSRHS196XruDlpPjCUK4e7rjEX6Wa xUWbUJwl9Jm4eNrFL54LROtXDWYTu9Peg2TvpyqJrIkYqIHXJoH0nvlrukSPfDIgMp jJC7mnfo+axVsN0wfkbZHOdHO7tta8ffznIggFCTU5ARxyf4Mo1Zum0o0H/FebX/38 vVCIGo5dcizvpJxSuXsztw8g50oHvOlp4hy37k5YKgRgZdJfFza9DlAA+TWIc1YXhu KyDZCAp4kMiqA== From: Frederic Weisbecker To: Thomas Gleixner Cc: LKML , Frederic Weisbecker , Anna-Maria Behnsen Subject: [PATCH 2/2] timers/migration: Deactivate per-capacity hierarchies under nohz_full Date: Wed, 20 May 2026 00:09:26 +0200 Message-ID: <20260519220926.63437-3-frederic@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260519220926.63437-1-frederic@kernel.org> References: <20260519220926.63437-1-frederic@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Nohz_full CPUs global timers are guaranteed to be handled by the timekeeper: that CPU never stops its tick and therefore remains active in the hierarchy. But since the introduction of per-capacity hierarchies, this guarantee is broken because the timekeeper may not belong to the same hierarchy as all the nohz_full CPUs. Fix it with simply turning off capacity awareness when nohz_full is running and force a single hierarchy. Nohz_full is not exactly optimized powerwise anyway. Fixes: 098cbaad8e57 ("timers/migration: Split per-capacity hierarchies") Signed-off-by: Frederic Weisbecker --- kernel/time/timer_migration.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 8032b0044f44..8ba53ad49173 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -1464,8 +1464,24 @@ static long tmigr_trigger_active(void *unused) return 0; } -static struct tmigr_hierarchy *__tmigr_get_hierarchy(unsigned int capacity) +static unsigned int tmigr_get_capacity(int cpu) { + /* + * nohz_full CPUs need to make sure there is always an available (online) + * and never idle migrator to handle all their global timers. That duty + * is served by the timekeeper which then never stops its tick. But the + * timekeeper must then belong to the same hierarchy as all the nohz_full + * CPUs. Simply turn off capacity awareness when nohz_full is running. + */ + if (tick_nohz_full_enabled()) + return SCHED_CAPACITY_SCALE; + else + return arch_scale_cpu_capacity(cpu); +} + +static struct tmigr_hierarchy *__tmigr_get_hierarchy(int cpu) +{ + unsigned int capacity = tmigr_get_capacity(cpu); struct tmigr_hierarchy *iter; list_for_each_entry(iter, &tmigr_hierarchy_list, node) { @@ -1500,7 +1516,7 @@ static int tmigr_clear_cpu_available(unsigned int cpu) } if (firstexp != KTIME_MAX) { - struct tmigr_hierarchy *hier = __tmigr_get_hierarchy(arch_scale_cpu_capacity(cpu)); + struct tmigr_hierarchy *hier = __tmigr_get_hierarchy(cpu); if (WARN_ON_ONCE(!hier)) return -EINVAL; @@ -1938,11 +1954,11 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, return err; } -static struct tmigr_hierarchy *tmigr_get_hierarchy(unsigned int capacity) +static struct tmigr_hierarchy *tmigr_get_hierarchy(int cpu) { struct tmigr_hierarchy *hier; - hier = __tmigr_get_hierarchy(capacity); + hier = __tmigr_get_hierarchy(cpu); if (hier) return hier; @@ -1962,7 +1978,7 @@ static struct tmigr_hierarchy *tmigr_get_hierarchy(unsigned int capacity) for (int i = 0; i < tmigr_hierarchy_levels; i++) INIT_LIST_HEAD(&hier->level_list[i]); - hier->capacity = capacity; + hier->capacity = tmigr_get_capacity(cpu); list_add_tail(&hier->node, &tmigr_hierarchy_list); return hier; @@ -2000,7 +2016,7 @@ static long connect_old_root_work(void *arg) struct tmigr_hierarchy *hier; int cpu = smp_processor_id(); - hier = __tmigr_get_hierarchy(arch_scale_cpu_capacity(cpu)); + hier = __tmigr_get_hierarchy(cpu); if (WARN_ON_ONCE(!hier)) return -EINVAL; @@ -2016,7 +2032,7 @@ static int tmigr_add_cpu(unsigned int cpu) guard(mutex)(&tmigr_mutex); - hier = tmigr_get_hierarchy(arch_scale_cpu_capacity(cpu)); + hier = tmigr_get_hierarchy(cpu); if (IS_ERR(hier)) return PTR_ERR(hier); -- 2.53.0