diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2025-05-09 15:42:48 +0200 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2025-05-17 10:55:00 +0200 |
commit | d35ef47a43f8a01252e89b1fd4a52c91017b5d59 (patch) | |
tree | 4750787893f1e530176f0cc04657f4e89b65d7c1 | |
parent | 5c4a8632e86aa68514eef9480b0b838d1aa3f24a (diff) |
s390/ptrace: Always inline regs_get_kernel_stack_nth() and regs_get_register()
Both regs_get_kernel_stack_nth() and regs_get_register() are not
inlined. With the new ftrace funcgraph-args feature they show up in
function graph tracing:
4) | sched_core_idle_cpu(cpu=4) {
4) 0.257 us | regs_get_register(regs=0x37fe00afa10, offset=2);
4) 0.218 us | regs_get_register(regs=0x37fe00afa10, offset=3);
4) 0.225 us | regs_get_register(regs=0x37fe00afa10, offset=4);
4) 0.239 us | regs_get_register(regs=0x37fe00afa10, offset=5);
4) 0.239 us | regs_get_register(regs=0x37fe00afa10, offset=6);
4) 0.245 us | regs_get_kernel_stack_nth(regs=0x37fe00afa10, n=20);
This is subtoptimal, since both functions are supposed to be ftrace
internal helper functions. If they appear in ftrace traces this reduces
readability significantly, plus this adds tons of extra useless extra
entries.
Address this by moving both functions and required helpers to ptrace.h and
always inline them. This way they don't appear in traces anymore. In
addition the overhead that comes with functions calls is also reduced.
Reviewed-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
-rw-r--r-- | arch/s390/include/asm/ptrace.h | 46 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 33 |
2 files changed, 39 insertions, 40 deletions
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 1545cdc65f7e..62c0ab4a4b9d 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <uapi/asm/ptrace.h> +#include <asm/thread_info.h> #include <asm/tpi.h> #define PIF_SYSCALL 0 /* inside a system call */ @@ -228,8 +229,44 @@ static inline void instruction_pointer_set(struct pt_regs *regs, int regs_query_register_offset(const char *name); const char *regs_query_register_name(unsigned int offset); -unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); -unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); + +static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->gprs[15]; +} + +static __always_inline unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) +{ + if (offset >= NUM_GPRS) + return 0; + return regs->gprs[offset]; +} + +static __always_inline int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ + unsigned long ksp = kernel_stack_pointer(regs); + + return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs:pt_regs which contains kernel stack pointer. + * @n:stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specifined by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +static __always_inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long addr; + + addr = kernel_stack_pointer(regs) + n * sizeof(long); + if (!regs_within_kernel_stack(regs, addr)) + return 0; + return READ_ONCE_NOCHECK(addr); +} /** * regs_get_kernel_argument() - get Nth function argument in kernel @@ -250,11 +287,6 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs, return regs_get_kernel_stack_nth(regs, argoffset + n); } -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ - return regs->gprs[15]; -} - static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) { regs->gprs[2] = rc; diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 34b8d9e745df..e1240f6b29fa 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -1524,13 +1524,6 @@ static const char *gpr_names[NUM_GPRS] = { "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", }; -unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) -{ - if (offset >= NUM_GPRS) - return 0; - return regs->gprs[offset]; -} - int regs_query_register_offset(const char *name) { unsigned long offset; @@ -1550,29 +1543,3 @@ const char *regs_query_register_name(unsigned int offset) return NULL; return gpr_names[offset]; } - -static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) -{ - unsigned long ksp = kernel_stack_pointer(regs); - - return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs:pt_regs which contains kernel stack pointer. - * @n:stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specifined by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) -{ - unsigned long addr; - - addr = kernel_stack_pointer(regs) + n * sizeof(long); - if (!regs_within_kernel_stack(regs, addr)) - return 0; - return READ_ONCE_NOCHECK(addr); -} |