Skip to content

Commit

Permalink
Tracepoints (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagoftsm authored Dec 10, 2021
1 parent ff4c656 commit bbc7dbc
Show file tree
Hide file tree
Showing 11 changed files with 1,005 additions and 0 deletions.
4 changes: 4 additions & 0 deletions co-re/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ _LIBC ?= glibc

APPS = cachestat \
dc \
disk \
fd \
filesystem \
hardirq \
mdflush \
mount \
oomkill \
process \
shm \
softirq \
swap \
sync \
#
Expand Down
98 changes: 98 additions & 0 deletions co-re/disk.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "vmlinux.h"
#include "bpf_tracing.h"
#include "bpf_helpers.h"

#include "netdata_core.h"
#include "netdata_disk.h"

/************************************************************************************
*
* MAPS
*
***********************************************************************************/

//Hardware
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
__type(key, block_key_t);
__type(value, __u64);
__uint(max_entries, NETDATA_DISK_HISTOGRAM_LENGTH);
} tbl_disk_iocall SEC(".maps");

// Temporary use only
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
__type(key, netdata_disk_key_t);
__type(value, __u64);
__uint(max_entries, 8192);
} tmp_disk_tp_stat SEC(".maps");


/************************************************************************************
*
* DISK SECTION
*
***********************************************************************************/

SEC("tracepoint/block/block_rq_issue")
int netdata_block_rq_issue(struct netdata_block_rq_issue *ptr)
{
// blkid generates these and we're not interested in them
if (!ptr->dev)
return 0;

netdata_disk_key_t key = {};
key.dev = ptr->dev;
key.sector = ptr->sector;

if (key.sector < 0)
key.sector = 0;

__u64 value = bpf_ktime_get_ns();

bpf_map_update_elem(&tmp_disk_tp_stat, &key, &value, BPF_ANY);

return 0;
}

SEC("tracepoint/block/block_rq_complete")
int netdata_block_rq_complete(struct netdata_block_rq_complete *ptr)
{
__u64 *fill;
netdata_disk_key_t key = {};
block_key_t blk = {};
key.dev = ptr->dev;
key.sector = ptr->sector;

if (key.sector < 0)
key.sector = 0;

fill = bpf_map_lookup_elem(&tmp_disk_tp_stat ,&key);
if (!fill)
return 0;

// calculate and convert to microsecond
u64 curr = bpf_ktime_get_ns();
__u64 data, *update;
curr -= *fill;
curr /= 1000;

blk.bin = libnetdata_select_idx(curr, NETDATA_FS_MAX_BINS_POS);
blk.dev = netdata_new_encode_dev(ptr->dev);

// Update IOPS
update = bpf_map_lookup_elem(&tbl_disk_iocall ,&blk);
if (update) {
libnetdata_update_u64(update, 1);
} else {
data = 1;
bpf_map_update_elem(&tbl_disk_iocall, &blk, &data, BPF_ANY);
}

bpf_map_delete_elem(&tmp_disk_tp_stat, &key);

return 0;
}

char _license[] SEC("license") = "GPL";

131 changes: 131 additions & 0 deletions co-re/disk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <getopt.h>

#define _GNU_SOURCE /* See feature_test_macros(7) */
#define __USE_GNU
#include <fcntl.h>
#include <unistd.h>

#include "netdata_tests.h"

#include "disk.skel.h"

// Copied and redefined from ../include/netdata_disk.h
typedef struct block_key {
uint32_t bin;
uint32_t dev;
} block_key_t;

static inline int ebpf_load_and_attach(struct disk_bpf *obj)
{
int ret = disk_bpf__load(obj);
if (ret) {
fprintf(stderr, "failed to load BPF object: %d\n", ret);
return -1;
}

ret = disk_bpf__attach(obj);
if (!ret) {
fprintf(stdout, "Disk loaded with success\n");
}

return ret;
}

static void ebpf_update_table(int global)
{
block_key_t idx = { .bin = 0, .dev = 0};
unsigned char value = 'a';
int ret = bpf_map_update_elem(global, &idx, &value, 0);
if (ret)
fprintf(stderr, "Cannot insert value to global table.");
}

static int disk_read_array(int fd, int ebpf_nprocs)
{
uint64_t *stored = calloc((size_t)ebpf_nprocs, sizeof(uint64_t));
if (!stored)
return 2;

uint64_t counter = 0;
block_key_t idx = { .bin = 0, .dev = 0};
if (!bpf_map_lookup_elem(fd, &idx, stored)) {
int j;
for (j = 0; j < ebpf_nprocs; j++) {
counter += stored[j];
}
}

free(stored);

if (counter) {
fprintf(stdout, "Data stored with success\n");
return 0;
}

return 2;
}

static int ebpf_disk_tests()
{
struct disk_bpf *obj = NULL;
int ebpf_nprocs = (int)sysconf(_SC_NPROCESSORS_ONLN);

obj = disk_bpf__open();
if (!obj) {
fprintf(stderr, "Cannot open or load BPF object\n");

return 2;
}

int ret = ebpf_load_and_attach(obj);
if (!ret) {
int fd = bpf_map__fd(obj->maps.tbl_disk_iocall);
ebpf_update_table(fd);

ret = disk_read_array(fd, ebpf_nprocs);
if (ret)
fprintf(stderr, "Cannot read global table\n");
} else
fprintf(stderr ,"%s", NETDATA_CORE_DEFAULT_ERROR);

disk_bpf__destroy(obj);

return ret;
}

int main(int argc, char **argv)
{
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{0, 0, 0, 0}
};

int option_index = 0;
while (1) {
int c = getopt_long(argc, argv, "", long_options, &option_index);
if (c == -1)
break;

switch (c) {
case 'h': {
ebpf_tracepoint_help("Disk");
exit(0);
}
default: {
break;
}
}
}

int ret = netdata_ebf_memlock_limit();
if (ret) {
fprintf(stderr, "Cannot increase memory: error = %d\n", ret);
return 1;
}

return ebpf_disk_tests();
}

Loading

0 comments on commit bbc7dbc

Please sign in to comment.