[v1,6/7] DCE/DSE: riscv: add HAVE_TRIM_UNUSED_SYSCALLS support

Message ID ce00dad5acdd4aff099b289843e30c83f7e31764.1695679700.git.falcon@tinylab.org
State New
Headers
Series DCE/DSE: Add Dead Syscalls Elimination support, part1 |

Commit Message

Zhangjin Wu Sept. 25, 2023, 10:42 p.m. UTC
  For HAVE_TRIM_UNUSED_SYSCALLS, the syscall tables are hacked with the
inputing unused_syscalls.

Firstly, the intermediate preprocessed .i files are generated from the
original C version of syscall tables respectively, and named with a
'used' suffix: syscall_table_used.i, compat_syscall_table_used.i.

Secondly, all of the unused syscalls are commented.

At last, two new objective files sufixed with 'used' are generated from
the hacked .i files and they are linked into the eventual kernel image.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 arch/riscv/Kconfig                  |  1 +
 arch/riscv/kernel/syscalls/Makefile | 37 +++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)
  

Comments

Arnd Bergmann Sept. 26, 2023, 6:10 a.m. UTC | #1
On Tue, Sep 26, 2023, at 00:42, Zhangjin Wu wrote:
> For HAVE_TRIM_UNUSED_SYSCALLS, the syscall tables are hacked with the
> inputing unused_syscalls.
>
> Firstly, the intermediate preprocessed .i files are generated from the
> original C version of syscall tables respectively, and named with a
> 'used' suffix: syscall_table_used.i, compat_syscall_table_used.i.
>
> Secondly, all of the unused syscalls are commented.
>
> At last, two new objective files sufixed with 'used' are generated from
> the hacked .i files and they are linked into the eventual kernel image.
>
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>

As mentioned in my comment on the mips patch, hacking the preprocessed
file here is too much strain on the old infrastructure, the
asm-generic/unistd.h file is already too hard to understand for
anyone and in need of an overhaul, so let's work together on fixing
it up first.

      Arnd
  
Zhangjin Wu Oct. 7, 2023, 1:29 p.m. UTC | #2
Hi, Arnd

> On Tue, Sep 26, 2023, at 00:42, Zhangjin Wu wrote:
> > For HAVE_TRIM_UNUSED_SYSCALLS, the syscall tables are hacked with the
> > inputing unused_syscalls.
> >
> > Firstly, the intermediate preprocessed .i files are generated from the
> > original C version of syscall tables respectively, and named with a
> > 'used' suffix: syscall_table_used.i, compat_syscall_table_used.i.
> >
> > Secondly, all of the unused syscalls are commented.
> >
> > At last, two new objective files sufixed with 'used' are generated from
> > the hacked .i files and they are linked into the eventual kernel image.
> >
> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> 
> As mentioned in my comment on the mips patch, hacking the preprocessed
> file here is too much strain on the old infrastructure, the
> asm-generic/unistd.h file is already too hard to understand for
> anyone and in need of an overhaul, so let's work together on fixing
> it up first.
>

Ok, I was thinking about using asm/syscall_table.h instead of asm/unistd.h like mips.

    void * const sys_call_table[NR_syscalls] = {
    	[0 ... NR_syscalls - 1] = __riscv_sys_ni_syscall,
    #include <asm/syscall_table.h>
    };

Therefore, we can generate syscall_table.h from asm/unist.h with a tool like scripts/syscallused.sh

Another solution may be firstly generate a list of `#define __USED_NR_##call 1`
for the used syscalls from Kconfig symbol, and then change __SYSCALL() macro
to:

   #define __SYSCALL(nr, call)     [nr] = __is_defined(__USED_NR_##call) ? __riscv_##call : __riscv_sys_ni_syscall,

`include/linux/kconfig.h` defined the '__is_defined'.

This method may work for the archs with .tbl files too.

Thanks,
Zhangjin

>       Arnd
  
Arnd Bergmann Oct. 7, 2023, 8:43 p.m. UTC | #3
On Sat, Oct 7, 2023, at 15:29, Zhangjin Wu wrote:
>> On Tue, Sep 26, 2023, at 00:42, Zhangjin Wu wrote:
>> > For HAVE_TRIM_UNUSED_SYSCALLS, the syscall tables are hacked with the
>> > inputing unused_syscalls.
>> >
>> > Firstly, the intermediate preprocessed .i files are generated from the
>> > original C version of syscall tables respectively, and named with a
>> > 'used' suffix: syscall_table_used.i, compat_syscall_table_used.i.
>> >
>> > Secondly, all of the unused syscalls are commented.
>> >
>> > At last, two new objective files sufixed with 'used' are generated from
>> > the hacked .i files and they are linked into the eventual kernel image.
>> >
>> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
>> 
>> As mentioned in my comment on the mips patch, hacking the preprocessed
>> file here is too much strain on the old infrastructure, the
>> asm-generic/unistd.h file is already too hard to understand for
>> anyone and in need of an overhaul, so let's work together on fixing
>> it up first.
>>
>
> Ok, I was thinking about using asm/syscall_table.h instead of 
> asm/unistd.h like mips.
>
>     void * const sys_call_table[NR_syscalls] = {
>     	[0 ... NR_syscalls - 1] = __riscv_sys_ni_syscall,
>     #include <asm/syscall_table.h>
>     };
>
> Therefore, we can generate syscall_table.h from asm/unist.h with a tool 
> like scripts/syscallused.sh
>
> Another solution may be firstly generate a list of `#define __USED_NR_##call 1`
> for the used syscalls from Kconfig symbol, and then change __SYSCALL() macro
> to:
>
>    #define __SYSCALL(nr, call)     [nr] = 
> __is_defined(__USED_NR_##call) ? __riscv_##call : 
> __riscv_sys_ni_syscall,
>
> `include/linux/kconfig.h` defined the '__is_defined'.
>
> This method may work for the archs with .tbl files too.

Right, either way would be much better than than your first
approach. For the mips version (and all the other
traditional architectures that use the syscall.tbl method)
I think I'd integrate the filtering in scripts/syscalltbl.sh
if we decide to go that way. For the riscv version
(and all the others using asm-generic/unistd.h), the
__USED_NR_## macro would be fine as an intermediate
step, until we manage to convert those to syscall.tbl
parsing.

On the other hand, based on the earlier findings, my
overall feeling is that we're better off not adding
the extra indirection at all, but instead add the
more Kconfig symbols to control the largest groups
of syscalls, with the hope of conditionally removing
additional code for each of these symbols beyond the
automatic gc-section logic.

      Arnd
  

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d607ab0f7c6d..b5e726b49a6f 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -140,6 +140,7 @@  config RISCV
 	select HAVE_RSEQ
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_TRIM_UNUSED_SYSCALLS if HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 	select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
diff --git a/arch/riscv/kernel/syscalls/Makefile b/arch/riscv/kernel/syscalls/Makefile
index 65abd0871ee5..3b5969aaa9e8 100644
--- a/arch/riscv/kernel/syscalls/Makefile
+++ b/arch/riscv/kernel/syscalls/Makefile
@@ -3,8 +3,45 @@ 
 # Makefile for the RISC-V syscall tables
 #
 
+ifndef CONFIG_TRIM_UNUSED_SYSCALLS
+
 CFLAGS_syscall_table.o        += $(call cc-option,-Wno-override-init,)
 CFLAGS_compat_syscall_table.o += $(call cc-option,-Wno-override-init,)
 
 obj-y                += syscall_table.o
 obj-$(CONFIG_COMPAT) += compat_syscall_table.o
+else # CONFIG_TRIM_UNUSED_SYSCALLS
+
+include $(srctree)/scripts/Makefile.syscalls
+
+CFLAGS_syscall_table_used.o        += $(call cc-option,-Wno-override-init,)
+CFLAGS_compat_syscall_table_used.o += $(call cc-option,-Wno-override-init,)
+
+obj-y                += syscall_table_used.o
+obj-$(CONFIG_COMPAT) += compat_syscall_table_used.o
+
+# comment the unused syscalls
+quiet_cmd_used = USED    $@
+      cmd_used = sed -E -e '/^\[([0-9]+|\([0-9]+ \+ [0-9]+\))\] = /{/= *__riscv_(__sys_|sys_|compat_)*($(used_syscalls)),/!{s%^%/* %g;s%$$% */%g}}' -i $@;
+
+$(obj)/syscall_table_used.c: $(src)/syscall_table.c
+	$(Q)cp $< $@
+
+$(obj)/syscall_table_used.i: $(src)/syscall_table_used.c $(used_syscalls_deps) FORCE
+	$(call if_changed_dep,cpp_i_c)
+	$(call cmd,used)
+
+$(obj)/syscall_table_used.o: $(obj)/syscall_table_used.i FORCE
+	$(call if_changed,cc_o_c)
+
+$(obj)/compat_syscall_table_used.c: $(src)/compat_syscall_table.c
+	$(Q)cp $< $@
+
+$(obj)/compat_syscall_table_used.i: $(src)/compat_syscall_table_used.c $(used_syscalls_deps) FORCE
+	$(call if_changed_dep,cpp_i_c)
+	$(call cmd,used)
+
+$(obj)/compat_syscall_table_used.o: $(obj)/compat_syscall_table_used.i FORCE
+	$(call if_changed,cc_o_c)
+
+endif # CONFIG_TRIM_UNUSED_SYSCALLS