Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp755715imu; Fri, 9 Nov 2018 05:40:22 -0800 (PST) X-Google-Smtp-Source: AJdET5fdA1gGtyyYfzyYgSTk/3p0lol8qvG9cH5nVqQ8jPq4pSQyXzVloKqyBUooVFlldj6VmBAK X-Received: by 2002:a63:451a:: with SMTP id s26mr7583243pga.150.1541770822567; Fri, 09 Nov 2018 05:40:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541770822; cv=none; d=google.com; s=arc-20160816; b=zXX92aemyrWhyipEktDIehRBfiYAFQLY6V4icDyoa0oybYe9c5S3RySUnHHQviHezU kNC8I8uEXa9Hkz/rXnRB2qCR5rwKBY9wGv+n6IxVsZKDTVhnlry4qHbylBgLpXo2KqiH 9Y72T/Q3JwShrcge2306/EMWHNxhH1AUoP3VV4hofcGGCOnfE+kq9LIao7f+FObbqTuZ LfyEbvaNSJvwbZNwVvvd/TRoVHdKx/E+Zz7PlfOP3drJbJTD2E5NQy1qtcb0cd2m3MTo 3T6S9l5Gsol9+p+ila0b9L9GF0/d2VkP0HGpzWGhDC97Z7/0LJPyZKn0uxV9Emha2r7v /8pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature; bh=41kNbker7pjMlSrMXESCPMU6qoot3isUmOITc7YdAuc=; b=B4b2LU6l82uTrT8+uNiufB5LCq90miJuZakMMhnZ+0/GM4JyBEnP0FIBgLw5oHKxOy jJBcUAV2wKRHaiI2/RU4uTvkQWEEPur2/5K56wbHkKAWKPmAuoZso1ejA8hFlRaaB8WH 4LExzf4KPCSpYifsG7sKnQ8ZDZny8KsuM7sBc5eFZR9Dro6FOAOO1EjmiI2Gdef7mUEp 9nxOl+yZGb79M64hJrlfVgfEhtfA6rB5gRjazwWQSJjGE1MKemXofB86hyxd8aVhZwoP rCTdpza7cd3+DTpnMiTsaWc6h/Zg1IEyFi6vmIrF5sY4ArN5k6+Yy5/KJnL5NMaNLB1H WDEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UoPOHMeA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1-v6si8068275plr.113.2018.11.09.05.39.55; Fri, 09 Nov 2018 05:40:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UoPOHMeA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727999AbeKIXT7 (ORCPT + 99 others); Fri, 9 Nov 2018 18:19:59 -0500 Received: from mail-it1-f195.google.com ([209.85.166.195]:39599 "EHLO mail-it1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727784AbeKIXT6 (ORCPT ); Fri, 9 Nov 2018 18:19:58 -0500 Received: by mail-it1-f195.google.com with SMTP id m15so3210344itl.4 for ; Fri, 09 Nov 2018 05:39:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=41kNbker7pjMlSrMXESCPMU6qoot3isUmOITc7YdAuc=; b=UoPOHMeA60tmrLPtRQrqJKmsdP4J+jX9orOhFyzJRoTxXxU+CWPtZ5kqK95Gnkmjp9 n4rzVhKX1bgWNX1CrhQm75CW/OpVpnLPCoB/QwRwOFhf6ytuW/ks7SdWh8s91URW5u0w +E0+Jzj3tOifeiH6fUlhakmmkBwqW2k/pufSY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=41kNbker7pjMlSrMXESCPMU6qoot3isUmOITc7YdAuc=; b=mkUUDFaBP8utLPqGCRSl9QWQfamoeoWMY0zMfOm61hgIxA/2DfmPPH/f2P3ODzDxTA IJz15PlYKdA+T5+gzjeoYmTlKDxk03N9txa97RuDn3Tw949sNZqCEa+lmKEXItD6Fqu2 REsodChaKqMgX85I2MWNcsvsKTPXGaOokjkWZ00bwH3eYnHPwIv5Gypxt3WbVjMXo4Ja TWJDbdOxgAO7/3rXVkCRmEK+me4B9iTVANDdTuOSx/x51l1/66ntkkf4xDoa70K9No0D qs0hW5CAIq+1eBT+rpWz/r3GUjlbGHLSBjbi/3P3+RxYfkzaCB43MwpR9QxXiRiAFhl5 eT0A== X-Gm-Message-State: AGRZ1gLCZ4kgK6EoZ2/WJkJBlA3vKkxO5y/PHWxuX+dBqBaK4zSnbeD8 sr6gB1ifA7u4YACKnIFvQ84oRsXIjKrCE3RyUeVEQg== X-Received: by 2002:a24:7d8d:: with SMTP id b135-v6mr1903970itc.121.1541770757881; Fri, 09 Nov 2018 05:39:17 -0800 (PST) MIME-Version: 1.0 Received: by 2002:a6b:4f16:0:0:0:0:0 with HTTP; Fri, 9 Nov 2018 05:39:17 -0800 (PST) In-Reply-To: <3cf04e113d71c9f8e4be95fb84a510f085aa4afa.1541711457.git.jpoimboe@redhat.com> References: <3cf04e113d71c9f8e4be95fb84a510f085aa4afa.1541711457.git.jpoimboe@redhat.com> From: Ard Biesheuvel Date: Fri, 9 Nov 2018 14:39:17 +0100 Message-ID: Subject: Re: [RFC PATCH 1/3] static_call: Add static call infrastructure To: Josh Poimboeuf Cc: Linux Kernel Mailing List , "the arch/x86 maintainers" , Andy Lutomirski , Steven Rostedt , Peter Zijlstra , Ingo Molnar , Thomas Gleixner , Linus Torvalds , Masami Hiramatsu , Jason Baron , Jiri Kosina , David Laight , Borislav Petkov Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 8 November 2018 at 22:15, Josh Poimboeuf wrote: > Add a static call infrastructure. Static calls use code patching to > hard-code function pointers into direct branch instructions. They give > the flexibility of function pointers, but with improved performance. > This is especially important for cases where retpolines would otherwise > be used, as retpolines can significantly impact performance. > > This code is heavily inspired by the jump label code (aka "static > jumps"), as some of the concepts are very similar. > > There are three implementations, depending on arch support: > > 1) optimized: patched call sites (CONFIG_HAVE_STATIC_CALL_OPTIMIZED) > 2) unoptimized: patched trampolines (CONFIG_HAVE_STATIC_CALL_UNOPTIMIZED) > 3) basic function pointers > > For more details, see the comments in include/linux/static_call.h. > > Signed-off-by: Josh Poimboeuf > --- > arch/Kconfig | 6 + > include/asm-generic/vmlinux.lds.h | 11 ++ > include/linux/module.h | 10 + > include/linux/static_call.h | 186 +++++++++++++++++++ > include/linux/static_call_types.h | 19 ++ > kernel/Makefile | 1 + > kernel/module.c | 5 + > kernel/static_call.c | 297 ++++++++++++++++++++++++++++++ > 8 files changed, 535 insertions(+) > create mode 100644 include/linux/static_call.h > create mode 100644 include/linux/static_call_types.h > create mode 100644 kernel/static_call.c > > diff --git a/kernel/static_call.c b/kernel/static_call.c > new file mode 100644 > index 000000000000..599ebc6fc4f1 > --- /dev/null > +++ b/kernel/static_call.c ... > +static void __init static_call_init(void) > +{ > + struct static_call_site *start = __start_static_call_sites; > + struct static_call_site *stop = __stop_static_call_sites; > + struct static_call_site *site; > + > + if (start == stop) { > + pr_warn("WARNING: empty static call table\n"); > + return; > + } > + > + cpus_read_lock(); > + static_call_lock(); > + > + static_call_sort_entries(start, stop); > + > + for (site = start; site < stop; site++) { > + struct static_call_key *key = static_call_key(site); > + unsigned long addr = static_call_addr(site); > + > + if (list_empty(&key->site_mods)) { > + struct static_call_mod *mod; > + > + mod = kzalloc(sizeof(*mod), GFP_KERNEL); > + if (!mod) { > + WARN(1, "Failed to allocate memory for static calls"); > + return; > + } > + > + mod->sites = site; > + list_add_tail(&mod->list, &key->site_mods); > + > + /* > + * The trampoline should no longer be used. Poison it > + * it with a BUG() to catch any stray callers. > + */ > + arch_static_call_poison_tramp(addr); This patches the wrong thing: the trampoline is at key->func not addr. However, patching it here means we poison it before all users are patched. I added this on top diff --git a/kernel/static_call.c b/kernel/static_call.c index 599ebc6fc4f1..d9562329bec6 100644 --- a/kernel/static_call.c +++ b/kernel/static_call.c @@ -248,6 +248,7 @@ static void __init static_call_init(void) struct static_call_site *start = __start_static_call_sites; struct static_call_site *stop = __stop_static_call_sites; struct static_call_site *site; + struct static_call_key *prev_key = NULL; if (start == stop) { pr_warn("WARNING: empty static call table\n"); @@ -279,7 +280,9 @@ static void __init static_call_init(void) * The trampoline should no longer be used. Poison it * it with a BUG() to catch any stray callers. */ - arch_static_call_poison_tramp(addr); + if (prev_key) + arch_static_call_poison_tramp((unsigned long)prev_key->func); + prev_key = key; } arch_static_call_transform(addr, key->func); > + } > + > + arch_static_call_transform(addr, key->func); > + } > + > + static_call_initialized = true; > + > + static_call_unlock(); > + cpus_read_unlock(); > + > +#ifdef CONFIG_MODULES > + register_module_notifier(&static_call_module_nb); > +#endif > +} > +early_initcall(static_call_init); > -- > 2.17.2 >