Messages in this thread Patch in this message | | | From | Denys Vlasenko <> | Subject | [PATCH] x86: Deinline cpuid_eax and friends | Date | Wed, 6 May 2015 19:07:37 +0200 |
| |
cpuid_e{a,b,c,d}x() functions compile to 44 bytes of machine code each. On x86 allyesconfig build they have 48 callsites. Deinlining all four of them shrinks kernel by about 1k:
text data bss dec hex filename 82434909 22255384 20627456 125317749 7783275 vmlinux.before 82433898 22255384 20627456 125316738 7782e82 vmlinux
Speed impact: CPUID instruction takes from 50 to 350+ cycles, call overhead is negligible in comparison.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> CC: Steven Rostedt <rostedt@goodmis.org> CC: Ingo Molnar <mingo@kernel.org> CC: Borislav Petkov <bp@alien8.de> CC: "H. Peter Anvin" <hpa@zytor.com> CC: Andy Lutomirski <luto@amacapital.net> CC: Frederic Weisbecker <fweisbec@gmail.com> CC: Alexei Starovoitov <ast@plumgrid.com> CC: Will Drewry <wad@chromium.org> CC: Kees Cook <keescook@chromium.org> CC: x86@kernel.org CC: linux-kernel@vger.kernel.org --- arch/x86/include/asm/processor.h | 39 ++++-------------------------------- arch/x86/kernel/cpu/common.c | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 35 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index ec1c935..67e1974 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -616,41 +616,10 @@ static inline void cpuid_count(unsigned int op, int count, /* * CPUID functions returning a single datum */ -static inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - - return eax; -} - -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - - return ebx; -} - -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - - return ecx; -} - -static inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - - return edx; -} +unsigned int cpuid_eax(unsigned int op); +unsigned int cpuid_ebx(unsigned int op); +unsigned int cpuid_ecx(unsigned int op); +unsigned int cpuid_edx(unsigned int op); /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ static inline void rep_nop(void) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 2346c95..1d2e270 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -307,6 +307,49 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) } /* + * CPUID functions returning a single datum + */ +unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + + return eax; +} +EXPORT_SYMBOL(cpuid_eax); + +unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + + return ebx; +} +EXPORT_SYMBOL(cpuid_ebx); + +unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + + return ecx; +} +EXPORT_SYMBOL(cpuid_ecx); + +unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + + return edx; +} +EXPORT_SYMBOL(cpuid_edx); + +/* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization * software. Add those features to this table to auto-disable them. -- 1.8.1.4
| |