From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 0BDE338B14C for ; Thu, 23 Apr 2026 16:54:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776963247; cv=none; b=roYUrMpl1O1YdXzcR6kEe6mFVwSNVS54Fn7lVYYvInRM6K+0gFAt3bspsVtdhl3MmhNbxCRTlyUMdF0OUZuNzwJrEmPKqJTIZHBQjMm7tABRBwvLRWbJTDS9XFVS3g8vkYHo5Pd5XhExTjA54klwCCE4ujCka3hTTBpG5XDH9LE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776963247; c=relaxed/simple; bh=eF7Gawkk5bH//TSVdBMnX+O+QtyOsNz3h0dhC817zwc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fUzvw323KPsuFFXE5sYc/KKWFvizQ7ZG4qsv0bWx/429dU3U1nbgfGa78/iven/Q6it4hy2iMgGaP5Mx13rOx2TcF2Vb/5OASX619lJr1DzZu9FK3EXkd6J0l7l1eQFmOzxwdTFmDH+69O61+oXqSRiITcwADuImylr9quB2AdI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y/iughz0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Y/iughz0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68BECC2BCB3; Thu, 23 Apr 2026 16:54:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776963246; bh=eF7Gawkk5bH//TSVdBMnX+O+QtyOsNz3h0dhC817zwc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y/iughz0K0tPNCEJlvh9+3rXuM1QNxTm2xIM57gsT00l5JM/Ll/7MMUIs6YkwIN5E uJlcYKKWCpBvAUzGDgdXfRbr6nO1eAzkeByPSW+xKrOv20ZuSMSxafoUwqh1KJ78T1 N/IljOhmnFsoiiqehAA+32R1H6+Qn5DcebgvzIjgXaw4z9yX8UCMPdRsfrIrPdCWx8 lh0ln2ZLIV2+uur9gi7aula+nvHtHIrxZnarc8DWY3zU4R58e9U14N031EXtYdDcfJ CQaVt7VzmOIhOrGwYqUTBQWOpft0FN1mxFzuiGoqgZ+ApK/Dyv5VJu7rxQ4ry1+flZ hKGdRNabyE3sw== From: Frederic Weisbecker To: LKML Cc: Frederic Weisbecker , Anna-Maria Behnsen , Sehee Jeong , Thomas Gleixner Subject: [PATCH 3/6] timers/migration: Track CPUs in a hierarchy Date: Thu, 23 Apr 2026 18:53:51 +0200 Message-ID: <20260423165354.95152-4-frederic@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260423165354.95152-1-frederic@kernel.org> References: <20260423165354.95152-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 When a new root is created, the old root is connected to it and propagates up its own assumed to be active state, since the hotplug control CPU is itself active and part of the old root. However with per-capacity hierarchies, this assumption won't be true anymore because the hotplug control CPU calling the timer migration prepare callback may not belong to the same hierarchy as the booting CPU. To solve this, track the available CPUs per hierarchies so that the root connection can be offlined to safe CPUs. Signed-off-by: Frederic Weisbecker --- kernel/time/timer_migration.c | 25 +++++++++++++++++++------ kernel/time/timer_migration.h | 2 ++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 52e97b880b1c..d0de9f64528e 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -1921,18 +1921,25 @@ static struct tmigr_hierarchy *tmigr_get_hierarchy(void) if (!hierarchy) return ERR_PTR(-ENOMEM); + hierarchy->cpumask = kzalloc(cpumask_size(), GFP_KERNEL); + if (!hierarchy->cpumask) + goto err; + hierarchy->level_list = kzalloc_objs(struct list_head, tmigr_hierarchy_levels); - if (!hierarchy->level_list) { - kfree(hierarchy); - hierarchy = NULL; - return ERR_PTR(-ENOMEM); - } + if (!hierarchy->level_list) + goto err; for (int i = 0; i < tmigr_hierarchy_levels; i++) INIT_LIST_HEAD(&hierarchy->level_list[i]); return hierarchy; +err: + kfree(hierarchy->cpumask); + kfree(hierarchy); + hierarchy = NULL; + + return ERR_PTR(-ENOMEM); } static int tmigr_add_cpu(unsigned int cpu) @@ -1952,8 +1959,11 @@ static int tmigr_add_cpu(unsigned int cpu) ret = tmigr_setup_groups(hier, cpu, node, NULL, false); + if (ret < 0) + return ret; + /* Root has changed? Connect the old one to the new */ - if (ret >= 0 && old_root && old_root != hier->root) { + if (old_root && old_root != hier->root) { /* * The target CPU must never do the prepare work, except * on early boot when the boot CPU is the target. Otherwise @@ -1970,6 +1980,9 @@ static int tmigr_add_cpu(unsigned int cpu) ret = tmigr_setup_groups(hier, -1, old_root->numa_node, old_root, true); } + if (ret >= 0) + cpumask_set_cpu(cpu, hier->cpumask); + return ret; } diff --git a/kernel/time/timer_migration.h b/kernel/time/timer_migration.h index 77df422e5f9a..0cfbb8d799a6 100644 --- a/kernel/time/timer_migration.h +++ b/kernel/time/timer_migration.h @@ -8,10 +8,12 @@ /** * struct tmigr_hierarchy - a hierarchy associated to a given CPU capacity. * @level_list: Per level lists of tmigr groups + * @cpumask: CPUs belonging to this hierarchy * @root: The current root of the hierarchy */ struct tmigr_hierarchy { struct list_head *level_list; + struct cpumask *cpumask; struct tmigr_group *root; }; -- 2.53.0