summaryrefslogtreecommitdiffstats
path: root/src/collectors/ebpf.plugin/ebpf_cachestat.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/collectors/ebpf.plugin/ebpf_cachestat.c (renamed from collectors/ebpf.plugin/ebpf_cachestat.c)481
1 files changed, 263 insertions, 218 deletions
diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/src/collectors/ebpf.plugin/ebpf_cachestat.c
index d9f8f7b06..45e09766f 100644
--- a/collectors/ebpf.plugin/ebpf_cachestat.c
+++ b/src/collectors/ebpf.plugin/ebpf_cachestat.c
@@ -58,9 +58,16 @@ netdata_ebpf_targets_t cachestat_targets[] = { {.name = "add_to_page_cache_lru",
static char *account_page[NETDATA_CACHESTAT_ACCOUNT_DIRTY_END] ={ "account_page_dirtied",
"__set_page_dirty", "__folio_mark_dirty" };
-#ifdef NETDATA_DEV_MODE
-int cachestat_disable_priority;
-#endif
+struct netdata_static_thread ebpf_read_cachestat = {
+ .name = "EBPF_READ_CACHESTAT",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+};
#ifdef LIBBPF_MAJOR_VERSION
/**
@@ -78,7 +85,6 @@ static void ebpf_cachestat_disable_probe(struct cachestat_bpf *obj)
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_kprobe, false);
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_kprobe, false);
bpf_program__set_autoload(obj->progs.netdata_mark_buffer_dirty_kprobe, false);
- bpf_program__set_autoload(obj->progs.netdata_release_task_kprobe, false);
}
/*
@@ -119,7 +125,6 @@ static void ebpf_cachestat_disable_trampoline(struct cachestat_bpf *obj)
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_fentry, false);
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_fentry, false);
bpf_program__set_autoload(obj->progs.netdata_mark_buffer_dirty_fentry, false);
- bpf_program__set_autoload(obj->progs.netdata_release_task_fentry, false);
}
/*
@@ -175,9 +180,6 @@ static inline void netdata_set_trampoline_target(struct cachestat_bpf *obj)
bpf_program__set_attach_target(obj->progs.netdata_mark_buffer_dirty_fentry, 0,
cachestat_targets[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY].name);
-
- bpf_program__set_attach_target(obj->progs.netdata_release_task_fentry, 0,
- EBPF_COMMON_FNCT_CLEAN_UP);
}
/**
@@ -194,7 +196,7 @@ static int ebpf_cachestat_attach_probe(struct cachestat_bpf *obj)
obj->links.netdata_add_to_page_cache_lru_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_add_to_page_cache_lru_kprobe,
false,
cachestat_targets[NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU].name);
- int ret = libbpf_get_error(obj->links.netdata_add_to_page_cache_lru_kprobe);
+ long ret = libbpf_get_error(obj->links.netdata_add_to_page_cache_lru_kprobe);
if (ret)
return -1;
@@ -234,13 +236,6 @@ static int ebpf_cachestat_attach_probe(struct cachestat_bpf *obj)
if (ret)
return -1;
- obj->links.netdata_release_task_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_release_task_kprobe,
- false,
- EBPF_COMMON_FNCT_CLEAN_UP);
- ret = libbpf_get_error(obj->links.netdata_release_task_kprobe);
- if (ret)
- return -1;
-
return 0;
}
@@ -277,19 +272,6 @@ static void ebpf_cachestat_set_hash_tables(struct cachestat_bpf *obj)
}
/**
- * Disable Release Task
- *
- * Disable release task when apps is not enabled.
- *
- * @param obj is the main structure for bpf objects.
- */
-static void ebpf_cachestat_disable_release_task(struct cachestat_bpf *obj)
-{
- bpf_program__set_autoload(obj->progs.netdata_release_task_kprobe, false);
- bpf_program__set_autoload(obj->progs.netdata_release_task_fentry, false);
-}
-
-/**
* Load and attach
*
* Load and attach the eBPF code in kernel.
@@ -316,9 +298,6 @@ static inline int ebpf_cachestat_load_and_attach(struct cachestat_bpf *obj, ebpf
ebpf_cachestat_adjust_map(obj, em);
- if (!em->apps_charts && !em->cgroup_charts)
- ebpf_cachestat_disable_release_task(obj);
-
int ret = cachestat_bpf__load(obj);
if (ret) {
return ret;
@@ -349,11 +328,11 @@ static void ebpf_obsolete_specific_cachestat_charts(char *type, int update_every
*
* @param em a pointer to `struct ebpf_module`
*/
-static void ebpf_obsolete_services(ebpf_module_t *em)
+static void ebpf_obsolete_cachestat_services(ebpf_module_t *em, char *id)
{
ebpf_write_chart_obsolete(NETDATA_SERVICE_FAMILY,
+ id,
NETDATA_CACHESTAT_HIT_RATIO_CHART,
- "",
"Hit ratio",
EBPF_COMMON_DIMENSION_PERCENTAGE,
NETDATA_CACHESTAT_SUBMENU,
@@ -363,8 +342,8 @@ static void ebpf_obsolete_services(ebpf_module_t *em)
em->update_every);
ebpf_write_chart_obsolete(NETDATA_SERVICE_FAMILY,
+ id,
NETDATA_CACHESTAT_DIRTY_CHART,
- "",
"Number of dirty pages",
EBPF_CACHESTAT_DIMENSION_PAGE,
NETDATA_CACHESTAT_SUBMENU,
@@ -374,8 +353,8 @@ static void ebpf_obsolete_services(ebpf_module_t *em)
em->update_every);
ebpf_write_chart_obsolete(NETDATA_SERVICE_FAMILY,
+ id,
NETDATA_CACHESTAT_HIT_CHART,
- "",
"Number of accessed files",
EBPF_CACHESTAT_DIMENSION_HITS,
NETDATA_CACHESTAT_SUBMENU,
@@ -385,8 +364,8 @@ static void ebpf_obsolete_services(ebpf_module_t *em)
em->update_every);
ebpf_write_chart_obsolete(NETDATA_SERVICE_FAMILY,
+ id,
NETDATA_CACHESTAT_MISSES_CHART,
- "",
"Files out of page cache",
EBPF_CACHESTAT_DIMENSION_MISSES,
NETDATA_CACHESTAT_SUBMENU,
@@ -406,12 +385,13 @@ static void ebpf_obsolete_services(ebpf_module_t *em)
static inline void ebpf_obsolete_cachestat_cgroup_charts(ebpf_module_t *em) {
pthread_mutex_lock(&mutex_cgroup_shm);
- ebpf_obsolete_services(em);
-
ebpf_cgroup_target_t *ect;
for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) {
- if (ect->systemd)
+ if (ect->systemd) {
+ ebpf_obsolete_cachestat_services(em, ect->name);
+
continue;
+ }
ebpf_obsolete_specific_cachestat_charts(ect->name, em->update_every);
}
@@ -483,6 +463,7 @@ void ebpf_obsolete_cachestat_apps_charts(struct ebpf_module *em)
{
struct ebpf_target *w;
int update_every = em->update_every;
+ pthread_mutex_lock(&collect_data_mutex);
for (w = apps_groups_root_target; w; w = w->next) {
if (unlikely(!(w->charts_created & (1<<EBPF_MODULE_CACHESTAT_IDX))))
continue;
@@ -532,6 +513,7 @@ void ebpf_obsolete_cachestat_apps_charts(struct ebpf_module *em)
update_every);
w->charts_created &= ~(1<<EBPF_MODULE_CACHESTAT_IDX);
}
+ pthread_mutex_unlock(&collect_data_mutex);
}
/**
@@ -545,6 +527,9 @@ static void ebpf_cachestat_exit(void *ptr)
{
ebpf_module_t *em = (ebpf_module_t *)ptr;
+ if (ebpf_read_cachestat.thread)
+ netdata_thread_cancel(*ebpf_read_cachestat.thread);
+
if (em->enabled == NETDATA_THREAD_EBPF_FUNCTION_RUNNING) {
pthread_mutex_lock(&lock);
if (em->cgroup_charts) {
@@ -558,12 +543,6 @@ static void ebpf_cachestat_exit(void *ptr)
ebpf_obsolete_cachestat_global(em);
-#ifdef NETDATA_DEV_MODE
- if (ebpf_aral_cachestat_pid)
- ebpf_statistic_obsolete_aral_chart(em, cachestat_disable_priority);
-#endif
-
-
fflush(stdout);
pthread_mutex_unlock(&lock);
}
@@ -688,13 +667,17 @@ static void cachestat_apps_accumulator(netdata_cachestat_pid_t *out, int maps_pe
{
int i, end = (maps_per_core) ? ebpf_nprocs : 1;
netdata_cachestat_pid_t *total = &out[0];
+ uint64_t ct = total->ct;
for (i = 1; i < end; i++) {
netdata_cachestat_pid_t *w = &out[i];
total->account_page_dirtied += w->account_page_dirtied;
total->add_to_page_cache_lru += w->add_to_page_cache_lru;
total->mark_buffer_dirty += w->mark_buffer_dirty;
total->mark_page_accessed += w->mark_page_accessed;
+ if (w->ct > ct)
+ ct = w->ct;
}
+ total->ct = ct;
}
/**
@@ -703,39 +686,18 @@ static void cachestat_apps_accumulator(netdata_cachestat_pid_t *out, int maps_pe
* Save the current values inside the structure
*
* @param out vector used to plot charts
- * @param publish vector with values read from hash tables.
+ * @param in vector with values read from hash tables.
*/
-static inline void cachestat_save_pid_values(netdata_publish_cachestat_t *out, netdata_cachestat_pid_t *publish)
+static inline void cachestat_save_pid_values(netdata_publish_cachestat_t *out, netdata_cachestat_pid_t *in)
{
+ out->ct = in->ct;
if (!out->current.mark_page_accessed) {
- memcpy(&out->current, &publish[0], sizeof(netdata_cachestat_pid_t));
+ memcpy(&out->current, &in[0], sizeof(netdata_cachestat_pid_t));
return;
}
memcpy(&out->prev, &out->current, sizeof(netdata_cachestat_pid_t));
- memcpy(&out->current, &publish[0], sizeof(netdata_cachestat_pid_t));
-}
-
-/**
- * Fill PID
- *
- * Fill PID structures
- *
- * @param current_pid pid that we are collecting data
- * @param out values read from hash tables;
- */
-static void cachestat_fill_pid(uint32_t current_pid, netdata_cachestat_pid_t *publish)
-{
- netdata_publish_cachestat_t *curr = cachestat_pid[current_pid];
- if (!curr) {
- curr = ebpf_publish_cachestat_get();
- cachestat_pid[current_pid] = curr;
-
- cachestat_save_pid_values(curr, publish);
- return;
- }
-
- cachestat_save_pid_values(curr, publish);
+ memcpy(&out->current, &in[0], sizeof(netdata_cachestat_pid_t));
}
/**
@@ -745,32 +707,39 @@ static void cachestat_fill_pid(uint32_t current_pid, netdata_cachestat_pid_t *pu
*
* @param maps_per_core do I need to read all cores?
*/
-static void ebpf_read_cachestat_apps_table(int maps_per_core)
+static void ebpf_read_cachestat_apps_table(int maps_per_core, int max_period)
{
netdata_cachestat_pid_t *cv = cachestat_vector;
- uint32_t key;
- struct ebpf_pid_stat *pids = ebpf_root_of_pids;
int fd = cachestat_maps[NETDATA_CACHESTAT_PID_STATS].map_fd;
size_t length = sizeof(netdata_cachestat_pid_t);
if (maps_per_core)
length *= ebpf_nprocs;
- while (pids) {
- key = pids->pid;
-
+ uint32_t key = 0, next_key = 0;
+ while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
if (bpf_map_lookup_elem(fd, &key, cv)) {
- pids = pids->next;
- continue;
+ goto end_cachestat_loop;
}
cachestat_apps_accumulator(cv, maps_per_core);
- cachestat_fill_pid(key, cv);
+ ebpf_pid_stat_t *local_pid = ebpf_get_pid_entry(key, cv->tgid);
+ if (!local_pid)
+ goto end_cachestat_loop;
+
+ netdata_publish_cachestat_t *publish = &local_pid->cachestat;
+ if (!publish->ct || publish->ct != cv->ct){
+ cachestat_save_pid_values(publish, cv);
+ local_pid->not_updated = 0;
+ } else if (++local_pid->not_updated >= max_period) {
+ bpf_map_delete_elem(fd, &key);
+ local_pid->not_updated = 0;
+ }
+end_cachestat_loop:
// We are cleaning to avoid passing data read from one process to other.
memset(cv, 0, length);
-
- pids = pids->next;
+ key = next_key;
}
}
@@ -781,14 +750,8 @@ static void ebpf_read_cachestat_apps_table(int maps_per_core)
*
* @param maps_per_core do I need to read all cores?
*/
-static void ebpf_update_cachestat_cgroup(int maps_per_core)
+static void ebpf_update_cachestat_cgroup()
{
- netdata_cachestat_pid_t *cv = cachestat_vector;
- int fd = cachestat_maps[NETDATA_CACHESTAT_PID_STATS].map_fd;
- size_t length = sizeof(netdata_cachestat_pid_t);
- if (maps_per_core)
- length *= ebpf_nprocs;
-
ebpf_cgroup_target_t *ect;
pthread_mutex_lock(&mutex_cgroup_shm);
for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
@@ -796,19 +759,11 @@ static void ebpf_update_cachestat_cgroup(int maps_per_core)
for (pids = ect->pids; pids; pids = pids->next) {
int pid = pids->pid;
netdata_cachestat_pid_t *out = &pids->cachestat;
- if (likely(cachestat_pid) && cachestat_pid[pid]) {
- netdata_publish_cachestat_t *in = cachestat_pid[pid];
+ ebpf_pid_stat_t *local_pid = ebpf_get_pid_entry(pid, 0);
+ if (local_pid) {
+ netdata_publish_cachestat_t *in = &local_pid->cachestat;
memcpy(out, &in->current, sizeof(netdata_cachestat_pid_t));
- } else {
- memset(cv, 0, length);
- if (bpf_map_lookup_elem(fd, &pid, cv)) {
- continue;
- }
-
- cachestat_apps_accumulator(cv, maps_per_core);
-
- memcpy(out, cv, sizeof(netdata_cachestat_pid_t));
}
}
}
@@ -816,6 +771,104 @@ static void ebpf_update_cachestat_cgroup(int maps_per_core)
}
/**
+ * Cachestat sum PIDs
+ *
+ * Sum values for all PIDs associated to a group
+ *
+ * @param publish output structure.
+ * @param root structure with listed IPs
+ */
+void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_pid_on_target *root)
+{
+ memcpy(&publish->prev, &publish->current,sizeof(publish->current));
+ memset(&publish->current, 0, sizeof(publish->current));
+
+ netdata_cachestat_pid_t *dst = &publish->current;
+ while (root) {
+ int32_t pid = root->pid;
+ ebpf_pid_stat_t *local_pid = ebpf_get_pid_entry(pid, 0);
+ if (local_pid) {
+ netdata_publish_cachestat_t *w = &local_pid->cachestat;
+ netdata_cachestat_pid_t *src = &w->current;
+ dst->account_page_dirtied += src->account_page_dirtied;
+ dst->add_to_page_cache_lru += src->add_to_page_cache_lru;
+ dst->mark_buffer_dirty += src->mark_buffer_dirty;
+ dst->mark_page_accessed += src->mark_page_accessed;
+ }
+
+ root = root->next;
+ }
+}
+
+/**
+ * Resume apps data
+ */
+void ebpf_resume_apps_data()
+{
+ struct ebpf_target *w;
+
+ for (w = apps_groups_root_target; w; w = w->next) {
+ if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_CACHESTAT_IDX))))
+ continue;
+
+ ebpf_cachestat_sum_pids(&w->cachestat, w->root_pid);
+ }
+}
+
+/**
+ * Cachestat thread
+ *
+ * Thread used to generate cachestat charts.
+ *
+ * @param ptr a pointer to `struct ebpf_module`
+ *
+ * @return It always return NULL
+ */
+void *ebpf_read_cachestat_thread(void *ptr)
+{
+ heartbeat_t hb;
+ heartbeat_init(&hb);
+
+ ebpf_module_t *em = (ebpf_module_t *)ptr;
+
+ int maps_per_core = em->maps_per_core;
+ int update_every = em->update_every;
+ int max_period = update_every * EBPF_CLEANUP_FACTOR;
+
+ int counter = update_every - 1;
+
+ uint32_t lifetime = em->lifetime;
+ uint32_t running_time = 0;
+ usec_t period = update_every * USEC_PER_SEC;
+ while (!ebpf_plugin_exit && running_time < lifetime) {
+ (void)heartbeat_next(&hb, period);
+ if (ebpf_plugin_exit || ++counter != update_every)
+ continue;
+
+ netdata_thread_disable_cancelability();
+
+ pthread_mutex_lock(&collect_data_mutex);
+ ebpf_read_cachestat_apps_table(maps_per_core, max_period);
+ ebpf_resume_apps_data();
+ pthread_mutex_unlock(&collect_data_mutex);
+
+ counter = 0;
+
+ pthread_mutex_lock(&ebpf_exit_cleanup);
+ if (running_time && !em->running_time)
+ running_time = update_every;
+ else
+ running_time += update_every;
+
+ em->running_time = running_time;
+ pthread_mutex_unlock(&ebpf_exit_cleanup);
+ netdata_thread_enable_cancelability();
+ }
+
+ return NULL;
+}
+
+/**
* Create apps charts
*
* Call ebpf_create_chart to create the charts on apps submenu.
@@ -944,7 +997,7 @@ static void cachestat_send_global(netdata_publish_cachestat_t *publish)
ebpf_one_dimension_write_charts(
NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_DIRTY_CHART, ptr[NETDATA_CACHESTAT_IDX_DIRTY].dimension,
- cachestat_hash_values[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY]);
+ (long long)cachestat_hash_values[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY]);
ebpf_one_dimension_write_charts(
NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_CHART, ptr[NETDATA_CACHESTAT_IDX_HIT].dimension, publish->hit);
@@ -955,35 +1008,6 @@ static void cachestat_send_global(netdata_publish_cachestat_t *publish)
}
/**
- * Cachestat sum PIDs
- *
- * Sum values for all PIDs associated to a group
- *
- * @param publish output structure.
- * @param root structure with listed IPs
- */
-void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_pid_on_target *root)
-{
- memcpy(&publish->prev, &publish->current,sizeof(publish->current));
- memset(&publish->current, 0, sizeof(publish->current));
-
- netdata_cachestat_pid_t *dst = &publish->current;
- while (root) {
- int32_t pid = root->pid;
- netdata_publish_cachestat_t *w = cachestat_pid[pid];
- if (w) {
- netdata_cachestat_pid_t *src = &w->current;
- dst->account_page_dirtied += src->account_page_dirtied;
- dst->add_to_page_cache_lru += src->add_to_page_cache_lru;
- dst->mark_buffer_dirty += src->mark_buffer_dirty;
- dst->mark_page_accessed += src->mark_page_accessed;
- }
-
- root = root->next;
- }
-}
-
-/**
* Send data to Netdata calling auxiliary functions.
*
* @param root the target list.
@@ -993,17 +1017,17 @@ void ebpf_cache_send_apps_data(struct ebpf_target *root)
struct ebpf_target *w;
collected_number value;
+ pthread_mutex_lock(&collect_data_mutex);
for (w = root; w; w = w->next) {
if (unlikely(!(w->charts_created & (1<<EBPF_MODULE_CACHESTAT_IDX))))
continue;
- ebpf_cachestat_sum_pids(&w->cachestat, w->root_pid);
netdata_cachestat_pid_t *current = &w->cachestat.current;
netdata_cachestat_pid_t *prev = &w->cachestat.prev;
uint64_t mpa = current->mark_page_accessed - prev->mark_page_accessed;
uint64_t mbd = current->mark_buffer_dirty - prev->mark_buffer_dirty;
- w->cachestat.dirty = mbd;
+ w->cachestat.dirty = (long long)mbd;
uint64_t apcl = current->add_to_page_cache_lru - prev->add_to_page_cache_lru;
uint64_t apd = current->account_page_dirtied - prev->account_page_dirtied;
@@ -1029,6 +1053,7 @@ void ebpf_cache_send_apps_data(struct ebpf_target *root)
write_chart_dimension("misses", value);
ebpf_write_end_chart();
}
+ pthread_mutex_unlock(&collect_data_mutex);
}
/**
@@ -1073,7 +1098,7 @@ void ebpf_cachestat_calc_chart_values()
uint64_t mpa = current->mark_page_accessed - prev->mark_page_accessed;
uint64_t mbd = current->mark_buffer_dirty - prev->mark_buffer_dirty;
- ect->publish_cachestat.dirty = mbd;
+ ect->publish_cachestat.dirty = (long long)mbd;
uint64_t apcl = current->add_to_page_cache_lru - prev->add_to_page_cache_lru;
uint64_t apd = current->account_page_dirtied - prev->account_page_dirtied;
@@ -1090,35 +1115,82 @@ void ebpf_cachestat_calc_chart_values()
**/
static void ebpf_create_systemd_cachestat_charts(int update_every)
{
- ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_HIT_RATIO_CHART,
- "Hit ratio",
- EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU,
- NETDATA_EBPF_CHART_TYPE_LINE, 21100,
- ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
- NETDATA_SYSTEMD_CACHESTAT_HIT_RATIO_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT,
- update_every);
+ static ebpf_systemd_args_t data_hit_ratio = {
+ .title = "Hit ratio",
+ .units = EBPF_COMMON_DIMENSION_PERCENTAGE,
+ .family = NETDATA_CACHESTAT_SUBMENU,
+ .charttype = NETDATA_EBPF_CHART_TYPE_LINE,
+ .order = 21100,
+ .algorithm = EBPF_CHART_ALGORITHM_ABSOLUTE,
+ .context = NETDATA_SYSTEMD_CACHESTAT_HIT_RATIO_CONTEXT,
+ .module = NETDATA_EBPF_MODULE_NAME_CACHESTAT,
+ .update_every = 0,
+ .suffix = NETDATA_CACHESTAT_HIT_RATIO_CHART,
+ .dimension = "percentage"
+ };
- ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_DIRTY_CHART,
- "Number of dirty pages",
- EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU,
- NETDATA_EBPF_CHART_TYPE_LINE, 21101,
- ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
- NETDATA_SYSTEMD_CACHESTAT_MODIFIED_CACHE_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT,
- update_every);
+ static ebpf_systemd_args_t data_dirty = {
+ .title = "Number of dirty pages",
+ .units = EBPF_CACHESTAT_DIMENSION_PAGE,
+ .family = NETDATA_CACHESTAT_SUBMENU,
+ .charttype = NETDATA_EBPF_CHART_TYPE_LINE,
+ .order = 21101,
+ .algorithm = EBPF_CHART_ALGORITHM_ABSOLUTE,
+ .context = NETDATA_SYSTEMD_CACHESTAT_MODIFIED_CACHE_CONTEXT,
+ .module = NETDATA_EBPF_MODULE_NAME_CACHESTAT,
+ .update_every = 0,
+ .suffix = NETDATA_CACHESTAT_DIRTY_CHART,
+ .dimension = "pages"
+ };
- ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_HIT_CHART, "Number of accessed files",
- EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU,
- NETDATA_EBPF_CHART_TYPE_LINE, 21102,
- ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
- NETDATA_SYSTEMD_CACHESTAT_HIT_FILE_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT,
- update_every);
+ static ebpf_systemd_args_t data_hit = {
+ .title = "Number of accessed pages",
+ .units = EBPF_CACHESTAT_DIMENSION_HITS,
+ .family = NETDATA_CACHESTAT_SUBMENU,
+ .charttype = NETDATA_EBPF_CHART_TYPE_LINE,
+ .order = 21102,
+ .algorithm = EBPF_CHART_ALGORITHM_ABSOLUTE,
+ .context = NETDATA_SYSTEMD_CACHESTAT_HIT_FILE_CONTEXT,
+ .module = NETDATA_EBPF_MODULE_NAME_CACHESTAT,
+ .update_every = 0,
+ .suffix = NETDATA_CACHESTAT_HIT_CHART,
+ .dimension = "hits"
+ };
- ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_MISSES_CHART, "Files out of page cache",
- EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU,
- NETDATA_EBPF_CHART_TYPE_LINE, 21103,
- ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
- NETDATA_SYSTEMD_CACHESTAT_MISS_FILES_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT,
- update_every);
+ static ebpf_systemd_args_t data_miss = {
+ .title = "Files out of page cache",
+ .units = EBPF_CACHESTAT_DIMENSION_MISSES,
+ .family = NETDATA_CACHESTAT_SUBMENU,
+ .charttype = NETDATA_EBPF_CHART_TYPE_LINE,
+ .order = 21103,
+ .algorithm = EBPF_CHART_ALGORITHM_ABSOLUTE,
+ .context = NETDATA_SYSTEMD_CACHESTAT_MISS_FILES_CONTEXT,
+ .module = NETDATA_EBPF_MODULE_NAME_CACHESTAT,
+ .update_every = 0,
+ .suffix = NETDATA_CACHESTAT_MISSES_CHART,
+ .dimension = "misses"
+ };
+
+ if (!data_miss.update_every)
+ data_hit_ratio.update_every = data_dirty.update_every =
+ data_hit.update_every = data_miss.update_every = update_every;
+
+ ebpf_cgroup_target_t *w;
+ for (w = ebpf_cgroup_pids; w; w = w->next) {
+ if (unlikely(!w->systemd || w->flags & NETDATA_EBPF_SERVICES_HAS_CACHESTAT_CHART))
+ continue;
+
+ data_hit_ratio.id = data_dirty.id = data_hit.id = data_miss.id = w->name;
+ ebpf_create_charts_on_systemd(&data_hit_ratio);
+
+ ebpf_create_charts_on_systemd(&data_dirty);
+
+ ebpf_create_charts_on_systemd(&data_hit);
+
+ ebpf_create_charts_on_systemd(&data_miss);
+
+ w->flags |= NETDATA_EBPF_SERVICES_HAS_CACHESTAT_CHART;
+ }
}
/**
@@ -1130,37 +1202,27 @@ static void ebpf_send_systemd_cachestat_charts()
{
ebpf_cgroup_target_t *ect;
- ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_CACHESTAT_HIT_RATIO_CHART, "");
for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
- if (unlikely(ect->systemd) && unlikely(ect->updated)) {
- write_chart_dimension(ect->name, (long long)ect->publish_cachestat.ratio);
+ if (unlikely(!(ect->flags & NETDATA_EBPF_SERVICES_HAS_CACHESTAT_CHART)) ) {
+ continue;
}
- }
- ebpf_write_end_chart();
- ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_CACHESTAT_DIRTY_CHART, "");
- for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
- if (unlikely(ect->systemd) && unlikely(ect->updated)) {
- write_chart_dimension(ect->name, (long long)ect->publish_cachestat.dirty);
- }
- }
- ebpf_write_end_chart();
+ ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, ect->name, NETDATA_CACHESTAT_HIT_RATIO_CHART);
+ write_chart_dimension("percentage", (long long)ect->publish_cachestat.ratio);
+ ebpf_write_end_chart();
- ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_CACHESTAT_HIT_CHART, "");
- for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
- if (unlikely(ect->systemd) && unlikely(ect->updated)) {
- write_chart_dimension(ect->name, (long long)ect->publish_cachestat.hit);
- }
- }
- ebpf_write_end_chart();
+ ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, ect->name, NETDATA_CACHESTAT_DIRTY_CHART);
+ write_chart_dimension("pages", (long long)ect->publish_cachestat.dirty);
+ ebpf_write_end_chart();
- ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_CACHESTAT_MISSES_CHART, "");
- for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
- if (unlikely(ect->systemd) && unlikely(ect->updated)) {
- write_chart_dimension(ect->name, (long long)ect->publish_cachestat.miss);
- }
+ ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, ect->name, NETDATA_CACHESTAT_HIT_CHART);
+ write_chart_dimension("hits", (long long)ect->publish_cachestat.hit);
+ ebpf_write_end_chart();
+
+ ebpf_write_begin_chart(NETDATA_SERVICE_FAMILY, ect->name, NETDATA_CACHESTAT_MISSES_CHART);
+ write_chart_dimension("misses", (long long)ect->publish_cachestat.miss);
+ ebpf_write_end_chart();
}
- ebpf_write_end_chart();
}
/**
@@ -1199,7 +1261,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every)
{
ebpf_create_chart(type, NETDATA_CACHESTAT_HIT_RATIO_CHART,
"Hit ratio",
- EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_CGROUP_SUBMENU,
+ EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU,
NETDATA_CGROUP_CACHESTAT_HIT_RATIO_CONTEXT,
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5200,
ebpf_create_global_dimension,
@@ -1207,7 +1269,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every)
ebpf_create_chart(type, NETDATA_CACHESTAT_DIRTY_CHART,
"Number of dirty pages",
- EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_CGROUP_SUBMENU,
+ EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU,
NETDATA_CGROUP_CACHESTAT_MODIFIED_CACHE_CONTEXT,
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5201,
ebpf_create_global_dimension,
@@ -1216,7 +1278,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every)
ebpf_create_chart(type, NETDATA_CACHESTAT_HIT_CHART,
"Number of accessed files",
- EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_CGROUP_SUBMENU,
+ EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU,
NETDATA_CGROUP_CACHESTAT_HIT_FILES_CONTEXT,
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5202,
ebpf_create_global_dimension,
@@ -1225,7 +1287,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every)
ebpf_create_chart(type, NETDATA_CACHESTAT_MISSES_CHART,
"Files out of page cache",
- EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_CGROUP_SUBMENU,
+ EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU,
NETDATA_CGROUP_CACHESTAT_MISS_FILES_CONTEXT,
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5203,
ebpf_create_global_dimension,
@@ -1279,15 +1341,11 @@ static void ebpf_obsolete_specific_cachestat_charts(char *type, int update_every
*/
void ebpf_cachestat_send_cgroup_data(int update_every)
{
- if (!ebpf_cgroup_pids)
- return;
-
pthread_mutex_lock(&mutex_cgroup_shm);
ebpf_cgroup_target_t *ect;
ebpf_cachestat_calc_chart_values();
- int has_systemd = shm_ebpf_cgroup.header->systemd_enabled;
- if (has_systemd) {
+ if (shm_ebpf_cgroup.header->systemd_enabled) {
if (send_cgroup_chart) {
ebpf_create_systemd_cachestat_charts(update_every);
}
@@ -1344,12 +1402,9 @@ static void cachestat_collector(ebpf_module_t *em)
counter = 0;
netdata_apps_integration_flags_t apps = em->apps_charts;
ebpf_cachestat_read_global_tables(stats, maps_per_core);
- pthread_mutex_lock(&collect_data_mutex);
- if (apps)
- ebpf_read_cachestat_apps_table(maps_per_core);
if (cgroups)
- ebpf_update_cachestat_cgroup(maps_per_core);
+ ebpf_update_cachestat_cgroup();
pthread_mutex_lock(&lock);
@@ -1358,16 +1413,10 @@ static void cachestat_collector(ebpf_module_t *em)
if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED)
ebpf_cache_send_apps_data(apps_groups_root_target);
-#ifdef NETDATA_DEV_MODE
- if (ebpf_aral_cachestat_pid)
- ebpf_send_data_aral_chart(ebpf_aral_cachestat_pid, em);
-#endif
-
if (cgroups)
ebpf_cachestat_send_cgroup_data(update_every);
pthread_mutex_unlock(&lock);
- pthread_mutex_unlock(&collect_data_mutex);
pthread_mutex_lock(&ebpf_exit_cleanup);
if (running_time && !em->running_time)
@@ -1442,17 +1491,10 @@ static void ebpf_create_memory_charts(ebpf_module_t *em)
*
* We are not testing the return, because callocz does this and shutdown the software
* case it was not possible to allocate.
- *
- * @param apps is apps enabled?
*/
-static void ebpf_cachestat_allocate_global_vectors(int apps)
+static void ebpf_cachestat_allocate_global_vectors()
{
- if (apps) {
- cachestat_pid = callocz((size_t)pid_max, sizeof(netdata_publish_cachestat_t *));
- ebpf_cachestat_aral_init();
- cachestat_vector = callocz((size_t)ebpf_nprocs, sizeof(netdata_cachestat_pid_t));
- }
-
+ cachestat_vector = callocz((size_t)ebpf_nprocs, sizeof(netdata_cachestat_pid_t));
cachestat_values = callocz((size_t)ebpf_nprocs, sizeof(netdata_idx_t));
memset(cachestat_hash_values, 0, NETDATA_CACHESTAT_END * sizeof(netdata_idx_t));
@@ -1560,7 +1602,7 @@ void *ebpf_cachestat_thread(void *ptr)
goto endcachestat;
}
- ebpf_cachestat_allocate_global_vectors(em->apps_charts);
+ ebpf_cachestat_allocate_global_vectors();
int algorithms[NETDATA_CACHESTAT_END] = {
NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX
@@ -1574,13 +1616,16 @@ void *ebpf_cachestat_thread(void *ptr)
ebpf_update_stats(&plugin_statistics, em);
ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps, EBPF_ACTION_STAT_ADD);
ebpf_create_memory_charts(em);
-#ifdef NETDATA_DEV_MODE
- if (ebpf_aral_cachestat_pid)
- cachestat_disable_priority = ebpf_statistic_create_aral_chart(NETDATA_EBPF_CACHESTAT_ARAL_NAME, em);
-#endif
pthread_mutex_unlock(&lock);
+ ebpf_read_cachestat.thread = mallocz(sizeof(netdata_thread_t));
+ netdata_thread_create(ebpf_read_cachestat.thread,
+ ebpf_read_cachestat.name,
+ NETDATA_THREAD_OPTION_DEFAULT,
+ ebpf_read_cachestat_thread,
+ em);
+
cachestat_collector(em);
endcachestat: