Skip to content

x86: macrofying inline asm

Nadav Amit linux-kbuild linux-sparse lkml virtualization 9 versions – In review

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v9 Latest10 patches 105 repliesIn review
  2. v810 patches 9 repliesSuperseded
  3. v710 patches 5 repliesSuperseded
Earlier versions · 6
VersionPostedPatchesRepliesStatus
v69 patches9 repliesSuperseded
v59 patches4 repliesSuperseded
v49 patches7 repliesSuperseded
v39 patches6 repliesSuperseded
v29 patches5 repliesSuperseded
v16 patches29 repliesSuperseded

Patches in v9 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/10xtensa: defining LINKER_SCRIPT for the linker scriptarch/xtensa/kernel/Makefile+2 -20 replies
2/10Makefile: Prepare for using macros for inline asmMakefile arch/x86/Makefile arch/x86/kernel/macros.S +2 more+26 -315 replies
3/10x86: objtool: use asm macro for better compiler decisionsarch/x86/kernel/macros.S include/linux/compiler.h+45 -130 replies
4/10x86: refcount: prevent gcc distortionsarch/x86/include/asm/refcount.h arch/x86/kernel/macros.S+46 -2928 replies
5/10x86: alternatives: macrofy locks for better inliningarch/x86/include/asm/alternative-asm.h arch/x86/include/asm/alternative.h arch/x86/kernel/macros.S+17 -150 replies
6/10x86: bug: prevent gcc distortionsarch/x86/include/asm/bug.h arch/x86/kernel/macros.S include/asm-generic/bug.h+61 -460 replies
7/10x86: prevent inline distortion by paravirt opsarch/x86/include/asm/paravirt_types.h arch/x86/kernel/macros.S+28 -290 replies
8/10x86: extable: use macros instead of inline assemblyarch/x86/include/asm/asm.h arch/x86/kernel/macros.S+28 -340 replies
9/10x86: cpufeature: use macros instead of inline assemblyarch/x86/include/asm/cpufeature.h arch/x86/kernel/macros.S+48 -350 replies
10/10x86: jump-labels: use macros instead of inline assemblyarch/x86/entry/calling.h arch/x86/include/asm/jump_label.h arch/x86/kernel/macros.S+30 -500 replies

Reviews trailers per patch

All 10 patches have a Reviewed-by or Acked-by.

PatchPeter Zijlstra (Intel)Josh PoimboeufKees CookJuergen GrossMasahiro YamadaMax Filippov
1/10A-b
2/10A-b T-b A-b
3/10A-b R-b T-b
4/10A-b A-b A-b A-b A-b A-b A-b A-b T-b T-b T-b T-b T-b T-b T-b T-b
5/10A-b T-b
6/10A-b T-b
7/10A-b T-b R-b
8/10A-b T-b
9/10A-b T-b
10/10A-b T-b

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes. Scroll the table sideways for all 6 reviewers.

Read the v9 thread

Cover letter [PATCH v9 00/10] x86: macrofying inline asm

This patch-set deals with an interesting yet stupid problem: kernel code that does not get inlined despite its simplicity. There are several causes for this behavior: "cold" attribute on __init, different function optimization levels; conditional constant computations based on __builtin_constant_p(); and finally large inline assembly blocks.

This patch-set deals with the inline assembly problem. I separated these patches from the others (that were sent in the RFC) for easier inclusion. I also separated the removal of unnecessary new-lines which would be sent separately.

The problem with inline assembly is that inline assembly is often used by the kernel for things that are other than code - for example, assembly directives and data. GCC however is oblivious to the content of the blocks and assumes their cost in space and time is proportional to the number of the perceived assembly "instruction", according to the number of newlines and semicolons. Alternatives, paravirt and other mechanisms are affected, causing code not to be inlined, and degrading compilation quality in general.

The solution that this patch-set carries for this problem is to create an assembly macro, and then call it from the inline assembly block. As a result, the compiler sees a single "instruction" and assigns the more appropriate cost to the code.

To avoid uglification of the code, as many noted, the macros are first precompiled into an assembly file, which is later assembled together with the C files. This also enables to avoid duplicate implementation that was set before for the asm and C code. This can be seen in the exception table changes.

Overall this patch-set slightly increases the kernel size (my build was done using my Ubuntu 18.04 config + localyesconfig for the record):

text data bss dec hex filename
18140829 10224724 2957312 31322865 1ddf2f1 ./vmlinux before 18163608 10227348 2957312 31348268 1de562c ./vmlinux after (+0.1%)

The number of static functions in the image is reduced by 379, but actually inlining is even better, which does not always shows in these
numbers: a function may be inlined causing the calling function not to be inlined.

I ran some limited number of benchmarks, and in general the performance impact is not very notable. You can still see >10 cycles shaved off some syscalls that manipulate page-tables (e.g., mprotect()), in which paravirt caused many functions not to be inlined. In addition this patch-set can prevent issues such as [1], and improves code readability and maintainability.

Update: Rasmus recently caused me (inadvertently) to become paranoid about the dependencies. To clarify: if any of the headers changes, any c file which uses macros that are included in macros.S would be fine as long as it includes the header as well (as it should). Adding an assertion to check this is done might become slightly ugly, and nobody else is concerned about it. Another minor issue is that changes of macros.S would not trigger a global rebuild, but that is pretty similar to changes of the Makefile that do not trigger a rebuild.

[1] https://patchwork.kernel.org/patch/10450037/

v8->v9: * Restoring the '-pipe' parameter (Rasmus)
* Adding Kees's tested-by tag (Kees)

v7->v8: * Add acks (Masahiro, Max)
* Rebase on 4.19 (Ingo)

v6->v7: * Fix context switch tracking (Ingo)
* Fix xtensa build error (Ingo)
* Rebase on 4.18-rc8

v5->v6: * Removing more code from jump-labels (PeterZ)
* Fix build issue on i386 (0-day, PeterZ)

v4->v5: * Makefile fixes (Masahiro, Sam)

v3->v4: * Changed naming of macros in 2 patches (PeterZ)
* Minor cleanup of the paravirt patch

v2->v3: * Several build issues resolved (0-day)
* Wrong comments fix (Josh)
* Change asm vs C order in refcount (Kees)

v1->v2: * Compiling the macros into a separate .s file, improving
readability (Linus)
* Improving assembly formatting, applying most of the comments according to my judgment (Jan)
* Adding exception-table, cpufeature and jump-labels
* Removing new-line cleanup; to be submitted separately

Cc Masahiro Yamada <[email protected]>
Cc Sam Ravnborg <[email protected]>
Cc Alok Kataria <[email protected]>
Cc Christopher Li <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jan Beulich <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Kate Stewart <[email protected]>
Cc Kees Cook <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Philippe Ombredanne <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Chris Zankel <[email protected]>
Cc Max Filippov <[email protected]>

Nadav Amit (10):
xtensa: defining LINKER_SCRIPT for the linker script
Makefile: Prepare for using macros for inline asm
x86: objtool: use asm macro for better compiler decisions
x86: refcount: prevent gcc distortions
x86: alternatives: macrofy locks for better inlining
x86: bug: prevent gcc distortions
x86: prevent inline distortion by paravirt ops
x86: extable: use macros instead of inline assembly
x86: cpufeature: use macros instead of inline assembly
x86: jump-labels: use macros instead of inline assembly

 Makefile                               |  9 ++-
 arch/x86/Makefile                      |  7 ++
 arch/x86/entry/calling.h               |  2 +-
 arch/x86/include/asm/alternative-asm.h | 20 ++++--
 arch/x86/include/asm/alternative.h     | 11 +--
 arch/x86/include/asm/asm.h             | 61 +++++++---------
 arch/x86/include/asm/bug.h             | 98 +++++++++++++++-----------
 arch/x86/include/asm/cpufeature.h      | 82 ++++++++++++---------
 arch/x86/include/asm/jump_label.h      | 77 ++++++++------------
 arch/x86/include/asm/paravirt_types.h  | 56 +++++++--------
 arch/x86/include/asm/refcount.h        | 74 +++++++++++--------
 arch/x86/kernel/macros.S               | 16 +++++
 arch/xtensa/kernel/Makefile            |  4 +-
 include/asm-generic/bug.h              |  8 +--
 include/linux/compiler.h               | 56 +++++++++++----
 scripts/Kbuild.include                 |  4 +-
 scripts/mod/Makefile                   |  2 +
 17 files changed, 331 insertions(+), 256 deletions(-)
 create mode 100644 arch/x86/kernel/macros.S
Signature · 1 line
2.17.1