* [PATCH v1 0/7] perf: Support multiple system call tables in the build
@ 2025-02-01 7:14 Ian Rogers
2025-02-01 7:14 ` [PATCH v1 1/7] perf syscalltble: Remove syscall_table.h Ian Rogers
` (8 more replies)
0 siblings, 9 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
This work builds on the clean up of system call tables and removal of
libaudit by Charlie Jenkins <charlie@rivosinc.com>.
The system call table in perf trace is used to map system call numbers
to names and vice versa. Prior to these changes, a single table
matching the perf binary's build was present. The table would be
incorrect if tracing say a 32-bit binary from a 64-bit version of
perf, the names and numbers wouldn't match.
Change the build so that a single system call file is built and the
potentially multiple tables are identifiable from the ELF machine type
of the process being examined. To determine the ELF machine type, the
executable's header is read from /proc/pid/exe with fallbacks to using
the perf's binary type when unknown.
Remove some runtime types used by the system call tables and make
equivalents generated at build time.
Ian Rogers (7):
perf syscalltble: Remove syscall_table.h
perf trace: Reorganize syscalls
perf syscalltbl: Remove struct syscalltbl
perf thread: Add support for reading the e_machine type for a thread
perf trace beauty: Add syscalltbl.sh generating all system call tables
perf syscalltbl: Use lookup table containing multiple architectures
perf build: Remove Makefile.syscalls
tools/perf/Makefile.perf | 10 +-
tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
.../alpha/entry/syscalls/Makefile.syscalls | 5 -
tools/perf/arch/alpha/include/syscall_table.h | 2 -
tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
.../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
tools/perf/arch/arc/include/syscall_table.h | 2 -
tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
.../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
tools/perf/arch/arm/include/syscall_table.h | 2 -
tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
.../arm64/entry/syscalls/Makefile.syscalls | 6 -
tools/perf/arch/arm64/include/syscall_table.h | 8 -
tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
.../csky/entry/syscalls/Makefile.syscalls | 3 -
tools/perf/arch/csky/include/syscall_table.h | 2 -
.../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
.../entry/syscalls/Makefile.syscalls | 3 -
.../arch/loongarch/include/syscall_table.h | 2 -
tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
.../mips/entry/syscalls/Makefile.syscalls | 5 -
tools/perf/arch/mips/include/syscall_table.h | 2 -
tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
.../parisc/entry/syscalls/Makefile.syscalls | 6 -
.../perf/arch/parisc/include/syscall_table.h | 8 -
tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
.../powerpc/entry/syscalls/Makefile.syscalls | 6 -
.../perf/arch/powerpc/include/syscall_table.h | 8 -
tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
.../riscv/entry/syscalls/Makefile.syscalls | 4 -
tools/perf/arch/riscv/include/syscall_table.h | 8 -
tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
.../s390/entry/syscalls/Makefile.syscalls | 5 -
tools/perf/arch/s390/include/syscall_table.h | 2 -
tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
.../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
tools/perf/arch/sh/include/syscall_table.h | 2 -
tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
.../sparc/entry/syscalls/Makefile.syscalls | 5 -
tools/perf/arch/sparc/include/syscall_table.h | 8 -
tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
.../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
tools/perf/arch/x86/include/syscall_table.h | 8 -
tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
.../xtensa/entry/syscalls/Makefile.syscalls | 4 -
.../perf/arch/xtensa/include/syscall_table.h | 2 -
tools/perf/builtin-trace.c | 275 +++++++++++-------
tools/perf/scripts/Makefile.syscalls | 61 ----
tools/perf/scripts/syscalltbl.sh | 86 ------
tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
tools/perf/util/syscalltbl.c | 142 ++++-----
tools/perf/util/syscalltbl.h | 22 +-
tools/perf/util/thread.c | 50 ++++
tools/perf/util/thread.h | 14 +-
54 files changed, 598 insertions(+), 506 deletions(-)
delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
delete mode 100644 tools/perf/scripts/Makefile.syscalls
delete mode 100755 tools/perf/scripts/syscalltbl.sh
create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
--
2.48.1.362.g079036d154-goog
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v1 1/7] perf syscalltble: Remove syscall_table.h
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 2/7] perf trace: Reorganize syscalls Ian Rogers
` (7 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
The definition of "static const char *const syscalltbl[] = {" is done
in a generated syscalls_32.h or syscalls_64.h that is architecture
dependent. In order to include the appropriate file a syscall_table.h
is found via the perf include path and it includes the syscalls_32.h
or syscalls_64.h as appropriate.
To support having multiple syscall tables, one for 32-bit and one for
64-bit, or for different architectures, an include path cannot be
used. Remove syscall_table.h because of this and inline what it does
into syscalltbl.c.
For architectures without a syscall_table.h this will cause a failure
to include either syscalls_32.h or syscalls_64.h rather than a failure
to include syscall_table.h. For architectures that only included one
or other, the behavior matches BITS_PER_LONG as previously done on
architectures supporting both syscalls_32.h and syscalls_64.h.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/arch/alpha/include/syscall_table.h | 2 --
tools/perf/arch/arc/include/syscall_table.h | 2 --
tools/perf/arch/arm/include/syscall_table.h | 2 --
tools/perf/arch/arm64/include/syscall_table.h | 8 --------
tools/perf/arch/csky/include/syscall_table.h | 2 --
tools/perf/arch/loongarch/include/syscall_table.h | 2 --
tools/perf/arch/mips/include/syscall_table.h | 2 --
tools/perf/arch/parisc/include/syscall_table.h | 8 --------
tools/perf/arch/powerpc/include/syscall_table.h | 8 --------
tools/perf/arch/riscv/include/syscall_table.h | 8 --------
tools/perf/arch/s390/include/syscall_table.h | 2 --
tools/perf/arch/sh/include/syscall_table.h | 2 --
tools/perf/arch/sparc/include/syscall_table.h | 8 --------
tools/perf/arch/x86/include/syscall_table.h | 8 --------
tools/perf/arch/xtensa/include/syscall_table.h | 2 --
tools/perf/util/syscalltbl.c | 8 +++++++-
16 files changed, 7 insertions(+), 67 deletions(-)
delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
diff --git a/tools/perf/arch/alpha/include/syscall_table.h b/tools/perf/arch/alpha/include/syscall_table.h
deleted file mode 100644
index b53e31c15805..000000000000
--- a/tools/perf/arch/alpha/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_64.h>
diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
deleted file mode 100644
index 4c942821662d..000000000000
--- a/tools/perf/arch/arc/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_32.h>
diff --git a/tools/perf/arch/arm/include/syscall_table.h b/tools/perf/arch/arm/include/syscall_table.h
deleted file mode 100644
index 4c942821662d..000000000000
--- a/tools/perf/arch/arm/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_32.h>
diff --git a/tools/perf/arch/arm64/include/syscall_table.h b/tools/perf/arch/arm64/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/arm64/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/csky/include/syscall_table.h b/tools/perf/arch/csky/include/syscall_table.h
deleted file mode 100644
index 4c942821662d..000000000000
--- a/tools/perf/arch/csky/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_32.h>
diff --git a/tools/perf/arch/loongarch/include/syscall_table.h b/tools/perf/arch/loongarch/include/syscall_table.h
deleted file mode 100644
index 9d0646d3455c..000000000000
--- a/tools/perf/arch/loongarch/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscall_table_64.h>
diff --git a/tools/perf/arch/mips/include/syscall_table.h b/tools/perf/arch/mips/include/syscall_table.h
deleted file mode 100644
index b53e31c15805..000000000000
--- a/tools/perf/arch/mips/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_64.h>
diff --git a/tools/perf/arch/parisc/include/syscall_table.h b/tools/perf/arch/parisc/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/parisc/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/powerpc/include/syscall_table.h b/tools/perf/arch/powerpc/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/powerpc/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/riscv/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/s390/include/syscall_table.h b/tools/perf/arch/s390/include/syscall_table.h
deleted file mode 100644
index b53e31c15805..000000000000
--- a/tools/perf/arch/s390/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_64.h>
diff --git a/tools/perf/arch/sh/include/syscall_table.h b/tools/perf/arch/sh/include/syscall_table.h
deleted file mode 100644
index 4c942821662d..000000000000
--- a/tools/perf/arch/sh/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_32.h>
diff --git a/tools/perf/arch/sparc/include/syscall_table.h b/tools/perf/arch/sparc/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/sparc/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/x86/include/syscall_table.h b/tools/perf/arch/x86/include/syscall_table.h
deleted file mode 100644
index 7ff51b783000..000000000000
--- a/tools/perf/arch/x86/include/syscall_table.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/bitsperlong.h>
-
-#if __BITS_PER_LONG == 64
-#include <asm/syscalls_64.h>
-#else
-#include <asm/syscalls_32.h>
-#endif
diff --git a/tools/perf/arch/xtensa/include/syscall_table.h b/tools/perf/arch/xtensa/include/syscall_table.h
deleted file mode 100644
index 4c942821662d..000000000000
--- a/tools/perf/arch/xtensa/include/syscall_table.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/syscalls_32.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 928aca4cd6e9..2f76241494c8 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -7,13 +7,19 @@
#include "syscalltbl.h"
#include <stdlib.h>
+#include <asm/bitsperlong.h>
#include <linux/compiler.h>
#include <linux/zalloc.h>
#include <string.h>
#include "string2.h"
-#include <syscall_table.h>
+#if __BITS_PER_LONG == 64
+ #include <asm/syscalls_64.h>
+#else
+ #include <asm/syscalls_32.h>
+#endif
+
const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
static const char *const *syscalltbl_native = syscalltbl;
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 2/7] perf trace: Reorganize syscalls
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
2025-02-01 7:14 ` [PATCH v1 1/7] perf syscalltble: Remove syscall_table.h Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-05 0:12 ` Howard Chu
2025-02-01 7:14 ` [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl Ian Rogers
` (6 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
Identify struct syscall information in the syscalls table by a machine
type and syscall number, not just system call number. Having the
machine type means that 32-bit system calls can be differentiated from
64-bit ones on a machine capable of both. Having a table for all
machine types and all system call numbers would be too large, so
maintain a sorted array of system calls as they are encountered.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/builtin-trace.c | 178 +++++++++++++++++++++++++------------
1 file changed, 119 insertions(+), 59 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index ac97632f13dc..10d3ad0d21f7 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -66,6 +66,7 @@
#include "rb_resort.h"
#include "../perf.h"
#include "trace_augment.h"
+#include "dwarf-regs.h"
#include <errno.h>
#include <inttypes.h>
@@ -86,6 +87,7 @@
#include <linux/ctype.h>
#include <perf/mmap.h>
+#include <tools/libc_compat.h>
#ifdef HAVE_LIBTRACEEVENT
#include <event-parse.h>
@@ -143,7 +145,10 @@ struct trace {
struct perf_tool tool;
struct syscalltbl *sctbl;
struct {
+ /** Sorted sycall numbers used by the trace. */
struct syscall *table;
+ /** Size of table. */
+ size_t table_size;
struct {
struct evsel *sys_enter,
*sys_exit,
@@ -1445,22 +1450,37 @@ static const struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias)
return __syscall_fmt__find_by_alias(syscall_fmts, nmemb, alias);
}
-/*
- * is_exit: is this "exit" or "exit_group"?
- * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter.
- * args_size: sum of the sizes of the syscall arguments, anything after that is augmented stuff: pathname for openat, etc.
- * nonexistent: Just a hole in the syscall table, syscall id not allocated
+/**
+ * struct syscall
*/
struct syscall {
+ /** @e_machine: The ELF machine associated with the entry. */
+ int e_machine;
+ /** @id: id value from the tracepoint, the system call number. */
+ int id;
struct tep_event *tp_format;
int nr_args;
+ /**
+ * @args_size: sum of the sizes of the syscall arguments, anything
+ * after that is augmented stuff: pathname for openat, etc.
+ */
+
int args_size;
struct {
struct bpf_program *sys_enter,
*sys_exit;
} bpf_prog;
+ /** @is_exit: is this "exit" or "exit_group"? */
bool is_exit;
+ /**
+ * @is_open: is this "open" or "openat"? To associate the fd returned in
+ * sys_exit with the pathname in sys_enter.
+ */
bool is_open;
+ /**
+ * @nonexistent: Name lookup failed. Just a hole in the syscall table,
+ * syscall id not allocated.
+ */
bool nonexistent;
bool use_btf;
struct tep_format_field *args;
@@ -2066,22 +2086,21 @@ static int syscall__set_arg_fmts(struct syscall *sc)
return 0;
}
-static int trace__read_syscall_info(struct trace *trace, int id)
+static int syscall__read_info(struct syscall *sc, struct trace *trace)
{
char tp_name[128];
- struct syscall *sc;
- const char *name = syscalltbl__name(trace->sctbl, id);
+ const char *name;
int err;
- if (trace->syscalls.table == NULL) {
- trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
- if (trace->syscalls.table == NULL)
- return -ENOMEM;
- }
- sc = trace->syscalls.table + id;
if (sc->nonexistent)
return -EEXIST;
+ if (sc->name) {
+ /* Info already read. */
+ return 0;
+ }
+
+ name = syscalltbl__name(trace->sctbl, sc->id);
if (name == NULL) {
sc->nonexistent = true;
return -EEXIST;
@@ -2104,11 +2123,12 @@ static int trace__read_syscall_info(struct trace *trace, int id)
*/
if (IS_ERR(sc->tp_format)) {
sc->nonexistent = true;
- return PTR_ERR(sc->tp_format);
+ err = PTR_ERR(sc->tp_format);
+ sc->tp_format = NULL;
+ return err;
}
- if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
- RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
+ if (syscall__alloc_arg_fmts(sc, sc->tp_format->format.nr_fields))
return -ENOMEM;
sc->args = sc->tp_format->format.fields;
@@ -2397,13 +2417,67 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
return printed;
}
+static void syscall__init(struct syscall *sc, int e_machine, int id)
+{
+ memset(sc, 0, sizeof(*sc));
+ sc->e_machine = e_machine;
+ sc->id = id;
+}
+
+static void syscall__exit(struct syscall *sc)
+{
+ if (!sc)
+ return;
+
+ zfree(&sc->arg_fmt);
+}
+
+static int syscall__cmp(const void *va, const void *vb)
+{
+ const struct syscall *a = va, *b = vb;
+
+ if (a->e_machine != b->e_machine)
+ return a->e_machine - b->e_machine;
+
+ return a->id - b->id;
+}
+
+static struct syscall *trace__find_syscall(struct trace *trace, int e_machine, int id)
+{
+ struct syscall key = {
+ .e_machine = e_machine,
+ .id = id,
+ };
+ struct syscall *sc, *tmp;
+
+ sc = bsearch(&key, trace->syscalls.table, trace->syscalls.table_size,
+ sizeof(struct syscall), syscall__cmp);
+ if (sc)
+ return sc;
+
+ tmp = reallocarray(trace->syscalls.table, trace->syscalls.table_size + 1,
+ sizeof(struct syscall));
+ if (!tmp)
+ return NULL;
+
+ trace->syscalls.table = tmp;
+ sc = &trace->syscalls.table[trace->syscalls.table_size++];
+ syscall__init(sc, e_machine, id);
+ qsort(trace->syscalls.table, trace->syscalls.table_size, sizeof(struct syscall),
+ syscall__cmp);
+ sc = bsearch(&key, trace->syscalls.table, trace->syscalls.table_size,
+ sizeof(struct syscall), syscall__cmp);
+ return sc;
+}
+
typedef int (*tracepoint_handler)(struct trace *trace, struct evsel *evsel,
union perf_event *event,
struct perf_sample *sample);
-static struct syscall *trace__syscall_info(struct trace *trace,
- struct evsel *evsel, int id)
+static struct syscall *trace__syscall_info(struct trace *trace, struct evsel *evsel,
+ int e_machine, int id)
{
+ struct syscall *sc;
int err = 0;
if (id < 0) {
@@ -2428,28 +2502,20 @@ static struct syscall *trace__syscall_info(struct trace *trace,
err = -EINVAL;
- if (id > trace->sctbl->syscalls.max_id) {
- goto out_cant_read;
- }
-
- if ((trace->syscalls.table == NULL || trace->syscalls.table[id].name == NULL) &&
- (err = trace__read_syscall_info(trace, id)) != 0)
- goto out_cant_read;
+ sc = trace__find_syscall(trace, e_machine, id);
+ if (sc)
+ err = syscall__read_info(sc, trace);
- if (trace->syscalls.table && trace->syscalls.table[id].nonexistent)
- goto out_cant_read;
-
- return &trace->syscalls.table[id];
-
-out_cant_read:
- if (verbose > 0) {
+ if (err && verbose > 0) {
char sbuf[STRERR_BUFSIZE];
- fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf)));
- if (id <= trace->sctbl->syscalls.max_id && trace->syscalls.table[id].name != NULL)
- fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
+
+ fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err,
+ str_error_r(-err, sbuf, sizeof(sbuf)));
+ if (sc && sc->name)
+ fprintf(trace->output, "(%s)", sc->name);
fputs(" information\n", trace->output);
}
- return NULL;
+ return err ? NULL : sc;
}
struct syscall_stats {
@@ -2596,14 +2662,6 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam
return NULL;
}
-static void syscall__exit(struct syscall *sc)
-{
- if (!sc)
- return;
-
- zfree(&sc->arg_fmt);
-}
-
static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
@@ -2615,7 +2673,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
int augmented_args_size = 0;
void *augmented_args = NULL;
- struct syscall *sc = trace__syscall_info(trace, evsel, id);
+ struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
struct thread_trace *ttrace;
if (sc == NULL)
@@ -2689,7 +2747,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
struct thread_trace *ttrace;
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
- struct syscall *sc = trace__syscall_info(trace, evsel, id);
+ struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
char msg[1024];
void *args, *augmented_args = NULL;
int augmented_args_size;
@@ -2764,7 +2822,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
int alignment = trace->args_alignment;
- struct syscall *sc = trace__syscall_info(trace, evsel, id);
+ struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
struct thread_trace *ttrace;
if (sc == NULL)
@@ -3117,7 +3175,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
if (evsel == trace->syscalls.events.bpf_output) {
int id = perf_evsel__sc_tp_uint(evsel, id, sample);
- struct syscall *sc = trace__syscall_info(trace, evsel, id);
+ struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
if (sc) {
fprintf(trace->output, "%s(", sc->name);
@@ -3622,7 +3680,7 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
if (sc == NULL)
return;
@@ -3633,20 +3691,20 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
}
static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
}
static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
{
struct tep_format_field *field;
- struct syscall *sc = trace__syscall_info(trace, NULL, key);
+ struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
const struct btf_type *bt;
char *struct_offset, *tmp, name[32];
bool can_augment = false;
@@ -3744,7 +3802,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
try_to_find_pair:
for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
int id = syscalltbl__id_at_idx(trace->sctbl, i);
- struct syscall *pair = trace__syscall_info(trace, NULL, id);
+ struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
struct bpf_program *pair_prog;
bool is_candidate = false;
@@ -3894,7 +3952,7 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
*/
for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
int key = syscalltbl__id_at_idx(trace->sctbl, i);
- struct syscall *sc = trace__syscall_info(trace, NULL, key);
+ struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
struct bpf_program *pair_prog;
int prog_fd;
@@ -4659,7 +4717,11 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
avg /= NSEC_PER_MSEC;
- sc = &trace->syscalls.table[syscall_stats_entry->syscall];
+ sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
+ syscall_stats_entry->syscall);
+ if (!sc)
+ continue;
+
printed += fprintf(fp, " %-15s", sc->name);
printed += fprintf(fp, " %8" PRIu64 " %6" PRIu64 " %9.3f %9.3f %9.3f",
n, stats->nr_failures, syscall_stats_entry->msecs, min, avg);
@@ -5067,12 +5129,10 @@ static int trace__config(const char *var, const char *value, void *arg)
static void trace__exit(struct trace *trace)
{
- int i;
-
strlist__delete(trace->ev_qualifier);
zfree(&trace->ev_qualifier_ids.entries);
if (trace->syscalls.table) {
- for (i = 0; i <= trace->sctbl->syscalls.max_id; i++)
+ for (size_t i = 0; i < trace->syscalls.table_size; i++)
syscall__exit(&trace->syscalls.table[i]);
zfree(&trace->syscalls.table);
}
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
2025-02-01 7:14 ` [PATCH v1 1/7] perf syscalltble: Remove syscall_table.h Ian Rogers
2025-02-01 7:14 ` [PATCH v1 2/7] perf trace: Reorganize syscalls Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-05 0:18 ` Howard Chu
2025-02-01 7:14 ` [PATCH v1 4/7] perf thread: Add support for reading the e_machine type for a thread Ian Rogers
` (5 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
The syscalltbl held entries of system call name and number pairs,
generated from a native syscalltbl at start up. As there are gaps in
the system call number there is a notion of index into the
table. Going forward we want the system call table to be identifiable
by a machine type, for example, i386 vs x86-64. Change the interface
to the syscalltbl so (1) a (currently unused machine type of EM_HOST)
is passed (2) the index to syscall number and system call name mapping
is computed at build time.
Two tables are used for this, an array of system call number to name,
an array of system call numbers sorted by the system call name. The
sorted array doesn't store strings in part to save memory and
relocations. The index notion is carried forward and is an index into
the sorted array of system call numbers, the data structures are
opaque (held only in syscalltbl.c), and so the number of indices for a
machine type is exposed as a new API.
The arrays are computed in the syscalltbl.sh script and so no start-up
time computation and storage is necessary.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/builtin-trace.c | 88 +++++++++++++-----------
tools/perf/scripts/syscalltbl.sh | 36 ++++------
tools/perf/util/syscalltbl.c | 113 ++++++++++---------------------
tools/perf/util/syscalltbl.h | 22 ++----
4 files changed, 103 insertions(+), 156 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 10d3ad0d21f7..7e3aa2f6c5e2 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -143,7 +143,6 @@ struct syscall_fmt {
struct trace {
struct perf_tool tool;
- struct syscalltbl *sctbl;
struct {
/** Sorted sycall numbers used by the trace. */
struct syscall *table;
@@ -2100,7 +2099,7 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
return 0;
}
- name = syscalltbl__name(trace->sctbl, sc->id);
+ name = syscalltbl__name(sc->e_machine, sc->id);
if (name == NULL) {
sc->nonexistent = true;
return -EEXIST;
@@ -2196,10 +2195,14 @@ static int trace__validate_ev_qualifier(struct trace *trace)
strlist__for_each_entry(pos, trace->ev_qualifier) {
const char *sc = pos->s;
- int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
+ /*
+ * TODO: Assume more than the validation/warnings are all for
+ * the same binary type as perf.
+ */
+ int id = syscalltbl__id(EM_HOST, sc), match_next = -1;
if (id < 0) {
- id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
+ id = syscalltbl__strglobmatch_first(EM_HOST, sc, &match_next);
if (id >= 0)
goto matches;
@@ -2219,7 +2222,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
continue;
while (1) {
- id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
+ id = syscalltbl__strglobmatch_next(EM_HOST, sc, &match_next);
if (id < 0)
break;
if (nr_allocated == nr_used) {
@@ -2673,6 +2676,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
int augmented_args_size = 0;
void *augmented_args = NULL;
+ /* TODO: get e_machine from thread. */
struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
struct thread_trace *ttrace;
@@ -2747,6 +2751,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
struct thread_trace *ttrace;
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
+ /* TODO: get e_machine from thread. */
struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
char msg[1024];
void *args, *augmented_args = NULL;
@@ -2822,6 +2827,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
int alignment = trace->args_alignment;
+ /* TODO: get e_machine from thread. */
struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
struct thread_trace *ttrace;
@@ -3175,6 +3181,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
if (evsel == trace->syscalls.events.bpf_output) {
int id = perf_evsel__sc_tp_uint(evsel, id, sample);
+ /* TODO: get e_machine from thread. */
struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
if (sc) {
@@ -3678,9 +3685,9 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
return trace->skel->progs.syscall_unaugmented;
}
-static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
+static void trace__init_syscall_bpf_progs(struct trace *trace, int e_machine, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
if (sc == NULL)
return;
@@ -3689,22 +3696,22 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit");
}
-static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
+static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int e_machine, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
}
-static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
+static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int e_machine, int id)
{
- struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
+ struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
}
-static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
+static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int e_machine, int key, unsigned int *beauty_array)
{
struct tep_format_field *field;
- struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
+ struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
const struct btf_type *bt;
char *struct_offset, *tmp, name[32];
bool can_augment = false;
@@ -3800,9 +3807,9 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
return NULL;
try_to_find_pair:
- for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
- int id = syscalltbl__id_at_idx(trace->sctbl, i);
- struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
+ for (int i = 0, num_idx = syscalltbl__num_idx(sc->e_machine); i < num_idx; ++i) {
+ int id = syscalltbl__id_at_idx(sc->e_machine, i);
+ struct syscall *pair = trace__syscall_info(trace, NULL, sc->e_machine, id);
struct bpf_program *pair_prog;
bool is_candidate = false;
@@ -3886,7 +3893,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
return NULL;
}
-static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
+static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace, int e_machine)
{
int map_enter_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_enter);
int map_exit_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_exit);
@@ -3894,27 +3901,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
int err = 0;
unsigned int beauty_array[6];
- for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
- int prog_fd, key = syscalltbl__id_at_idx(trace->sctbl, i);
+ for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
+ int prog_fd, key = syscalltbl__id_at_idx(e_machine, i);
if (!trace__syscall_enabled(trace, key))
continue;
- trace__init_syscall_bpf_progs(trace, key);
+ trace__init_syscall_bpf_progs(trace, e_machine, key);
// It'll get at least the "!raw_syscalls:unaugmented"
- prog_fd = trace__bpf_prog_sys_enter_fd(trace, key);
+ prog_fd = trace__bpf_prog_sys_enter_fd(trace, e_machine, key);
err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY);
if (err)
break;
- prog_fd = trace__bpf_prog_sys_exit_fd(trace, key);
+ prog_fd = trace__bpf_prog_sys_exit_fd(trace, e_machine, key);
err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY);
if (err)
break;
/* use beauty_map to tell BPF how many bytes to collect, set beauty_map's value here */
memset(beauty_array, 0, sizeof(beauty_array));
- err = trace__bpf_sys_enter_beauty_map(trace, key, (unsigned int *)beauty_array);
+ err = trace__bpf_sys_enter_beauty_map(trace, e_machine, key, (unsigned int *)beauty_array);
if (err)
continue;
err = bpf_map_update_elem(beauty_map_fd, &key, beauty_array, BPF_ANY);
@@ -3950,9 +3957,9 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
* first and second arg (this one on the raw_syscalls:sys_exit prog
* array tail call, then that one will be used.
*/
- for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
- int key = syscalltbl__id_at_idx(trace->sctbl, i);
- struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
+ for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
+ int key = syscalltbl__id_at_idx(e_machine, i);
+ struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
struct bpf_program *pair_prog;
int prog_fd;
@@ -4389,8 +4396,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
goto out_error_mem;
#ifdef HAVE_BPF_SKEL
- if (trace->skel && trace->skel->progs.sys_enter)
- trace__init_syscalls_bpf_prog_array_maps(trace);
+ if (trace->skel && trace->skel->progs.sys_enter) {
+ /*
+ * TODO: Initialize for all host binary machine types, not just
+ * those matching the perf binary.
+ */
+ trace__init_syscalls_bpf_prog_array_maps(trace, EM_HOST);
+ }
#endif
if (trace->ev_qualifier_ids.nr > 0) {
@@ -4415,7 +4427,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
* So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is
* not in use.
*/
- trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close"));
+ /* TODO: support for more than just perf binary machine type close. */
+ trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(EM_HOST, "close"));
err = trace__expand_filters(trace, &evsel);
if (err)
@@ -4688,8 +4701,7 @@ DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs,
entry->msecs = stats ? (u64)stats->stats.n * (avg_stats(&stats->stats) / NSEC_PER_MSEC) : 0;
}
-static size_t thread__dump_stats(struct thread_trace *ttrace,
- struct trace *trace, FILE *fp)
+static size_t thread__dump_stats(struct thread_trace *ttrace, struct trace *trace, int e_machine, FILE *fp)
{
size_t printed = 0;
struct syscall *sc;
@@ -4717,7 +4729,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
avg /= NSEC_PER_MSEC;
- sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
+ sc = trace__syscall_info(trace, /*evsel=*/NULL, e_machine,
syscall_stats_entry->syscall);
if (!sc)
continue;
@@ -4767,7 +4779,8 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
else if (fputc('\n', fp) != EOF)
++printed;
- printed += thread__dump_stats(ttrace, trace, fp);
+ /* TODO: get e_machine from thread. */
+ printed += thread__dump_stats(ttrace, trace, EM_HOST, fp);
return printed;
}
@@ -4999,8 +5012,9 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
*sep = '\0';
list = 0;
- if (syscalltbl__id(trace->sctbl, s) >= 0 ||
- syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
+ /* TODO: support for more than just perf binary machine type syscalls. */
+ if (syscalltbl__id(EM_HOST, s) >= 0 ||
+ syscalltbl__strglobmatch_first(EM_HOST, s, &idx) >= 0) {
list = 1;
goto do_concat;
}
@@ -5136,7 +5150,6 @@ static void trace__exit(struct trace *trace)
syscall__exit(&trace->syscalls.table[i]);
zfree(&trace->syscalls.table);
}
- syscalltbl__delete(trace->sctbl);
zfree(&trace->perfconfig_events);
}
@@ -5282,9 +5295,8 @@ int cmd_trace(int argc, const char **argv)
sigaction(SIGCHLD, &sigchld_act, NULL);
trace.evlist = evlist__new();
- trace.sctbl = syscalltbl__new();
- if (trace.evlist == NULL || trace.sctbl == NULL) {
+ if (trace.evlist == NULL) {
pr_err("Not enough memory to run!\n");
err = -ENOMEM;
goto out;
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
index 1ce0d5aa8b50..a39b3013b103 100755
--- a/tools/perf/scripts/syscalltbl.sh
+++ b/tools/perf/scripts/syscalltbl.sh
@@ -50,37 +50,27 @@ fi
infile="$1"
outfile="$2"
-nxt=0
-
-syscall_macro() {
- nr="$1"
- name="$2"
-
- echo " [$nr] = \"$name\","
-}
-
-emit() {
- nr="$1"
- entry="$2"
-
- syscall_macro "$nr" "$entry"
-}
-
-echo "static const char *const syscalltbl[] = {" > $outfile
-
sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
-max_nr=0
+echo "static const char *const syscall_num_to_name[] = {" > $outfile
# the params are: nr abi name entry compat
# use _ for intentionally unused variables according to SC2034
while read nr _ name _ _; do
- emit "$nr" "$name" >> $outfile
- max_nr=$nr
+ echo " [$nr] = \"$name\"," >> $outfile
done < $sorted_table
+echo "};" >> $outfile
-rm -f $sorted_table
+echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile
+# When sorting by name, add a suffix of 0s upto 20 characters so that system
+# calls that differ with a numerical suffix don't sort before those
+# without. This default behavior of sort differs from that of strcmp used at
+# runtime. Use sed to strip the trailing 0s suffix afterwards.
+grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table
+while read name nr; do
+ echo " $nr, /* $name */" >> $outfile
+done < $sorted_table
echo "};" >> $outfile
-echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
+rm -f $sorted_table
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 2f76241494c8..760ac4d0869f 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <asm/bitsperlong.h>
#include <linux/compiler.h>
+#include <linux/kernel.h>
#include <linux/zalloc.h>
#include <string.h>
@@ -20,112 +21,66 @@
#include <asm/syscalls_32.h>
#endif
-const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl;
+const char *syscalltbl__name(int e_machine __maybe_unused, int id)
+{
+ if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
+ return syscall_num_to_name[id];
+ return NULL;
+}
-struct syscall {
- int id;
+struct syscall_cmp_key {
const char *name;
+ const char *const *tbl;
};
static int syscallcmpname(const void *vkey, const void *ventry)
{
- const char *key = vkey;
- const struct syscall *entry = ventry;
+ const struct syscall_cmp_key *key = vkey;
+ const uint16_t *entry = ventry;
- return strcmp(key, entry->name);
+ return strcmp(key->name, key->tbl[*entry]);
}
-static int syscallcmp(const void *va, const void *vb)
+int syscalltbl__id(int e_machine __maybe_unused, const char *name)
{
- const struct syscall *a = va, *b = vb;
-
- return strcmp(a->name, b->name);
+ struct syscall_cmp_key key = {
+ .name = name,
+ .tbl = syscall_num_to_name,
+ };
+ const int *id = bsearch(&key, syscall_sorted_names,
+ ARRAY_SIZE(syscall_sorted_names),
+ sizeof(syscall_sorted_names[0]),
+ syscallcmpname);
+
+ return id ? *id : -1;
}
-static int syscalltbl__init_native(struct syscalltbl *tbl)
+int syscalltbl__num_idx(int e_machine __maybe_unused)
{
- int nr_entries = 0, i, j;
- struct syscall *entries;
-
- for (i = 0; i <= syscalltbl_native_max_id; ++i)
- if (syscalltbl_native[i])
- ++nr_entries;
-
- entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
- if (tbl->syscalls.entries == NULL)
- return -1;
-
- for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
- if (syscalltbl_native[i]) {
- entries[j].name = syscalltbl_native[i];
- entries[j].id = i;
- ++j;
- }
- }
-
- qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
- tbl->syscalls.nr_entries = nr_entries;
- tbl->syscalls.max_id = syscalltbl_native_max_id;
- return 0;
+ return ARRAY_SIZE(syscall_sorted_names);
}
-struct syscalltbl *syscalltbl__new(void)
+int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
{
- struct syscalltbl *tbl = malloc(sizeof(*tbl));
- if (tbl) {
- if (syscalltbl__init_native(tbl)) {
- free(tbl);
- return NULL;
- }
- }
- return tbl;
-}
-
-void syscalltbl__delete(struct syscalltbl *tbl)
-{
- zfree(&tbl->syscalls.entries);
- free(tbl);
-}
-
-const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
-{
- return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
-}
-
-int syscalltbl__id(struct syscalltbl *tbl, const char *name)
-{
- struct syscall *sc = bsearch(name, tbl->syscalls.entries,
- tbl->syscalls.nr_entries, sizeof(*sc),
- syscallcmpname);
-
- return sc ? sc->id : -1;
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx)
-{
- struct syscall *syscalls = tbl->syscalls.entries;
-
- return idx < tbl->syscalls.nr_entries ? syscalls[idx].id : -1;
+ return syscall_sorted_names[idx];
}
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
{
- int i;
- struct syscall *syscalls = tbl->syscalls.entries;
+ for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
+ const char *name = syscall_num_to_name[syscall_sorted_names[i]];
- for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
- if (strglobmatch(syscalls[i].name, syscall_glob)) {
+ if (strglobmatch(name, syscall_glob)) {
*idx = i;
- return syscalls[i].id;
+ return syscall_sorted_names[i];
}
}
return -1;
}
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx)
{
*idx = -1;
- return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
+ return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx);
}
diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
index 362411a6d849..2bb628eff367 100644
--- a/tools/perf/util/syscalltbl.h
+++ b/tools/perf/util/syscalltbl.h
@@ -2,22 +2,12 @@
#ifndef __PERF_SYSCALLTBL_H
#define __PERF_SYSCALLTBL_H
-struct syscalltbl {
- struct {
- int max_id;
- int nr_entries;
- void *entries;
- } syscalls;
-};
+const char *syscalltbl__name(int e_machine, int id);
+int syscalltbl__id(int e_machine, const char *name);
+int syscalltbl__num_idx(int e_machine);
+int syscalltbl__id_at_idx(int e_machine, int idx);
-struct syscalltbl *syscalltbl__new(void);
-void syscalltbl__delete(struct syscalltbl *tbl);
-
-const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
-int syscalltbl__id(struct syscalltbl *tbl, const char *name);
-int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx);
-
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
+int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx);
+int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx);
#endif /* __PERF_SYSCALLTBL_H */
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 4/7] perf thread: Add support for reading the e_machine type for a thread
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (2 preceding siblings ...)
2025-02-01 7:14 ` [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 5/7] perf trace beauty: Add syscalltbl.sh generating all system call tables Ian Rogers
` (4 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
Use the executable from /proc/pid/exe and read the e_machine from the
ELF header. On failure use EM_HOST. Change builtin-trace syscall
functions to pass e_machine from the thread rather than EM_HOST, so
that in later patches when syscalltbl can use the e_machine the system
calls are specific to the architecture.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/builtin-trace.c | 41 ++++++++++++++++---------------
tools/perf/util/thread.c | 50 ++++++++++++++++++++++++++++++++++++++
tools/perf/util/thread.h | 14 ++++++++++-
3 files changed, 85 insertions(+), 20 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7e3aa2f6c5e2..d60db6a23852 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2674,16 +2674,17 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
int printed = 0;
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
- int augmented_args_size = 0;
+ int augmented_args_size = 0, e_machine;
void *augmented_args = NULL;
/* TODO: get e_machine from thread. */
- struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
+ struct syscall *sc;
struct thread_trace *ttrace;
- if (sc == NULL)
- return -1;
-
thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+ e_machine = thread__e_machine(thread, trace->host);
+ sc = trace__syscall_info(trace, evsel, e_machine, id);
+ if (sc == NULL)
+ goto out_put;
ttrace = thread__trace(thread, trace->output);
if (ttrace == NULL)
goto out_put;
@@ -2752,16 +2753,18 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
/* TODO: get e_machine from thread. */
- struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
+ struct syscall *sc;
char msg[1024];
void *args, *augmented_args = NULL;
- int augmented_args_size;
+ int augmented_args_size, e_machine;
size_t printed = 0;
- if (sc == NULL)
- return -1;
thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+ e_machine = thread__e_machine(thread, trace->host);
+ sc = trace__syscall_info(trace, evsel, e_machine, id);
+ if (sc == NULL)
+ return -1;
ttrace = thread__trace(thread, trace->output);
/*
* We need to get ttrace just to make sure it is there when syscall__scnprintf_args()
@@ -2826,15 +2829,15 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
bool duration_calculated = false;
struct thread *thread;
int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
- int alignment = trace->args_alignment;
- /* TODO: get e_machine from thread. */
- struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
+ int alignment = trace->args_alignment, e_machine;
+ struct syscall *sc;
struct thread_trace *ttrace;
- if (sc == NULL)
- return -1;
-
thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+ e_machine = thread__e_machine(thread, trace->host);
+ sc = trace__syscall_info(trace, evsel, e_machine, id);
+ if (sc == NULL)
+ goto out_put;
ttrace = thread__trace(thread, trace->output);
if (ttrace == NULL)
goto out_put;
@@ -3181,8 +3184,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
if (evsel == trace->syscalls.events.bpf_output) {
int id = perf_evsel__sc_tp_uint(evsel, id, sample);
- /* TODO: get e_machine from thread. */
- struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
+ int e_machine = thread ? thread__e_machine(thread, trace->host) : EM_HOST;
+ struct syscall *sc = trace__syscall_info(trace, evsel, e_machine, id);
if (sc) {
fprintf(trace->output, "%s(", sc->name);
@@ -4760,6 +4763,7 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
{
size_t printed = 0;
struct thread_trace *ttrace = thread__priv(thread);
+ int e_machine = thread__e_machine(thread, trace->host);
double ratio;
if (ttrace == NULL)
@@ -4779,8 +4783,7 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
else if (fputc('\n', fp) != EOF)
++printed;
- /* TODO: get e_machine from thread. */
- printed += thread__dump_stats(ttrace, trace, EM_HOST, fp);
+ printed += thread__dump_stats(ttrace, trace, e_machine, fp);
return printed;
}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 0ffdd52d86d7..a07446a280ed 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
+#include <elf.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -16,6 +18,7 @@
#include "symbol.h"
#include "unwind.h"
#include "callchain.h"
+#include "dwarf-regs.h"
#include <api/fs/fs.h>
@@ -51,6 +54,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
thread__set_ppid(thread, -1);
thread__set_cpu(thread, -1);
thread__set_guest_cpu(thread, -1);
+ thread__set_e_machine(thread, EM_NONE);
thread__set_lbr_stitch_enable(thread, false);
INIT_LIST_HEAD(thread__namespaces_list(thread));
INIT_LIST_HEAD(thread__comm_list(thread));
@@ -423,6 +427,52 @@ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
}
}
+static uint16_t read_proc_e_machine_for_pid(pid_t pid)
+{
+ char path[6 /* "/proc/" */ + 11 /* max length of pid */ + 5 /* "/exe\0" */];
+ int fd;
+ uint16_t e_machine = EM_NONE;
+
+ snprintf(path, sizeof(path), "/proc/%d/exe", pid);
+ fd = open(path, O_RDONLY);
+ if (fd >= 0) {
+ _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset");
+ _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset");
+ if (pread(fd, &e_machine, sizeof(e_machine), 18) != sizeof(e_machine))
+ e_machine = EM_NONE;
+ close(fd);
+ }
+ return e_machine;
+}
+
+uint16_t thread__e_machine(struct thread *thread, struct machine *machine)
+{
+ pid_t tid, pid;
+ uint16_t e_machine = RC_CHK_ACCESS(thread)->e_machine;
+
+ if (e_machine != EM_NONE)
+ return e_machine;
+
+ tid = thread__tid(thread);
+ pid = thread__pid(thread);
+ if (pid != tid) {
+ struct thread *parent = machine__findnew_thread(machine, pid, pid);
+
+ if (parent) {
+ e_machine = thread__e_machine(parent, machine);
+ thread__set_e_machine(thread, e_machine);
+ return e_machine;
+ }
+ /* Something went wrong, fallback. */
+ }
+ e_machine = read_proc_e_machine_for_pid(pid);
+ if (e_machine != EM_NONE)
+ thread__set_e_machine(thread, e_machine);
+ else
+ e_machine = EM_HOST;
+ return e_machine;
+}
+
struct thread *thread__main_thread(struct machine *machine, struct thread *thread)
{
if (thread__pid(thread) == thread__tid(thread))
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 6cbf6eb2812e..cd574a896418 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -60,7 +60,11 @@ DECLARE_RC_STRUCT(thread) {
struct srccode_state srccode_state;
bool filter;
int filter_entry_depth;
-
+ /**
+ * @e_machine: The ELF EM_* associated with the thread. EM_NONE if not
+ * computed.
+ */
+ uint16_t e_machine;
/* LBR call stack stitch */
bool lbr_stitch_enable;
struct lbr_stitch *lbr_stitch;
@@ -302,6 +306,14 @@ static inline void thread__set_filter_entry_depth(struct thread *thread, int dep
RC_CHK_ACCESS(thread)->filter_entry_depth = depth;
}
+uint16_t thread__e_machine(struct thread *thread, struct machine *machine);
+
+static inline void thread__set_e_machine(struct thread *thread, uint16_t e_machine)
+{
+ RC_CHK_ACCESS(thread)->e_machine = e_machine;
+}
+
+
static inline bool thread__lbr_stitch_enable(const struct thread *thread)
{
return RC_CHK_ACCESS(thread)->lbr_stitch_enable;
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 5/7] perf trace beauty: Add syscalltbl.sh generating all system call tables
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (3 preceding siblings ...)
2025-02-01 7:14 ` [PATCH v1 4/7] perf thread: Add support for reading the e_machine type for a thread Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures Ian Rogers
` (3 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
Rather than generating individual syscall header files generate a
single trace/beauty/generated/syscalltbl.c. In a syscalltbls array
have references to each architectures tables along with the
corresponding e_machine. When the 32-bit or 64-bit table is ambiguous,
match the perf binary's type. For ARM32 don't use the arm64 32-bit
table which is smaller. EM_NONE is present for is no machine matches.
Conditionally compile the tables, only having the appropriate 32 and
64-bit table. If ALL_SYSCALLTBL is defined all tables can be
compiled.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/Makefile.perf | 9 +
tools/perf/trace/beauty/syscalltbl.sh | 274 ++++++++++++++++++++++++++
2 files changed, 283 insertions(+)
create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 55d6ce9ea52f..793e702f9aaf 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -559,6 +559,14 @@ beauty_ioctl_outdir := $(beauty_outdir)/ioctl
# Create output directory if not already present
$(shell [ -d '$(beauty_ioctl_outdir)' ] || mkdir -p '$(beauty_ioctl_outdir)')
+syscall_array := $(beauty_outdir)/syscalltbl.c
+syscall_tbl := $(srctree)/tools/perf/trace/beauty/syscalltbl.sh
+syscall_tbl_data := $(srctree)/tools/scripts/syscall.tbl \
+ $(wildcard $(srctree)/tools/perf/arch/*/entry/syscalls/syscall*.tbl)
+
+$(syscall_array): $(syscall_tbl) $(syscall_tbl_data)
+ $(Q)$(SHELL) '$(syscall_tbl)' $(srctree)/tools $@
+
fs_at_flags_array := $(beauty_outdir)/fs_at_flags_array.c
fs_at_flags_tbl := $(srctree)/tools/perf/trace/beauty/fs_at_flags.sh
@@ -878,6 +886,7 @@ build-dir = $(or $(__build-dir),.)
prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders \
arm64-sysreg-defs \
+ $(syscall_array) \
$(fs_at_flags_array) \
$(clone_flags_array) \
$(drm_ioctl_array) \
diff --git a/tools/perf/trace/beauty/syscalltbl.sh b/tools/perf/trace/beauty/syscalltbl.sh
new file mode 100755
index 000000000000..635924dc5f59
--- /dev/null
+++ b/tools/perf/trace/beauty/syscalltbl.sh
@@ -0,0 +1,274 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate all syscall tables.
+#
+# Each line of the syscall table should have the following format:
+#
+# NR ABI NAME [NATIVE] [COMPAT]
+#
+# NR syscall number
+# ABI ABI name
+# NAME syscall name
+# NATIVE native entry point (optional)
+# COMPAT compat entry point (optional)
+
+set -e
+
+usage() {
+ cat >&2 <<EOF
+usage: $0 <TOOLS DIRECTORY> <OUTFILE>
+
+ <TOOLS DIRECTORY> path to kernel tools directory
+ <OUTFILE> output header file
+EOF
+ exit 1
+}
+
+if [ $# -ne 2 ]; then
+ usage
+fi
+tools_dir=$1
+outfile=$2
+
+build_tables() {
+ infile="$1"
+ outfile="$2"
+ abis=$(echo "($3)" | tr ',' '|')
+ e_machine="$4"
+
+ if [ ! -f "$infile" ]
+ then
+ echo "Missing file $infile"
+ exit 1
+ fi
+ sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
+ grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > "$sorted_table"
+
+ echo "static const char *const syscall_num_to_name_${e_machine}[] = {" >> "$outfile"
+ # the params are: nr abi name entry compat
+ # use _ for intentionally unused variables according to SC2034
+ while read -r nr _ name _ _; do
+ echo " [$nr] = \"$name\"," >> "$outfile"
+ done < "$sorted_table"
+ echo "};" >> "$outfile"
+
+ echo "static const uint16_t syscall_sorted_names_${e_machine}[] = {" >> "$outfile"
+
+ # When sorting by name, add a suffix of 0s upto 20 characters so that
+ # system calls that differ with a numerical suffix don't sort before
+ # those without. This default behavior of sort differs from that of
+ # strcmp used at runtime. Use sed to strip the trailing 0s suffix
+ # afterwards.
+ grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > "$sorted_table"
+ while read -r name nr; do
+ echo " $nr, /* $name */" >> "$outfile"
+ done < "$sorted_table"
+ echo "};" >> "$outfile"
+
+ rm -f "$sorted_table"
+}
+
+rm -f "$outfile"
+cat >> "$outfile" <<EOF
+#include <elf.h>
+#include <stdint.h>
+#include <asm/bitsperlong.h>
+#include <linux/kernel.h>
+
+struct syscalltbl {
+ const char *const *num_to_name;
+ const uint16_t *sorted_names;
+ uint16_t e_machine;
+ uint16_t num_to_name_len;
+ uint16_t sorted_names_len;
+};
+
+#if defined(ALL_SYSCALLTBL) || defined(__alpha__)
+EOF
+build_tables "$tools_dir/perf/arch/alpha/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_ALPHA
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__alpha__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__)
+EOF
+build_tables "$tools_dir/perf/arch/arm/entry/syscalls/syscall.tbl" "$outfile" common,32,oabi EM_ARM
+build_tables "$tools_dir/perf/arch/arm64/entry/syscalls/syscall_64.tbl" "$outfile" common,64,renameat,rlimit,memfd_secret EM_AARCH64
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__csky__)
+EOF
+build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32,csky,time32,stat64,rlimit EM_CSKY
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__csky__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__mips__)
+EOF
+build_tables "$tools_dir/perf/arch/mips/entry/syscalls/syscall_n64.tbl" "$outfile" common,64,n64 EM_MIPS
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__mips__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__hppa__)
+#if __BITS_PER_LONG != 64
+EOF
+build_tables "$tools_dir/perf/arch/parisc/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_PARISC
+echo "#else" >> "$outfile"
+build_tables "$tools_dir/perf/arch/parisc/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_PARISC
+cat >> "$outfile" <<EOF
+#endif //__BITS_PER_LONG != 64
+#endif // defined(ALL_SYSCALLTBL) || defined(__hppa__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__)
+EOF
+build_tables "$tools_dir/perf/arch/powerpc/entry/syscalls/syscall.tbl" "$outfile" common,32,nospu EM_PPC
+build_tables "$tools_dir/perf/arch/powerpc/entry/syscalls/syscall.tbl" "$outfile" common,64,nospu EM_PPC64
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__riscv)
+#if __BITS_PER_LONG != 64
+EOF
+build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32,riscv,memfd_secret EM_RISCV
+echo "#else" >> "$outfile"
+build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,64,riscv,rlimit,memfd_secret EM_RISCV
+cat >> "$outfile" <<EOF
+#endif //__BITS_PER_LONG != 64
+#endif // defined(ALL_SYSCALLTBL) || defined(__riscv)
+#if defined(ALL_SYSCALLTBL) || defined(__s390x__)
+EOF
+build_tables "$tools_dir/perf/arch/s390/entry/syscalls/syscall.tbl" "$outfile" common,64,renameat,rlimit,memfd_secret EM_S390
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__s390x__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__sh__)
+EOF
+build_tables "$tools_dir/perf/arch/sh/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_SH
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__sh__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__)
+#if __BITS_PER_LONG != 64
+EOF
+build_tables "$tools_dir/perf/arch/sparc/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_SPARC
+echo "#else" >> "$outfile"
+build_tables "$tools_dir/perf/arch/sparc/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_SPARC
+cat >> "$outfile" <<EOF
+#endif //__BITS_PER_LONG != 64
+#endif // defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__)
+EOF
+build_tables "$tools_dir/perf/arch/x86/entry/syscalls/syscall_32.tbl" "$outfile" common,32,i386 EM_386
+build_tables "$tools_dir/perf/arch/x86/entry/syscalls/syscall_64.tbl" "$outfile" common,64 EM_X86_64
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__xtensa__)
+EOF
+build_tables "$tools_dir/perf/arch/xtensa/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_XTENSA
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__xtensa__)
+
+#if __BITS_PER_LONG != 64
+EOF
+build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32 EM_NONE
+echo "#else" >> "$outfile"
+build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,64 EM_NONE
+echo "#endif //__BITS_PER_LONG != 64" >> "$outfile"
+
+build_outer_table() {
+ e_machine=$1
+ outfile="$2"
+ cat >> "$outfile" <<EOF
+ {
+ .num_to_name = syscall_num_to_name_$e_machine,
+ .sorted_names = syscall_sorted_names_$e_machine,
+ .e_machine = $e_machine,
+ .num_to_name_len = ARRAY_SIZE(syscall_num_to_name_$e_machine),
+ .sorted_names_len = ARRAY_SIZE(syscall_sorted_names_$e_machine),
+ },
+EOF
+}
+
+cat >> "$outfile" <<EOF
+static const struct syscalltbl syscalltbls[] = {
+#if defined(ALL_SYSCALLTBL) || defined(__alpha__)
+EOF
+build_outer_table EM_ALPHA "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__alpha__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__)
+EOF
+build_outer_table EM_ARM "$outfile"
+build_outer_table EM_AARCH64 "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__csky__)
+EOF
+build_outer_table EM_CSKY "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__csky__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__mips__)
+EOF
+build_outer_table EM_MIPS "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__mips__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__hppa__)
+EOF
+build_outer_table EM_PARISC "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__hppa__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__)
+EOF
+build_outer_table EM_PPC "$outfile"
+build_outer_table EM_PPC64 "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__riscv)
+EOF
+build_outer_table EM_RISCV "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__riscv)
+
+#if defined(ALL_SYSCALLTBL) || defined(__s390x__)
+EOF
+build_outer_table EM_S390 "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__s390x__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__sh__)
+EOF
+build_outer_table EM_SH "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__sh__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__)
+EOF
+build_outer_table EM_SPARC "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__)
+EOF
+build_outer_table EM_386 "$outfile"
+build_outer_table EM_X86_64 "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__)
+
+#if defined(ALL_SYSCALLTBL) || defined(__xtensa__)
+EOF
+build_outer_table EM_XTENSA "$outfile"
+cat >> "$outfile" <<EOF
+#endif // defined(ALL_SYSCALLTBL) || defined(__xtensa__)
+EOF
+build_outer_table EM_NONE "$outfile"
+cat >> "$outfile" <<EOF
+};
+EOF
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (4 preceding siblings ...)
2025-02-01 7:14 ` [PATCH v1 5/7] perf trace beauty: Add syscalltbl.sh generating all system call tables Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-05 0:24 ` Howard Chu
2025-02-01 7:14 ` [PATCH v1 7/7] perf build: Remove Makefile.syscalls Ian Rogers
` (2 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
Switch to use the lookup table containing all architectures rather
than tables matching the perf binary.
This fixes perf trace when executed on a 32-bit i386 binary on an
x86-64 machine. Note in the following the system call names of the
32-bit i386 binary as seen by an x86-64 perf.
Before:
```
? ( ): a.out/447296 ... [continued]: munmap()) = 0
0.024 ( 0.001 ms): a.out/447296 recvfrom(ubuf: 0x2, size: 4160585708, flags: DONTROUTE|CTRUNC|TRUNC|DONTWAIT|EOR|WAITALL|FIN|SYN|CONFIRM|RST|ERRQUEUE|NOSIGNAL|WAITFORONE|BATCH|SOCK_DEVMEM|ZEROCOPY|FASTOPEN|CMSG_CLOEXEC|0x91f80000, addr: 0xe30, addr_len: 0xffce438c) = 1475198976
0.042 ( 0.003 ms): a.out/447296 lgetxattr(name: "", value: 0x3, size: 34) = 4160344064
0.054 ( 0.003 ms): a.out/447296 dup2(oldfd: -134422744, newfd: 4) = -1 ENOENT (No such file or directory)
0.060 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x2e646c2f6374652f,.iov_len = (__kernel_size_t)7307199665335594867,}, vlen: 557056, pos_h: 4160585708) = 3
0.074 ( 0.004 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2) = 4160237568
0.080 ( 0.001 ms): a.out/447296 lstat(filename: "", statbuf: 0x193f6) = 0
0.089 ( 0.007 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x3833692f62696c2f,.iov_len = (__kernel_size_t)3276497845987585334,}, vlen: 557056, pos_h: 4160585708) = 3
0.097 ( 0.002 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 512
0.103 ( 0.002 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2050) = 4157935616
0.107 ( 0.007 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x5, size: 2066) = 4158078976
0.116 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x1, size: 2066) = 4159639552
0.121 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 2066) = 4160184320
0.129 ( 0.002 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 50) = 4160196608
0.138 ( 0.001 ms): a.out/447296 lstat(filename: "") = 0
0.145 ( 0.002 ms): a.out/447296 mq_timedreceive(mqdes: 4291706800, u_msg_ptr: 0xf7f9ea48, msg_len: 134616640, u_msg_prio: 0xf7fd7fec, u_abs_timeout: (struct __kernel_timespec){.tv_sec = (__kernel_time64_t)-578174027777317696,.tv_nsec = (long long int)4160349376,}) = 0
0.148 ( 0.001 ms): a.out/447296 mkdirat(dfd: -134617816, pathname: " ��� ���▒���▒���", mode: IFREG|ISUID|IRUSR|IWGRP|0xf7fd0000) = 447296
0.150 ( 0.001 ms): a.out/447296 process_vm_writev(pid: -134617812, lvec: (struct iovec){.iov_base = (void *)0xf7f9e9c8f7f9e4c0,.iov_len = (__kernel_size_t)4160349376,}, liovcnt: 4160588048, rvec: (struct iovec){}, riovcnt: 4160585708, flags: 4291707352) = 0
0.197 ( 0.004 ms): a.out/447296 capget(header: 4160184320, dataptr: 8192) = 0
0.202 ( 0.002 ms): a.out/447296 capget(header: 1448669184, dataptr: 4096) = 0
0.208 ( 0.002 ms): a.out/447296 capget(header: 4160577536, dataptr: 8192) = 0
0.220 ( 0.001 ms): a.out/447296 getxattr(pathname: "", name: "c������", value: 0xf7f77e34, size: 1) = 0
0.228 ( 0.005 ms): a.out/447296 fchmod(fd: -134729728, mode: IRUGO|IWUGO|IFREG|IFIFO|ISVTX|IXUSR|0x10000) = 0
0.240 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: 0x5658e008, pos_h: 4160192052) = 3
0.250 ( 0.008 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 1436
0.260 ( 0.018 ms): a.out/447296 stat(filename: "", statbuf: 0xffce32ac) = 1436
0.288 (1000.213 ms): a.out/447296 readlinkat(buf: 0xffce31d4, bufsiz: 4291703244) = 0
```
After:
```
? ( ): a.out/442930 ... [continued]: execve()) = 0
0.023 ( 0.002 ms): a.out/442930 brk() = 0x57760000
0.052 ( 0.003 ms): a.out/442930 access(filename: 0xf7f5af28, mode: R) = -1 ENOENT (No such file or directory)
0.059 ( 0.009 ms): a.out/442930 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
0.078 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
0.087 ( 0.007 ms): a.out/442930 openat(dfd: CWD, filename: "/lib/i386-linux-", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
0.095 ( 0.002 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdbb70, count: 512) = 512
0.135 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
0.148 ( 0.001 ms): a.out/442930 set_tid_address(tidptr: 0xf7f2b528) = 442930 (a.out)
0.150 ( 0.001 ms): a.out/442930 set_robust_list(head: 0xf7f2b52c, len: 12) =
0.196 ( 0.004 ms): a.out/442930 mprotect(start: 0xf7f03000, len: 8192, prot: READ) = 0
0.202 ( 0.002 ms): a.out/442930 mprotect(start: 0x5658e000, len: 4096, prot: READ) = 0
0.207 ( 0.002 ms): a.out/442930 mprotect(start: 0xf7f63000, len: 8192, prot: READ) = 0
0.230 ( 0.005 ms): a.out/442930 munmap(addr: 0xf7f10000, len: 103414) = 0
0.244 ( 0.010 ms): a.out/442930 openat(dfd: CWD, filename: 0x5658d008) = 3
0.255 ( 0.007 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdb67c, count: 4096) = 1436
0.264 ( 0.018 ms): a.out/442930 write(fd: 1</dev/pts/4>, buf: , count: 1436) = 1436
0.292 (1000.173 ms): a.out/442930 clock_nanosleep(rqtp: { .tv_sec: 17866546940376776704, .tv_nsec: 4159878336 }, rmtp: 0xffbdb59c) = 0
1000.478 ( ): a.out/442930 exit_group() = ?
```
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/syscalltbl.c | 89 ++++++++++++++++++++++++++----------
1 file changed, 64 insertions(+), 25 deletions(-)
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 760ac4d0869f..572083ba1efe 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -15,16 +15,39 @@
#include <string.h>
#include "string2.h"
-#if __BITS_PER_LONG == 64
- #include <asm/syscalls_64.h>
-#else
- #include <asm/syscalls_32.h>
-#endif
+#include "trace/beauty/generated/syscalltbl.c"
-const char *syscalltbl__name(int e_machine __maybe_unused, int id)
+static const struct syscalltbl *find_table(int e_machine)
{
- if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
- return syscall_num_to_name[id];
+ static const struct syscalltbl *last_table;
+ static int last_table_machine = EM_NONE;
+
+ /* Tables only exist for EM_SPARC. */
+ if (e_machine == EM_SPARCV9)
+ e_machine = EM_SPARC;
+
+ if (last_table_machine == e_machine && e_machine != EM_NONE)
+ return last_table;
+
+ for (size_t i = 0; i < ARRAY_SIZE(syscalltbls); i++) {
+ const struct syscalltbl *entry = &syscalltbls[i];
+
+ if (entry->e_machine != e_machine && entry->e_machine != EM_NONE)
+ continue;
+
+ last_table = entry;
+ last_table_machine = e_machine;
+ return entry;
+ }
+ return NULL;
+}
+
+const char *syscalltbl__name(int e_machine, int id)
+{
+ const struct syscalltbl *table = find_table(e_machine);
+
+ if (table && id >= 0 && id < table->num_to_name_len)
+ return table->num_to_name[id];
return NULL;
}
@@ -41,38 +64,54 @@ static int syscallcmpname(const void *vkey, const void *ventry)
return strcmp(key->name, key->tbl[*entry]);
}
-int syscalltbl__id(int e_machine __maybe_unused, const char *name)
+int syscalltbl__id(int e_machine, const char *name)
{
- struct syscall_cmp_key key = {
- .name = name,
- .tbl = syscall_num_to_name,
- };
- const int *id = bsearch(&key, syscall_sorted_names,
- ARRAY_SIZE(syscall_sorted_names),
- sizeof(syscall_sorted_names[0]),
- syscallcmpname);
+ const struct syscalltbl *table = find_table(e_machine);
+ struct syscall_cmp_key key;
+ const int *id;
+
+ if (!table)
+ return -1;
+
+ key.name = name;
+ key.tbl = table->num_to_name;
+ id = bsearch(&key, table->sorted_names, table->sorted_names_len,
+ sizeof(table->sorted_names[0]), syscallcmpname);
return id ? *id : -1;
}
-int syscalltbl__num_idx(int e_machine __maybe_unused)
+int syscalltbl__num_idx(int e_machine)
{
- return ARRAY_SIZE(syscall_sorted_names);
+ const struct syscalltbl *table = find_table(e_machine);
+
+ if (!table)
+ return 0;
+
+ return table->sorted_names_len;
}
-int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
+int syscalltbl__id_at_idx(int e_machine, int idx)
{
- return syscall_sorted_names[idx];
+ const struct syscalltbl *table = find_table(e_machine);
+
+ if (!table)
+ return -1;
+
+ assert(idx >= 0 && idx < table->sorted_names_len);
+ return table->sorted_names[idx];
}
-int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
+int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx)
{
- for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
- const char *name = syscall_num_to_name[syscall_sorted_names[i]];
+ const struct syscalltbl *table = find_table(e_machine);
+
+ for (int i = *idx + 1; table && i < table->sorted_names_len; ++i) {
+ const char *name = table->num_to_name[table->sorted_names[i]];
if (strglobmatch(name, syscall_glob)) {
*idx = i;
- return syscall_sorted_names[i];
+ return table->sorted_names[i];
}
}
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v1 7/7] perf build: Remove Makefile.syscalls
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (5 preceding siblings ...)
2025-02-01 7:14 ` [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures Ian Rogers
@ 2025-02-01 7:14 ` Ian Rogers
2025-02-01 8:51 ` [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
2025-02-03 19:02 ` Charlie Jenkins
8 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 7:14 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
Now a single beauty file is generated and used by all architectures,
remove the per-architecture Makefiles, Kbuild files and previous
generator script.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/Makefile.perf | 1 -
tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
.../alpha/entry/syscalls/Makefile.syscalls | 5 --
tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
.../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
.../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
.../arm64/entry/syscalls/Makefile.syscalls | 6 --
tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
.../csky/entry/syscalls/Makefile.syscalls | 3 -
.../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
.../entry/syscalls/Makefile.syscalls | 3 -
tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
.../mips/entry/syscalls/Makefile.syscalls | 5 --
tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
.../parisc/entry/syscalls/Makefile.syscalls | 6 --
tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
.../powerpc/entry/syscalls/Makefile.syscalls | 6 --
tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
.../riscv/entry/syscalls/Makefile.syscalls | 4 -
tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
.../s390/entry/syscalls/Makefile.syscalls | 5 --
tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
.../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
.../sparc/entry/syscalls/Makefile.syscalls | 5 --
tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
.../arch/x86/entry/syscalls/Makefile.syscalls | 6 --
tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
.../xtensa/entry/syscalls/Makefile.syscalls | 4 -
tools/perf/scripts/Makefile.syscalls | 61 ---------------
tools/perf/scripts/syscalltbl.sh | 76 -------------------
33 files changed, 242 deletions(-)
delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
delete mode 100644 tools/perf/scripts/Makefile.syscalls
delete mode 100755 tools/perf/scripts/syscalltbl.sh
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 793e702f9aaf..62176d685445 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -339,7 +339,6 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
FEATURE_TESTS := all
endif
endif
-include $(srctree)/tools/perf/scripts/Makefile.syscalls
include Makefile.config
endif
diff --git a/tools/perf/arch/alpha/entry/syscalls/Kbuild b/tools/perf/arch/alpha/entry/syscalls/Kbuild
deleted file mode 100644
index 9a41e3572c3a..000000000000
--- a/tools/perf/arch/alpha/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 690168aac34d..000000000000
--- a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_64 +=
-
-syscalltbl = $(srctree)/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
deleted file mode 100644
index 11707c481a24..000000000000
--- a/tools/perf/arch/arc/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 391d30ab7a83..000000000000
--- a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/tools/perf/arch/arm/entry/syscalls/Kbuild b/tools/perf/arch/arm/entry/syscalls/Kbuild
deleted file mode 100644
index 9d777540f089..000000000000
--- a/tools/perf/arch/arm/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += oabi
-syscalltbl = $(srctree)/tools/perf/arch/arm/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 11707c481a24..000000000000
--- a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Kbuild b/tools/perf/arch/arm64/entry/syscalls/Kbuild
deleted file mode 100644
index 84c6599b4ea6..000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index e7e78c2d1c02..000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 +=
-syscall_abis_64 += renameat rlimit memfd_secret
-
-syscalltbl = $(srctree)/tools/perf/arch/arm64/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/csky/entry/syscalls/Kbuild b/tools/perf/arch/csky/entry/syscalls/Kbuild
deleted file mode 100644
index 11707c481a24..000000000000
--- a/tools/perf/arch/csky/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index ea2dd10d0571..000000000000
--- a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += csky time32 stat64 rlimit
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Kbuild b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
deleted file mode 100644
index 9a41e3572c3a..000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 47d32da2aed8..000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_64 +=
diff --git a/tools/perf/arch/mips/entry/syscalls/Kbuild b/tools/perf/arch/mips/entry/syscalls/Kbuild
deleted file mode 100644
index 9a41e3572c3a..000000000000
--- a/tools/perf/arch/mips/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 9ee914bdfb05..000000000000
--- a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_64 += n64
-
-syscalltbl = $(srctree)/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
diff --git a/tools/perf/arch/parisc/entry/syscalls/Kbuild b/tools/perf/arch/parisc/entry/syscalls/Kbuild
deleted file mode 100644
index 84c6599b4ea6..000000000000
--- a/tools/perf/arch/parisc/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index ae326fecb83b..000000000000
--- a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 +=
-syscall_abis_64 +=
-
-syscalltbl = $(srctree)/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Kbuild b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
deleted file mode 100644
index 84c6599b4ea6..000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index e35afbc57c79..000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += nospu
-syscall_abis_64 += nospu
-
-syscalltbl = $(srctree)/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
deleted file mode 100644
index 9a41e3572c3a..000000000000
--- a/tools/perf/arch/riscv/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 9668fd1faf60..000000000000
--- a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += riscv memfd_secret
-syscall_abis_64 += riscv rlimit memfd_secret
diff --git a/tools/perf/arch/s390/entry/syscalls/Kbuild b/tools/perf/arch/s390/entry/syscalls/Kbuild
deleted file mode 100644
index 9a41e3572c3a..000000000000
--- a/tools/perf/arch/s390/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 9762d7abf17c..000000000000
--- a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_64 += renameat rlimit memfd_secret
-
-syscalltbl = $(srctree)/tools/perf/arch/s390/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sh/entry/syscalls/Kbuild b/tools/perf/arch/sh/entry/syscalls/Kbuild
deleted file mode 100644
index 11707c481a24..000000000000
--- a/tools/perf/arch/sh/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 25080390e4ed..000000000000
--- a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 +=
-syscalltbl = $(srctree)/tools/perf/arch/sh/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sparc/entry/syscalls/Kbuild b/tools/perf/arch/sparc/entry/syscalls/Kbuild
deleted file mode 100644
index 84c6599b4ea6..000000000000
--- a/tools/perf/arch/sparc/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index 212c1800b644..000000000000
--- a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 +=
-syscall_abis_64 +=
-syscalltbl = $(srctree)/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/x86/entry/syscalls/Kbuild b/tools/perf/arch/x86/entry/syscalls/Kbuild
deleted file mode 100644
index 84c6599b4ea6..000000000000
--- a/tools/perf/arch/x86/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
-syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index db3d5d6d4e56..000000000000
--- a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 += i386
-syscall_abis_64 +=
-
-syscalltbl = $(srctree)/tools/perf/arch/x86/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Kbuild b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
deleted file mode 100644
index 11707c481a24..000000000000
--- a/tools/perf/arch/xtensa/entry/syscalls/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
deleted file mode 100644
index d4aa2358460c..000000000000
--- a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-syscall_abis_32 +=
-syscalltbl = $(srctree)/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
deleted file mode 100644
index 8bf55333262e..000000000000
--- a/tools/perf/scripts/Makefile.syscalls
+++ /dev/null
@@ -1,61 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# This Makefile generates headers in
-# tools/perf/arch/$(SRCARCH)/include/generated/asm from the architecture's
-# syscall table. This will either be from the generic syscall table, or from a
-# table that is specific to that architecture.
-
-PHONY := all
-all:
-
-obj := $(OUTPUT)arch/$(SRCARCH)/include/generated/asm
-
-syscall_abis_32 := common,32
-syscall_abis_64 := common,64
-syscalltbl := $(srctree)/tools/scripts/syscall.tbl
-
-# let architectures override $(syscall_abis_%) and $(syscalltbl)
--include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
-include $(srctree)/tools/build/Build.include
--include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
-
-systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
-
-syscall-y := $(addprefix $(obj)/, $(syscall-y))
-
-# Remove stale wrappers when the corresponding files are removed from generic-y
-old-headers := $(wildcard $(obj)/*.h)
-unwanted := $(filter-out $(syscall-y),$(old-headers))
-
-quiet_cmd_remove = REMOVE $(unwanted)
- cmd_remove = rm -f $(unwanted)
-
-quiet_cmd_systbl = SYSTBL $@
- cmd_systbl = $(CONFIG_SHELL) $(systbl) \
- $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
- --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
- $< $@
-
-all: $(syscall-y)
- $(if $(unwanted),$(call cmd,remove))
- @:
-
-$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
- $(call if_changed,systbl)
-
-targets := $(syscall-y)
-
-# Create output directory. Skip it if at least one old header exists
-# since we know the output directory already exists.
-ifeq ($(old-headers),)
-$(shell mkdir -p $(obj))
-endif
-
-PHONY += FORCE
-
-FORCE:
-
-existing-targets := $(wildcard $(sort $(targets)))
-
--include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
-
-.PHONY: $(PHONY)
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
deleted file mode 100755
index a39b3013b103..000000000000
--- a/tools/perf/scripts/syscalltbl.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate a syscall table header.
-#
-# Each line of the syscall table should have the following format:
-#
-# NR ABI NAME [NATIVE] [COMPAT]
-#
-# NR syscall number
-# ABI ABI name
-# NAME syscall name
-# NATIVE native entry point (optional)
-# COMPAT compat entry point (optional)
-
-set -e
-
-usage() {
- echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2
- echo >&2
- echo >&2 " INFILE input syscall table"
- echo >&2 " OUTFILE output header file"
- echo >&2
- echo >&2 "options:"
- echo >&2 " --abis ABIS ABI(s) to handle (By default, all lines are handled)"
- exit 1
-}
-
-# default unless specified by options
-abis=
-
-while [ $# -gt 0 ]
-do
- case $1 in
- --abis)
- abis=$(echo "($2)" | tr ',' '|')
- shift 2;;
- -*)
- echo "$1: unknown option" >&2
- usage;;
- *)
- break;;
- esac
-done
-
-if [ $# -ne 2 ]; then
- usage
-fi
-
-infile="$1"
-outfile="$2"
-
-sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
-grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
-
-echo "static const char *const syscall_num_to_name[] = {" > $outfile
-# the params are: nr abi name entry compat
-# use _ for intentionally unused variables according to SC2034
-while read nr _ name _ _; do
- echo " [$nr] = \"$name\"," >> $outfile
-done < $sorted_table
-echo "};" >> $outfile
-
-echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile
-
-# When sorting by name, add a suffix of 0s upto 20 characters so that system
-# calls that differ with a numerical suffix don't sort before those
-# without. This default behavior of sort differs from that of strcmp used at
-# runtime. Use sed to strip the trailing 0s suffix afterwards.
-grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table
-while read name nr; do
- echo " $nr, /* $name */" >> $outfile
-done < $sorted_table
-echo "};" >> $outfile
-
-rm -f $sorted_table
--
2.48.1.362.g079036d154-goog
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (6 preceding siblings ...)
2025-02-01 7:14 ` [PATCH v1 7/7] perf build: Remove Makefile.syscalls Ian Rogers
@ 2025-02-01 8:51 ` Ian Rogers
2025-02-03 18:28 ` Ian Rogers
2025-02-03 19:02 ` Charlie Jenkins
8 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-01 8:51 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
>
> This work builds on the clean up of system call tables and removal of
> libaudit by Charlie Jenkins <charlie@rivosinc.com>.
>
> The system call table in perf trace is used to map system call numbers
> to names and vice versa. Prior to these changes, a single table
> matching the perf binary's build was present. The table would be
> incorrect if tracing say a 32-bit binary from a 64-bit version of
> perf, the names and numbers wouldn't match.
>
> Change the build so that a single system call file is built and the
> potentially multiple tables are identifiable from the ELF machine type
> of the process being examined. To determine the ELF machine type, the
> executable's header is read from /proc/pid/exe with fallbacks to using
> the perf's binary type when unknown.
>
> Remove some runtime types used by the system call tables and make
> equivalents generated at build time.
>
> Ian Rogers (7):
> perf syscalltble: Remove syscall_table.h
> perf trace: Reorganize syscalls
> perf syscalltbl: Remove struct syscalltbl
> perf thread: Add support for reading the e_machine type for a thread
> perf trace beauty: Add syscalltbl.sh generating all system call tables
> perf syscalltbl: Use lookup table containing multiple architectures
> perf build: Remove Makefile.syscalls
If you are looking for the improvement this series achieves, patch 6
has sample before and after output:
https://lore.kernel.org/lkml/20250201071455.718247-7-irogers@google.com/
Thanks,
Ian
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-01 8:51 ` [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
@ 2025-02-03 18:28 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-03 18:28 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Kan Liang, John Garry, Will Deacon,
James Clark, Mike Leach, Leo Yan, Guo Ren, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Charlie Jenkins, Bibo Mao,
Arnd Bergmann, Huacai Chen, Catalin Marinas, Jiri Slaby,
Björn Töpel, Howard Chu, linux-kernel, linux-perf-users,
linux-arm-kernel, linux-csky, linux-riscv
On Sat, Feb 1, 2025 at 12:51 AM Ian Rogers <irogers@google.com> wrote:
>
> On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
> >
> > This work builds on the clean up of system call tables and removal of
> > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> >
> > The system call table in perf trace is used to map system call numbers
> > to names and vice versa. Prior to these changes, a single table
> > matching the perf binary's build was present. The table would be
> > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > perf, the names and numbers wouldn't match.
> >
> > Change the build so that a single system call file is built and the
> > potentially multiple tables are identifiable from the ELF machine type
> > of the process being examined. To determine the ELF machine type, the
> > executable's header is read from /proc/pid/exe with fallbacks to using
> > the perf's binary type when unknown.
> >
> > Remove some runtime types used by the system call tables and make
> > equivalents generated at build time.
> >
> > Ian Rogers (7):
> > perf syscalltble: Remove syscall_table.h
> > perf trace: Reorganize syscalls
> > perf syscalltbl: Remove struct syscalltbl
> > perf thread: Add support for reading the e_machine type for a thread
> > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > perf syscalltbl: Use lookup table containing multiple architectures
> > perf build: Remove Makefile.syscalls
>
> If you are looking for the improvement this series achieves, patch 6
> has sample before and after output:
> https://lore.kernel.org/lkml/20250201071455.718247-7-irogers@google.com/
I think there is a follow up to these patches to clean up the notion
of "arch" and its "name" member:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/disasm.h?h=perf-tools-next#n20
The name on x86-64 has the value "x86" and isn't known to be i386 or
x86-64, causing ambiguity to work around:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/disasm.c?h=perf-tools-next#n1898
It feels likely that rather than recording (in env) a string based on
uname and bashing it around:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/env.c?h=perf-tools-next#n440
It would be better to record the e_machine values for the set of
threads in the record, or just a set of potential e_machine values. We
can get rid of name in arch, use e_machine from some dso helper, and
then deal with this as appropriate without needing to carry around
is_64bit to deal with ambiguity.
A change like this would need its own feature flag, and helpers
between the old name and e_machine so all notions of the old style
name could be removed, etc. It may be convenient to duplicate arch
tables for i386/x86-64 rather than have disasm's arch deal with a set
of e_machines.
Thanks,
Ian
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
` (7 preceding siblings ...)
2025-02-01 8:51 ` [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
@ 2025-02-03 19:02 ` Charlie Jenkins
2025-02-03 19:10 ` Ian Rogers
8 siblings, 1 reply; 26+ messages in thread
From: Charlie Jenkins @ 2025-02-03 19:02 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> This work builds on the clean up of system call tables and removal of
> libaudit by Charlie Jenkins <charlie@rivosinc.com>.
>
> The system call table in perf trace is used to map system call numbers
> to names and vice versa. Prior to these changes, a single table
> matching the perf binary's build was present. The table would be
> incorrect if tracing say a 32-bit binary from a 64-bit version of
> perf, the names and numbers wouldn't match.
>
> Change the build so that a single system call file is built and the
> potentially multiple tables are identifiable from the ELF machine type
> of the process being examined. To determine the ELF machine type, the
> executable's header is read from /proc/pid/exe with fallbacks to using
> the perf's binary type when unknown.
>
> Remove some runtime types used by the system call tables and make
> equivalents generated at build time.
Our approaches are very different but I sent out a patch to do this a
couple of weeks ago [1].
Did you look at that and decide you didn't like the approach?
- Charlie
>
> Ian Rogers (7):
> perf syscalltble: Remove syscall_table.h
> perf trace: Reorganize syscalls
> perf syscalltbl: Remove struct syscalltbl
> perf thread: Add support for reading the e_machine type for a thread
> perf trace beauty: Add syscalltbl.sh generating all system call tables
> perf syscalltbl: Use lookup table containing multiple architectures
> perf build: Remove Makefile.syscalls
>
> tools/perf/Makefile.perf | 10 +-
> tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> tools/perf/arch/alpha/include/syscall_table.h | 2 -
> tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> tools/perf/arch/arc/include/syscall_table.h | 2 -
> tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> tools/perf/arch/arm/include/syscall_table.h | 2 -
> tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> tools/perf/arch/arm64/include/syscall_table.h | 8 -
> tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> .../csky/entry/syscalls/Makefile.syscalls | 3 -
> tools/perf/arch/csky/include/syscall_table.h | 2 -
> .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> .../entry/syscalls/Makefile.syscalls | 3 -
> .../arch/loongarch/include/syscall_table.h | 2 -
> tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> .../mips/entry/syscalls/Makefile.syscalls | 5 -
> tools/perf/arch/mips/include/syscall_table.h | 2 -
> tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> .../perf/arch/parisc/include/syscall_table.h | 8 -
> tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> .../perf/arch/powerpc/include/syscall_table.h | 8 -
> tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> tools/perf/arch/riscv/include/syscall_table.h | 8 -
> tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> .../s390/entry/syscalls/Makefile.syscalls | 5 -
> tools/perf/arch/s390/include/syscall_table.h | 2 -
> tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> tools/perf/arch/sh/include/syscall_table.h | 2 -
> tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> tools/perf/arch/sparc/include/syscall_table.h | 8 -
> tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> tools/perf/arch/x86/include/syscall_table.h | 8 -
> tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> .../perf/arch/xtensa/include/syscall_table.h | 2 -
> tools/perf/builtin-trace.c | 275 +++++++++++-------
> tools/perf/scripts/Makefile.syscalls | 61 ----
> tools/perf/scripts/syscalltbl.sh | 86 ------
> tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> tools/perf/util/syscalltbl.c | 142 ++++-----
> tools/perf/util/syscalltbl.h | 22 +-
> tools/perf/util/thread.c | 50 ++++
> tools/perf/util/thread.h | 14 +-
> 54 files changed, 598 insertions(+), 506 deletions(-)
> delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> delete mode 100644 tools/perf/scripts/Makefile.syscalls
> delete mode 100755 tools/perf/scripts/syscalltbl.sh
> create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
>
> --
> 2.48.1.362.g079036d154-goog
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 19:02 ` Charlie Jenkins
@ 2025-02-03 19:10 ` Ian Rogers
2025-02-03 19:15 ` Charlie Jenkins
0 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-03 19:10 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > This work builds on the clean up of system call tables and removal of
> > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> >
> > The system call table in perf trace is used to map system call numbers
> > to names and vice versa. Prior to these changes, a single table
> > matching the perf binary's build was present. The table would be
> > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > perf, the names and numbers wouldn't match.
> >
> > Change the build so that a single system call file is built and the
> > potentially multiple tables are identifiable from the ELF machine type
> > of the process being examined. To determine the ELF machine type, the
> > executable's header is read from /proc/pid/exe with fallbacks to using
> > the perf's binary type when unknown.
> >
> > Remove some runtime types used by the system call tables and make
> > equivalents generated at build time.
>
> Our approaches are very different but I sent out a patch to do this a
> couple of weeks ago [1].
>
> Did you look at that and decide you didn't like the approach?
Missing link?
The patches generating a syscall(_32|_64)?.h landed. These changes
take your changes and make it so that we just run the script once
building a header file for all architectures. On x86 we then have the
tables be guarded by ifdefs on i386 and x86-64. Then rather than the
table just matching the host architecture the ELF machine is used for
the executable running.
Thanks,
Ian
> - Charlie
>
> >
> > Ian Rogers (7):
> > perf syscalltble: Remove syscall_table.h
> > perf trace: Reorganize syscalls
> > perf syscalltbl: Remove struct syscalltbl
> > perf thread: Add support for reading the e_machine type for a thread
> > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > perf syscalltbl: Use lookup table containing multiple architectures
> > perf build: Remove Makefile.syscalls
> >
> > tools/perf/Makefile.perf | 10 +-
> > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > .../entry/syscalls/Makefile.syscalls | 3 -
> > .../arch/loongarch/include/syscall_table.h | 2 -
> > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > tools/perf/scripts/Makefile.syscalls | 61 ----
> > tools/perf/scripts/syscalltbl.sh | 86 ------
> > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > tools/perf/util/syscalltbl.c | 142 ++++-----
> > tools/perf/util/syscalltbl.h | 22 +-
> > tools/perf/util/thread.c | 50 ++++
> > tools/perf/util/thread.h | 14 +-
> > 54 files changed, 598 insertions(+), 506 deletions(-)
> > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> >
> > --
> > 2.48.1.362.g079036d154-goog
> >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 19:10 ` Ian Rogers
@ 2025-02-03 19:15 ` Charlie Jenkins
2025-02-03 19:39 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Charlie Jenkins @ 2025-02-03 19:15 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 03, 2025 at 11:10:49AM -0800, Ian Rogers wrote:
> On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > > This work builds on the clean up of system call tables and removal of
> > > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> > >
> > > The system call table in perf trace is used to map system call numbers
> > > to names and vice versa. Prior to these changes, a single table
> > > matching the perf binary's build was present. The table would be
> > > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > > perf, the names and numbers wouldn't match.
> > >
> > > Change the build so that a single system call file is built and the
> > > potentially multiple tables are identifiable from the ELF machine type
> > > of the process being examined. To determine the ELF machine type, the
> > > executable's header is read from /proc/pid/exe with fallbacks to using
> > > the perf's binary type when unknown.
> > >
> > > Remove some runtime types used by the system call tables and make
> > > equivalents generated at build time.
> >
> > Our approaches are very different but I sent out a patch to do this a
> > couple of weeks ago [1].
> >
> > Did you look at that and decide you didn't like the approach?
>
> Missing link?
Whoops here is the link:
https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/
>
> The patches generating a syscall(_32|_64)?.h landed. These changes
> take your changes and make it so that we just run the script once
> building a header file for all architectures. On x86 we then have the
> tables be guarded by ifdefs on i386 and x86-64. Then rather than the
> table just matching the host architecture the ELF machine is used for
> the executable running.
>
> Thanks,
> Ian
>
> > - Charlie
> >
> > >
> > > Ian Rogers (7):
> > > perf syscalltble: Remove syscall_table.h
> > > perf trace: Reorganize syscalls
> > > perf syscalltbl: Remove struct syscalltbl
> > > perf thread: Add support for reading the e_machine type for a thread
> > > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > > perf syscalltbl: Use lookup table containing multiple architectures
> > > perf build: Remove Makefile.syscalls
> > >
> > > tools/perf/Makefile.perf | 10 +-
> > > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > > .../entry/syscalls/Makefile.syscalls | 3 -
> > > .../arch/loongarch/include/syscall_table.h | 2 -
> > > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > > tools/perf/scripts/Makefile.syscalls | 61 ----
> > > tools/perf/scripts/syscalltbl.sh | 86 ------
> > > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > > tools/perf/util/syscalltbl.c | 142 ++++-----
> > > tools/perf/util/syscalltbl.h | 22 +-
> > > tools/perf/util/thread.c | 50 ++++
> > > tools/perf/util/thread.h | 14 +-
> > > 54 files changed, 598 insertions(+), 506 deletions(-)
> > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> > >
> > > --
> > > 2.48.1.362.g079036d154-goog
> > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 19:15 ` Charlie Jenkins
@ 2025-02-03 19:39 ` Ian Rogers
2025-02-03 20:06 ` Charlie Jenkins
0 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-03 19:39 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 3, 2025 at 11:15 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> On Mon, Feb 03, 2025 at 11:10:49AM -0800, Ian Rogers wrote:
> > On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > >
> > > On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > > > This work builds on the clean up of system call tables and removal of
> > > > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> > > >
> > > > The system call table in perf trace is used to map system call numbers
> > > > to names and vice versa. Prior to these changes, a single table
> > > > matching the perf binary's build was present. The table would be
> > > > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > > > perf, the names and numbers wouldn't match.
> > > >
> > > > Change the build so that a single system call file is built and the
> > > > potentially multiple tables are identifiable from the ELF machine type
> > > > of the process being examined. To determine the ELF machine type, the
> > > > executable's header is read from /proc/pid/exe with fallbacks to using
> > > > the perf's binary type when unknown.
> > > >
> > > > Remove some runtime types used by the system call tables and make
> > > > equivalents generated at build time.
> > >
> > > Our approaches are very different but I sent out a patch to do this a
> > > couple of weeks ago [1].
> > >
> > > Did you look at that and decide you didn't like the approach?
> >
> > Missing link?
>
> Whoops here is the link:
>
> https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/
I agree it is similar and progress, I think I prefer my changes :-)
Anything in the arch directories is only going to be built given a
Makefile SRCARCH:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/arch/Build?h=perf-tools-next#n2
which means if we want the system call tables for say ARM on x86-64 we
need to reinvent the build - this isn't a problem today but perhaps
something to consider if we wanted a cross-architecture perf trace
record. I'd like to do away entirely with the arch directory for this
kind of reason. For example, if we run perf on a user space emulator
(say a testing set up) and it sees AMD data fabric PMUs, logic for
those PMUs currently lives in the arch directory for x86 and likely
wasn't even built into the perf tool. We should be able to identify
PMUs and act accordingly based on their names. In the case of the
overloaded "cpu" PMU we can identify it with the CPUID. The less code
in arch and the fewer architecture ifdefs, the better things should
work cross-architecture, in testing scenarios, etc. We also win by
getting code coverage without, for example, having to build and test
on csky or super H.
Your changes are using the string for the architecture name. I think
that string is something we should get rid of:
https://lore.kernel.org/lkml/CAP-5=fX2BtFzhGLCSqO1QszqfX=HT8RrTdG_5Ttp5Gw4seSstA@mail.gmail.com/
but there's no reason we couldn't clean that up on top of your change.
The build with lots of separate Build/Makefiles is something of a pain
to port/maintain in a bazel version of the build I maintain at Google
(happy to open source if anyone cares). In these changes you just run
a big script and get a big header file out the end, which largely
matches the other perf trace beauty things we build.
Thanks,
Ian
> >
> > The patches generating a syscall(_32|_64)?.h landed. These changes
> > take your changes and make it so that we just run the script once
> > building a header file for all architectures. On x86 we then have the
> > tables be guarded by ifdefs on i386 and x86-64. Then rather than the
> > table just matching the host architecture the ELF machine is used for
> > the executable running.
> >
> > Thanks,
> > Ian
> >
> > > - Charlie
> > >
> > > >
> > > > Ian Rogers (7):
> > > > perf syscalltble: Remove syscall_table.h
> > > > perf trace: Reorganize syscalls
> > > > perf syscalltbl: Remove struct syscalltbl
> > > > perf thread: Add support for reading the e_machine type for a thread
> > > > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > > > perf syscalltbl: Use lookup table containing multiple architectures
> > > > perf build: Remove Makefile.syscalls
> > > >
> > > > tools/perf/Makefile.perf | 10 +-
> > > > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > > > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > > > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > > > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > > > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > > > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > > > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > > > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > > > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > > > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > > > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > > > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > > > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > > > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > > > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > > > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > > > .../entry/syscalls/Makefile.syscalls | 3 -
> > > > .../arch/loongarch/include/syscall_table.h | 2 -
> > > > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > > > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > > > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > > > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > > > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > > > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > > > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > > > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > > > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > > > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > > > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > > > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > > > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > > > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > > > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > > > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > > > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > > > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > > > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > > > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > > > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > > > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > > > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > > > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > > > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > > > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > > > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > > > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > > > tools/perf/scripts/Makefile.syscalls | 61 ----
> > > > tools/perf/scripts/syscalltbl.sh | 86 ------
> > > > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > > > tools/perf/util/syscalltbl.c | 142 ++++-----
> > > > tools/perf/util/syscalltbl.h | 22 +-
> > > > tools/perf/util/thread.c | 50 ++++
> > > > tools/perf/util/thread.h | 14 +-
> > > > 54 files changed, 598 insertions(+), 506 deletions(-)
> > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > > > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > > > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > > > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > > > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> > > >
> > > > --
> > > > 2.48.1.362.g079036d154-goog
> > > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 19:39 ` Ian Rogers
@ 2025-02-03 20:06 ` Charlie Jenkins
2025-02-03 20:54 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Charlie Jenkins @ 2025-02-03 20:06 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 03, 2025 at 11:39:01AM -0800, Ian Rogers wrote:
> On Mon, Feb 3, 2025 at 11:15 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > On Mon, Feb 03, 2025 at 11:10:49AM -0800, Ian Rogers wrote:
> > > On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > >
> > > > On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > > > > This work builds on the clean up of system call tables and removal of
> > > > > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> > > > >
> > > > > The system call table in perf trace is used to map system call numbers
> > > > > to names and vice versa. Prior to these changes, a single table
> > > > > matching the perf binary's build was present. The table would be
> > > > > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > > > > perf, the names and numbers wouldn't match.
> > > > >
> > > > > Change the build so that a single system call file is built and the
> > > > > potentially multiple tables are identifiable from the ELF machine type
> > > > > of the process being examined. To determine the ELF machine type, the
> > > > > executable's header is read from /proc/pid/exe with fallbacks to using
> > > > > the perf's binary type when unknown.
> > > > >
> > > > > Remove some runtime types used by the system call tables and make
> > > > > equivalents generated at build time.
> > > >
> > > > Our approaches are very different but I sent out a patch to do this a
> > > > couple of weeks ago [1].
> > > >
> > > > Did you look at that and decide you didn't like the approach?
> > >
> > > Missing link?
> >
> > Whoops here is the link:
> >
> > https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/
>
> I agree it is similar and progress, I think I prefer my changes :-)
>
> Anything in the arch directories is only going to be built given a
> Makefile SRCARCH:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/arch/Build?h=perf-tools-next#n2
> which means if we want the system call tables for say ARM on x86-64 we
> need to reinvent the build - this isn't a problem today but perhaps
> something to consider if we wanted a cross-architecture perf trace
> record. I'd like to do away entirely with the arch directory for this
> kind of reason. For example, if we run perf on a user space emulator
> (say a testing set up) and it sees AMD data fabric PMUs, logic for
> those PMUs currently lives in the arch directory for x86 and likely
> wasn't even built into the perf tool. We should be able to identify
> PMUs and act accordingly based on their names. In the case of the
> overloaded "cpu" PMU we can identify it with the CPUID. The less code
> in arch and the fewer architecture ifdefs, the better things should
> work cross-architecture, in testing scenarios, etc. We also win by
> getting code coverage without, for example, having to build and test
> on csky or super H.
>
> Your changes are using the string for the architecture name. I think
> that string is something we should get rid of:
> https://lore.kernel.org/lkml/CAP-5=fX2BtFzhGLCSqO1QszqfX=HT8RrTdG_5Ttp5Gw4seSstA@mail.gmail.com/
> but there's no reason we couldn't clean that up on top of your change.
Yes that part is not ideal.
>
> The build with lots of separate Build/Makefiles is something of a pain
> to port/maintain in a bazel version of the build I maintain at Google
> (happy to open source if anyone cares). In these changes you just run
> a big script and get a big header file out the end, which largely
> matches the other perf trace beauty things we build.
Fair enough! I wanted to mimic how the kernel was building the syscall
tables as closely as possible, it's convenient to have cohesion.
What is the usecase for the bazel version?
- Charlie
>
> Thanks,
> Ian
>
> > >
> > > The patches generating a syscall(_32|_64)?.h landed. These changes
> > > take your changes and make it so that we just run the script once
> > > building a header file for all architectures. On x86 we then have the
> > > tables be guarded by ifdefs on i386 and x86-64. Then rather than the
> > > table just matching the host architecture the ELF machine is used for
> > > the executable running.
> > >
> > > Thanks,
> > > Ian
> > >
> > > > - Charlie
> > > >
> > > > >
> > > > > Ian Rogers (7):
> > > > > perf syscalltble: Remove syscall_table.h
> > > > > perf trace: Reorganize syscalls
> > > > > perf syscalltbl: Remove struct syscalltbl
> > > > > perf thread: Add support for reading the e_machine type for a thread
> > > > > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > > > > perf syscalltbl: Use lookup table containing multiple architectures
> > > > > perf build: Remove Makefile.syscalls
> > > > >
> > > > > tools/perf/Makefile.perf | 10 +-
> > > > > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > > > > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > > > > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > > > > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > > > > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > > > > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > > > > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > > > > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > > > > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > > > > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > > > > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > > > > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > > > > .../entry/syscalls/Makefile.syscalls | 3 -
> > > > > .../arch/loongarch/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > > > > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > > > > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > > > > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > > > > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > > > > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > > > > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > > > > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > > > > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > > > > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > > > > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > > > > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > > > > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > > > > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > > > > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > > > > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > > > > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > > > > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > > > > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > > > > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > > > > tools/perf/scripts/Makefile.syscalls | 61 ----
> > > > > tools/perf/scripts/syscalltbl.sh | 86 ------
> > > > > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > > > > tools/perf/util/syscalltbl.c | 142 ++++-----
> > > > > tools/perf/util/syscalltbl.h | 22 +-
> > > > > tools/perf/util/thread.c | 50 ++++
> > > > > tools/perf/util/thread.h | 14 +-
> > > > > 54 files changed, 598 insertions(+), 506 deletions(-)
> > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > > > > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > > > > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > > > > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > > > > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> > > > >
> > > > > --
> > > > > 2.48.1.362.g079036d154-goog
> > > > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 20:06 ` Charlie Jenkins
@ 2025-02-03 20:54 ` Ian Rogers
2025-02-03 23:02 ` Charlie Jenkins
0 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-03 20:54 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 3, 2025 at 12:06 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> On Mon, Feb 03, 2025 at 11:39:01AM -0800, Ian Rogers wrote:
> > On Mon, Feb 3, 2025 at 11:15 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > >
> > > On Mon, Feb 03, 2025 at 11:10:49AM -0800, Ian Rogers wrote:
> > > > On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > > >
> > > > > On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > > > > > This work builds on the clean up of system call tables and removal of
> > > > > > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> > > > > >
> > > > > > The system call table in perf trace is used to map system call numbers
> > > > > > to names and vice versa. Prior to these changes, a single table
> > > > > > matching the perf binary's build was present. The table would be
> > > > > > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > > > > > perf, the names and numbers wouldn't match.
> > > > > >
> > > > > > Change the build so that a single system call file is built and the
> > > > > > potentially multiple tables are identifiable from the ELF machine type
> > > > > > of the process being examined. To determine the ELF machine type, the
> > > > > > executable's header is read from /proc/pid/exe with fallbacks to using
> > > > > > the perf's binary type when unknown.
> > > > > >
> > > > > > Remove some runtime types used by the system call tables and make
> > > > > > equivalents generated at build time.
> > > > >
> > > > > Our approaches are very different but I sent out a patch to do this a
> > > > > couple of weeks ago [1].
> > > > >
> > > > > Did you look at that and decide you didn't like the approach?
> > > >
> > > > Missing link?
> > >
> > > Whoops here is the link:
> > >
> > > https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/
> >
> > I agree it is similar and progress, I think I prefer my changes :-)
> >
> > Anything in the arch directories is only going to be built given a
> > Makefile SRCARCH:
> > https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/arch/Build?h=perf-tools-next#n2
> > which means if we want the system call tables for say ARM on x86-64 we
> > need to reinvent the build - this isn't a problem today but perhaps
> > something to consider if we wanted a cross-architecture perf trace
> > record. I'd like to do away entirely with the arch directory for this
> > kind of reason. For example, if we run perf on a user space emulator
> > (say a testing set up) and it sees AMD data fabric PMUs, logic for
> > those PMUs currently lives in the arch directory for x86 and likely
> > wasn't even built into the perf tool. We should be able to identify
> > PMUs and act accordingly based on their names. In the case of the
> > overloaded "cpu" PMU we can identify it with the CPUID. The less code
> > in arch and the fewer architecture ifdefs, the better things should
> > work cross-architecture, in testing scenarios, etc. We also win by
> > getting code coverage without, for example, having to build and test
> > on csky or super H.
> >
> > Your changes are using the string for the architecture name. I think
> > that string is something we should get rid of:
> > https://lore.kernel.org/lkml/CAP-5=fX2BtFzhGLCSqO1QszqfX=HT8RrTdG_5Ttp5Gw4seSstA@mail.gmail.com/
> > but there's no reason we couldn't clean that up on top of your change.
>
> Yes that part is not ideal.
>
> >
> > The build with lots of separate Build/Makefiles is something of a pain
> > to port/maintain in a bazel version of the build I maintain at Google
> > (happy to open source if anyone cares). In these changes you just run
> > a big script and get a big header file out the end, which largely
> > matches the other perf trace beauty things we build.
>
> Fair enough! I wanted to mimic how the kernel was building the syscall
> tables as closely as possible, it's convenient to have cohesion.
I think it makes sense in the kernel, as the built binary doesn't have
cross-platform concerns. This is probably also the reason why the perf
tool has an arch directory. Let me know what you think is the right
direction for the perf tool syscall table code.
> What is the usecase for the bazel version?
I'm sure there's more info in:
https://bazel.build/
but the main thing is having hermetic and reproducible builds. The
main problem with open sourcing would be dealing with external
repositories, test set up, etc. Tbh, hermetic builds are a challenge
as things like lex and yacc will vary the C code they generate based
on the platform they run on. Bazel has plans to change the world so
maybe this could be more of a thing in the future.
Fwiw, I did push changes into the perf tree so that man page building
was reproducible:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/commit/tools/perf/Documentation?h=perf-tools-next&id=d586ac10ce56b2381b8e1d8ed74660c1b2b8ab0d
The man pages used to reflect the date/time they were built, but now
reflect the date the of the commit of the file being built:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/Documentation/Makefile?h=perf-tools-next#n255
Thanks,
Ian
> - Charlie
>
> >
> > Thanks,
> > Ian
> >
> > > >
> > > > The patches generating a syscall(_32|_64)?.h landed. These changes
> > > > take your changes and make it so that we just run the script once
> > > > building a header file for all architectures. On x86 we then have the
> > > > tables be guarded by ifdefs on i386 and x86-64. Then rather than the
> > > > table just matching the host architecture the ELF machine is used for
> > > > the executable running.
> > > >
> > > > Thanks,
> > > > Ian
> > > >
> > > > > - Charlie
> > > > >
> > > > > >
> > > > > > Ian Rogers (7):
> > > > > > perf syscalltble: Remove syscall_table.h
> > > > > > perf trace: Reorganize syscalls
> > > > > > perf syscalltbl: Remove struct syscalltbl
> > > > > > perf thread: Add support for reading the e_machine type for a thread
> > > > > > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > > > > > perf syscalltbl: Use lookup table containing multiple architectures
> > > > > > perf build: Remove Makefile.syscalls
> > > > > >
> > > > > > tools/perf/Makefile.perf | 10 +-
> > > > > > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > > > > > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > > > > > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > > > > > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > > > > > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > > > > > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > > > > > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > > > > > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > > > > > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > > > > > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > > > > > .../entry/syscalls/Makefile.syscalls | 3 -
> > > > > > .../arch/loongarch/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > > > > > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > > > > > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > > > > > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > > > > > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > > > > > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > > > > > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > > > > > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > > > > > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > > > > > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > > > > > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > > > > > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > > > > > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > > > > > tools/perf/scripts/Makefile.syscalls | 61 ----
> > > > > > tools/perf/scripts/syscalltbl.sh | 86 ------
> > > > > > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > > > > > tools/perf/util/syscalltbl.c | 142 ++++-----
> > > > > > tools/perf/util/syscalltbl.h | 22 +-
> > > > > > tools/perf/util/thread.c | 50 ++++
> > > > > > tools/perf/util/thread.h | 14 +-
> > > > > > 54 files changed, 598 insertions(+), 506 deletions(-)
> > > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > > > > > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > > > > > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > > > > > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > > > > > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> > > > > >
> > > > > > --
> > > > > > 2.48.1.362.g079036d154-goog
> > > > > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 20:54 ` Ian Rogers
@ 2025-02-03 23:02 ` Charlie Jenkins
2025-02-04 1:58 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Charlie Jenkins @ 2025-02-03 23:02 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 03, 2025 at 12:54:59PM -0800, Ian Rogers wrote:
> On Mon, Feb 3, 2025 at 12:06 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > On Mon, Feb 03, 2025 at 11:39:01AM -0800, Ian Rogers wrote:
> > > On Mon, Feb 3, 2025 at 11:15 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > >
> > > > On Mon, Feb 03, 2025 at 11:10:49AM -0800, Ian Rogers wrote:
> > > > > On Mon, Feb 3, 2025 at 11:02 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > > > >
> > > > > > On Fri, Jan 31, 2025 at 11:14:48PM -0800, Ian Rogers wrote:
> > > > > > > This work builds on the clean up of system call tables and removal of
> > > > > > > libaudit by Charlie Jenkins <charlie@rivosinc.com>.
> > > > > > >
> > > > > > > The system call table in perf trace is used to map system call numbers
> > > > > > > to names and vice versa. Prior to these changes, a single table
> > > > > > > matching the perf binary's build was present. The table would be
> > > > > > > incorrect if tracing say a 32-bit binary from a 64-bit version of
> > > > > > > perf, the names and numbers wouldn't match.
> > > > > > >
> > > > > > > Change the build so that a single system call file is built and the
> > > > > > > potentially multiple tables are identifiable from the ELF machine type
> > > > > > > of the process being examined. To determine the ELF machine type, the
> > > > > > > executable's header is read from /proc/pid/exe with fallbacks to using
> > > > > > > the perf's binary type when unknown.
> > > > > > >
> > > > > > > Remove some runtime types used by the system call tables and make
> > > > > > > equivalents generated at build time.
> > > > > >
> > > > > > Our approaches are very different but I sent out a patch to do this a
> > > > > > couple of weeks ago [1].
> > > > > >
> > > > > > Did you look at that and decide you didn't like the approach?
> > > > >
> > > > > Missing link?
> > > >
> > > > Whoops here is the link:
> > > >
> > > > https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/
> > >
> > > I agree it is similar and progress, I think I prefer my changes :-)
> > >
> > > Anything in the arch directories is only going to be built given a
> > > Makefile SRCARCH:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/arch/Build?h=perf-tools-next#n2
> > > which means if we want the system call tables for say ARM on x86-64 we
> > > need to reinvent the build - this isn't a problem today but perhaps
> > > something to consider if we wanted a cross-architecture perf trace
> > > record. I'd like to do away entirely with the arch directory for this
> > > kind of reason. For example, if we run perf on a user space emulator
> > > (say a testing set up) and it sees AMD data fabric PMUs, logic for
> > > those PMUs currently lives in the arch directory for x86 and likely
> > > wasn't even built into the perf tool. We should be able to identify
> > > PMUs and act accordingly based on their names. In the case of the
> > > overloaded "cpu" PMU we can identify it with the CPUID. The less code
> > > in arch and the fewer architecture ifdefs, the better things should
> > > work cross-architecture, in testing scenarios, etc. We also win by
> > > getting code coverage without, for example, having to build and test
> > > on csky or super H.
> > >
> > > Your changes are using the string for the architecture name. I think
> > > that string is something we should get rid of:
> > > https://lore.kernel.org/lkml/CAP-5=fX2BtFzhGLCSqO1QszqfX=HT8RrTdG_5Ttp5Gw4seSstA@mail.gmail.com/
> > > but there's no reason we couldn't clean that up on top of your change.
> >
> > Yes that part is not ideal.
> >
> > >
> > > The build with lots of separate Build/Makefiles is something of a pain
> > > to port/maintain in a bazel version of the build I maintain at Google
> > > (happy to open source if anyone cares). In these changes you just run
> > > a big script and get a big header file out the end, which largely
> > > matches the other perf trace beauty things we build.
> >
> > Fair enough! I wanted to mimic how the kernel was building the syscall
> > tables as closely as possible, it's convenient to have cohesion.
>
> I think it makes sense in the kernel, as the built binary doesn't have
> cross-platform concerns. This is probably also the reason why the perf
> tool has an arch directory. Let me know what you think is the right
> direction for the perf tool syscall table code.
I am hesitant about moving all of the arch-specific syscall generation
flags into a single file. There is currently a really clean separation
between the architectures and it's possible to generate all of the
syscall tables for all of the architecutures based on the paths to the
syscall table. What causes the arch directory to be a pain for Bazel? I
guess I am mostly confused why it makes sense to change the kernel
Makefiles in order to accomidate a rewrite of the build system in Bazel
that isn't planned to be used upstream.
- Charlie
>
> > What is the usecase for the bazel version?
>
> I'm sure there's more info in:
> https://bazel.build/
> but the main thing is having hermetic and reproducible builds. The
> main problem with open sourcing would be dealing with external
> repositories, test set up, etc. Tbh, hermetic builds are a challenge
> as things like lex and yacc will vary the C code they generate based
> on the platform they run on. Bazel has plans to change the world so
> maybe this could be more of a thing in the future.
>
> Fwiw, I did push changes into the perf tree so that man page building
> was reproducible:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/commit/tools/perf/Documentation?h=perf-tools-next&id=d586ac10ce56b2381b8e1d8ed74660c1b2b8ab0d
> The man pages used to reflect the date/time they were built, but now
> reflect the date the of the commit of the file being built:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/Documentation/Makefile?h=perf-tools-next#n255
>
> Thanks,
> Ian
>
> > - Charlie
> >
> > >
> > > Thanks,
> > > Ian
> > >
> > > > >
> > > > > The patches generating a syscall(_32|_64)?.h landed. These changes
> > > > > take your changes and make it so that we just run the script once
> > > > > building a header file for all architectures. On x86 we then have the
> > > > > tables be guarded by ifdefs on i386 and x86-64. Then rather than the
> > > > > table just matching the host architecture the ELF machine is used for
> > > > > the executable running.
> > > > >
> > > > > Thanks,
> > > > > Ian
> > > > >
> > > > > > - Charlie
> > > > > >
> > > > > > >
> > > > > > > Ian Rogers (7):
> > > > > > > perf syscalltble: Remove syscall_table.h
> > > > > > > perf trace: Reorganize syscalls
> > > > > > > perf syscalltbl: Remove struct syscalltbl
> > > > > > > perf thread: Add support for reading the e_machine type for a thread
> > > > > > > perf trace beauty: Add syscalltbl.sh generating all system call tables
> > > > > > > perf syscalltbl: Use lookup table containing multiple architectures
> > > > > > > perf build: Remove Makefile.syscalls
> > > > > > >
> > > > > > > tools/perf/Makefile.perf | 10 +-
> > > > > > > tools/perf/arch/alpha/entry/syscalls/Kbuild | 2 -
> > > > > > > .../alpha/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > > tools/perf/arch/alpha/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/arc/entry/syscalls/Kbuild | 2 -
> > > > > > > .../arch/arc/entry/syscalls/Makefile.syscalls | 3 -
> > > > > > > tools/perf/arch/arc/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/arm/entry/syscalls/Kbuild | 4 -
> > > > > > > .../arch/arm/entry/syscalls/Makefile.syscalls | 2 -
> > > > > > > tools/perf/arch/arm/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/arm64/entry/syscalls/Kbuild | 3 -
> > > > > > > .../arm64/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > > tools/perf/arch/arm64/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/csky/entry/syscalls/Kbuild | 2 -
> > > > > > > .../csky/entry/syscalls/Makefile.syscalls | 3 -
> > > > > > > tools/perf/arch/csky/include/syscall_table.h | 2 -
> > > > > > > .../perf/arch/loongarch/entry/syscalls/Kbuild | 2 -
> > > > > > > .../entry/syscalls/Makefile.syscalls | 3 -
> > > > > > > .../arch/loongarch/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/mips/entry/syscalls/Kbuild | 2 -
> > > > > > > .../mips/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > > tools/perf/arch/mips/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/parisc/entry/syscalls/Kbuild | 3 -
> > > > > > > .../parisc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > > .../perf/arch/parisc/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/powerpc/entry/syscalls/Kbuild | 3 -
> > > > > > > .../powerpc/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > > .../perf/arch/powerpc/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/riscv/entry/syscalls/Kbuild | 2 -
> > > > > > > .../riscv/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > > tools/perf/arch/riscv/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/s390/entry/syscalls/Kbuild | 2 -
> > > > > > > .../s390/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > > tools/perf/arch/s390/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/sh/entry/syscalls/Kbuild | 2 -
> > > > > > > .../arch/sh/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > > tools/perf/arch/sh/include/syscall_table.h | 2 -
> > > > > > > tools/perf/arch/sparc/entry/syscalls/Kbuild | 3 -
> > > > > > > .../sparc/entry/syscalls/Makefile.syscalls | 5 -
> > > > > > > tools/perf/arch/sparc/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/x86/entry/syscalls/Kbuild | 3 -
> > > > > > > .../arch/x86/entry/syscalls/Makefile.syscalls | 6 -
> > > > > > > tools/perf/arch/x86/include/syscall_table.h | 8 -
> > > > > > > tools/perf/arch/xtensa/entry/syscalls/Kbuild | 2 -
> > > > > > > .../xtensa/entry/syscalls/Makefile.syscalls | 4 -
> > > > > > > .../perf/arch/xtensa/include/syscall_table.h | 2 -
> > > > > > > tools/perf/builtin-trace.c | 275 +++++++++++-------
> > > > > > > tools/perf/scripts/Makefile.syscalls | 61 ----
> > > > > > > tools/perf/scripts/syscalltbl.sh | 86 ------
> > > > > > > tools/perf/trace/beauty/syscalltbl.sh | 274 +++++++++++++++++
> > > > > > > tools/perf/util/syscalltbl.c | 142 ++++-----
> > > > > > > tools/perf/util/syscalltbl.h | 22 +-
> > > > > > > tools/perf/util/thread.c | 50 ++++
> > > > > > > tools/perf/util/thread.h | 14 +-
> > > > > > > 54 files changed, 598 insertions(+), 506 deletions(-)
> > > > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/alpha/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/arc/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/arm/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/arm64/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/csky/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/loongarch/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/mips/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/parisc/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/powerpc/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/riscv/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/s390/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/sh/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/sparc/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/x86/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Kbuild
> > > > > > > delete mode 100644 tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
> > > > > > > delete mode 100644 tools/perf/arch/xtensa/include/syscall_table.h
> > > > > > > delete mode 100644 tools/perf/scripts/Makefile.syscalls
> > > > > > > delete mode 100755 tools/perf/scripts/syscalltbl.sh
> > > > > > > create mode 100755 tools/perf/trace/beauty/syscalltbl.sh
> > > > > > >
> > > > > > > --
> > > > > > > 2.48.1.362.g079036d154-goog
> > > > > > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-03 23:02 ` Charlie Jenkins
@ 2025-02-04 1:58 ` Ian Rogers
2025-02-04 19:05 ` Charlie Jenkins
0 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2025-02-04 1:58 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 3, 2025 at 3:02 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> On Mon, Feb 03, 2025 at 12:54:59PM -0800, Ian Rogers wrote:
[snip]
> > I think it makes sense in the kernel, as the built binary doesn't have
> > cross-platform concerns. This is probably also the reason why the perf
> > tool has an arch directory. Let me know what you think is the right
> > direction for the perf tool syscall table code.
>
> I am hesitant about moving all of the arch-specific syscall generation
> flags into a single file.
In these changes I had a single file to build up a mapping from ELF
machine to syscall table in an array and I wanted to keep the logic to
build the array alongside the logic to build up the components of the
array - so the ifdefs were visually the same. As the scope is a single
file and the variables are static, this can give useful C compiler
"unused definition" warnings. You can trick the linker to give similar
warnings at the scope of a file, so this isn't a deal breaker.
> There is currently a really clean separation
> between the architectures and it's possible to generate all of the
> syscall tables for all of the architecutures based on the paths to the
> syscall table.
This doesn't happen currently as the build of the arch directory is to
add in $(SRCARCH) only. So
tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls will only be
included into the build if SRCARCH==arm64. As I've said I'm against
the idea of the arch directory as it nearly always causes cross
platform problems - not an issue in a Linux kernel build. We recently
eliminated dwarf-regs for this reason (and hopefully fixing up cross
platform disassembly issues as a consequence):
https://lore.kernel.org/all/20241108234606.429459-1-irogers@google.com/
We could have the syscall table logic not under arch and generate
multiple files, but we'd be adding extra logic to pull things apart to
then pull things back together again, which feels like unnecessary
complexity.
It seems in your changes the Kbuild and Makefile.syscalls are running
in the arch directory - this feels like a lot of peculiar and
separated build logic for just iterating over a bunch of arch
directory names and calling a shell function on them - albeit with
some arch specific parameters. There's also an extra C helper
executable in your code. I kind of like that I get a single header
that is the same across all architectures and with no more build
system requirements than to support ifdefs - in fact the ifdefs are
just there to keep the code size down there is a #define to make them
all have no effect. I hear your "clean separation" but I also think
separation across files can make things harder to read, state is in >1
place. I've tried to cleanly separate within the script.
I do think there is some tech debt in both changes. My:
```
#if defined(ALL_SYSCALLTBL) || defined(__riscv)
#if __BITS_PER_LONG != 64
EOF
build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
common,32,riscv,memfd_secret EM_RISCV
echo "#else" >> "$outfile"
build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
common,64,riscv,rlimit,memfd_secret EM_RISC
V
cat >> "$outfile" <<EOF
#endif //__BITS_PER_LONG != 64
```
means the perf binary word size determines the syscall table support.
This is because the e_machine in the ELF header isn't unique in these
two cases and having both tables would have no effect. You've moved
this into the env arch name handling, but I think having >1 way to
encode a binary type is suboptimal. There are some ELF flag ABI bits
that resolve disassembler things on csky, so perhaps a resolution is
to pass ELF flags along with the machine type. I'm not clear in your
change how "32_riscv" is generated to solve the same problem. Imo,
it'd kind of be nice not to introduce notions like "64_arm64" as we
seem to be always mapping/normalizing/... these different notions and
they feel inherently brittle.
> What causes the arch directory to be a pain for Bazel? I
> guess I am mostly confused why it makes sense to change the kernel
> Makefiles in order to accomidate a rewrite of the build system in Bazel
> that isn't planned to be used upstream.
It's just software and so the issues are resolvable, ie I don't think
bazel should be determining what happens upstream - it motivates me to
some extent. For the bazel build I need to match the Makefile behavior
with bits of script called genrule, the scope and quantity of these
increase with the arch directory model, extra executables to have in
the build etc. I also imagine cross platform stuff will add
complexity, like mapping blaze's notions of machine type to those
introduced in your change. It is all a lot of stuff and I think what's
in these changes keeps things about as simple as they can be. It'd be
nice to integrate the best features of both changes and I think some
of the e_machine stuff here can be added onto your change to get the
i386/x86-64 case to work. I'm not sold on the complexity of the build
in your changes though, multiple files, Kbuild and Makefile.syscalls,
the arch directory not optionally being built, helper executables.
Ultimately it is the same shell logic in both changes, and your
previous work laid out all the ground work for this (I'm very grateful
for it :-) ).
Thanks,
Ian
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-04 1:58 ` Ian Rogers
@ 2025-02-04 19:05 ` Charlie Jenkins
2025-02-04 19:17 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Charlie Jenkins @ 2025-02-04 19:05 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Mon, Feb 03, 2025 at 05:58:29PM -0800, Ian Rogers wrote:
> On Mon, Feb 3, 2025 at 3:02 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > On Mon, Feb 03, 2025 at 12:54:59PM -0800, Ian Rogers wrote:
> [snip]
> > > I think it makes sense in the kernel, as the built binary doesn't have
> > > cross-platform concerns. This is probably also the reason why the perf
> > > tool has an arch directory. Let me know what you think is the right
> > > direction for the perf tool syscall table code.
> >
> > I am hesitant about moving all of the arch-specific syscall generation
> > flags into a single file.
>
> In these changes I had a single file to build up a mapping from ELF
> machine to syscall table in an array and I wanted to keep the logic to
> build the array alongside the logic to build up the components of the
> array - so the ifdefs were visually the same. As the scope is a single
> file and the variables are static, this can give useful C compiler
> "unused definition" warnings. You can trick the linker to give similar
> warnings at the scope of a file, so this isn't a deal breaker.
>
> > There is currently a really clean separation
> > between the architectures and it's possible to generate all of the
> > syscall tables for all of the architecutures based on the paths to the
> > syscall table.
>
> This doesn't happen currently as the build of the arch directory is to
> add in $(SRCARCH) only. So
> tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls will only be
> included into the build if SRCARCH==arm64. As I've said I'm against
> the idea of the arch directory as it nearly always causes cross
> platform problems - not an issue in a Linux kernel build. We recently
> eliminated dwarf-regs for this reason (and hopefully fixing up cross
> platform disassembly issues as a consequence):
> https://lore.kernel.org/all/20241108234606.429459-1-irogers@google.com/
> We could have the syscall table logic not under arch and generate
> multiple files, but we'd be adding extra logic to pull things apart to
> then pull things back together again, which feels like unnecessary
> complexity.
>
> It seems in your changes the Kbuild and Makefile.syscalls are running
> in the arch directory - this feels like a lot of peculiar and
> separated build logic for just iterating over a bunch of arch
> directory names and calling a shell function on them - albeit with
> some arch specific parameters. There's also an extra C helper
> executable in your code.
Yes, I can understand why you be opposed to that and I don't have a good
counterargument.
> I kind of like that I get a single header
> that is the same across all architectures and with no more build
> system requirements than to support ifdefs - in fact the ifdefs are
> just there to keep the code size down there is a #define to make them
> all have no effect. I hear your "clean separation" but I also think
> separation across files can make things harder to read, state is in >1
> place. I've tried to cleanly separate within the script.
>
> I do think there is some tech debt in both changes. My:
> ```
> #if defined(ALL_SYSCALLTBL) || defined(__riscv)
> #if __BITS_PER_LONG != 64
> EOF
> build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
> common,32,riscv,memfd_secret EM_RISCV
> echo "#else" >> "$outfile"
> build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
> common,64,riscv,rlimit,memfd_secret EM_RISC
> V
> cat >> "$outfile" <<EOF
> #endif //__BITS_PER_LONG != 64
> ```
> means the perf binary word size determines the syscall table support.
> This is because the e_machine in the ELF header isn't unique in these
> two cases and having both tables would have no effect. You've moved
> this into the env arch name handling, but I think having >1 way to
> encode a binary type is suboptimal. There are some ELF flag ABI bits
> that resolve disassembler things on csky, so perhaps a resolution is
> to pass ELF flags along with the machine type. I'm not clear in your
> change how "32_riscv" is generated to solve the same problem. Imo,
> it'd kind of be nice not to introduce notions like "64_arm64" as we
> seem to be always mapping/normalizing/... these different notions and
> they feel inherently brittle.
Maybe it is brittle? It could be mapped to e_machine, but that just
might not be reasonable to work into the method from my patch.
>
> > What causes the arch directory to be a pain for Bazel? I
> > guess I am mostly confused why it makes sense to change the kernel
> > Makefiles in order to accomidate a rewrite of the build system in Bazel
> > that isn't planned to be used upstream.
>
> It's just software and so the issues are resolvable, ie I don't think
> bazel should be determining what happens upstream - it motivates me to
> some extent. For the bazel build I need to match the Makefile behavior
> with bits of script called genrule, the scope and quantity of these
> increase with the arch directory model, extra executables to have in
> the build etc. I also imagine cross platform stuff will add
> complexity, like mapping blaze's notions of machine type to those
> introduced in your change. It is all a lot of stuff and I think what's
> in these changes keeps things about as simple as they can be. It'd be
> nice to integrate the best features of both changes and I think some
> of the e_machine stuff here can be added onto your change to get the
> i386/x86-64 case to work. I'm not sold on the complexity of the build
> in your changes though, multiple files, Kbuild and Makefile.syscalls,
> the arch directory not optionally being built, helper executables.
> Ultimately it is the same shell logic in both changes, and your
> previous work laid out all the ground work for this (I'm very grateful
> for it :-) ).
Thanks for elaborating on this! I do wish we had more of this
conversation on the original patch so we could have molded the original
patch closer to what this one is doing. I know you did mention you would
like to get rid of the arch directory as feedback on that patch but I
hadn't realized that this was the direction you were hoping to take
this. It does seem like the changes you have made in this patch will
lead to a something that is more robust and simpler to maintain, so we
can move forward with reviewing this patch and stop reviewing the one I
wrote.
- Charlie
>
> Thanks,
> Ian
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 0/7] perf: Support multiple system call tables in the build
2025-02-04 19:05 ` Charlie Jenkins
@ 2025-02-04 19:17 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-04 19:17 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Bibo Mao, Arnd Bergmann, Huacai Chen, Catalin Marinas,
Jiri Slaby, Björn Töpel, Howard Chu, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Tue, Feb 4, 2025 at 11:05 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> On Mon, Feb 03, 2025 at 05:58:29PM -0800, Ian Rogers wrote:
> > On Mon, Feb 3, 2025 at 3:02 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > On Mon, Feb 03, 2025 at 12:54:59PM -0800, Ian Rogers wrote:
> > [snip]
> > > > I think it makes sense in the kernel, as the built binary doesn't have
> > > > cross-platform concerns. This is probably also the reason why the perf
> > > > tool has an arch directory. Let me know what you think is the right
> > > > direction for the perf tool syscall table code.
> > >
> > > I am hesitant about moving all of the arch-specific syscall generation
> > > flags into a single file.
> >
> > In these changes I had a single file to build up a mapping from ELF
> > machine to syscall table in an array and I wanted to keep the logic to
> > build the array alongside the logic to build up the components of the
> > array - so the ifdefs were visually the same. As the scope is a single
> > file and the variables are static, this can give useful C compiler
> > "unused definition" warnings. You can trick the linker to give similar
> > warnings at the scope of a file, so this isn't a deal breaker.
> >
> > > There is currently a really clean separation
> > > between the architectures and it's possible to generate all of the
> > > syscall tables for all of the architecutures based on the paths to the
> > > syscall table.
> >
> > This doesn't happen currently as the build of the arch directory is to
> > add in $(SRCARCH) only. So
> > tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls will only be
> > included into the build if SRCARCH==arm64. As I've said I'm against
> > the idea of the arch directory as it nearly always causes cross
> > platform problems - not an issue in a Linux kernel build. We recently
> > eliminated dwarf-regs for this reason (and hopefully fixing up cross
> > platform disassembly issues as a consequence):
> > https://lore.kernel.org/all/20241108234606.429459-1-irogers@google.com/
> > We could have the syscall table logic not under arch and generate
> > multiple files, but we'd be adding extra logic to pull things apart to
> > then pull things back together again, which feels like unnecessary
> > complexity.
> >
> > It seems in your changes the Kbuild and Makefile.syscalls are running
> > in the arch directory - this feels like a lot of peculiar and
> > separated build logic for just iterating over a bunch of arch
> > directory names and calling a shell function on them - albeit with
> > some arch specific parameters. There's also an extra C helper
> > executable in your code.
>
> Yes, I can understand why you be opposed to that and I don't have a good
> counterargument.
>
> > I kind of like that I get a single header
> > that is the same across all architectures and with no more build
> > system requirements than to support ifdefs - in fact the ifdefs are
> > just there to keep the code size down there is a #define to make them
> > all have no effect. I hear your "clean separation" but I also think
> > separation across files can make things harder to read, state is in >1
> > place. I've tried to cleanly separate within the script.
> >
> > I do think there is some tech debt in both changes. My:
> > ```
> > #if defined(ALL_SYSCALLTBL) || defined(__riscv)
> > #if __BITS_PER_LONG != 64
> > EOF
> > build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
> > common,32,riscv,memfd_secret EM_RISCV
> > echo "#else" >> "$outfile"
> > build_tables "$tools_dir/scripts/syscall.tbl" "$outfile"
> > common,64,riscv,rlimit,memfd_secret EM_RISC
> > V
> > cat >> "$outfile" <<EOF
> > #endif //__BITS_PER_LONG != 64
> > ```
> > means the perf binary word size determines the syscall table support.
> > This is because the e_machine in the ELF header isn't unique in these
> > two cases and having both tables would have no effect. You've moved
> > this into the env arch name handling, but I think having >1 way to
> > encode a binary type is suboptimal. There are some ELF flag ABI bits
> > that resolve disassembler things on csky, so perhaps a resolution is
> > to pass ELF flags along with the machine type. I'm not clear in your
> > change how "32_riscv" is generated to solve the same problem. Imo,
> > it'd kind of be nice not to introduce notions like "64_arm64" as we
> > seem to be always mapping/normalizing/... these different notions and
> > they feel inherently brittle.
>
> Maybe it is brittle? It could be mapped to e_machine, but that just
> might not be reasonable to work into the method from my patch.
>
> >
> > > What causes the arch directory to be a pain for Bazel? I
> > > guess I am mostly confused why it makes sense to change the kernel
> > > Makefiles in order to accomidate a rewrite of the build system in Bazel
> > > that isn't planned to be used upstream.
> >
> > It's just software and so the issues are resolvable, ie I don't think
> > bazel should be determining what happens upstream - it motivates me to
> > some extent. For the bazel build I need to match the Makefile behavior
> > with bits of script called genrule, the scope and quantity of these
> > increase with the arch directory model, extra executables to have in
> > the build etc. I also imagine cross platform stuff will add
> > complexity, like mapping blaze's notions of machine type to those
> > introduced in your change. It is all a lot of stuff and I think what's
> > in these changes keeps things about as simple as they can be. It'd be
> > nice to integrate the best features of both changes and I think some
> > of the e_machine stuff here can be added onto your change to get the
> > i386/x86-64 case to work. I'm not sold on the complexity of the build
> > in your changes though, multiple files, Kbuild and Makefile.syscalls,
> > the arch directory not optionally being built, helper executables.
> > Ultimately it is the same shell logic in both changes, and your
> > previous work laid out all the ground work for this (I'm very grateful
> > for it :-) ).
>
> Thanks for elaborating on this! I do wish we had more of this
> conversation on the original patch so we could have molded the original
> patch closer to what this one is doing. I know you did mention you would
> like to get rid of the arch directory as feedback on that patch but I
> hadn't realized that this was the direction you were hoping to take
> this. It does seem like the changes you have made in this patch will
> lead to a something that is more robust and simpler to maintain, so we
> can move forward with reviewing this patch and stop reviewing the one I
> wrote.
Thanks and sorry for work done that may not land - the maintainers may
prefer the approach in your patch and my opinions matter little to
them. If it is any consolation I wrote an entire Rust symbol demangler
[1] that I don't expect to land :-) I also appreciate that you've been
cleaning up the tools build infrastructure along with your changes,
something there isn't enough of.
Thanks,
Ian
[1] https://lore.kernel.org/lkml/20250129193037.573431-1-irogers@google.com/
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 2/7] perf trace: Reorganize syscalls
2025-02-01 7:14 ` [PATCH v1 2/7] perf trace: Reorganize syscalls Ian Rogers
@ 2025-02-05 0:12 ` Howard Chu
2025-02-05 5:00 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Howard Chu @ 2025-02-05 0:12 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
Hello Ian,
Thanks for doing this.
On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
>
> Identify struct syscall information in the syscalls table by a machine
> type and syscall number, not just system call number. Having the
> machine type means that 32-bit system calls can be differentiated from
> 64-bit ones on a machine capable of both. Having a table for all
> machine types and all system call numbers would be too large, so
> maintain a sorted array of system calls as they are encountered.
>
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
> tools/perf/builtin-trace.c | 178 +++++++++++++++++++++++++------------
> 1 file changed, 119 insertions(+), 59 deletions(-)
>
> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index ac97632f13dc..10d3ad0d21f7 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
> @@ -66,6 +66,7 @@
> #include "rb_resort.h"
> #include "../perf.h"
> #include "trace_augment.h"
> +#include "dwarf-regs.h"
>
> #include <errno.h>
> #include <inttypes.h>
> @@ -86,6 +87,7 @@
>
> #include <linux/ctype.h>
> #include <perf/mmap.h>
> +#include <tools/libc_compat.h>
>
> #ifdef HAVE_LIBTRACEEVENT
> #include <event-parse.h>
> @@ -143,7 +145,10 @@ struct trace {
> struct perf_tool tool;
> struct syscalltbl *sctbl;
> struct {
> + /** Sorted sycall numbers used by the trace. */
> struct syscall *table;
> + /** Size of table. */
> + size_t table_size;
> struct {
> struct evsel *sys_enter,
> *sys_exit,
> @@ -1445,22 +1450,37 @@ static const struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias)
> return __syscall_fmt__find_by_alias(syscall_fmts, nmemb, alias);
> }
>
> -/*
> - * is_exit: is this "exit" or "exit_group"?
> - * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter.
> - * args_size: sum of the sizes of the syscall arguments, anything after that is augmented stuff: pathname for openat, etc.
> - * nonexistent: Just a hole in the syscall table, syscall id not allocated
> +/**
> + * struct syscall
> */
> struct syscall {
> + /** @e_machine: The ELF machine associated with the entry. */
> + int e_machine;
> + /** @id: id value from the tracepoint, the system call number. */
> + int id;
> struct tep_event *tp_format;
> int nr_args;
> + /**
> + * @args_size: sum of the sizes of the syscall arguments, anything
> + * after that is augmented stuff: pathname for openat, etc.
> + */
> +
> int args_size;
> struct {
> struct bpf_program *sys_enter,
> *sys_exit;
> } bpf_prog;
> + /** @is_exit: is this "exit" or "exit_group"? */
> bool is_exit;
> + /**
> + * @is_open: is this "open" or "openat"? To associate the fd returned in
> + * sys_exit with the pathname in sys_enter.
> + */
> bool is_open;
> + /**
> + * @nonexistent: Name lookup failed. Just a hole in the syscall table,
> + * syscall id not allocated.
> + */
> bool nonexistent;
> bool use_btf;
> struct tep_format_field *args;
> @@ -2066,22 +2086,21 @@ static int syscall__set_arg_fmts(struct syscall *sc)
> return 0;
> }
>
> -static int trace__read_syscall_info(struct trace *trace, int id)
> +static int syscall__read_info(struct syscall *sc, struct trace *trace)
> {
> char tp_name[128];
> - struct syscall *sc;
> - const char *name = syscalltbl__name(trace->sctbl, id);
> + const char *name;
> int err;
>
> - if (trace->syscalls.table == NULL) {
> - trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
> - if (trace->syscalls.table == NULL)
> - return -ENOMEM;
> - }
> - sc = trace->syscalls.table + id;
> if (sc->nonexistent)
> return -EEXIST;
>
> + if (sc->name) {
> + /* Info already read. */
> + return 0;
> + }
> +
> + name = syscalltbl__name(trace->sctbl, sc->id);
> if (name == NULL) {
> sc->nonexistent = true;
> return -EEXIST;
> @@ -2104,11 +2123,12 @@ static int trace__read_syscall_info(struct trace *trace, int id)
> */
> if (IS_ERR(sc->tp_format)) {
> sc->nonexistent = true;
> - return PTR_ERR(sc->tp_format);
> + err = PTR_ERR(sc->tp_format);
> + sc->tp_format = NULL;
> + return err;
> }
>
> - if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
> - RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
> + if (syscall__alloc_arg_fmts(sc, sc->tp_format->format.nr_fields))
Makes sense because IS_ERR(sc->tp_format) is checked a few lines
above. However, nr_fields can be 7 with the __syscall_nr prefix. I
sent a patch to fix this, but it's not included here... Never mind,
it's off-topic. This patch looks good.
Thanks,
Howard
> return -ENOMEM;
>
> sc->args = sc->tp_format->format.fields;
> @@ -2397,13 +2417,67 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
> return printed;
> }
>
> +static void syscall__init(struct syscall *sc, int e_machine, int id)
> +{
> + memset(sc, 0, sizeof(*sc));
> + sc->e_machine = e_machine;
> + sc->id = id;
> +}
> +
> +static void syscall__exit(struct syscall *sc)
> +{
> + if (!sc)
> + return;
> +
> + zfree(&sc->arg_fmt);
> +}
> +
> +static int syscall__cmp(const void *va, const void *vb)
> +{
> + const struct syscall *a = va, *b = vb;
> +
> + if (a->e_machine != b->e_machine)
> + return a->e_machine - b->e_machine;
> +
> + return a->id - b->id;
> +}
> +
> +static struct syscall *trace__find_syscall(struct trace *trace, int e_machine, int id)
> +{
> + struct syscall key = {
> + .e_machine = e_machine,
> + .id = id,
> + };
> + struct syscall *sc, *tmp;
> +
> + sc = bsearch(&key, trace->syscalls.table, trace->syscalls.table_size,
> + sizeof(struct syscall), syscall__cmp);
> + if (sc)
> + return sc;
> +
> + tmp = reallocarray(trace->syscalls.table, trace->syscalls.table_size + 1,
> + sizeof(struct syscall));
> + if (!tmp)
> + return NULL;
> +
> + trace->syscalls.table = tmp;
> + sc = &trace->syscalls.table[trace->syscalls.table_size++];
> + syscall__init(sc, e_machine, id);
> + qsort(trace->syscalls.table, trace->syscalls.table_size, sizeof(struct syscall),
> + syscall__cmp);
> + sc = bsearch(&key, trace->syscalls.table, trace->syscalls.table_size,
> + sizeof(struct syscall), syscall__cmp);
> + return sc;
> +}
> +
> typedef int (*tracepoint_handler)(struct trace *trace, struct evsel *evsel,
> union perf_event *event,
> struct perf_sample *sample);
>
> -static struct syscall *trace__syscall_info(struct trace *trace,
> - struct evsel *evsel, int id)
> +static struct syscall *trace__syscall_info(struct trace *trace, struct evsel *evsel,
> + int e_machine, int id)
> {
> + struct syscall *sc;
> int err = 0;
>
> if (id < 0) {
> @@ -2428,28 +2502,20 @@ static struct syscall *trace__syscall_info(struct trace *trace,
>
> err = -EINVAL;
>
> - if (id > trace->sctbl->syscalls.max_id) {
> - goto out_cant_read;
> - }
> -
> - if ((trace->syscalls.table == NULL || trace->syscalls.table[id].name == NULL) &&
> - (err = trace__read_syscall_info(trace, id)) != 0)
> - goto out_cant_read;
> + sc = trace__find_syscall(trace, e_machine, id);
> + if (sc)
> + err = syscall__read_info(sc, trace);
>
> - if (trace->syscalls.table && trace->syscalls.table[id].nonexistent)
> - goto out_cant_read;
> -
> - return &trace->syscalls.table[id];
> -
> -out_cant_read:
> - if (verbose > 0) {
> + if (err && verbose > 0) {
> char sbuf[STRERR_BUFSIZE];
> - fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf)));
> - if (id <= trace->sctbl->syscalls.max_id && trace->syscalls.table[id].name != NULL)
> - fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
> +
> + fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err,
> + str_error_r(-err, sbuf, sizeof(sbuf)));
> + if (sc && sc->name)
> + fprintf(trace->output, "(%s)", sc->name);
> fputs(" information\n", trace->output);
> }
> - return NULL;
> + return err ? NULL : sc;
> }
>
> struct syscall_stats {
> @@ -2596,14 +2662,6 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam
> return NULL;
> }
>
> -static void syscall__exit(struct syscall *sc)
> -{
> - if (!sc)
> - return;
> -
> - zfree(&sc->arg_fmt);
> -}
> -
> static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
> union perf_event *event __maybe_unused,
> struct perf_sample *sample)
> @@ -2615,7 +2673,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> int augmented_args_size = 0;
> void *augmented_args = NULL;
> - struct syscall *sc = trace__syscall_info(trace, evsel, id);
> + struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> if (sc == NULL)
> @@ -2689,7 +2747,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
> struct thread_trace *ttrace;
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> - struct syscall *sc = trace__syscall_info(trace, evsel, id);
> + struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> char msg[1024];
> void *args, *augmented_args = NULL;
> int augmented_args_size;
> @@ -2764,7 +2822,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
> int alignment = trace->args_alignment;
> - struct syscall *sc = trace__syscall_info(trace, evsel, id);
> + struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> if (sc == NULL)
> @@ -3117,7 +3175,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
>
> if (evsel == trace->syscalls.events.bpf_output) {
> int id = perf_evsel__sc_tp_uint(evsel, id, sample);
> - struct syscall *sc = trace__syscall_info(trace, evsel, id);
> + struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
>
> if (sc) {
> fprintf(trace->output, "%s(", sc->name);
> @@ -3622,7 +3680,7 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
>
> static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
>
> if (sc == NULL)
> return;
> @@ -3633,20 +3691,20 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
>
> static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
> {
> struct tep_format_field *field;
> - struct syscall *sc = trace__syscall_info(trace, NULL, key);
> + struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> const struct btf_type *bt;
> char *struct_offset, *tmp, name[32];
> bool can_augment = false;
> @@ -3744,7 +3802,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> try_to_find_pair:
> for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> int id = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *pair = trace__syscall_info(trace, NULL, id);
> + struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
> struct bpf_program *pair_prog;
> bool is_candidate = false;
>
> @@ -3894,7 +3952,7 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> */
> for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> int key = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *sc = trace__syscall_info(trace, NULL, key);
> + struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> struct bpf_program *pair_prog;
> int prog_fd;
>
> @@ -4659,7 +4717,11 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
> pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
> avg /= NSEC_PER_MSEC;
>
> - sc = &trace->syscalls.table[syscall_stats_entry->syscall];
> + sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
> + syscall_stats_entry->syscall);
> + if (!sc)
> + continue;
> +
> printed += fprintf(fp, " %-15s", sc->name);
> printed += fprintf(fp, " %8" PRIu64 " %6" PRIu64 " %9.3f %9.3f %9.3f",
> n, stats->nr_failures, syscall_stats_entry->msecs, min, avg);
> @@ -5067,12 +5129,10 @@ static int trace__config(const char *var, const char *value, void *arg)
>
> static void trace__exit(struct trace *trace)
> {
> - int i;
> -
> strlist__delete(trace->ev_qualifier);
> zfree(&trace->ev_qualifier_ids.entries);
> if (trace->syscalls.table) {
> - for (i = 0; i <= trace->sctbl->syscalls.max_id; i++)
> + for (size_t i = 0; i < trace->syscalls.table_size; i++)
> syscall__exit(&trace->syscalls.table[i]);
> zfree(&trace->syscalls.table);
> }
> --
> 2.48.1.362.g079036d154-goog
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl
2025-02-01 7:14 ` [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl Ian Rogers
@ 2025-02-05 0:18 ` Howard Chu
2025-02-05 5:09 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Howard Chu @ 2025-02-05 0:18 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
Hello Ian,
On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
>
> The syscalltbl held entries of system call name and number pairs,
> generated from a native syscalltbl at start up. As there are gaps in
> the system call number there is a notion of index into the
> table. Going forward we want the system call table to be identifiable
> by a machine type, for example, i386 vs x86-64. Change the interface
> to the syscalltbl so (1) a (currently unused machine type of EM_HOST)
> is passed (2) the index to syscall number and system call name mapping
> is computed at build time.
>
> Two tables are used for this, an array of system call number to name,
> an array of system call numbers sorted by the system call name. The
> sorted array doesn't store strings in part to save memory and
> relocations. The index notion is carried forward and is an index into
> the sorted array of system call numbers, the data structures are
> opaque (held only in syscalltbl.c), and so the number of indices for a
> machine type is exposed as a new API.
>
> The arrays are computed in the syscalltbl.sh script and so no start-up
> time computation and storage is necessary.
>
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
> tools/perf/builtin-trace.c | 88 +++++++++++++-----------
> tools/perf/scripts/syscalltbl.sh | 36 ++++------
> tools/perf/util/syscalltbl.c | 113 ++++++++++---------------------
> tools/perf/util/syscalltbl.h | 22 ++----
> 4 files changed, 103 insertions(+), 156 deletions(-)
>
> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index 10d3ad0d21f7..7e3aa2f6c5e2 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
> @@ -143,7 +143,6 @@ struct syscall_fmt {
>
> struct trace {
> struct perf_tool tool;
> - struct syscalltbl *sctbl;
> struct {
> /** Sorted sycall numbers used by the trace. */
> struct syscall *table;
> @@ -2100,7 +2099,7 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
> return 0;
> }
>
> - name = syscalltbl__name(trace->sctbl, sc->id);
> + name = syscalltbl__name(sc->e_machine, sc->id);
> if (name == NULL) {
> sc->nonexistent = true;
> return -EEXIST;
> @@ -2196,10 +2195,14 @@ static int trace__validate_ev_qualifier(struct trace *trace)
>
> strlist__for_each_entry(pos, trace->ev_qualifier) {
> const char *sc = pos->s;
> - int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
> + /*
> + * TODO: Assume more than the validation/warnings are all for
> + * the same binary type as perf.
> + */
> + int id = syscalltbl__id(EM_HOST, sc), match_next = -1;
>
> if (id < 0) {
> - id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
> + id = syscalltbl__strglobmatch_first(EM_HOST, sc, &match_next);
> if (id >= 0)
> goto matches;
>
> @@ -2219,7 +2222,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
> continue;
>
> while (1) {
> - id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
> + id = syscalltbl__strglobmatch_next(EM_HOST, sc, &match_next);
> if (id < 0)
> break;
> if (nr_allocated == nr_used) {
> @@ -2673,6 +2676,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> int augmented_args_size = 0;
> void *augmented_args = NULL;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> @@ -2747,6 +2751,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
> struct thread_trace *ttrace;
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> char msg[1024];
> void *args, *augmented_args = NULL;
> @@ -2822,6 +2827,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
> int alignment = trace->args_alignment;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> @@ -3175,6 +3181,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
>
> if (evsel == trace->syscalls.events.bpf_output) {
> int id = perf_evsel__sc_tp_uint(evsel, id, sample);
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
>
> if (sc) {
> @@ -3678,9 +3685,9 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
> return trace->skel->progs.syscall_unaugmented;
> }
>
> -static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> +static void trace__init_syscall_bpf_progs(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
>
> if (sc == NULL)
> return;
> @@ -3689,22 +3696,22 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit");
> }
>
> -static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
> +static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> -static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
> +static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> -static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
> +static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int e_machine, int key, unsigned int *beauty_array)
> {
> struct tep_format_field *field;
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> const struct btf_type *bt;
> char *struct_offset, *tmp, name[32];
> bool can_augment = false;
> @@ -3800,9 +3807,9 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> return NULL;
>
> try_to_find_pair:
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int id = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
> + for (int i = 0, num_idx = syscalltbl__num_idx(sc->e_machine); i < num_idx; ++i) {
> + int id = syscalltbl__id_at_idx(sc->e_machine, i);
> + struct syscall *pair = trace__syscall_info(trace, NULL, sc->e_machine, id);
> struct bpf_program *pair_prog;
> bool is_candidate = false;
>
> @@ -3886,7 +3893,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> return NULL;
> }
>
> -static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace, int e_machine)
> {
> int map_enter_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_enter);
> int map_exit_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_exit);
> @@ -3894,27 +3901,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> int err = 0;
> unsigned int beauty_array[6];
>
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int prog_fd, key = syscalltbl__id_at_idx(trace->sctbl, i);
> + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> + int prog_fd, key = syscalltbl__id_at_idx(e_machine, i);
>
> if (!trace__syscall_enabled(trace, key))
> continue;
>
> - trace__init_syscall_bpf_progs(trace, key);
> + trace__init_syscall_bpf_progs(trace, e_machine, key);
>
> // It'll get at least the "!raw_syscalls:unaugmented"
> - prog_fd = trace__bpf_prog_sys_enter_fd(trace, key);
> + prog_fd = trace__bpf_prog_sys_enter_fd(trace, e_machine, key);
> err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY);
> if (err)
> break;
> - prog_fd = trace__bpf_prog_sys_exit_fd(trace, key);
> + prog_fd = trace__bpf_prog_sys_exit_fd(trace, e_machine, key);
> err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY);
> if (err)
> break;
>
> /* use beauty_map to tell BPF how many bytes to collect, set beauty_map's value here */
> memset(beauty_array, 0, sizeof(beauty_array));
> - err = trace__bpf_sys_enter_beauty_map(trace, key, (unsigned int *)beauty_array);
> + err = trace__bpf_sys_enter_beauty_map(trace, e_machine, key, (unsigned int *)beauty_array);
> if (err)
> continue;
> err = bpf_map_update_elem(beauty_map_fd, &key, beauty_array, BPF_ANY);
> @@ -3950,9 +3957,9 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> * first and second arg (this one on the raw_syscalls:sys_exit prog
> * array tail call, then that one will be used.
> */
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int key = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> + int key = syscalltbl__id_at_idx(e_machine, i);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> struct bpf_program *pair_prog;
> int prog_fd;
>
> @@ -4389,8 +4396,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> goto out_error_mem;
>
> #ifdef HAVE_BPF_SKEL
> - if (trace->skel && trace->skel->progs.sys_enter)
> - trace__init_syscalls_bpf_prog_array_maps(trace);
> + if (trace->skel && trace->skel->progs.sys_enter) {
> + /*
> + * TODO: Initialize for all host binary machine types, not just
> + * those matching the perf binary.
> + */
> + trace__init_syscalls_bpf_prog_array_maps(trace, EM_HOST);
> + }
> #endif
>
> if (trace->ev_qualifier_ids.nr > 0) {
> @@ -4415,7 +4427,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> * So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is
> * not in use.
> */
> - trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close"));
> + /* TODO: support for more than just perf binary machine type close. */
> + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(EM_HOST, "close"));
>
> err = trace__expand_filters(trace, &evsel);
> if (err)
> @@ -4688,8 +4701,7 @@ DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs,
> entry->msecs = stats ? (u64)stats->stats.n * (avg_stats(&stats->stats) / NSEC_PER_MSEC) : 0;
> }
>
> -static size_t thread__dump_stats(struct thread_trace *ttrace,
> - struct trace *trace, FILE *fp)
> +static size_t thread__dump_stats(struct thread_trace *ttrace, struct trace *trace, int e_machine, FILE *fp)
> {
> size_t printed = 0;
> struct syscall *sc;
> @@ -4717,7 +4729,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
> pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
> avg /= NSEC_PER_MSEC;
>
> - sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
> + sc = trace__syscall_info(trace, /*evsel=*/NULL, e_machine,
> syscall_stats_entry->syscall);
> if (!sc)
> continue;
> @@ -4767,7 +4779,8 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
> else if (fputc('\n', fp) != EOF)
> ++printed;
>
> - printed += thread__dump_stats(ttrace, trace, fp);
> + /* TODO: get e_machine from thread. */
> + printed += thread__dump_stats(ttrace, trace, EM_HOST, fp);
>
> return printed;
> }
> @@ -4999,8 +5012,9 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
> *sep = '\0';
>
> list = 0;
> - if (syscalltbl__id(trace->sctbl, s) >= 0 ||
> - syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
> + /* TODO: support for more than just perf binary machine type syscalls. */
> + if (syscalltbl__id(EM_HOST, s) >= 0 ||
> + syscalltbl__strglobmatch_first(EM_HOST, s, &idx) >= 0) {
> list = 1;
> goto do_concat;
> }
> @@ -5136,7 +5150,6 @@ static void trace__exit(struct trace *trace)
> syscall__exit(&trace->syscalls.table[i]);
> zfree(&trace->syscalls.table);
> }
> - syscalltbl__delete(trace->sctbl);
> zfree(&trace->perfconfig_events);
> }
>
> @@ -5282,9 +5295,8 @@ int cmd_trace(int argc, const char **argv)
> sigaction(SIGCHLD, &sigchld_act, NULL);
>
> trace.evlist = evlist__new();
> - trace.sctbl = syscalltbl__new();
>
> - if (trace.evlist == NULL || trace.sctbl == NULL) {
> + if (trace.evlist == NULL) {
> pr_err("Not enough memory to run!\n");
> err = -ENOMEM;
> goto out;
> diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
> index 1ce0d5aa8b50..a39b3013b103 100755
> --- a/tools/perf/scripts/syscalltbl.sh
> +++ b/tools/perf/scripts/syscalltbl.sh
> @@ -50,37 +50,27 @@ fi
> infile="$1"
> outfile="$2"
>
> -nxt=0
> -
> -syscall_macro() {
> - nr="$1"
> - name="$2"
> -
> - echo " [$nr] = \"$name\","
> -}
> -
> -emit() {
> - nr="$1"
> - entry="$2"
> -
> - syscall_macro "$nr" "$entry"
> -}
> -
> -echo "static const char *const syscalltbl[] = {" > $outfile
> -
> sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
> grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
>
> -max_nr=0
> +echo "static const char *const syscall_num_to_name[] = {" > $outfile
> # the params are: nr abi name entry compat
> # use _ for intentionally unused variables according to SC2034
> while read nr _ name _ _; do
> - emit "$nr" "$name" >> $outfile
> - max_nr=$nr
> + echo " [$nr] = \"$name\"," >> $outfile
> done < $sorted_table
> +echo "};" >> $outfile
>
> -rm -f $sorted_table
> +echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile
>
> +# When sorting by name, add a suffix of 0s upto 20 characters so that system
> +# calls that differ with a numerical suffix don't sort before those
> +# without. This default behavior of sort differs from that of strcmp used at
> +# runtime. Use sed to strip the trailing 0s suffix afterwards.
> +grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table
> +while read name nr; do
> + echo " $nr, /* $name */" >> $outfile
> +done < $sorted_table
> echo "};" >> $outfile
>
> -echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
> +rm -f $sorted_table
> diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> index 2f76241494c8..760ac4d0869f 100644
> --- a/tools/perf/util/syscalltbl.c
> +++ b/tools/perf/util/syscalltbl.c
> @@ -9,6 +9,7 @@
> #include <stdlib.h>
> #include <asm/bitsperlong.h>
> #include <linux/compiler.h>
> +#include <linux/kernel.h>
> #include <linux/zalloc.h>
>
> #include <string.h>
> @@ -20,112 +21,66 @@
> #include <asm/syscalls_32.h>
> #endif
>
> -const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
> -static const char *const *syscalltbl_native = syscalltbl;
> +const char *syscalltbl__name(int e_machine __maybe_unused, int id)
> +{
> + if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
> + return syscall_num_to_name[id];
> + return NULL;
> +}
>
> -struct syscall {
> - int id;
> +struct syscall_cmp_key {
> const char *name;
> + const char *const *tbl;
> };
>
> static int syscallcmpname(const void *vkey, const void *ventry)
> {
> - const char *key = vkey;
> - const struct syscall *entry = ventry;
> + const struct syscall_cmp_key *key = vkey;
> + const uint16_t *entry = ventry;
>
> - return strcmp(key, entry->name);
> + return strcmp(key->name, key->tbl[*entry]);
> }
>
> -static int syscallcmp(const void *va, const void *vb)
> +int syscalltbl__id(int e_machine __maybe_unused, const char *name)
> {
> - const struct syscall *a = va, *b = vb;
> -
> - return strcmp(a->name, b->name);
> + struct syscall_cmp_key key = {
> + .name = name,
> + .tbl = syscall_num_to_name,
> + };
> + const int *id = bsearch(&key, syscall_sorted_names,
> + ARRAY_SIZE(syscall_sorted_names),
> + sizeof(syscall_sorted_names[0]),
> + syscallcmpname);
This has puzzled me several times lol. Searching in
syscall_sorted_names returns an int id... I get that it's sorted by
name, but maybe call it syscall_ids_sorted_by_name, syscall_ids, or
syscall_ids_sorted instead?
> +
> + return id ? *id : -1;
> }
>
> -static int syscalltbl__init_native(struct syscalltbl *tbl)
> +int syscalltbl__num_idx(int e_machine __maybe_unused)
I haven't found many instances of *num_idx in the source tree
indicating the length of an array. Are you okay with
syscalltbl__nr_idx()?
Otherwise LGTM.
Thanks,
Howard
> {
> - int nr_entries = 0, i, j;
> - struct syscall *entries;
> -
> - for (i = 0; i <= syscalltbl_native_max_id; ++i)
> - if (syscalltbl_native[i])
> - ++nr_entries;
> -
> - entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
> - if (tbl->syscalls.entries == NULL)
> - return -1;
> -
> - for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
> - if (syscalltbl_native[i]) {
> - entries[j].name = syscalltbl_native[i];
> - entries[j].id = i;
> - ++j;
> - }
> - }
> -
> - qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
> - tbl->syscalls.nr_entries = nr_entries;
> - tbl->syscalls.max_id = syscalltbl_native_max_id;
> - return 0;
> + return ARRAY_SIZE(syscall_sorted_names);
> }
>
> -struct syscalltbl *syscalltbl__new(void)
> +int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
> {
> - struct syscalltbl *tbl = malloc(sizeof(*tbl));
> - if (tbl) {
> - if (syscalltbl__init_native(tbl)) {
> - free(tbl);
> - return NULL;
> - }
> - }
> - return tbl;
> -}
> -
> -void syscalltbl__delete(struct syscalltbl *tbl)
> -{
> - zfree(&tbl->syscalls.entries);
> - free(tbl);
> -}
> -
> -const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
> -{
> - return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> -}
> -
> -int syscalltbl__id(struct syscalltbl *tbl, const char *name)
> -{
> - struct syscall *sc = bsearch(name, tbl->syscalls.entries,
> - tbl->syscalls.nr_entries, sizeof(*sc),
> - syscallcmpname);
> -
> - return sc ? sc->id : -1;
> -}
> -
> -int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx)
> -{
> - struct syscall *syscalls = tbl->syscalls.entries;
> -
> - return idx < tbl->syscalls.nr_entries ? syscalls[idx].id : -1;
> + return syscall_sorted_names[idx];
> }
>
> -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> +int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
> {
> - int i;
> - struct syscall *syscalls = tbl->syscalls.entries;
> + for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
> + const char *name = syscall_num_to_name[syscall_sorted_names[i]];
>
> - for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
> - if (strglobmatch(syscalls[i].name, syscall_glob)) {
> + if (strglobmatch(name, syscall_glob)) {
> *idx = i;
> - return syscalls[i].id;
> + return syscall_sorted_names[i];
> }
> }
>
> return -1;
> }
>
> -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> +int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx)
> {
> *idx = -1;
> - return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
> + return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx);
> }
> diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
> index 362411a6d849..2bb628eff367 100644
> --- a/tools/perf/util/syscalltbl.h
> +++ b/tools/perf/util/syscalltbl.h
> @@ -2,22 +2,12 @@
> #ifndef __PERF_SYSCALLTBL_H
> #define __PERF_SYSCALLTBL_H
>
> -struct syscalltbl {
> - struct {
> - int max_id;
> - int nr_entries;
> - void *entries;
> - } syscalls;
> -};
> +const char *syscalltbl__name(int e_machine, int id);
> +int syscalltbl__id(int e_machine, const char *name);
> +int syscalltbl__num_idx(int e_machine);
> +int syscalltbl__id_at_idx(int e_machine, int idx);
>
> -struct syscalltbl *syscalltbl__new(void);
> -void syscalltbl__delete(struct syscalltbl *tbl);
> -
> -const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
> -int syscalltbl__id(struct syscalltbl *tbl, const char *name);
> -int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx);
> -
> -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> +int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx);
> +int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx);
>
> #endif /* __PERF_SYSCALLTBL_H */
> --
> 2.48.1.362.g079036d154-goog
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures
2025-02-01 7:14 ` [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures Ian Rogers
@ 2025-02-05 0:24 ` Howard Chu
2025-02-05 5:17 ` Ian Rogers
0 siblings, 1 reply; 26+ messages in thread
From: Howard Chu @ 2025-02-05 0:24 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
Hello,
On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
>
> Switch to use the lookup table containing all architectures rather
> than tables matching the perf binary.
>
> This fixes perf trace when executed on a 32-bit i386 binary on an
> x86-64 machine. Note in the following the system call names of the
> 32-bit i386 binary as seen by an x86-64 perf.
>
> Before:
> ```
> ? ( ): a.out/447296 ... [continued]: munmap()) = 0
> 0.024 ( 0.001 ms): a.out/447296 recvfrom(ubuf: 0x2, size: 4160585708, flags: DONTROUTE|CTRUNC|TRUNC|DONTWAIT|EOR|WAITALL|FIN|SYN|CONFIRM|RST|ERRQUEUE|NOSIGNAL|WAITFORONE|BATCH|SOCK_DEVMEM|ZEROCOPY|FASTOPEN|CMSG_CLOEXEC|0x91f80000, addr: 0xe30, addr_len: 0xffce438c) = 1475198976
> 0.042 ( 0.003 ms): a.out/447296 lgetxattr(name: "", value: 0x3, size: 34) = 4160344064
> 0.054 ( 0.003 ms): a.out/447296 dup2(oldfd: -134422744, newfd: 4) = -1 ENOENT (No such file or directory)
> 0.060 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x2e646c2f6374652f,.iov_len = (__kernel_size_t)7307199665335594867,}, vlen: 557056, pos_h: 4160585708) = 3
> 0.074 ( 0.004 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2) = 4160237568
> 0.080 ( 0.001 ms): a.out/447296 lstat(filename: "", statbuf: 0x193f6) = 0
> 0.089 ( 0.007 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x3833692f62696c2f,.iov_len = (__kernel_size_t)3276497845987585334,}, vlen: 557056, pos_h: 4160585708) = 3
> 0.097 ( 0.002 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 512
> 0.103 ( 0.002 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2050) = 4157935616
> 0.107 ( 0.007 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x5, size: 2066) = 4158078976
> 0.116 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x1, size: 2066) = 4159639552
> 0.121 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 2066) = 4160184320
> 0.129 ( 0.002 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 50) = 4160196608
> 0.138 ( 0.001 ms): a.out/447296 lstat(filename: "") = 0
> 0.145 ( 0.002 ms): a.out/447296 mq_timedreceive(mqdes: 4291706800, u_msg_ptr: 0xf7f9ea48, msg_len: 134616640, u_msg_prio: 0xf7fd7fec, u_abs_timeout: (struct __kernel_timespec){.tv_sec = (__kernel_time64_t)-578174027777317696,.tv_nsec = (long long int)4160349376,}) = 0
> 0.148 ( 0.001 ms): a.out/447296 mkdirat(dfd: -134617816, pathname: " ��� ���▒���▒���", mode: IFREG|ISUID|IRUSR|IWGRP|0xf7fd0000) = 447296
> 0.150 ( 0.001 ms): a.out/447296 process_vm_writev(pid: -134617812, lvec: (struct iovec){.iov_base = (void *)0xf7f9e9c8f7f9e4c0,.iov_len = (__kernel_size_t)4160349376,}, liovcnt: 4160588048, rvec: (struct iovec){}, riovcnt: 4160585708, flags: 4291707352) = 0
> 0.197 ( 0.004 ms): a.out/447296 capget(header: 4160184320, dataptr: 8192) = 0
> 0.202 ( 0.002 ms): a.out/447296 capget(header: 1448669184, dataptr: 4096) = 0
> 0.208 ( 0.002 ms): a.out/447296 capget(header: 4160577536, dataptr: 8192) = 0
> 0.220 ( 0.001 ms): a.out/447296 getxattr(pathname: "", name: "c������", value: 0xf7f77e34, size: 1) = 0
> 0.228 ( 0.005 ms): a.out/447296 fchmod(fd: -134729728, mode: IRUGO|IWUGO|IFREG|IFIFO|ISVTX|IXUSR|0x10000) = 0
> 0.240 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: 0x5658e008, pos_h: 4160192052) = 3
> 0.250 ( 0.008 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 1436
> 0.260 ( 0.018 ms): a.out/447296 stat(filename: "", statbuf: 0xffce32ac) = 1436
> 0.288 (1000.213 ms): a.out/447296 readlinkat(buf: 0xffce31d4, bufsiz: 4291703244) = 0
> ```
>
> After:
> ```
> ? ( ): a.out/442930 ... [continued]: execve()) = 0
> 0.023 ( 0.002 ms): a.out/442930 brk() = 0x57760000
> 0.052 ( 0.003 ms): a.out/442930 access(filename: 0xf7f5af28, mode: R) = -1 ENOENT (No such file or directory)
> 0.059 ( 0.009 ms): a.out/442930 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
> 0.078 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
> 0.087 ( 0.007 ms): a.out/442930 openat(dfd: CWD, filename: "/lib/i386-linux-", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
> 0.095 ( 0.002 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdbb70, count: 512) = 512
> 0.135 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
> 0.148 ( 0.001 ms): a.out/442930 set_tid_address(tidptr: 0xf7f2b528) = 442930 (a.out)
> 0.150 ( 0.001 ms): a.out/442930 set_robust_list(head: 0xf7f2b52c, len: 12) =
> 0.196 ( 0.004 ms): a.out/442930 mprotect(start: 0xf7f03000, len: 8192, prot: READ) = 0
> 0.202 ( 0.002 ms): a.out/442930 mprotect(start: 0x5658e000, len: 4096, prot: READ) = 0
> 0.207 ( 0.002 ms): a.out/442930 mprotect(start: 0xf7f63000, len: 8192, prot: READ) = 0
> 0.230 ( 0.005 ms): a.out/442930 munmap(addr: 0xf7f10000, len: 103414) = 0
> 0.244 ( 0.010 ms): a.out/442930 openat(dfd: CWD, filename: 0x5658d008) = 3
> 0.255 ( 0.007 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdb67c, count: 4096) = 1436
> 0.264 ( 0.018 ms): a.out/442930 write(fd: 1</dev/pts/4>, buf: , count: 1436) = 1436
> 0.292 (1000.173 ms): a.out/442930 clock_nanosleep(rqtp: { .tv_sec: 17866546940376776704, .tv_nsec: 4159878336 }, rmtp: 0xffbdb59c) = 0
> 1000.478 ( ): a.out/442930 exit_group() = ?
> ```
>
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
> tools/perf/util/syscalltbl.c | 89 ++++++++++++++++++++++++++----------
> 1 file changed, 64 insertions(+), 25 deletions(-)
>
> diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> index 760ac4d0869f..572083ba1efe 100644
> --- a/tools/perf/util/syscalltbl.c
> +++ b/tools/perf/util/syscalltbl.c
> @@ -15,16 +15,39 @@
> #include <string.h>
> #include "string2.h"
>
> -#if __BITS_PER_LONG == 64
> - #include <asm/syscalls_64.h>
> -#else
> - #include <asm/syscalls_32.h>
> -#endif
> +#include "trace/beauty/generated/syscalltbl.c"
>
> -const char *syscalltbl__name(int e_machine __maybe_unused, int id)
> +static const struct syscalltbl *find_table(int e_machine)
> {
> - if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
> - return syscall_num_to_name[id];
> + static const struct syscalltbl *last_table;
> + static int last_table_machine = EM_NONE;
> +
> + /* Tables only exist for EM_SPARC. */
> + if (e_machine == EM_SPARCV9)
> + e_machine = EM_SPARC;
> +
> + if (last_table_machine == e_machine && e_machine != EM_NONE)
I don't think it should be && e_machine != EM_NONE. last_table_machine
== e_machine == EM_NONE could mean last_table being uninitialized, but
what if the called *is* trying to search for e_machine == EM_NONE? Now
perf will need to traverse the whole syscalltbls array just to find
the last EM_NONE table.
My suggestion is:
static const struct syscalltbl *last_table = NULL;
and then:
if (last_table_machine == e_machine && last_table)
return last_table;
Thanks,
Howard
> + return last_table;
> +
> + for (size_t i = 0; i < ARRAY_SIZE(syscalltbls); i++) {
> + const struct syscalltbl *entry = &syscalltbls[i];
> +
> + if (entry->e_machine != e_machine && entry->e_machine != EM_NONE)
> + continue;
> +
> + last_table = entry;
> + last_table_machine = e_machine;
> + return entry;
> + }
> + return NULL;
> +}
> +
> +const char *syscalltbl__name(int e_machine, int id)
> +{
> + const struct syscalltbl *table = find_table(e_machine);
> +
> + if (table && id >= 0 && id < table->num_to_name_len)
> + return table->num_to_name[id];
> return NULL;
> }
>
> @@ -41,38 +64,54 @@ static int syscallcmpname(const void *vkey, const void *ventry)
> return strcmp(key->name, key->tbl[*entry]);
> }
>
> -int syscalltbl__id(int e_machine __maybe_unused, const char *name)
> +int syscalltbl__id(int e_machine, const char *name)
> {
> - struct syscall_cmp_key key = {
> - .name = name,
> - .tbl = syscall_num_to_name,
> - };
> - const int *id = bsearch(&key, syscall_sorted_names,
> - ARRAY_SIZE(syscall_sorted_names),
> - sizeof(syscall_sorted_names[0]),
> - syscallcmpname);
> + const struct syscalltbl *table = find_table(e_machine);
> + struct syscall_cmp_key key;
> + const int *id;
> +
> + if (!table)
> + return -1;
> +
> + key.name = name;
> + key.tbl = table->num_to_name;
> + id = bsearch(&key, table->sorted_names, table->sorted_names_len,
> + sizeof(table->sorted_names[0]), syscallcmpname);
>
> return id ? *id : -1;
> }
>
> -int syscalltbl__num_idx(int e_machine __maybe_unused)
> +int syscalltbl__num_idx(int e_machine)
> {
> - return ARRAY_SIZE(syscall_sorted_names);
> + const struct syscalltbl *table = find_table(e_machine);
> +
> + if (!table)
> + return 0;
> +
> + return table->sorted_names_len;
> }
>
> -int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
> +int syscalltbl__id_at_idx(int e_machine, int idx)
> {
> - return syscall_sorted_names[idx];
> + const struct syscalltbl *table = find_table(e_machine);
> +
> + if (!table)
> + return -1;
> +
> + assert(idx >= 0 && idx < table->sorted_names_len);
> + return table->sorted_names[idx];
> }
>
> -int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
> +int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx)
> {
> - for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
> - const char *name = syscall_num_to_name[syscall_sorted_names[i]];
> + const struct syscalltbl *table = find_table(e_machine);
> +
> + for (int i = *idx + 1; table && i < table->sorted_names_len; ++i) {
> + const char *name = table->num_to_name[table->sorted_names[i]];
>
> if (strglobmatch(name, syscall_glob)) {
> *idx = i;
> - return syscall_sorted_names[i];
> + return table->sorted_names[i];
> }
> }
>
> --
> 2.48.1.362.g079036d154-goog
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 2/7] perf trace: Reorganize syscalls
2025-02-05 0:12 ` Howard Chu
@ 2025-02-05 5:00 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-05 5:00 UTC (permalink / raw)
To: Howard Chu
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Tue, Feb 4, 2025 at 4:12 PM Howard Chu <howardchu95@gmail.com> wrote:
>
> Hello Ian,
>
> Thanks for doing this.
>
> On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
[snip]
> > @@ -2104,11 +2123,12 @@ static int trace__read_syscall_info(struct trace *trace, int id)
> > */
> > if (IS_ERR(sc->tp_format)) {
> > sc->nonexistent = true;
> > - return PTR_ERR(sc->tp_format);
> > + err = PTR_ERR(sc->tp_format);
> > + sc->tp_format = NULL;
> > + return err;
> > }
> >
> > - if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
> > - RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
> > + if (syscall__alloc_arg_fmts(sc, sc->tp_format->format.nr_fields))
>
> Makes sense because IS_ERR(sc->tp_format) is checked a few lines
> above. However, nr_fields can be 7 with the __syscall_nr prefix. I
> sent a patch to fix this, but it's not included here... Never mind,
> it's off-topic. This patch looks good.
:-) So is this a reviewed-by? What about the other patches?
Thanks,
Ian
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl
2025-02-05 0:18 ` Howard Chu
@ 2025-02-05 5:09 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-05 5:09 UTC (permalink / raw)
To: Howard Chu
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Tue, Feb 4, 2025 at 4:18 PM Howard Chu <howardchu95@gmail.com> wrote:
>
> Hello Ian,
>
> On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
> >
> > The syscalltbl held entries of system call name and number pairs,
> > generated from a native syscalltbl at start up. As there are gaps in
> > the system call number there is a notion of index into the
> > table. Going forward we want the system call table to be identifiable
> > by a machine type, for example, i386 vs x86-64. Change the interface
> > to the syscalltbl so (1) a (currently unused machine type of EM_HOST)
> > is passed (2) the index to syscall number and system call name mapping
> > is computed at build time.
> >
> > Two tables are used for this, an array of system call number to name,
> > an array of system call numbers sorted by the system call name. The
> > sorted array doesn't store strings in part to save memory and
> > relocations. The index notion is carried forward and is an index into
> > the sorted array of system call numbers, the data structures are
> > opaque (held only in syscalltbl.c), and so the number of indices for a
> > machine type is exposed as a new API.
> >
> > The arrays are computed in the syscalltbl.sh script and so no start-up
> > time computation and storage is necessary.
> >
> > Signed-off-by: Ian Rogers <irogers@google.com>
> > ---
> > tools/perf/builtin-trace.c | 88 +++++++++++++-----------
> > tools/perf/scripts/syscalltbl.sh | 36 ++++------
> > tools/perf/util/syscalltbl.c | 113 ++++++++++---------------------
> > tools/perf/util/syscalltbl.h | 22 ++----
> > 4 files changed, 103 insertions(+), 156 deletions(-)
> >
> > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> > index 10d3ad0d21f7..7e3aa2f6c5e2 100644
> > --- a/tools/perf/builtin-trace.c
> > +++ b/tools/perf/builtin-trace.c
> > @@ -143,7 +143,6 @@ struct syscall_fmt {
> >
> > struct trace {
> > struct perf_tool tool;
> > - struct syscalltbl *sctbl;
> > struct {
> > /** Sorted sycall numbers used by the trace. */
> > struct syscall *table;
> > @@ -2100,7 +2099,7 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
> > return 0;
> > }
> >
> > - name = syscalltbl__name(trace->sctbl, sc->id);
> > + name = syscalltbl__name(sc->e_machine, sc->id);
> > if (name == NULL) {
> > sc->nonexistent = true;
> > return -EEXIST;
> > @@ -2196,10 +2195,14 @@ static int trace__validate_ev_qualifier(struct trace *trace)
> >
> > strlist__for_each_entry(pos, trace->ev_qualifier) {
> > const char *sc = pos->s;
> > - int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
> > + /*
> > + * TODO: Assume more than the validation/warnings are all for
> > + * the same binary type as perf.
> > + */
> > + int id = syscalltbl__id(EM_HOST, sc), match_next = -1;
> >
> > if (id < 0) {
> > - id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
> > + id = syscalltbl__strglobmatch_first(EM_HOST, sc, &match_next);
> > if (id >= 0)
> > goto matches;
> >
> > @@ -2219,7 +2222,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
> > continue;
> >
> > while (1) {
> > - id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
> > + id = syscalltbl__strglobmatch_next(EM_HOST, sc, &match_next);
> > if (id < 0)
> > break;
> > if (nr_allocated == nr_used) {
> > @@ -2673,6 +2676,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
> > int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> > int augmented_args_size = 0;
> > void *augmented_args = NULL;
> > + /* TODO: get e_machine from thread. */
> > struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> > struct thread_trace *ttrace;
> >
> > @@ -2747,6 +2751,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
> > struct thread_trace *ttrace;
> > struct thread *thread;
> > int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> > + /* TODO: get e_machine from thread. */
> > struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> > char msg[1024];
> > void *args, *augmented_args = NULL;
> > @@ -2822,6 +2827,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
> > struct thread *thread;
> > int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
> > int alignment = trace->args_alignment;
> > + /* TODO: get e_machine from thread. */
> > struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> > struct thread_trace *ttrace;
> >
> > @@ -3175,6 +3181,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
> >
> > if (evsel == trace->syscalls.events.bpf_output) {
> > int id = perf_evsel__sc_tp_uint(evsel, id, sample);
> > + /* TODO: get e_machine from thread. */
> > struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> >
> > if (sc) {
> > @@ -3678,9 +3685,9 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
> > return trace->skel->progs.syscall_unaugmented;
> > }
> >
> > -static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> > +static void trace__init_syscall_bpf_progs(struct trace *trace, int e_machine, int id)
> > {
> > - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> > + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> >
> > if (sc == NULL)
> > return;
> > @@ -3689,22 +3696,22 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> > sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit");
> > }
> >
> > -static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
> > +static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int e_machine, int id)
> > {
> > - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> > + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> > return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> > }
> >
> > -static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
> > +static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int e_machine, int id)
> > {
> > - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> > + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> > return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> > }
> >
> > -static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
> > +static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int e_machine, int key, unsigned int *beauty_array)
> > {
> > struct tep_format_field *field;
> > - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> > + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> > const struct btf_type *bt;
> > char *struct_offset, *tmp, name[32];
> > bool can_augment = false;
> > @@ -3800,9 +3807,9 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> > return NULL;
> >
> > try_to_find_pair:
> > - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> > - int id = syscalltbl__id_at_idx(trace->sctbl, i);
> > - struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
> > + for (int i = 0, num_idx = syscalltbl__num_idx(sc->e_machine); i < num_idx; ++i) {
> > + int id = syscalltbl__id_at_idx(sc->e_machine, i);
> > + struct syscall *pair = trace__syscall_info(trace, NULL, sc->e_machine, id);
> > struct bpf_program *pair_prog;
> > bool is_candidate = false;
> >
> > @@ -3886,7 +3893,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> > return NULL;
> > }
> >
> > -static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> > +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace, int e_machine)
> > {
> > int map_enter_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_enter);
> > int map_exit_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_exit);
> > @@ -3894,27 +3901,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> > int err = 0;
> > unsigned int beauty_array[6];
> >
> > - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> > - int prog_fd, key = syscalltbl__id_at_idx(trace->sctbl, i);
> > + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> > + int prog_fd, key = syscalltbl__id_at_idx(e_machine, i);
> >
> > if (!trace__syscall_enabled(trace, key))
> > continue;
> >
> > - trace__init_syscall_bpf_progs(trace, key);
> > + trace__init_syscall_bpf_progs(trace, e_machine, key);
> >
> > // It'll get at least the "!raw_syscalls:unaugmented"
> > - prog_fd = trace__bpf_prog_sys_enter_fd(trace, key);
> > + prog_fd = trace__bpf_prog_sys_enter_fd(trace, e_machine, key);
> > err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY);
> > if (err)
> > break;
> > - prog_fd = trace__bpf_prog_sys_exit_fd(trace, key);
> > + prog_fd = trace__bpf_prog_sys_exit_fd(trace, e_machine, key);
> > err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY);
> > if (err)
> > break;
> >
> > /* use beauty_map to tell BPF how many bytes to collect, set beauty_map's value here */
> > memset(beauty_array, 0, sizeof(beauty_array));
> > - err = trace__bpf_sys_enter_beauty_map(trace, key, (unsigned int *)beauty_array);
> > + err = trace__bpf_sys_enter_beauty_map(trace, e_machine, key, (unsigned int *)beauty_array);
> > if (err)
> > continue;
> > err = bpf_map_update_elem(beauty_map_fd, &key, beauty_array, BPF_ANY);
> > @@ -3950,9 +3957,9 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> > * first and second arg (this one on the raw_syscalls:sys_exit prog
> > * array tail call, then that one will be used.
> > */
> > - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> > - int key = syscalltbl__id_at_idx(trace->sctbl, i);
> > - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> > + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> > + int key = syscalltbl__id_at_idx(e_machine, i);
> > + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> > struct bpf_program *pair_prog;
> > int prog_fd;
> >
> > @@ -4389,8 +4396,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> > goto out_error_mem;
> >
> > #ifdef HAVE_BPF_SKEL
> > - if (trace->skel && trace->skel->progs.sys_enter)
> > - trace__init_syscalls_bpf_prog_array_maps(trace);
> > + if (trace->skel && trace->skel->progs.sys_enter) {
> > + /*
> > + * TODO: Initialize for all host binary machine types, not just
> > + * those matching the perf binary.
> > + */
> > + trace__init_syscalls_bpf_prog_array_maps(trace, EM_HOST);
> > + }
> > #endif
> >
> > if (trace->ev_qualifier_ids.nr > 0) {
> > @@ -4415,7 +4427,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> > * So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is
> > * not in use.
> > */
> > - trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close"));
> > + /* TODO: support for more than just perf binary machine type close. */
> > + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(EM_HOST, "close"));
> >
> > err = trace__expand_filters(trace, &evsel);
> > if (err)
> > @@ -4688,8 +4701,7 @@ DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs,
> > entry->msecs = stats ? (u64)stats->stats.n * (avg_stats(&stats->stats) / NSEC_PER_MSEC) : 0;
> > }
> >
> > -static size_t thread__dump_stats(struct thread_trace *ttrace,
> > - struct trace *trace, FILE *fp)
> > +static size_t thread__dump_stats(struct thread_trace *ttrace, struct trace *trace, int e_machine, FILE *fp)
> > {
> > size_t printed = 0;
> > struct syscall *sc;
> > @@ -4717,7 +4729,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
> > pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
> > avg /= NSEC_PER_MSEC;
> >
> > - sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
> > + sc = trace__syscall_info(trace, /*evsel=*/NULL, e_machine,
> > syscall_stats_entry->syscall);
> > if (!sc)
> > continue;
> > @@ -4767,7 +4779,8 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
> > else if (fputc('\n', fp) != EOF)
> > ++printed;
> >
> > - printed += thread__dump_stats(ttrace, trace, fp);
> > + /* TODO: get e_machine from thread. */
> > + printed += thread__dump_stats(ttrace, trace, EM_HOST, fp);
> >
> > return printed;
> > }
> > @@ -4999,8 +5012,9 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
> > *sep = '\0';
> >
> > list = 0;
> > - if (syscalltbl__id(trace->sctbl, s) >= 0 ||
> > - syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
> > + /* TODO: support for more than just perf binary machine type syscalls. */
> > + if (syscalltbl__id(EM_HOST, s) >= 0 ||
> > + syscalltbl__strglobmatch_first(EM_HOST, s, &idx) >= 0) {
> > list = 1;
> > goto do_concat;
> > }
> > @@ -5136,7 +5150,6 @@ static void trace__exit(struct trace *trace)
> > syscall__exit(&trace->syscalls.table[i]);
> > zfree(&trace->syscalls.table);
> > }
> > - syscalltbl__delete(trace->sctbl);
> > zfree(&trace->perfconfig_events);
> > }
> >
> > @@ -5282,9 +5295,8 @@ int cmd_trace(int argc, const char **argv)
> > sigaction(SIGCHLD, &sigchld_act, NULL);
> >
> > trace.evlist = evlist__new();
> > - trace.sctbl = syscalltbl__new();
> >
> > - if (trace.evlist == NULL || trace.sctbl == NULL) {
> > + if (trace.evlist == NULL) {
> > pr_err("Not enough memory to run!\n");
> > err = -ENOMEM;
> > goto out;
> > diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
> > index 1ce0d5aa8b50..a39b3013b103 100755
> > --- a/tools/perf/scripts/syscalltbl.sh
> > +++ b/tools/perf/scripts/syscalltbl.sh
> > @@ -50,37 +50,27 @@ fi
> > infile="$1"
> > outfile="$2"
> >
> > -nxt=0
> > -
> > -syscall_macro() {
> > - nr="$1"
> > - name="$2"
> > -
> > - echo " [$nr] = \"$name\","
> > -}
> > -
> > -emit() {
> > - nr="$1"
> > - entry="$2"
> > -
> > - syscall_macro "$nr" "$entry"
> > -}
> > -
> > -echo "static const char *const syscalltbl[] = {" > $outfile
> > -
> > sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
> > grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
> >
> > -max_nr=0
> > +echo "static const char *const syscall_num_to_name[] = {" > $outfile
> > # the params are: nr abi name entry compat
> > # use _ for intentionally unused variables according to SC2034
> > while read nr _ name _ _; do
> > - emit "$nr" "$name" >> $outfile
> > - max_nr=$nr
> > + echo " [$nr] = \"$name\"," >> $outfile
> > done < $sorted_table
> > +echo "};" >> $outfile
> >
> > -rm -f $sorted_table
> > +echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile
> >
> > +# When sorting by name, add a suffix of 0s upto 20 characters so that system
> > +# calls that differ with a numerical suffix don't sort before those
> > +# without. This default behavior of sort differs from that of strcmp used at
> > +# runtime. Use sed to strip the trailing 0s suffix afterwards.
> > +grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table
> > +while read name nr; do
> > + echo " $nr, /* $name */" >> $outfile
> > +done < $sorted_table
> > echo "};" >> $outfile
> >
> > -echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
> > +rm -f $sorted_table
> > diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> > index 2f76241494c8..760ac4d0869f 100644
> > --- a/tools/perf/util/syscalltbl.c
> > +++ b/tools/perf/util/syscalltbl.c
> > @@ -9,6 +9,7 @@
> > #include <stdlib.h>
> > #include <asm/bitsperlong.h>
> > #include <linux/compiler.h>
> > +#include <linux/kernel.h>
> > #include <linux/zalloc.h>
> >
> > #include <string.h>
> > @@ -20,112 +21,66 @@
> > #include <asm/syscalls_32.h>
> > #endif
> >
> > -const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
> > -static const char *const *syscalltbl_native = syscalltbl;
> > +const char *syscalltbl__name(int e_machine __maybe_unused, int id)
> > +{
> > + if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
> > + return syscall_num_to_name[id];
> > + return NULL;
> > +}
> >
> > -struct syscall {
> > - int id;
> > +struct syscall_cmp_key {
> > const char *name;
> > + const char *const *tbl;
> > };
> >
> > static int syscallcmpname(const void *vkey, const void *ventry)
> > {
> > - const char *key = vkey;
> > - const struct syscall *entry = ventry;
> > + const struct syscall_cmp_key *key = vkey;
> > + const uint16_t *entry = ventry;
> >
> > - return strcmp(key, entry->name);
> > + return strcmp(key->name, key->tbl[*entry]);
> > }
> >
> > -static int syscallcmp(const void *va, const void *vb)
> > +int syscalltbl__id(int e_machine __maybe_unused, const char *name)
> > {
> > - const struct syscall *a = va, *b = vb;
> > -
> > - return strcmp(a->name, b->name);
> > + struct syscall_cmp_key key = {
> > + .name = name,
> > + .tbl = syscall_num_to_name,
> > + };
> > + const int *id = bsearch(&key, syscall_sorted_names,
> > + ARRAY_SIZE(syscall_sorted_names),
> > + sizeof(syscall_sorted_names[0]),
> > + syscallcmpname);
>
> This has puzzled me several times lol. Searching in
> syscall_sorted_names returns an int id... I get that it's sorted by
> name, but maybe call it syscall_ids_sorted_by_name, syscall_ids, or
> syscall_ids_sorted instead?
>
> > +
> > + return id ? *id : -1;
> > }
> >
> > -static int syscalltbl__init_native(struct syscalltbl *tbl)
> > +int syscalltbl__num_idx(int e_machine __maybe_unused)
>
> I haven't found many instances of *num_idx in the source tree
> indicating the length of an array. Are you okay with
> syscalltbl__nr_idx()?
>
> Otherwise LGTM.
So the idx rather than id (wish it were called syscall_nr) logic is
used with handling command line system call filters. You can see it in
the glob code:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/syscalltbl.c?h=perf-tools-next#n106
The code wants to iterate over syscalls with no NULLs, as the name to
syscall number table doesn't contain NULLs it serves the same purpose
and is also sorted the same way.
Thanks,
Ian
> Thanks,
> Howard
> > {
> > - int nr_entries = 0, i, j;
> > - struct syscall *entries;
> > -
> > - for (i = 0; i <= syscalltbl_native_max_id; ++i)
> > - if (syscalltbl_native[i])
> > - ++nr_entries;
> > -
> > - entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
> > - if (tbl->syscalls.entries == NULL)
> > - return -1;
> > -
> > - for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
> > - if (syscalltbl_native[i]) {
> > - entries[j].name = syscalltbl_native[i];
> > - entries[j].id = i;
> > - ++j;
> > - }
> > - }
> > -
> > - qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
> > - tbl->syscalls.nr_entries = nr_entries;
> > - tbl->syscalls.max_id = syscalltbl_native_max_id;
> > - return 0;
> > + return ARRAY_SIZE(syscall_sorted_names);
> > }
> >
> > -struct syscalltbl *syscalltbl__new(void)
> > +int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
> > {
> > - struct syscalltbl *tbl = malloc(sizeof(*tbl));
> > - if (tbl) {
> > - if (syscalltbl__init_native(tbl)) {
> > - free(tbl);
> > - return NULL;
> > - }
> > - }
> > - return tbl;
> > -}
> > -
> > -void syscalltbl__delete(struct syscalltbl *tbl)
> > -{
> > - zfree(&tbl->syscalls.entries);
> > - free(tbl);
> > -}
> > -
> > -const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
> > -{
> > - return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> > -}
> > -
> > -int syscalltbl__id(struct syscalltbl *tbl, const char *name)
> > -{
> > - struct syscall *sc = bsearch(name, tbl->syscalls.entries,
> > - tbl->syscalls.nr_entries, sizeof(*sc),
> > - syscallcmpname);
> > -
> > - return sc ? sc->id : -1;
> > -}
> > -
> > -int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx)
> > -{
> > - struct syscall *syscalls = tbl->syscalls.entries;
> > -
> > - return idx < tbl->syscalls.nr_entries ? syscalls[idx].id : -1;
> > + return syscall_sorted_names[idx];
> > }
> >
> > -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> > +int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
> > {
> > - int i;
> > - struct syscall *syscalls = tbl->syscalls.entries;
> > + for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
> > + const char *name = syscall_num_to_name[syscall_sorted_names[i]];
> >
> > - for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
> > - if (strglobmatch(syscalls[i].name, syscall_glob)) {
> > + if (strglobmatch(name, syscall_glob)) {
> > *idx = i;
> > - return syscalls[i].id;
> > + return syscall_sorted_names[i];
> > }
> > }
> >
> > return -1;
> > }
> >
> > -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> > +int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx)
> > {
> > *idx = -1;
> > - return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
> > + return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx);
> > }
> > diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
> > index 362411a6d849..2bb628eff367 100644
> > --- a/tools/perf/util/syscalltbl.h
> > +++ b/tools/perf/util/syscalltbl.h
> > @@ -2,22 +2,12 @@
> > #ifndef __PERF_SYSCALLTBL_H
> > #define __PERF_SYSCALLTBL_H
> >
> > -struct syscalltbl {
> > - struct {
> > - int max_id;
> > - int nr_entries;
> > - void *entries;
> > - } syscalls;
> > -};
> > +const char *syscalltbl__name(int e_machine, int id);
> > +int syscalltbl__id(int e_machine, const char *name);
> > +int syscalltbl__num_idx(int e_machine);
> > +int syscalltbl__id_at_idx(int e_machine, int idx);
> >
> > -struct syscalltbl *syscalltbl__new(void);
> > -void syscalltbl__delete(struct syscalltbl *tbl);
> > -
> > -const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
> > -int syscalltbl__id(struct syscalltbl *tbl, const char *name);
> > -int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx);
> > -
> > -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> > -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> > +int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx);
> > +int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx);
> >
> > #endif /* __PERF_SYSCALLTBL_H */
> > --
> > 2.48.1.362.g079036d154-goog
> >
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures
2025-02-05 0:24 ` Howard Chu
@ 2025-02-05 5:17 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2025-02-05 5:17 UTC (permalink / raw)
To: Howard Chu
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, Kan Liang, John Garry, Will Deacon, James Clark,
Mike Leach, Leo Yan, Guo Ren, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Charlie Jenkins, Bibo Mao, Arnd Bergmann, Huacai Chen,
Catalin Marinas, Jiri Slaby, Björn Töpel, linux-kernel,
linux-perf-users, linux-arm-kernel, linux-csky, linux-riscv
On Tue, Feb 4, 2025 at 4:24 PM Howard Chu <howardchu95@gmail.com> wrote:
>
> Hello,
>
> On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
> >
> > Switch to use the lookup table containing all architectures rather
> > than tables matching the perf binary.
> >
> > This fixes perf trace when executed on a 32-bit i386 binary on an
> > x86-64 machine. Note in the following the system call names of the
> > 32-bit i386 binary as seen by an x86-64 perf.
> >
> > Before:
> > ```
> > ? ( ): a.out/447296 ... [continued]: munmap()) = 0
> > 0.024 ( 0.001 ms): a.out/447296 recvfrom(ubuf: 0x2, size: 4160585708, flags: DONTROUTE|CTRUNC|TRUNC|DONTWAIT|EOR|WAITALL|FIN|SYN|CONFIRM|RST|ERRQUEUE|NOSIGNAL|WAITFORONE|BATCH|SOCK_DEVMEM|ZEROCOPY|FASTOPEN|CMSG_CLOEXEC|0x91f80000, addr: 0xe30, addr_len: 0xffce438c) = 1475198976
> > 0.042 ( 0.003 ms): a.out/447296 lgetxattr(name: "", value: 0x3, size: 34) = 4160344064
> > 0.054 ( 0.003 ms): a.out/447296 dup2(oldfd: -134422744, newfd: 4) = -1 ENOENT (No such file or directory)
> > 0.060 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x2e646c2f6374652f,.iov_len = (__kernel_size_t)7307199665335594867,}, vlen: 557056, pos_h: 4160585708) = 3
> > 0.074 ( 0.004 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2) = 4160237568
> > 0.080 ( 0.001 ms): a.out/447296 lstat(filename: "", statbuf: 0x193f6) = 0
> > 0.089 ( 0.007 ms): a.out/447296 preadv(fd: 4294967196, vec: (struct iovec){.iov_base = (void *)0x3833692f62696c2f,.iov_len = (__kernel_size_t)3276497845987585334,}, vlen: 557056, pos_h: 4160585708) = 3
> > 0.097 ( 0.002 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 512
> > 0.103 ( 0.002 ms): a.out/447296 lgetxattr(name: "", value: 0x1, size: 2050) = 4157935616
> > 0.107 ( 0.007 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x5, size: 2066) = 4158078976
> > 0.116 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x1, size: 2066) = 4159639552
> > 0.121 ( 0.003 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 2066) = 4160184320
> > 0.129 ( 0.002 ms): a.out/447296 lgetxattr(pathname: "", name: "", value: 0x3, size: 50) = 4160196608
> > 0.138 ( 0.001 ms): a.out/447296 lstat(filename: "") = 0
> > 0.145 ( 0.002 ms): a.out/447296 mq_timedreceive(mqdes: 4291706800, u_msg_ptr: 0xf7f9ea48, msg_len: 134616640, u_msg_prio: 0xf7fd7fec, u_abs_timeout: (struct __kernel_timespec){.tv_sec = (__kernel_time64_t)-578174027777317696,.tv_nsec = (long long int)4160349376,}) = 0
> > 0.148 ( 0.001 ms): a.out/447296 mkdirat(dfd: -134617816, pathname: " ��� ���▒���▒���", mode: IFREG|ISUID|IRUSR|IWGRP|0xf7fd0000) = 447296
> > 0.150 ( 0.001 ms): a.out/447296 process_vm_writev(pid: -134617812, lvec: (struct iovec){.iov_base = (void *)0xf7f9e9c8f7f9e4c0,.iov_len = (__kernel_size_t)4160349376,}, liovcnt: 4160588048, rvec: (struct iovec){}, riovcnt: 4160585708, flags: 4291707352) = 0
> > 0.197 ( 0.004 ms): a.out/447296 capget(header: 4160184320, dataptr: 8192) = 0
> > 0.202 ( 0.002 ms): a.out/447296 capget(header: 1448669184, dataptr: 4096) = 0
> > 0.208 ( 0.002 ms): a.out/447296 capget(header: 4160577536, dataptr: 8192) = 0
> > 0.220 ( 0.001 ms): a.out/447296 getxattr(pathname: "", name: "c������", value: 0xf7f77e34, size: 1) = 0
> > 0.228 ( 0.005 ms): a.out/447296 fchmod(fd: -134729728, mode: IRUGO|IWUGO|IFREG|IFIFO|ISVTX|IXUSR|0x10000) = 0
> > 0.240 ( 0.009 ms): a.out/447296 preadv(fd: 4294967196, vec: 0x5658e008, pos_h: 4160192052) = 3
> > 0.250 ( 0.008 ms): a.out/447296 close(fd: 3</proc/447296/status>) = 1436
> > 0.260 ( 0.018 ms): a.out/447296 stat(filename: "", statbuf: 0xffce32ac) = 1436
> > 0.288 (1000.213 ms): a.out/447296 readlinkat(buf: 0xffce31d4, bufsiz: 4291703244) = 0
> > ```
> >
> > After:
> > ```
> > ? ( ): a.out/442930 ... [continued]: execve()) = 0
> > 0.023 ( 0.002 ms): a.out/442930 brk() = 0x57760000
> > 0.052 ( 0.003 ms): a.out/442930 access(filename: 0xf7f5af28, mode: R) = -1 ENOENT (No such file or directory)
> > 0.059 ( 0.009 ms): a.out/442930 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
> > 0.078 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
> > 0.087 ( 0.007 ms): a.out/442930 openat(dfd: CWD, filename: "/lib/i386-linux-", flags: RDONLY|CLOEXEC|LARGEFILE) = 3
> > 0.095 ( 0.002 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdbb70, count: 512) = 512
> > 0.135 ( 0.001 ms): a.out/442930 close(fd: 3</proc/442930/status>) = 0
> > 0.148 ( 0.001 ms): a.out/442930 set_tid_address(tidptr: 0xf7f2b528) = 442930 (a.out)
> > 0.150 ( 0.001 ms): a.out/442930 set_robust_list(head: 0xf7f2b52c, len: 12) =
> > 0.196 ( 0.004 ms): a.out/442930 mprotect(start: 0xf7f03000, len: 8192, prot: READ) = 0
> > 0.202 ( 0.002 ms): a.out/442930 mprotect(start: 0x5658e000, len: 4096, prot: READ) = 0
> > 0.207 ( 0.002 ms): a.out/442930 mprotect(start: 0xf7f63000, len: 8192, prot: READ) = 0
> > 0.230 ( 0.005 ms): a.out/442930 munmap(addr: 0xf7f10000, len: 103414) = 0
> > 0.244 ( 0.010 ms): a.out/442930 openat(dfd: CWD, filename: 0x5658d008) = 3
> > 0.255 ( 0.007 ms): a.out/442930 read(fd: 3</proc/442930/status>, buf: 0xffbdb67c, count: 4096) = 1436
> > 0.264 ( 0.018 ms): a.out/442930 write(fd: 1</dev/pts/4>, buf: , count: 1436) = 1436
> > 0.292 (1000.173 ms): a.out/442930 clock_nanosleep(rqtp: { .tv_sec: 17866546940376776704, .tv_nsec: 4159878336 }, rmtp: 0xffbdb59c) = 0
> > 1000.478 ( ): a.out/442930 exit_group() = ?
> > ```
> >
> > Signed-off-by: Ian Rogers <irogers@google.com>
> > ---
> > tools/perf/util/syscalltbl.c | 89 ++++++++++++++++++++++++++----------
> > 1 file changed, 64 insertions(+), 25 deletions(-)
> >
> > diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> > index 760ac4d0869f..572083ba1efe 100644
> > --- a/tools/perf/util/syscalltbl.c
> > +++ b/tools/perf/util/syscalltbl.c
> > @@ -15,16 +15,39 @@
> > #include <string.h>
> > #include "string2.h"
> >
> > -#if __BITS_PER_LONG == 64
> > - #include <asm/syscalls_64.h>
> > -#else
> > - #include <asm/syscalls_32.h>
> > -#endif
> > +#include "trace/beauty/generated/syscalltbl.c"
> >
> > -const char *syscalltbl__name(int e_machine __maybe_unused, int id)
> > +static const struct syscalltbl *find_table(int e_machine)
> > {
> > - if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
> > - return syscall_num_to_name[id];
> > + static const struct syscalltbl *last_table;
> > + static int last_table_machine = EM_NONE;
> > +
> > + /* Tables only exist for EM_SPARC. */
> > + if (e_machine == EM_SPARCV9)
> > + e_machine = EM_SPARC;
> > +
> > + if (last_table_machine == e_machine && e_machine != EM_NONE)
>
> I don't think it should be && e_machine != EM_NONE. last_table_machine
> == e_machine == EM_NONE could mean last_table being uninitialized, but
> what if the called *is* trying to search for e_machine == EM_NONE? Now
> perf will need to traverse the whole syscalltbls array just to find
> the last EM_NONE table.
>
> My suggestion is:
>
> static const struct syscalltbl *last_table = NULL;
>
> and then:
>
> if (last_table_machine == e_machine && last_table)
> return last_table;
Agreed this is better. I'll add it in v2 with your tags :-)
Thanks,
Ian
> > + return last_table;
> > +
> > + for (size_t i = 0; i < ARRAY_SIZE(syscalltbls); i++) {
> > + const struct syscalltbl *entry = &syscalltbls[i];
> > +
> > + if (entry->e_machine != e_machine && entry->e_machine != EM_NONE)
> > + continue;
> > +
> > + last_table = entry;
> > + last_table_machine = e_machine;
> > + return entry;
> > + }
> > + return NULL;
> > +}
> > +
> > +const char *syscalltbl__name(int e_machine, int id)
> > +{
> > + const struct syscalltbl *table = find_table(e_machine);
> > +
> > + if (table && id >= 0 && id < table->num_to_name_len)
> > + return table->num_to_name[id];
> > return NULL;
> > }
> >
> > @@ -41,38 +64,54 @@ static int syscallcmpname(const void *vkey, const void *ventry)
> > return strcmp(key->name, key->tbl[*entry]);
> > }
> >
> > -int syscalltbl__id(int e_machine __maybe_unused, const char *name)
> > +int syscalltbl__id(int e_machine, const char *name)
> > {
> > - struct syscall_cmp_key key = {
> > - .name = name,
> > - .tbl = syscall_num_to_name,
> > - };
> > - const int *id = bsearch(&key, syscall_sorted_names,
> > - ARRAY_SIZE(syscall_sorted_names),
> > - sizeof(syscall_sorted_names[0]),
> > - syscallcmpname);
> > + const struct syscalltbl *table = find_table(e_machine);
> > + struct syscall_cmp_key key;
> > + const int *id;
> > +
> > + if (!table)
> > + return -1;
> > +
> > + key.name = name;
> > + key.tbl = table->num_to_name;
> > + id = bsearch(&key, table->sorted_names, table->sorted_names_len,
> > + sizeof(table->sorted_names[0]), syscallcmpname);
> >
> > return id ? *id : -1;
> > }
> >
> > -int syscalltbl__num_idx(int e_machine __maybe_unused)
> > +int syscalltbl__num_idx(int e_machine)
> > {
> > - return ARRAY_SIZE(syscall_sorted_names);
> > + const struct syscalltbl *table = find_table(e_machine);
> > +
> > + if (!table)
> > + return 0;
> > +
> > + return table->sorted_names_len;
> > }
> >
> > -int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
> > +int syscalltbl__id_at_idx(int e_machine, int idx)
> > {
> > - return syscall_sorted_names[idx];
> > + const struct syscalltbl *table = find_table(e_machine);
> > +
> > + if (!table)
> > + return -1;
> > +
> > + assert(idx >= 0 && idx < table->sorted_names_len);
> > + return table->sorted_names[idx];
> > }
> >
> > -int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
> > +int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx)
> > {
> > - for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
> > - const char *name = syscall_num_to_name[syscall_sorted_names[i]];
> > + const struct syscalltbl *table = find_table(e_machine);
> > +
> > + for (int i = *idx + 1; table && i < table->sorted_names_len; ++i) {
> > + const char *name = table->num_to_name[table->sorted_names[i]];
> >
> > if (strglobmatch(name, syscall_glob)) {
> > *idx = i;
> > - return syscall_sorted_names[i];
> > + return table->sorted_names[i];
> > }
> > }
> >
> > --
> > 2.48.1.362.g079036d154-goog
> >
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2025-02-05 5:19 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-01 7:14 [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
2025-02-01 7:14 ` [PATCH v1 1/7] perf syscalltble: Remove syscall_table.h Ian Rogers
2025-02-01 7:14 ` [PATCH v1 2/7] perf trace: Reorganize syscalls Ian Rogers
2025-02-05 0:12 ` Howard Chu
2025-02-05 5:00 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl Ian Rogers
2025-02-05 0:18 ` Howard Chu
2025-02-05 5:09 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 4/7] perf thread: Add support for reading the e_machine type for a thread Ian Rogers
2025-02-01 7:14 ` [PATCH v1 5/7] perf trace beauty: Add syscalltbl.sh generating all system call tables Ian Rogers
2025-02-01 7:14 ` [PATCH v1 6/7] perf syscalltbl: Use lookup table containing multiple architectures Ian Rogers
2025-02-05 0:24 ` Howard Chu
2025-02-05 5:17 ` Ian Rogers
2025-02-01 7:14 ` [PATCH v1 7/7] perf build: Remove Makefile.syscalls Ian Rogers
2025-02-01 8:51 ` [PATCH v1 0/7] perf: Support multiple system call tables in the build Ian Rogers
2025-02-03 18:28 ` Ian Rogers
2025-02-03 19:02 ` Charlie Jenkins
2025-02-03 19:10 ` Ian Rogers
2025-02-03 19:15 ` Charlie Jenkins
2025-02-03 19:39 ` Ian Rogers
2025-02-03 20:06 ` Charlie Jenkins
2025-02-03 20:54 ` Ian Rogers
2025-02-03 23:02 ` Charlie Jenkins
2025-02-04 1:58 ` Ian Rogers
2025-02-04 19:05 ` Charlie Jenkins
2025-02-04 19:17 ` Ian Rogers
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).