linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Enable dead code elimination
@ 2023-02-13 17:39 Falcon
  2023-02-13 19:39 ` Conor Dooley
  0 siblings, 1 reply; 3+ messages in thread
From: Falcon @ 2023-02-13 17:39 UTC (permalink / raw)
  To: linux-riscv, Palmer Dabbelt
  Cc: Nicholas Piggin, Paul Burton, Paul Walmsley, Guo Ren,
	Vincent Chen, Falcon

Select CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION for RISC-V, allowing
the user to enable dead code elimination. In order for this to work,
ensure that we keep the alternative table by annotating them with KEEP.

This boots well on qemu with both rv32_defconfig & rv64 defconfig, but
it only shrinks their builds by ~1%, a smaller config is thereforce
customized to test this feature:

          | rv32                   | rv64
  --------|------------------------|---------------------
   No DCE | 4460684                | 4893488
      DCE | 3986716                | 4376400
   Shrink |  473968 (~10.6%)       |  517088 (~10.5%)

The config used above only reserves necessary options to boot on qemu
with serial console, more like the size-critical embedded scenes:

  - rv64 config: https://pastebin.com/crz82T0s
  - rv32 config: rv64 config + 32-bit.config

Signed-off-by: Falcon <falcon@tinylab.org>
---
 arch/riscv/Kconfig              | 1 +
 arch/riscv/kernel/vmlinux.lds.S | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index e2b656043abf..8a73d7180cb8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -103,6 +103,7 @@ config RISCV
 	select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
 	select HAVE_KRETPROBES if !XIP_KERNEL
 	select HAVE_RETHOOK if !XIP_KERNEL
+	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 	select HAVE_MOVE_PMD
 	select HAVE_MOVE_PUD
 	select HAVE_PCI
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index 4e6c88aa4d87..51218cfe1ee4 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -101,7 +101,7 @@ SECTIONS
 	. = ALIGN(8);
 	.alternative : {
 		__alt_start = .;
-		*(.alternative)
+		KEEP(*(.alternative))
 		__alt_end = .;
 	}
 	__init_end = .;
-- 
2.25.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] RISC-V: Enable dead code elimination
  2023-02-13 17:39 [PATCH] RISC-V: Enable dead code elimination Falcon
@ 2023-02-13 19:39 ` Conor Dooley
  2023-02-14  8:42   ` Wu Zhangjin
  0 siblings, 1 reply; 3+ messages in thread
From: Conor Dooley @ 2023-02-13 19:39 UTC (permalink / raw)
  To: Falcon
  Cc: linux-riscv, Palmer Dabbelt, Nicholas Piggin, Paul Burton,
	Paul Walmsley, Guo Ren, Vincent Chen


[-- Attachment #1.1: Type: text/plain, Size: 1102 bytes --]

On Tue, Feb 14, 2023 at 01:39:06AM +0800, Falcon wrote:
> Select CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION for RISC-V, allowing
> the user to enable dead code elimination. In order for this to work,
> ensure that we keep the alternative table by annotating them with KEEP.
> 
> This boots well on qemu with both rv32_defconfig & rv64 defconfig, but
> it only shrinks their builds by ~1%, a smaller config is thereforce
> customized to test this feature:
> 
>           | rv32                   | rv64
>   --------|------------------------|---------------------
>    No DCE | 4460684                | 4893488
>       DCE | 3986716                | 4376400
>    Shrink |  473968 (~10.6%)       |  517088 (~10.5%)
> 
> The config used above only reserves necessary options to boot on qemu
> with serial console, more like the size-critical embedded scenes:
> 
>   - rv64 config: https://pastebin.com/crz82T0s
>   - rv32 config: rv64 config + 32-bit.config
> 
> Signed-off-by: Falcon <falcon@tinylab.org>

I feel like I "need" to ask - is Falcon your actual name?

Sorry,
Conor.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 161 bytes --]

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Re: [PATCH] RISC-V: Enable dead code elimination
  2023-02-13 19:39 ` Conor Dooley
@ 2023-02-14  8:42   ` Wu Zhangjin
  0 siblings, 0 replies; 3+ messages in thread
From: Wu Zhangjin @ 2023-02-14  8:42 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Wu Zhangjin, linux-riscv, Palmer Dabbelt, Nicholas Piggin,
	Paul Burton, Paul Walmsley, Guo Ren, Vincent Chen, Willy Tarreau,
	Paul E . McKenney, Nicholas Mc Guire

On 2023-02-13 19:39 UTC, Conor wrote:
> On Tue, Feb 14, 2023 at 01:39:06AM +0800, Falcon wrote:
> > Select CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION for RISC-V, allowing
> > the user to enable dead code elimination. In order for this to work,
> > ensure that we keep the alternative table by annotating them with KEEP.
> >
> > This boots well on qemu with both rv32_defconfig & rv64 defconfig, but
> > it only shrinks their builds by ~1%, a smaller config is thereforce
> > customized to test this feature:
> >
> >           | rv32                   | rv64
> >   --------|------------------------|---------------------
> >    No DCE | 4460684                | 4893488
> >       DCE | 3986716                | 4376400
> >    Shrink |  473968 (~10.6%)       |  517088 (~10.5%)
> >
> > The config used above only reserves necessary options to boot on qemu
> > with serial console, more like the size-critical embedded scenes:
> >
> >   - rv64 config: https://pastebin.com/crz82T0s
> >   - rv32 config: rv64 config + 32-bit.config
> >
> > Signed-off-by: Falcon <falcon@tinylab.org>
> 
> I feel like I "need" to ask - is Falcon your actual name?
>

Oh, no ;-) my actual name is 'Wu Zhangjin', will update both Signed-off-by and
Author lines in v2, and also the configuration in my `~/.gitconfig` later,
'Falcon' is the nickname used in my own open source projects.

FYI, this guy is me, but the email address is not often used now:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?h=v6.2-rc8&qt=author&q=wuzhangjin%40gmail.com

By the way, just introduce why i send such a patch. I worked on gc-sections 10+
years ago: http://elinux.org/Work_on_Tiny_Linux_Kernel, and the repo is here:
https://github.com/tinyclub/tinylinux/tree/2.6.35/dev/gc-sections 

Several days ago, the article 'Nolibc: a minimal C-library replacement shipped
with the kernel' from https://lwn.net/Articles/920158/ waked up my memory about
shrinking the dead system calls automatically, my old gc-sections work have
tried to let more system calls configurable, but that is manual and not
flexible.

With the new integrated user-space nolibc, the elimination of dead system calls
become easier. but we also need the 'gc-sections' support, which has already
been upstreamed by Nick, this patch tries to add it for risc-v.

Based on `tools/include/nolibc` from Willy, the extremely small applications
(match the idea of 'Kernel-only deployments' from Paul) used system calls can
be easily dumped out with the help of objdump. To only reserve the system calls
used, we also need to enable gc-sections for nolibc to eliminate the unused c
functions and the system calls they called, see an example here:
https://gitee.com/tinylab/linux-lab/commit/2027573595aca46fe6ab19ee381c5ef92be62f5f,
and then, the `arch/riscv/kernel/syscall_table.c` can be simply updated to
something like this:

    #include <linux/linkage.h>
    #include <linux/syscalls.h>
    #include <asm-generic/syscalls.h>
    #include <asm/syscall.h>

    #undef __SYSCALL
    #define __SYSCALL(nr, call)     [nr] = (call),

    void * const sys_call_table[__NR_syscalls] = {
    	[0 ... __NR_syscalls - 1] = sys_ni_syscall,

    #ifdef HAVE_LD_DEAD_SYSCALL_ELIMINATION
    	#include <asm/unistd_used.h>
    #else
    	#include <asm/unistd.h>
    #endif

    };

The `asm/unistd_used.h` can be generated automatically from a nolibc-objdump
script or more generically from a `CONFIG_SYSCALLS_USED` configuration (may be
required by the other libcs). A draft version of such a nolibc-objdump script:
https://gitee.com/tinylab/linux-lab/commit/057afb26fea336d20864b3889346fbac00924740

For example, such a simple hello.c:

    #ifndef NOLIBC
    #include <stdio.h>
    #include <unistd.h>
    #else
    #define __NOLIBC__
    #endif
    
    int main(int argc, char *argv[])
    {
    	printf("Hello, nolibc!\n");
    
    #ifdef __NOLIBC__
    	reboot(LINUX_REBOOT_CMD_HALT);
    #endif
    
    	return 0;
    }

It only requires `sys_write`, `sys_reboot` and `sys_exit`, so, the
`asm/unistd_used.h` looks like this:

    asm/unistd_used.h:

    	[142] = sys_reboot,
    	[93] = sys_exit,
    	[64] = sys_write,

Without the explicit using in the above system call table, the unused system
calls and their callees, if also not called internally in the kernel, they will
be eliminated by gc-sections automatically, this can be observed by simply
adding a `--print-gc-sections` after the `--gc-sections` in Makefile:

    Makefile:

    - LDFLAGS_vmlinux += --gc-sections
    + LDFLAGS_vmlinux += --gc-sections --print-gc-sections

If `CONFIG_COMPAT` enabled, the `arch/riscv/kernel/compat_syscall_table.c` file
should be updated similarly too.

To share more changes, the old `asm/unistd.h` can be changed to something like
`asm/unistd_wrapper.h` and the control of `HAVE_LD_DEAD_SYSCALL_ELIMINATION` should
be moved in.

    arch/riscv/kernel/syscall_table.c:

    - #include <asm/unistd.h>
    + #include <asm/unistd_wrapper.h>

    arch/riscv/kernel/compat_syscall_table.c:

    - #include <asm/unistd.h>
    + #include <asm/unistd_wrapper.h>

    asm/unistd_wrapper.h:

    #ifdef HAVE_LD_DEAD_SYSCALL_ELIMINATION
    	#include <asm/unistd_used.h>
    #else
    	#include <asm/unistd.h>
    #endif

With the above change, the unused system calls will be eliminated automatically
by gc-sections. tests shows, in rv64, with the above rv64 config, it saves
another (4376400-4172848)=203552 bytes, by ~4.6%.

Beside the size optimization, dead system call elimination may also help
security (shrink the path to protect) and safety (shrink the work to estimate).

>
> Sorry,
> Conor.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-02-14  9:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-13 17:39 [PATCH] RISC-V: Enable dead code elimination Falcon
2023-02-13 19:39 ` Conor Dooley
2023-02-14  8:42   ` Wu Zhangjin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).