Skip to content

Commit d35ef47

Browse files
committed
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 <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent 5c4a863 commit d35ef47

File tree

2 files changed

+39
-40
lines changed

2 files changed

+39
-40
lines changed

arch/s390/include/asm/ptrace.h

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <linux/bits.h>
1111
#include <uapi/asm/ptrace.h>
12+
#include <asm/thread_info.h>
1213
#include <asm/tpi.h>
1314

1415
#define PIF_SYSCALL 0 /* inside a system call */
@@ -228,8 +229,44 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
228229

229230
int regs_query_register_offset(const char *name);
230231
const char *regs_query_register_name(unsigned int offset);
231-
unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset);
232-
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
232+
233+
static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
234+
{
235+
return regs->gprs[15];
236+
}
237+
238+
static __always_inline unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
239+
{
240+
if (offset >= NUM_GPRS)
241+
return 0;
242+
return regs->gprs[offset];
243+
}
244+
245+
static __always_inline int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
246+
{
247+
unsigned long ksp = kernel_stack_pointer(regs);
248+
249+
return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
250+
}
251+
252+
/**
253+
* regs_get_kernel_stack_nth() - get Nth entry of the stack
254+
* @regs:pt_regs which contains kernel stack pointer.
255+
* @n:stack entry number.
256+
*
257+
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
258+
* is specifined by @regs. If the @n th entry is NOT in the kernel stack,
259+
* this returns 0.
260+
*/
261+
static __always_inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
262+
{
263+
unsigned long addr;
264+
265+
addr = kernel_stack_pointer(regs) + n * sizeof(long);
266+
if (!regs_within_kernel_stack(regs, addr))
267+
return 0;
268+
return READ_ONCE_NOCHECK(addr);
269+
}
233270

234271
/**
235272
* 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,
250287
return regs_get_kernel_stack_nth(regs, argoffset + n);
251288
}
252289

253-
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
254-
{
255-
return regs->gprs[15];
256-
}
257-
258290
static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
259291
{
260292
regs->gprs[2] = rc;

arch/s390/kernel/ptrace.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,13 +1524,6 @@ static const char *gpr_names[NUM_GPRS] = {
15241524
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
15251525
};
15261526

1527-
unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
1528-
{
1529-
if (offset >= NUM_GPRS)
1530-
return 0;
1531-
return regs->gprs[offset];
1532-
}
1533-
15341527
int regs_query_register_offset(const char *name)
15351528
{
15361529
unsigned long offset;
@@ -1550,29 +1543,3 @@ const char *regs_query_register_name(unsigned int offset)
15501543
return NULL;
15511544
return gpr_names[offset];
15521545
}
1553-
1554-
static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
1555-
{
1556-
unsigned long ksp = kernel_stack_pointer(regs);
1557-
1558-
return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
1559-
}
1560-
1561-
/**
1562-
* regs_get_kernel_stack_nth() - get Nth entry of the stack
1563-
* @regs:pt_regs which contains kernel stack pointer.
1564-
* @n:stack entry number.
1565-
*
1566-
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1567-
* is specifined by @regs. If the @n th entry is NOT in the kernel stack,
1568-
* this returns 0.
1569-
*/
1570-
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1571-
{
1572-
unsigned long addr;
1573-
1574-
addr = kernel_stack_pointer(regs) + n * sizeof(long);
1575-
if (!regs_within_kernel_stack(regs, addr))
1576-
return 0;
1577-
return READ_ONCE_NOCHECK(addr);
1578-
}

0 commit comments

Comments
 (0)