From nobody Sun Dec 14 05:53:26 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B47DC6FD1F for ; Wed, 22 Mar 2023 04:00:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230295AbjCVEAc (ORCPT ); Wed, 22 Mar 2023 00:00:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229595AbjCVEAY (ORCPT ); Wed, 22 Mar 2023 00:00:24 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA6B347403 for ; Tue, 21 Mar 2023 21:00:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 528A961E67 for ; Wed, 22 Mar 2023 04:00:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 373A5C433EF; Wed, 22 Mar 2023 04:00:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1679457622; bh=dXZSCwSD/LB/FwBrcGE2iL96HfH7dZ9DVcvMcF87LjU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oSKzXycDKQNaMvn2h8NBJQs2QZSi0Zh4P76GaPXTPlaXwOJ92MTbFHtmKvLg1fPUO hmAsQ5LTALa0dyq+apNn1KYtEKywnGn6nYoOwd7SxLof57UX6Tw2qFqYWYtIv23Oyj Pvw5wtxTTvbd7UXOIy8hTZsI4eCKXWroqpQZtnuykyOfVpiHBd2F4mbF5HwkoXnyRr o9dIG+laLvTs0VRmKAGWVVk4Wq0ud4oS7pn0wMSbkujqwCZyFpyq3NAv77ZmKM9WTs noCXFq9ny3o+k688pOnpE6y9YJrPQghaP4YW/orbGeAsiu67vsGNg89jAv1bExRo8M FSFlT7TPRcMAA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Peter Zijlstra , Mark Rutland , Jason Baron , Steven Rostedt , Ard Biesheuvel , Christophe Leroy , Paolo Bonzini , Sean Christopherson , Sami Tolvanen , Nick Desaulniers , Will McVicker , Kees Cook , linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 01/11] static_call: Improve key type abstraction Date: Tue, 21 Mar 2023 21:00:07 -0700 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Make the static_call_key union less fragile by abstracting all knowledge about the type bit into helper functions. Signed-off-by: Josh Poimboeuf --- include/linux/static_call_types.h | 4 +- kernel/static_call_inline.c | 51 +++++++++++++++++-------- tools/include/linux/static_call_types.h | 4 +- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/include/linux/static_call_types.h b/include/linux/static_call_= types.h index 5a00b8b2cf9f..87c3598609e8 100644 --- a/include/linux/static_call_types.h +++ b/include/linux/static_call_types.h @@ -63,8 +63,8 @@ struct static_call_key { union { /* bit 0: 0 =3D mods, 1 =3D sites */ unsigned long type; - struct static_call_mod *mods; - struct static_call_site *sites; + struct static_call_mod *_mods; + struct static_call_site *_sites; }; }; =20 diff --git a/kernel/static_call_inline.c b/kernel/static_call_inline.c index 639397b5491c..41f6bda6773a 100644 --- a/kernel/static_call_inline.c +++ b/kernel/static_call_inline.c @@ -112,15 +112,21 @@ static inline void static_call_sort_entries(struct st= atic_call_site *start, =20 static inline bool static_call_key_has_mods(struct static_call_key *key) { - return !(key->type & 1); + return !!(key->type & 1); } =20 -static inline struct static_call_mod *static_call_key_next(struct static_c= all_key *key) +static inline struct static_call_mod *static_call_key_mods(struct static_c= all_key *key) { if (!static_call_key_has_mods(key)) return NULL; =20 - return key->mods; + return (struct static_call_mod *)(key->type & ~1); +} + +static inline void static_call_key_set_mods(struct static_call_key *key, s= truct static_call_mod *mods) +{ + key->_mods =3D mods; + key->type |=3D 1; } =20 static inline struct static_call_site *static_call_key_sites(struct static= _call_key *key) @@ -128,7 +134,12 @@ static inline struct static_call_site *static_call_key= _sites(struct static_call_ if (static_call_key_has_mods(key)) return NULL; =20 - return (struct static_call_site *)(key->type & ~1); + return key->_sites; +} + +static inline void static_call_key_set_sites(struct static_call_key *key, = struct static_call_site *sites) +{ + key->_sites =3D sites; } =20 void __static_call_update(struct static_call_key *key, void *tramp, void *= func) @@ -154,7 +165,7 @@ void __static_call_update(struct static_call_key *key, = void *tramp, void *func) goto done; =20 first =3D (struct static_call_mod){ - .next =3D static_call_key_next(key), + .next =3D static_call_key_mods(key), .mod =3D NULL, .sites =3D static_call_key_sites(key), }; @@ -250,8 +261,7 @@ static int __static_call_init(struct module *mod, * static_call_init() before memory allocation works. */ if (!mod) { - key->sites =3D site; - key->type |=3D 1; + static_call_key_set_sites(key, site); goto do_transform; } =20 @@ -266,10 +276,10 @@ static int __static_call_init(struct module *mod, */ if (static_call_key_sites(key)) { site_mod->mod =3D NULL; - site_mod->next =3D NULL; site_mod->sites =3D static_call_key_sites(key); + site_mod->next =3D NULL; =20 - key->mods =3D site_mod; + static_call_key_set_mods(key, site_mod); =20 site_mod =3D kzalloc(sizeof(*site_mod), GFP_KERNEL); if (!site_mod) @@ -278,8 +288,9 @@ static int __static_call_init(struct module *mod, =20 site_mod->mod =3D mod; site_mod->sites =3D site; - site_mod->next =3D static_call_key_next(key); - key->mods =3D site_mod; + site_mod->next =3D static_call_key_mods(key); + + static_call_key_set_mods(key, site_mod); } =20 do_transform: @@ -406,7 +417,7 @@ static void static_call_del_module(struct module *mod) struct static_call_site *stop =3D mod->static_call_sites + mod->num_static_call_sites; struct static_call_key *key, *prev_key =3D NULL; - struct static_call_mod *site_mod, **prev; + struct static_call_mod *site_mod, *prev; struct static_call_site *site; =20 for (site =3D start; site < stop; site++) { @@ -416,15 +427,25 @@ static void static_call_del_module(struct module *mod) =20 prev_key =3D key; =20 - for (prev =3D &key->mods, site_mod =3D key->mods; + site_mod =3D static_call_key_mods(key); + if (!site_mod) + continue; + + if (site_mod->mod =3D=3D mod) { + static_call_key_set_mods(key, site_mod->next); + kfree(site_mod); + continue; + } + + for (prev =3D site_mod, site_mod =3D site_mod->next; site_mod && site_mod->mod !=3D mod; - prev =3D &site_mod->next, site_mod =3D site_mod->next) + prev =3D site_mod, site_mod =3D site_mod->next) ; =20 if (!site_mod) continue; =20 - *prev =3D site_mod->next; + prev->next =3D site_mod->next; kfree(site_mod); } } diff --git a/tools/include/linux/static_call_types.h b/tools/include/linux/= static_call_types.h index 5a00b8b2cf9f..87c3598609e8 100644 --- a/tools/include/linux/static_call_types.h +++ b/tools/include/linux/static_call_types.h @@ -63,8 +63,8 @@ struct static_call_key { union { /* bit 0: 0 =3D mods, 1 =3D sites */ unsigned long type; - struct static_call_mod *mods; - struct static_call_site *sites; + struct static_call_mod *_mods; + struct static_call_site *_sites; }; }; =20 --=20 2.39.2