Skip to content

Commit dd9c9a6

Browse files
Jinjie Ruanakpm00
authored andcommitted
arm64: avoid memcpy() for syscall_get_arguments()
Do not use memcpy() to extract syscall arguments from struct pt_regs but rather just perform direct assignments. Update syscall_set_arguments() too to keep syscall_get_arguments() and syscall_set_arguments() in sync. With Generic Entry patch[1] and turn on audit, the performance benchmarks from perf bench basic syscall on kunpeng920 gives roughly a 1% performance uplift. | Metric | W/O this patch | With this patch | Change | | ---------- | -------------- | --------------- | --------- | | Total time | 2.241 [sec] | 2.211 [sec] | ↓1.36% | | usecs/op | 0.224157 | 0.221146 | ↓1.36% | | ops/sec | 4,461,157 | 4,501,409 | ↑0.9% | Disassembly shows that using direct assignment causes syscall_set_arguments() to be inlined and cuts the instruction count by five or six compared to memcpy(). Because __audit_syscall_entry() only uses four syscall arguments, the compiler has also elided the copy of regs->regs[4] and regs->regs[5]. Before: <syscall_get_arguments.constprop.0>: aa0103e2 mov x2, x1 91002003 add x3, x0, #0x8 f9408804 ldr x4, [x0, torvalds#272] f8008444 str x4, [x2], torvalds#8 a9409404 ldp x4, x5, [x0, torvalds#8] a9009424 stp x4, x5, [x1, torvalds#8] a9418400 ldp x0, x1, [x0, torvalds#24] a9010440 stp x0, x1, [x2, torvalds#16] f9401060 ldr x0, [x3, torvalds#32] f9001040 str x0, [x2, torvalds#32] d65f03c0 ret d503201f nop After: a9408e82 ldp x2, x3, [x20, torvalds#8] 2a1603e0 mov w0, w22 f9400e84 ldr x4, [x20, torvalds#24] f9408a81 ldr x1, [x20, torvalds#272] 9401c4ba bl ffff800080215ca8 <__audit_syscall_entry> This also aligns the implementation with x86 and RISC-V. Link: https://lkml.kernel.org/r/[email protected] Link: https://lore.kernel.org/all/[email protected]/ [1] Signed-off-by: Jinjie Ruan <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Charlie Jenkins <[email protected]> Cc: Christian Zankel <[email protected]> Cc: "Dmitry V. Levin" <[email protected]> Cc: Helge Deller <[email protected]> Cc: Maciej W. Rozycki <[email protected]> Cc: Marc Rutland <[email protected]> Cc: Max Filippov <[email protected]> Cc: Russell King (Oracle) <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Thomas Gleinxer <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 5297774 commit dd9c9a6

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

arch/arm64/include/asm/syscall.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,24 @@ static inline void syscall_get_arguments(struct task_struct *task,
8282
unsigned long *args)
8383
{
8484
args[0] = regs->orig_x0;
85-
args++;
86-
87-
memcpy(args, &regs->regs[1], 5 * sizeof(args[0]));
85+
args[1] = regs->regs[1];
86+
args[2] = regs->regs[2];
87+
args[3] = regs->regs[3];
88+
args[4] = regs->regs[4];
89+
args[5] = regs->regs[5];
8890
}
8991

9092
static inline void syscall_set_arguments(struct task_struct *task,
9193
struct pt_regs *regs,
9294
const unsigned long *args)
9395
{
94-
memcpy(&regs->regs[0], args, 6 * sizeof(args[0]));
96+
regs->regs[0] = args[0];
97+
regs->regs[1] = args[1];
98+
regs->regs[2] = args[2];
99+
regs->regs[3] = args[3];
100+
regs->regs[4] = args[4];
101+
regs->regs[5] = args[5];
102+
95103
/*
96104
* Also copy the first argument into orig_x0
97105
* so that syscall_get_arguments() would return it

0 commit comments

Comments
 (0)