From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout.efficios.com (smtpout.efficios.com [158.69.130.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 2BB1E41612A for ; Tue, 7 Jul 2026 13:16:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=158.69.130.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783430180; cv=none; b=AKQJD7P2Ld5ykQmUJJVFAyKM286mEiZf8FN+HA0UcSHsLHzVoDgTBze0XM9pJ8QyeEnAjITUqftcbHeGcEVrJOKjIQYKRzBN/JQq//luj5BByD5Oy7GW2HJiD1AXf80Mk2GLjx940iQv7yJJ16cp5exDsMcuiv+Vxc7VPv6fK+E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783430180; c=relaxed/simple; bh=P+zGQj1y1FEcVMhoQD9/wnzza4ZnWTYDUUbi1pMK8g8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YKuE1Flnq3BT1PtIZBSRVYOJkOCw7ZEtka6jq17gbdLDsfJGE+QNQu46bzO6xMxiIYzBIz7dNZrHx+N6jx1BC5zUuDuxWVopjrB/YAfSvIpVbezhISqmkRkzqPnshtQmUl/66wKNKP/cCt6KrRRY2cLxdd5tDi/cXqzyGLT8ugI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=efficios.com; spf=pass smtp.mailfrom=efficios.com; dkim=pass (2048-bit key) header.d=efficios.com header.i=@efficios.com header.b=NVTM7TmE; arc=none smtp.client-ip=158.69.130.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=efficios.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=efficios.com header.i=@efficios.com header.b="NVTM7TmE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=smtpout1; t=1783430170; bh=8BY90LeqBHzCUPC6E14M8ud3i54LkNH0/MYRmw4hVf8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NVTM7TmEvOhJklen7kj32jap5k/yu6Jf4fHSgD/D0oLfqSEFbzOxVfq448KCUlvez 1R90+HdMckX5rBBzjVXHNXxrKdJaYU6bb1Sdarl/QxyzgsFiMI4cgIe0Dk68viv9sV jJ2Q+NAxj0JulA+l6gv6HAt0axhnQaKtuhFXTa0T52365sCgb7CqJT1Y/GaXl+MkuZ ZTCK/HJ3xpsuh6AWIiKfggi+S4j4krokn37rrO54AyDARtTHGGLx94vLVhfUEy73ia gaRp/xuoQD5TkqXSspGgMLXgZ1v+opxLYuFe+3ByW4aKO+VwDa4NPe1RJDb2nQ4LOg mXQCxv+R1v5rg== Received: from compudjdev.. (mtl.efficios.com [216.120.195.104]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4gvhZ25mGZzVKP; Tue, 07 Jul 2026 09:16:10 -0400 (EDT) From: Mathieu Desnoyers To: Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers Subject: [PATCH v20 6/6] lib: inline percpu_counter_tree_items_size with boot-safety sentinel Date: Tue, 7 Jul 2026 09:15:36 -0400 Message-ID: <20260707131544.75906-7-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707131544.75906-1-mathieu.desnoyers@efficios.com> References: <20260707131544.75906-1-mathieu.desnoyers@efficios.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Replace the out-of-line percpu_counter_tree_items_size() function with a static inline that loads the __ro_after_init variable __percpu_counter_tree_items_size directly. This eliminates a function call on paths that compute mm_struct flexible array layout offsets. Initialize the variable to SIZE_MAX as a sentinel value, and add a WARN_ON_ONCE check in the inline accessor to catch any accidental use before percpu_counter_tree_subsystem_init() sets the real value based on nr_cpu_ids. An early misuse would produce an absurd offset that triggers the warning with a stack trace pointing at the offending caller, rather than silently computing wrong memory offsets. percpu_counter_tree_subsystem_init() sets the variable to the runtime value immediately after deriving counter_config from nr_cpu_ids, before calculate_accuracy_topology(). After boot, __ro_after_init moves the variable into read-only memory. On !CONFIG_SMP, the existing inline returning 0 is unchanged and requires no sentinel. Signed-off-by: Mathieu Desnoyers --- include/linux/percpu_counter_tree.h | 19 ++++++++++++++++++- lib/percpu_counter_tree.c | 24 ++++++++---------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/include/linux/percpu_counter_tree.h b/include/linux/percpu_counter_tree.h index 3e8a820e2d1d..4095acdc879b 100644 --- a/include/linux/percpu_counter_tree.h +++ b/include/linux/percpu_counter_tree.h @@ -101,7 +101,24 @@ struct percpu_counter_tree { } approx_accuracy_range; }; -size_t percpu_counter_tree_items_size(void); +extern size_t __percpu_counter_tree_items_size __ro_after_init; + +/* + * percpu_counter_tree_items_size - Query the size required for counter tree items. + * + * Query the size of the memory area required to hold the counter tree + * items. This depends on the hardware topology and is invariant after + * boot. + * + * Return: Size required to hold tree items. + */ +static inline +size_t percpu_counter_tree_items_size(void) +{ + WARN_ON_ONCE(__percpu_counter_tree_items_size == SIZE_MAX); + return __percpu_counter_tree_items_size; +} + int percpu_counter_tree_init_many(struct percpu_counter_tree *counters, struct percpu_counter_tree_level_item *items, unsigned int nr_counters, unsigned long batch_size, gfp_t gfp_flags); int percpu_counter_tree_init(struct percpu_counter_tree *counter, struct percpu_counter_tree_level_item *items, diff --git a/lib/percpu_counter_tree.c b/lib/percpu_counter_tree.c index 5c8fc2dcdc16..cfa5b04e05d7 100644 --- a/lib/percpu_counter_tree.c +++ b/lib/percpu_counter_tree.c @@ -653,22 +653,9 @@ void percpu_counter_tree_set(struct percpu_counter_tree *counter, long v) } EXPORT_SYMBOL_GPL(percpu_counter_tree_set); -/* - * percpu_counter_tree_items_size - Query the size required for counter tree items. - * - * Query the size of the memory area required to hold the counter tree - * items. This depends on the hardware topology and is invariant after - * boot. - * - * Return: Size required to hold tree items. - */ -size_t percpu_counter_tree_items_size(void) -{ - if (!nr_cpus_order) - return 0; - return counter_config->nr_items * sizeof(struct percpu_counter_tree_level_item); -} -EXPORT_SYMBOL_GPL(percpu_counter_tree_items_size); +/* Initialize to SIZE_MAX to catch early boot misuses. */ +size_t __percpu_counter_tree_items_size __ro_after_init = SIZE_MAX; +EXPORT_SYMBOL_GPL(__percpu_counter_tree_items_size); static void __init calculate_accuracy_topology(void) { @@ -697,6 +684,11 @@ int __init percpu_counter_tree_subsystem_init(void) return -1; } counter_config = &per_nr_cpu_order_config[nr_cpus_order]; + if (!nr_cpus_order) + __percpu_counter_tree_items_size = 0; + else + __percpu_counter_tree_items_size = counter_config->nr_items * + sizeof(struct percpu_counter_tree_level_item); calculate_accuracy_topology(); return 0; } -- 2.43.0