Skip to content

Commit

Permalink
Update algorithms (#355)
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagoftsm authored Oct 6, 2023
1 parent 6021b1a commit ad436a6
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 81 deletions.
17 changes: 9 additions & 8 deletions includes/netdata_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@

typedef struct netdata_cachestat {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

__u64 add_to_page_cache_lru;
__u64 mark_page_accessed;
__u64 account_page_dirtied;
__u64 mark_buffer_dirty;
__s64 total;
__s64 misses;
__u64 dirty;
} netdata_cachestat_t;

enum cachestat_counters {
NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU,
NETDATA_KEY_CALLS_MARK_PAGE_ACCESSED,
NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED,
NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY,
NETDATA_KEY_TOTAL,
NETDATA_KEY_MISSES,
NETDATA_KEY_DIRTY,

// Keep this as last and don't skip numbers as it is used as element counter
NETDATA_CACHESTAT_END
Expand Down
47 changes: 37 additions & 10 deletions includes/netdata_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ static __always_inline void libnetdata_update_u64(__u64 *res, __u64 value)
}
}

static __always_inline void libnetdata_update_global(void *tbl,__u32 key, __u64 value)
static __always_inline void libnetdata_update_s64(__u64 *res, __s64 value)
{
__sync_fetch_and_add(res, value);
}

static __always_inline void libnetdata_update_global(void *tbl, __u32 key, __u64 value)
{
__u64 *res;
res = bpf_map_lookup_elem(tbl, &key);
Expand All @@ -31,6 +36,23 @@ static __always_inline void libnetdata_update_global(void *tbl,__u32 key, __u64
bpf_map_update_elem(tbl, &key, &value, BPF_EXIST);
}

static __always_inline void libnetdata_update_sglobal(void *tbl, __u32 key, __s64 value)
{
__s64 *res;
res = bpf_map_lookup_elem(tbl, &key);
if (res)
libnetdata_update_s64(res, value) ;
else
bpf_map_update_elem(tbl, &key, &value, BPF_EXIST);
}

static __always_inline void libnetdata_update_uid_gid(__u32 *uid, __u32 *gid)
{
__u64 uid_gid = bpf_get_current_uid_gid();
*uid = (__u32)uid_gid;
*gid = (__u32)(uid_gid>>32);
}

/**
* The motive we are using log2 to plot instead the raw value is well explained
* inside this paper https://www.fsl.cs.stonybrook.edu/docs/osprof-osdi2006/osprof.pdf
Expand Down Expand Up @@ -150,37 +172,42 @@ static __always_inline __u32 netdata_get_parent_pid()
return ppid;
}

static __always_inline __u32 netdata_get_current_pid()
static __always_inline __u32 netdata_get_current_pid(__u32 *tgid)
{
__u32 pid;
__u64 pid_tgid = bpf_get_current_pid_tgid();
pid = (__u32)(pid_tgid >> 32);
pid = (__u32)pid_tgid;
*tgid = (__u32)(pid_tgid>>32);

return pid;
}

static __always_inline __u32 netdata_get_pid(void *ctrl_tbl)
static __always_inline __u32 netdata_get_pid(void *ctrl_tbl, __u32 *tgid)
{
__u32 key = NETDATA_CONTROLLER_APPS_LEVEL;

__u64 *level = bpf_map_lookup_elem(ctrl_tbl ,&key);
if (level) {
if (*level == NETDATA_APPS_LEVEL_REAL_PARENT)
if (*level == NETDATA_APPS_LEVEL_REAL_PARENT) {
__u64 pid_tgid = bpf_get_current_pid_tgid();
*tgid = (__u32)(pid_tgid>>32);
return netdata_get_real_parent_pid();
else if (*level == NETDATA_APPS_LEVEL_PARENT)
} else if (*level == NETDATA_APPS_LEVEL_PARENT) {
__u64 pid_tgid = bpf_get_current_pid_tgid();
*tgid = (__u32)(pid_tgid>>32);
return netdata_get_parent_pid();
else if (*level == NETDATA_APPS_LEVEL_ALL)
return netdata_get_current_pid();
} else if (*level == NETDATA_APPS_LEVEL_ALL)
return netdata_get_current_pid(tgid);
else if (*level == NETDATA_APPS_LEVEL_IGNORE) // Ignore PID
return 0;
}

return netdata_get_real_parent_pid();
}

static __always_inline void *netdata_get_pid_structure(__u32 *store_pid, void *ctrl_tbl, void *pid_tbl)
static __always_inline void *netdata_get_pid_structure(__u32 *store_pid, __u32 *store_tgid, void *ctrl_tbl, void *pid_tbl)
{
__u32 pid = netdata_get_pid(ctrl_tbl);
__u32 pid = netdata_get_pid(ctrl_tbl, store_tgid);

*store_pid = pid;

Expand Down
4 changes: 3 additions & 1 deletion includes/netdata_dc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

typedef struct netdata_dc_stat {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];


__u64 references;
__u64 slow;
__u64 missed;
Expand Down
3 changes: 3 additions & 0 deletions includes/netdata_fd.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

struct netdata_fd_stat_t {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

//Counter
Expand Down
2 changes: 2 additions & 0 deletions includes/netdata_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ typedef struct netdata_sched_process_exec {

struct netdata_pid_stat_t {
__u64 ct;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

__u32 tgid; //Task id
Expand Down
3 changes: 3 additions & 0 deletions includes/netdata_shm.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

typedef struct netdata_shm {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

__u32 get;
Expand Down
3 changes: 3 additions & 0 deletions includes/netdata_swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

typedef struct netdata_swap_access {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

__u64 read;
Expand Down
3 changes: 3 additions & 0 deletions includes/netdata_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

struct netdata_vfs_stat_t {
__u64 ct;
__u32 tgid;
__u32 uid;
__u32 gid;
char name[TASK_COMM_LEN];

//Counter
Expand Down
58 changes: 38 additions & 20 deletions kernel/cachestat_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,27 @@ SEC("kprobe/add_to_page_cache_lru")
int netdata_add_to_page_cache_lru(struct pt_regs* ctx)
{
netdata_cachestat_t *fill, data = {};
libnetdata_update_global(&cstat_global, NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU, 1);
libnetdata_update_global(&cstat_global, NETDATA_KEY_MISSES, 1);

__u32 key = 0;
__u32 tgid = 0;
if (!monitor_apps(&cstat_ctrl))
return 0;

fill = netdata_get_pid_structure(&key, &cstat_ctrl, &cstat_pid);
fill = netdata_get_pid_structure(&key, &tgid, &cstat_ctrl, &cstat_pid);
if (fill) {
libnetdata_update_u64(&fill->add_to_page_cache_lru, 1);
libnetdata_update_s64(&fill->misses, 1);
} else {
data.ct = bpf_ktime_get_ns();
libnetdata_update_uid_gid(&data.uid, &data.gid);
data.tgid = tgid;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,11,0))
bpf_get_current_comm(&data.name, TASK_COMM_LEN);
#else
data.name[0] = '\0';
#endif

data.add_to_page_cache_lru = 1;
data.misses = 1;
bpf_map_update_elem(&cstat_pid, &key, &data, BPF_ANY);

libnetdata_update_global(&cstat_ctrl, NETDATA_CONTROLLER_PID_TABLE_ADD, 1);
Expand All @@ -104,24 +107,27 @@ SEC("kprobe/mark_page_accessed")
int netdata_mark_page_accessed(struct pt_regs* ctx)
{
netdata_cachestat_t *fill, data = {};
libnetdata_update_global(&cstat_global, NETDATA_KEY_CALLS_MARK_PAGE_ACCESSED, 1);
libnetdata_update_global(&cstat_global, NETDATA_KEY_TOTAL, 1);

__u32 key = 0;
__u32 tgid = 0;
if (!monitor_apps(&cstat_ctrl))
return 0;

fill = netdata_get_pid_structure(&key, &cstat_ctrl, &cstat_pid);
fill = netdata_get_pid_structure(&key, &tgid, &cstat_ctrl, &cstat_pid);
if (fill) {
libnetdata_update_u64(&fill->mark_page_accessed, 1);
libnetdata_update_s64(&fill->total, 1);
} else {
data.ct = bpf_ktime_get_ns();
libnetdata_update_uid_gid(&data.uid, &data.gid);
data.tgid = tgid;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,11,0))
bpf_get_current_comm(&data.name, TASK_COMM_LEN);
#else
data.name[0] = '\0';
#endif

data.mark_page_accessed = 1;
data.total = 1;
bpf_map_update_elem(&cstat_pid, &key, &data, BPF_ANY);

libnetdata_update_global(&cstat_ctrl, NETDATA_CONTROLLER_PID_TABLE_ADD, 1);
Expand Down Expand Up @@ -153,24 +159,27 @@ int netdata_set_page_dirty(struct pt_regs* ctx)
#endif

netdata_cachestat_t *fill, data = {};
libnetdata_update_global(&cstat_global, NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED, 1);
libnetdata_update_sglobal(&cstat_global, NETDATA_KEY_MISSES, -1);

__u32 key = 0;
__u32 tgid = 0;
if (!monitor_apps(&cstat_ctrl))
return 0;

fill = netdata_get_pid_structure(&key, &cstat_ctrl, &cstat_pid);
fill = netdata_get_pid_structure(&key, &tgid, &cstat_ctrl, &cstat_pid);
if (fill) {
libnetdata_update_u64(&fill->account_page_dirtied, 1);
libnetdata_update_s64(&fill->misses, -1);
} else {
data.ct = bpf_ktime_get_ns();
libnetdata_update_uid_gid(&data.uid, &data.gid);
data.tgid = tgid;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,11,0))
bpf_get_current_comm(&data.name, TASK_COMM_LEN);
#else
data.name[0] = '\0';
#endif

data.account_page_dirtied = 1;
data.misses = -1;
bpf_map_update_elem(&cstat_pid, &key, &data, BPF_ANY);

libnetdata_update_global(&cstat_ctrl, NETDATA_CONTROLLER_PID_TABLE_ADD, 1);
Expand All @@ -187,24 +196,27 @@ SEC("kprobe/account_page_dirtied")
int netdata_account_page_dirtied(struct pt_regs* ctx)
{
netdata_cachestat_t *fill, data = {};
libnetdata_update_global(&cstat_global, NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED, 1);
libnetdata_update_sglobal(&cstat_global, NETDATA_KEY_MISSES, -1);

__u32 key = 0;
__u32 tgid = 0;
if (!monitor_apps(&cstat_ctrl))
return 0;

fill = netdata_get_pid_structure(&key, &cstat_ctrl, &cstat_pid);
fill = netdata_get_pid_structure(&key, &tgid, &cstat_ctrl, &cstat_pid);
if (fill) {
libnetdata_update_u64(&fill->account_page_dirtied, 1);
libnetdata_update_s64(&fill->misses, -1);
} else {
data.ct = bpf_ktime_get_ns();
libnetdata_update_uid_gid(&data.uid, &data.gid);
data.tgid = tgid;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,11,0))
bpf_get_current_comm(&data.name, TASK_COMM_LEN);
#else
data.name[0] = '\0';
#endif

data.account_page_dirtied = 1;
data.misses = -1;
bpf_map_update_elem(&cstat_pid, &key, &data, BPF_ANY);

libnetdata_update_global(&cstat_ctrl, NETDATA_CONTROLLER_PID_TABLE_ADD, 1);
Expand All @@ -218,24 +230,30 @@ SEC("kprobe/mark_buffer_dirty")
int netdata_mark_buffer_dirty(struct pt_regs* ctx)
{
netdata_cachestat_t *fill, data = {};
libnetdata_update_global(&cstat_global, NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY, 1);
libnetdata_update_sglobal(&cstat_global, NETDATA_KEY_TOTAL, -1);
libnetdata_update_global(&cstat_global, NETDATA_KEY_DIRTY, 1);

__u32 key = 0;
__u32 tgid = 0;
if (!monitor_apps(&cstat_ctrl))
return 0;

fill = netdata_get_pid_structure(&key, &cstat_ctrl, &cstat_pid);
fill = netdata_get_pid_structure(&key, &tgid, &cstat_ctrl, &cstat_pid);
if (fill) {
libnetdata_update_u64(&fill->mark_buffer_dirty, 1);
libnetdata_update_u64(&fill->total, -1);
libnetdata_update_u64(&fill->dirty, 1);
} else {
data.ct = bpf_ktime_get_ns();
libnetdata_update_uid_gid(&data.uid, &data.gid);
data.tgid = tgid;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,11,0))
bpf_get_current_comm(&data.name, TASK_COMM_LEN);
#else
data.name[0] = '\0';
#endif

data.mark_buffer_dirty = 1;
data.dirty = 1;
data.total = -1;
bpf_map_update_elem(&cstat_pid, &key, &data, BPF_ANY);

libnetdata_update_global(&cstat_ctrl, NETDATA_CONTROLLER_PID_TABLE_ADD, 1);
Expand Down
Loading

0 comments on commit ad436a6

Please sign in to comment.