Skip to content

Commit

Permalink
Merge pull request #7 from louxiu/master
Browse files Browse the repository at this point in the history
FIX: Ensure that the type of vals matches counts's
  • Loading branch information
yunwei37 authored Nov 7, 2024
2 parents 5263a71 + c4e3757 commit b0477fe
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 15 deletions.
47 changes: 36 additions & 11 deletions bpftools/profile_nginx_lua/profile.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const volatile bool disable_lua_user_trace = false;
const volatile bool include_idle = false;
const volatile pid_t targ_pid = -1;
const volatile pid_t targ_tid = -1;
const volatile __u64 targ_ns_dev = 0;
const volatile __u64 targ_ns_ino = 0;
const volatile __u64 stack_depth_limit = 0;

struct
{
Expand Down Expand Up @@ -84,7 +87,7 @@ static inline int lua_get_funcdata(struct bpf_perf_event_data *ctx, cTValue *fra
if (!src)
return -1;
bpf_probe_read_user_str(eventp->name, sizeof(eventp->name), src);
bpf_printk("level= %d, fn_name=%s\n", level, eventp->name);
//bpf_printk("level= %d, fn_name=%s\n", level, eventp->name);
}
else if (iscfunc(fn))
{
Expand Down Expand Up @@ -127,7 +130,7 @@ static int fix_lua_stack(struct bpf_perf_event_data *ctx, __u32 tid, int stack_i
frame = nextframe = BPF_PROBE_READ_USER(L, base) - 1;
/* Traverse frames backwards. */
// for the ebpf verifier insns (limit 1000000), we need to limit the max loop times to 13
for (; i < 15 && frame > bot; i++)
for (; i < stack_depth_limit && frame > bot; i++)
{
if (frame_gc(frame) == obj2gco(L))
{
Expand Down Expand Up @@ -159,12 +162,33 @@ static int fix_lua_stack(struct bpf_perf_event_data *ctx, __u32 tid, int stack_i
return 0;
}

static long get_current_pid_tgid(__u32 *pid, __u32 *tid)
{
if (targ_ns_dev == 0 && targ_ns_ino == 0)
{
__u64 id = bpf_get_current_pid_tgid();
*pid = id >> 32;
*tid = id;
return 0;
}

struct bpf_pidns_info ns = {};
long ret = bpf_get_ns_current_pid_tgid(targ_ns_dev, targ_ns_ino, &ns, sizeof(struct bpf_pidns_info));
if (ret)
return ret;

*pid = ns.pid;
*tid = ns.tgid;
return 0;
}

SEC("perf_event")
int do_perf_event(struct bpf_perf_event_data *ctx)
{
__u64 id = bpf_get_current_pid_tgid();
__u32 pid = id >> 32;
__u32 tid = id;
__u32 pid = 0, tid = 0;
if (get_current_pid_tgid(&pid, &tid))
return 0;

__u64 *valp;
static const __u64 zero;
struct profile_key_t key = {};
Expand Down Expand Up @@ -220,9 +244,9 @@ static int probe_entry_lua_cancel(struct pt_regs *ctx)
if (!PT_REGS_PARM4(ctx))
return 0;

__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
__u32 tid = (__u32)pid_tgid;
__u32 pid = 0, tid = 0;
if (get_current_pid_tgid(&pid, &tid))
return 0;

if (targ_pid != -1 && targ_pid != pid)
return 0;
Expand All @@ -241,9 +265,10 @@ static int probe_entry_lua(struct pt_regs *ctx)
if (!PT_REGS_PARM1(ctx))
return 0;

__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
__u32 tid = (__u32)pid_tgid;
__u32 pid = 0, tid = 0;
if (get_current_pid_tgid(&pid, &tid))
return 0;

struct lua_stack_event event = {};

if (targ_pid != -1 && targ_pid != pid)
Expand Down
54 changes: 50 additions & 4 deletions bpftools/profile_nginx_lua/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <unistd.h>
#include <time.h>
#include <linux/perf_event.h>
#include <sys/stat.h>
#include <asm/unistd.h>
#include <bpf/libbpf.h>
#include <bpf/bpf.h>
Expand All @@ -38,12 +39,15 @@ static struct env
{
pid_t pid;
pid_t tid;
__u64 ns_dev;
__u64 ns_ino;
bool user_stacks_only;
bool kernel_stacks_only;
// control lua user space stack trace
bool disable_lua_user_trace;
bool lua_user_stacks_only;
int stack_storage_size;
int stack_depth_limit;
int perf_max_stack_depth;
int duration;
bool verbose;
Expand All @@ -56,7 +60,10 @@ static struct env
} env = {
.pid = -1,
.tid = -1,
.ns_dev = 0,
.ns_ino = 0,
.stack_storage_size = 8192,
.stack_depth_limit = 15,
.perf_max_stack_depth = 127,
.duration = 3,
.freq = 1,
Expand Down Expand Up @@ -87,8 +94,9 @@ const char argp_program_doc[] =

#define OPT_PERF_MAX_STACK_DEPTH 1 /* --perf-max-stack-depth */
#define OPT_STACK_STORAGE_SIZE 2 /* --stack-storage-size */
#define OPT_LUA_USER_STACK_ONLY 3 /* --lua-user-stacks-only */
#define OPT_DISABLE_LUA_USER_TRACE 4 /* --disable-lua-user-trace */
#define OPT_STACK_DEPTH_LIMIT 3 /* --stack-depth-limit */
#define OPT_LUA_USER_STACK_ONLY 4 /* --lua-user-stacks-only */
#define OPT_DISABLE_LUA_USER_TRACE 5 /* --disable-lua-user-trace */
#define PERF_BUFFER_PAGES 16
#define PERF_POLL_TIMEOUT_MS 100

Expand All @@ -109,6 +117,8 @@ static const struct argp_option opts[] = {
{"folded", 'f', NULL, 0, "output folded format, one line per stack (for flame graphs)"},
{"stack-storage-size", OPT_STACK_STORAGE_SIZE, "STACK-STORAGE-SIZE", 0,
"the number of unique stack traces that can be stored and displayed (default 1024)"},
{"stack-depth-limit", OPT_STACK_DEPTH_LIMIT, "OPT_STACK_DEPTH_LIMIT", 0,
"the limit depth of stack that be traversed (default 15)"},
{"cpu", 'C', "CPU", 0, "cpu number to run profile on"},
{"perf-max-stack-depth", OPT_PERF_MAX_STACK_DEPTH,
"PERF-MAX-STACK-DEPTH", 0, "the limit for both kernel and user stack traces (default 127)"},
Expand All @@ -117,6 +127,22 @@ static const struct argp_option opts[] = {
{},
};

static int read_ns_dev_ino( __u64 *ns_dev, __u64 *ns_ino)
{
struct stat statbuf;
const char *path = "/proc/self/ns/pid";

if (stat(path, &statbuf) == -1) {
perror("stat");
return 1;
}

*ns_dev = statbuf.st_dev;
*ns_ino = statbuf.st_ino;

return 0;
}

static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
static int pos_args;
Expand Down Expand Up @@ -198,6 +224,15 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
argp_usage(state);
}
break;
case OPT_STACK_DEPTH_LIMIT:
errno = 0;
env.stack_depth_limit = strtol(arg, NULL, 10);
if (errno)
{
fprintf(stderr, "invalid stack depth limit: %s\n", arg);
argp_usage(state);
}
break;
case OPT_LUA_USER_STACK_ONLY:
env.lua_user_stacks_only = true;
break;
Expand Down Expand Up @@ -299,7 +334,7 @@ static bool read_batch_counts_map(int fd, struct key_ext_t *items, __u32 *count)
void *in = NULL, *out;
__u32 i, n, n_read = 0;
int err = 0;
__u32 vals[*count];
__u64 vals[*count];
struct profile_key_t keys[*count];

while (n_read < *count && !err)
Expand Down Expand Up @@ -774,9 +809,18 @@ int main(int argc, char **argv)
return 1;
}

if(read_ns_dev_ino(&env.ns_dev, &env.ns_ino))
{
fprintf(stderr, "failed to read ns_dev and ns_ino\n");
return 1;
}

/* initialize global data (filtering options) */
obj->rodata->targ_pid = env.pid;
obj->rodata->targ_tid = env.tid;
obj->rodata->targ_ns_dev = env.ns_dev;
obj->rodata->targ_ns_ino = env.ns_ino;
obj->rodata->stack_depth_limit = env.stack_depth_limit;
obj->rodata->user_stacks_only = env.user_stacks_only;
obj->rodata->kernel_stacks_only = env.kernel_stacks_only;
obj->rodata->include_idle = env.include_idle;
Expand All @@ -788,7 +832,9 @@ int main(int argc, char **argv)
err = profile_bpf__load(obj);
if (err)
{
fprintf(stderr, "failed to load BPF programs\n");
fprintf(stderr, "failed to load BPF programs. "
"if the error message indicates `BPF program is too large`, "
"consider using the `--stack-depth-limit` option.\n");
goto cleanup;
}
ksyms = ksyms__load();
Expand Down

0 comments on commit b0477fe

Please sign in to comment.