Commit eb6ddc0e authored by Yonghong Song's avatar Yonghong Song

bpf: make test py_test_tools_smoke pass on arm64

Changes include:
  . Add PT_REGS_FP to access base(FP) register in x64
  . Use macros, intead of directly ctx-><reg_name>
    in a few places
  . Let userspace fill in the value of PAGE_SIZE.
    Otherwise, arm64 needs additional headers to
    get this value for kernel.
  . In tools/wakeuptime.py, arm64 and x86_64 have
    the same stack walker mechanism. But they
    have different symbol/macro to represent
    kernel start address.
With these changes, the test py_test_tools_smoke
can pass on arm64.
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
parent 740c4074
...@@ -566,6 +566,7 @@ int bpf_usdt_readarg_p(int argc, struct pt_regs *ctx, void *buf, u64 len) asm("l ...@@ -566,6 +566,7 @@ int bpf_usdt_readarg_p(int argc, struct pt_regs *ctx, void *buf, u64 len) asm("l
#define PT_REGS_PARM4(ctx) ((ctx)->cx) #define PT_REGS_PARM4(ctx) ((ctx)->cx)
#define PT_REGS_PARM5(ctx) ((ctx)->r8) #define PT_REGS_PARM5(ctx) ((ctx)->r8)
#define PT_REGS_PARM6(ctx) ((ctx)->r9) #define PT_REGS_PARM6(ctx) ((ctx)->r9)
#define PT_REGS_FP(ctx) ((ctx)->bp) /* Works only with CONFIG_FRAME_POINTER */
#define PT_REGS_RC(ctx) ((ctx)->ax) #define PT_REGS_RC(ctx) ((ctx)->ax)
#define PT_REGS_IP(ctx) ((ctx)->ip) #define PT_REGS_IP(ctx) ((ctx)->ip)
#define PT_REGS_SP(ctx) ((ctx)->sp) #define PT_REGS_SP(ctx) ((ctx)->sp)
......
...@@ -185,7 +185,7 @@ int trace_return(struct pt_regs *ctx) { ...@@ -185,7 +185,7 @@ int trace_return(struct pt_regs *ctx) {
#ifdef SYSCALLS #ifdef SYSCALLS
int syscall_entry(struct pt_regs *ctx) { int syscall_entry(struct pt_regs *ctx) {
u64 pid = bpf_get_current_pid_tgid(); u64 pid = bpf_get_current_pid_tgid();
u64 *valp, ip = ctx->ip, val = 0; u64 *valp, ip = PT_REGS_IP(ctx), val = 0;
PID_FILTER PID_FILTER
#ifdef LATENCY #ifdef LATENCY
struct syscall_entry_t data = {}; struct syscall_entry_t data = {};
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
from bcc import BPF from bcc import BPF
from time import sleep from time import sleep
from datetime import datetime from datetime import datetime
import resource
import argparse import argparse
import subprocess import subprocess
import os import os
...@@ -366,6 +367,7 @@ if kernel_trace: ...@@ -366,6 +367,7 @@ if kernel_trace:
bpf_source = bpf_source.replace("SHOULD_PRINT", "1" if trace_all else "0") bpf_source = bpf_source.replace("SHOULD_PRINT", "1" if trace_all else "0")
bpf_source = bpf_source.replace("SAMPLE_EVERY_N", str(sample_every_n)) bpf_source = bpf_source.replace("SAMPLE_EVERY_N", str(sample_every_n))
bpf_source = bpf_source.replace("PAGE_SIZE", str(resource.getpagesize()))
size_filter = "" size_filter = ""
if min_size is not None and max_size is not None: if min_size is not None and max_size is not None:
......
...@@ -76,13 +76,19 @@ BPF_HASH(start, u32); ...@@ -76,13 +76,19 @@ BPF_HASH(start, u32);
static u64 get_frame(u64 *bp) { static u64 get_frame(u64 *bp) {
if (*bp) { if (*bp) {
// The following stack walker is x86_64 specific // The following stack walker is x86_64/arm64 specific
u64 ret = 0; u64 ret = 0;
if (bpf_probe_read(&ret, sizeof(ret), (void *)(*bp+8))) if (bpf_probe_read(&ret, sizeof(ret), (void *)(*bp+8)))
return 0; return 0;
if (bpf_probe_read(bp, sizeof(*bp), (void *)*bp)) if (bpf_probe_read(bp, sizeof(*bp), (void *)*bp))
return 0; return 0;
#ifdef __x86_64__
if (ret < __START_KERNEL_map) if (ret < __START_KERNEL_map)
#elif __aarch64__
if (ret < VA_START)
#else
#error "Unsupported architecture for stack walker"
#endif
return 0; return 0;
return ret; return ret;
} }
...@@ -121,7 +127,7 @@ int waker(struct pt_regs *ctx, struct task_struct *p) { ...@@ -121,7 +127,7 @@ int waker(struct pt_regs *ctx, struct task_struct *p) {
bpf_probe_read(&key.target, sizeof(key.target), p->comm); bpf_probe_read(&key.target, sizeof(key.target), p->comm);
bpf_get_current_comm(&key.waker, sizeof(key.waker)); bpf_get_current_comm(&key.waker, sizeof(key.waker));
bp = ctx->bp; bp = PT_REGS_FP(ctx);
// unrolled loop (MAXDEPTH): // unrolled loop (MAXDEPTH):
if (!(key.ret[depth++] = get_frame(&bp))) goto out; if (!(key.ret[depth++] = get_frame(&bp))) goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment