Skip to content

Commit

Permalink
Merge pull request #4 from iovisor/master
Browse files Browse the repository at this point in the history
Merge pull request iovisor#4089 from davemarchevsky/davemarchevsky_fi…
  • Loading branch information
fengjixuchui committed Jul 5, 2022
2 parents 22015af + c54336e commit b71a347
Show file tree
Hide file tree
Showing 29 changed files with 839 additions and 107 deletions.
4 changes: 2 additions & 2 deletions docs/reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1145,9 +1145,9 @@ Examples in situ:
### 13. BPF_XSKMAP
Syntax: ```BPF_XSKMAP(name, size)```
Syntax: ```BPF_XSKMAP(name, size [, "/sys/fs/bpf/xyz"])```

This creates a xsk map named ```name``` with ```size``` entries. Each entry represents one NIC's queue id. This map is only used in XDP to redirect packet to an AF_XDP socket. If the AF_XDP socket is binded to a queue which is different than the current packet's queue id, the packet will be dropped. For kernel v5.3 and latter, `lookup` method is available and can be used to check whether and AF_XDP socket is available for the current packet's queue id. More details at [AF_XDP](https://www.kernel.org/doc/html/latest/networking/af_xdp.html).
This creates a xsk map named ```name``` with ```size``` entries and pin it to the bpffs as a FILE. Each entry represents one NIC's queue id. This map is only used in XDP to redirect packet to an AF_XDP socket. If the AF_XDP socket is binded to a queue which is different than the current packet's queue id, the packet will be dropped. For kernel v5.3 and latter, `lookup` method is available and can be used to check whether and AF_XDP socket is available for the current packet's queue id. More details at [AF_XDP](https://www.kernel.org/doc/html/latest/networking/af_xdp.html).

For example:
```C
Expand Down
1 change: 1 addition & 0 deletions libbpf-tools/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
/syscount
/tcpconnect
/tcpconnlat
/tcplife
/tcprtt
/tcpsynbl
/vfsstat
Expand Down
1 change: 1 addition & 0 deletions libbpf-tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ APPS = \
syscount \
tcpconnect \
tcpconnlat \
tcplife \
tcprtt \
tcpsynbl \
vfsstat \
Expand Down
21 changes: 17 additions & 4 deletions libbpf-tools/biopattern.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <bpf/bpf_tracing.h>
#include "biopattern.h"
#include "maps.bpf.h"
#include "core_fixes.bpf.h"

const volatile bool filter_dev = false;
const volatile __u32 targ_dev = 0;
Expand All @@ -17,12 +18,24 @@ struct {
} counters SEC(".maps");

SEC("tracepoint/block/block_rq_complete")
int handle__block_rq_complete(struct trace_event_raw_block_rq_complete *ctx)
int handle__block_rq_complete(void *args)
{
sector_t sector = ctx->sector;
struct counter *counterp, zero = {};
u32 nr_sector = ctx->nr_sector;
u32 dev = ctx->dev;
sector_t sector;
u32 nr_sector;
u32 dev;

if (has_block_rq_completion()) {
struct trace_event_raw_block_rq_completion___x *ctx = args;
sector = BPF_CORE_READ(ctx, sector);
nr_sector = BPF_CORE_READ(ctx, nr_sector);
dev = BPF_CORE_READ(ctx, dev);
} else {
struct trace_event_raw_block_rq_complete *ctx = args;
sector = BPF_CORE_READ(ctx, sector);
nr_sector = BPF_CORE_READ(ctx, nr_sector);
dev = BPF_CORE_READ(ctx, dev);
}

if (filter_dev && targ_dev != dev)
return 0;
Expand Down
40 changes: 31 additions & 9 deletions libbpf-tools/core_fixes.bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ struct task_struct___x {
unsigned int __state;
} __attribute__((preserve_access_index));

static __always_inline __s64 get_task_state(void *task)
{
struct task_struct___x *t = task;

if (bpf_core_field_exists(t->__state))
return BPF_CORE_READ(t, __state);
return BPF_CORE_READ((struct task_struct *)task, state);
}

/**
* commit 309dca309fc3 ("block: store a block_device pointer in struct bio")
* adds a new member bi_bdev which is a pointer to struct block_device
Expand All @@ -27,15 +36,6 @@ struct bio___x {
struct block_device *bi_bdev;
} __attribute__((preserve_access_index));

static __always_inline __s64 get_task_state(void *task)
{
struct task_struct___x *t = task;

if (bpf_core_field_exists(t->__state))
return BPF_CORE_READ(t, __state);
return BPF_CORE_READ((struct task_struct *)task, state);
}

static __always_inline struct gendisk *get_gendisk(void *bio)
{
struct bio___x *b = bio;
Expand All @@ -45,4 +45,26 @@ static __always_inline struct gendisk *get_gendisk(void *bio)
return BPF_CORE_READ((struct bio *)bio, bi_disk);
}

/**
* commit d5869fdc189f ("block: introduce block_rq_error tracepoint")
* adds a new tracepoint block_rq_error and it shares the same arguments
* with tracepoint block_rq_complete. As a result, the kernel BTF now has
* a `struct trace_event_raw_block_rq_completion` instead of
* `struct trace_event_raw_block_rq_complete`.
* see:
* https://github.com/torvalds/linux/commit/d5869fdc189f
*/
struct trace_event_raw_block_rq_completion___x {
dev_t dev;
sector_t sector;
unsigned int nr_sector;
} __attribute__((preserve_access_index));

static __always_inline bool has_block_rq_completion()
{
if (bpf_core_type_exists(struct trace_event_raw_block_rq_completion___x))
return true;
return false;
}

#endif /* __CORE_FIXES_BPF_H */
3 changes: 3 additions & 0 deletions libbpf-tools/filelife.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ int main(int argc, char **argv)
/* initialize global data (filtering options) */
obj->rodata->targ_tgid = env.pid;

if (!kprobe_exists("security_inode_create"))
bpf_program__set_autoload(obj->progs.security_inode_create, false);

err = filelife_bpf__load(obj);
if (err) {
fprintf(stderr, "failed to load BPF object: %d\n", err);
Expand Down
35 changes: 21 additions & 14 deletions libbpf-tools/llcstat.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,43 @@
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "maps.bpf.h"
#include "llcstat.h"

#define MAX_ENTRIES 10240

const volatile bool targ_per_thread = false;

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_ENTRIES);
__type(key, u64);
__type(value, struct info);
__type(key, struct key_info);
__type(value, struct value_info);
} infos SEC(".maps");

static __always_inline
int trace_event(__u64 sample_period, bool miss)
{
u64 pid = bpf_get_current_pid_tgid();
u32 cpu = bpf_get_smp_processor_id();
struct info *infop, info = {};
u64 key = pid << 32 | cpu;

infop = bpf_map_lookup_elem(&infos, &key);
if (!infop) {
bpf_get_current_comm(info.comm, sizeof(info.comm));
infop = &info;
}
struct key_info key = {};
struct value_info *infop, zero = {};

u64 pid_tgid = bpf_get_current_pid_tgid();
key.cpu = bpf_get_smp_processor_id();
key.pid = pid_tgid >> 32;
if (targ_per_thread)
key.tid = (u32)pid_tgid;
else
key.tid = key.pid;

infop = bpf_map_lookup_or_try_init(&infos, &key, &zero);
if (!infop)
return 0;
if (miss)
infop->miss += sample_period;
else
infop->ref += sample_period;
if (infop == &info)
bpf_map_update_elem(&infos, &key, infop, 0);
bpf_get_current_comm(infop->comm, sizeof(infop->comm));

return 0;
}

Expand Down
40 changes: 29 additions & 11 deletions libbpf-tools/llcstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// Based on llcstat(8) from BCC by Teng Qin.
// 29-Sep-2020 Wenbo Zhang Created this.
// 20-Jun-2022 YeZhengMao Added tid info.
#include <argp.h>
#include <signal.h>
#include <stdio.h>
Expand All @@ -21,6 +22,7 @@ struct env {
int sample_period;
time_t duration;
bool verbose;
bool per_thread;
} env = {
.sample_period = 100,
.duration = 10,
Expand All @@ -40,6 +42,8 @@ static const struct argp_option opts[] = {
{ "sample_period", 'c', "SAMPLE_PERIOD", 0, "Sample one in this many "
"number of cache reference / miss events" },
{ "verbose", 'v', NULL, 0, "Verbose debug output" },
{ "tid", 't', NULL, 0,
"Summarize cache references and misses by PID/TID" },
{ NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" },
{},
};
Expand All @@ -55,6 +59,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
case 'v':
env.verbose = true;
break;
case 't':
env.per_thread = true;
break;
case 'c':
errno = 0;
env.sample_period = strtol(arg, NULL, 10);
Expand Down Expand Up @@ -131,10 +138,10 @@ static void sig_handler(int sig)
static void print_map(struct bpf_map *map)
{
__u64 total_ref = 0, total_miss = 0, total_hit, hit;
__u64 lookup_key = -1, next_key;
__u32 pid, cpu, tid;
struct key_info lookup_key = { .cpu = -1 }, next_key;
int err, fd = bpf_map__fd(map);
struct info info;
__u32 pid, cpu;
struct value_info info;

while (!bpf_map_get_next_key(fd, &lookup_key, &next_key)) {
err = bpf_map_lookup_elem(fd, &next_key, &info);
Expand All @@ -143,11 +150,16 @@ static void print_map(struct bpf_map *map)
return;
}
hit = info.ref > info.miss ? info.ref - info.miss : 0;
pid = next_key >> 32;
cpu = next_key;
printf("%-8u %-16s %-4u %12llu %12llu %6.2f%%\n", pid, info.comm,
cpu, info.ref, info.miss, info.ref > 0 ?
hit * 1.0 / info.ref * 100 : 0);
cpu = next_key.cpu;
pid = next_key.pid;
tid = next_key.tid;
printf("%-8u ", pid);
if (env.per_thread) {
printf("%-8u ", tid);
}
printf("%-16s %-4u %12llu %12llu %6.2f%%\n",
info.comm, cpu, info.ref, info.miss,
info.ref > 0 ? hit * 1.0 / info.ref * 100 : 0);
total_miss += info.miss;
total_ref += info.ref;
lookup_key = next_key;
Expand All @@ -157,7 +169,7 @@ static void print_map(struct bpf_map *map)
total_ref, total_miss, total_ref > 0 ?
total_hit * 1.0 / total_ref * 100 : 0);

lookup_key = -1;
lookup_key.cpu = -1;
while (!bpf_map_get_next_key(fd, &lookup_key, &next_key)) {
err = bpf_map_delete_elem(fd, &next_key);
if (err < 0) {
Expand Down Expand Up @@ -212,6 +224,8 @@ int main(int argc, char **argv)
goto cleanup;
}

obj->rodata->targ_per_thread = env.per_thread;

err = llcstat_bpf__load(obj);
if (err) {
fprintf(stderr, "failed to load BPF object: %d\n", err);
Expand All @@ -233,8 +247,12 @@ int main(int argc, char **argv)

sleep(env.duration);

printf("%-8s %-16s %-4s %12s %12s %7s\n",
"PID", "NAME", "CPU", "REFERENCE", "MISS", "HIT%");
printf("%-8s ", "PID");
if (env.per_thread) {
printf("%-8s ", "TID");
}
printf("%-16s %-4s %12s %12s %7s\n",
"NAME", "CPU", "REFERENCE", "MISS", "HIT%");

print_map(obj->maps.infos);

Expand Down
8 changes: 7 additions & 1 deletion libbpf-tools/llcstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@

#define TASK_COMM_LEN 16

struct info {
struct value_info {
__u64 ref;
__u64 miss;
char comm[TASK_COMM_LEN];
};

struct key_info {
__u32 cpu;
__u32 pid;
__u32 tid;
};

#endif /* __LLCSTAT_H */
5 changes: 3 additions & 2 deletions libbpf-tools/syscount.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
static const struct data_t zero;
pid_t pid = id >> 32;
struct data_t *val;
u64 *start_ts;
u64 *start_ts, lat = 0;
u32 tid = id;
u32 key;

Expand All @@ -97,6 +97,7 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
start_ts = bpf_map_lookup_elem(&start, &tid);
if (!start_ts)
return 0;
lat = bpf_ktime_get_ns() - *start_ts;
}

key = (count_by_process) ? pid : args->id;
Expand All @@ -106,7 +107,7 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
if (count_by_process)
save_proc_name(val);
if (measure_latency)
__sync_fetch_and_add(&val->total_ns, bpf_ktime_get_ns() - *start_ts);
__sync_fetch_and_add(&val->total_ns, lat);
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion libbpf-tools/tcpconnect.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static __always_inline bool filter_port(__u16 port)
if (filter_ports_len == 0)
return false;

for (i = 0; i < filter_ports_len; i++) {
for (i = 0; i < filter_ports_len && i < MAX_PORTS; i++) {
if (port == filter_ports[i])
return false;
}
Expand Down
Loading

0 comments on commit b71a347

Please sign in to comment.