Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp768021imm; Thu, 4 Oct 2018 03:04:01 -0700 (PDT) X-Google-Smtp-Source: ACcGV62wkHc3ZfSiFXrTm/xR3K/+cQ29Mr6Ym/p8vuMSSYwS+33juW1WMcAnP9CnBD6u3JGSW3kj X-Received: by 2002:a63:584f:: with SMTP id i15-v6mr5102093pgm.178.1538647441139; Thu, 04 Oct 2018 03:04:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538647441; cv=none; d=google.com; s=arc-20160816; b=Ttl2xd7Qr2iB5bSyA+vJcvp/YWVsOpqmW5LfmjjGoZJd4xl1VRIhZV+j3lfdO4arrG vr7nWVjDntiDjT7OhourzxErz6PScq8RoQUIAR3ECdREwDLo9SnaVHmn5J5HMCF4Fffb 6Ds551TUm9b0uWFoFebx0Nj0fjuI15H2v0DrowZ8A+ZaOQZXVCrW0MyvKEx3ed4k81hx 7pSSHdLR66Mu9QN1fVNDaKLJBRS4YISZN1Teq7/GovBqD8FIgLp8aaRrl7bBTc0/9hlB NDWo5BFWmTecPP1Do5S61iMqc2i8ve3hdZP+vQwTC80uzJAfcIfVzYVCBO8XoGNQC5DO rKcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date; bh=eFIZr9xWOElMi4BDFsw4wfIzDqLyqBRxorNOZS4QZi8=; b=T5AVkr2U5Tz8hgMml4UlYzEd7IRMSZBWXfpRQ3eCswDBzxlr50d60odtDGsv4IkWnm NAvyR7WshiDukyi9qAoB0MGnvH4E9uAmgmN6zaZu+qHyj1aymTwgPFxIQ0Pv/kykh1Tb wn3tuFjPiA6KLZjOfNa7McR3aZWmyUiuE1JTZLmp98OL6vN6NrvmJ38T2QDOz1fRiKMQ /Fv0MMd4UMdXJaWxCawDUJrbwAUUrowZ9jzwZdamIOspmjrjsLARO1l+sk+Y90zMcWCG ydWuTEHrwwm6dDEog+fFRsJzcd49gzC2WyrQuW98XfKtCyAQjALgJm7k9D6cgSreeVh5 AVeA== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x10-v6si4387128plo.100.2018.10.04.03.03.45; Thu, 04 Oct 2018 03:04:01 -0700 (PDT) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728031AbeJDQzt (ORCPT + 99 others); Thu, 4 Oct 2018 12:55:49 -0400 Received: from terminus.zytor.com ([198.137.202.136]:50245 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727311AbeJDQzt (ORCPT ); Thu, 4 Oct 2018 12:55:49 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id w94A2X4K2701490 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 4 Oct 2018 03:02:33 -0700 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id w94A2XwE2701483; Thu, 4 Oct 2018 03:02:33 -0700 Date: Thu, 4 Oct 2018 03:02:33 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Nadav Amit Message-ID: Cc: namit@vmware.com, tglx@linutronix.de, brgerst@gmail.com, hpa@zytor.com, torvalds@linux-foundation.org, jpoimboe@redhat.com, dvlasenk@redhat.com, JBeulich@suse.com, bp@alien8.de, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, luto@amacapital.net, keescook@chromium.org Reply-To: jpoimboe@redhat.com, dvlasenk@redhat.com, torvalds@linux-foundation.org, JBeulich@suse.com, brgerst@gmail.com, hpa@zytor.com, namit@vmware.com, tglx@linutronix.de, mingo@kernel.org, luto@amacapital.net, keescook@chromium.org, linux-kernel@vger.kernel.org, peterz@infradead.org, bp@alien8.de In-Reply-To: <20181003213100.189959-5-namit@vmware.com> References: <20181003213100.189959-5-namit@vmware.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/build] x86/refcount: Work around GCC inlining bug Git-Commit-ID: 9e1725b410594911cc5981b6c7b4cea4ec054ca8 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=-0.8 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_96_Q,FREEMAIL_FORGED_REPLYTO autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 9e1725b410594911cc5981b6c7b4cea4ec054ca8 Gitweb: https://git.kernel.org/tip/9e1725b410594911cc5981b6c7b4cea4ec054ca8 Author: Nadav Amit AuthorDate: Wed, 3 Oct 2018 14:30:54 -0700 Committer: Ingo Molnar CommitDate: Thu, 4 Oct 2018 11:24:59 +0200 x86/refcount: Work around GCC inlining bug As described in: 77b0bf55bc67: ("kbuild/Makefile: Prepare for using macros in inline assembly code to work around asm() related GCC inlining bugs") GCC's inlining heuristics are broken with common asm() patterns used in kernel code, resulting in the effective disabling of inlining. The workaround is to set an assembly macro and call it from the inline assembly block. As a result GCC considers the inline assembly block as a single instruction. (Which it isn't, but that's the best we can get.) This patch allows GCC to inline simple functions such as __get_seccomp_filter(). To no-one's surprise the result is that GCC performs more aggressive (read: correct) inlining decisions in these senarios, which reduces the kernel size and presumably also speeds it up: text data bss dec hex filename 18140970 10225412 2957312 31323694 1ddf62e ./vmlinux before 18140140 10225284 2957312 31322736 1ddf270 ./vmlinux after (-958) 16 fewer static text symbols: Before: 40302 After: 40286 (-16) these got inlined instead. Functions such as kref_get(), free_user(), fuse_file_get() now get inlined. Hurray! [ mingo: Rewrote the changelog. ] Tested-by: Kees Cook Signed-off-by: Nadav Amit Acked-by: Peter Zijlstra (Intel) Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jan Beulich Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/20181003213100.189959-5-namit@vmware.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/refcount.h | 74 +++++++++++++++++++++++++---------------- arch/x86/kernel/macros.S | 1 + 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h index 19b90521954c..c92909da0686 100644 --- a/arch/x86/include/asm/refcount.h +++ b/arch/x86/include/asm/refcount.h @@ -4,6 +4,41 @@ * x86-specific implementation of refcount_t. Based on PAX_REFCOUNT from * PaX/grsecurity. */ + +#ifdef __ASSEMBLY__ + +#include +#include + +.macro REFCOUNT_EXCEPTION counter:req + .pushsection .text..refcount +111: lea \counter, %_ASM_CX +112: ud2 + ASM_UNREACHABLE + .popsection +113: _ASM_EXTABLE_REFCOUNT(112b, 113b) +.endm + +/* Trigger refcount exception if refcount result is negative. */ +.macro REFCOUNT_CHECK_LT_ZERO counter:req + js 111f + REFCOUNT_EXCEPTION counter="\counter" +.endm + +/* Trigger refcount exception if refcount result is zero or negative. */ +.macro REFCOUNT_CHECK_LE_ZERO counter:req + jz 111f + REFCOUNT_CHECK_LT_ZERO counter="\counter" +.endm + +/* Trigger refcount exception unconditionally. */ +.macro REFCOUNT_ERROR counter:req + jmp 111f + REFCOUNT_EXCEPTION counter="\counter" +.endm + +#else /* __ASSEMBLY__ */ + #include #include @@ -15,34 +50,11 @@ * central refcount exception. The fixup address for the exception points * back to the regular execution flow in .text. */ -#define _REFCOUNT_EXCEPTION \ - ".pushsection .text..refcount\n" \ - "111:\tlea %[counter], %%" _ASM_CX "\n" \ - "112:\t" ASM_UD2 "\n" \ - ASM_UNREACHABLE \ - ".popsection\n" \ - "113:\n" \ - _ASM_EXTABLE_REFCOUNT(112b, 113b) - -/* Trigger refcount exception if refcount result is negative. */ -#define REFCOUNT_CHECK_LT_ZERO \ - "js 111f\n\t" \ - _REFCOUNT_EXCEPTION - -/* Trigger refcount exception if refcount result is zero or negative. */ -#define REFCOUNT_CHECK_LE_ZERO \ - "jz 111f\n\t" \ - REFCOUNT_CHECK_LT_ZERO - -/* Trigger refcount exception unconditionally. */ -#define REFCOUNT_ERROR \ - "jmp 111f\n\t" \ - _REFCOUNT_EXCEPTION static __always_inline void refcount_add(unsigned int i, refcount_t *r) { asm volatile(LOCK_PREFIX "addl %1,%0\n\t" - REFCOUNT_CHECK_LT_ZERO + "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\"" : [counter] "+m" (r->refs.counter) : "ir" (i) : "cc", "cx"); @@ -51,7 +63,7 @@ static __always_inline void refcount_add(unsigned int i, refcount_t *r) static __always_inline void refcount_inc(refcount_t *r) { asm volatile(LOCK_PREFIX "incl %0\n\t" - REFCOUNT_CHECK_LT_ZERO + "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\"" : [counter] "+m" (r->refs.counter) : : "cc", "cx"); } @@ -59,7 +71,7 @@ static __always_inline void refcount_inc(refcount_t *r) static __always_inline void refcount_dec(refcount_t *r) { asm volatile(LOCK_PREFIX "decl %0\n\t" - REFCOUNT_CHECK_LE_ZERO + "REFCOUNT_CHECK_LE_ZERO counter=\"%[counter]\"" : [counter] "+m" (r->refs.counter) : : "cc", "cx"); } @@ -67,13 +79,15 @@ static __always_inline void refcount_dec(refcount_t *r) static __always_inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r) { - GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO, + GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", + "REFCOUNT_CHECK_LT_ZERO counter=\"%0\"", r->refs.counter, "er", i, "%0", e, "cx"); } static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r) { - GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO, + GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", + "REFCOUNT_CHECK_LT_ZERO counter=\"%0\"", r->refs.counter, "%0", e, "cx"); } @@ -91,7 +105,7 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r) /* Did we try to increment from/to an undesirable state? */ if (unlikely(c < 0 || c == INT_MAX || result < c)) { - asm volatile(REFCOUNT_ERROR + asm volatile("REFCOUNT_ERROR counter=\"%[counter]\"" : : [counter] "m" (r->refs.counter) : "cc", "cx"); break; @@ -107,4 +121,6 @@ static __always_inline __must_check bool refcount_inc_not_zero(refcount_t *r) return refcount_add_not_zero(1, r); } +#endif /* __ASSEMBLY__ */ + #endif diff --git a/arch/x86/kernel/macros.S b/arch/x86/kernel/macros.S index cee28c3246dc..f1fe1d570365 100644 --- a/arch/x86/kernel/macros.S +++ b/arch/x86/kernel/macros.S @@ -7,3 +7,4 @@ */ #include +#include