From b34affaed52d794f5bd1cd209dfe711cc2de787e Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Tue, 28 Feb 2017 00:23:19 +0200 Subject: [PATCH] fix numa plugin to work only on the expected values; fixes #1868 --- src/sys_devices_system_node.c | 85 ++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/src/sys_devices_system_node.c b/src/sys_devices_system_node.c index 449bbf0d..a7690e7b 100644 --- a/src/sys_devices_system_node.c +++ b/src/sys_devices_system_node.c @@ -60,26 +60,34 @@ static int find_all_nodes() { int do_proc_sys_devices_system_node(int update_every, usec_t dt) { (void)dt; - static int numa_node_count = 0; + static uint32_t hash_local_node = 0, hash_numa_foreign = 0, hash_interleave_hit = 0, hash_other_node = 0, hash_numa_hit = 0, hash_numa_miss = 0; + static int do_numastat = -1, numa_node_count = 0; + struct node *m; if(unlikely(numa_root == NULL)) { - numa_node_count = find_all_nodes(update_every); + numa_node_count = find_all_nodes(); if(unlikely(numa_root == NULL)) return 1; } - static int do_numastat = -1; - struct node *m; - if(unlikely(do_numastat == -1)) { do_numastat = config_get_boolean_ondemand("plugin:proc:/sys/devices/system/node", "enable per-node numa metrics", CONFIG_BOOLEAN_AUTO); + + hash_local_node = simple_hash("local_node"); + hash_numa_foreign = simple_hash("numa_foreign"); + hash_interleave_hit = simple_hash("interleave_hit"); + hash_other_node = simple_hash("other_node"); + hash_numa_hit = simple_hash("numa_hit"); + hash_numa_miss = simple_hash("numa_miss"); } if(do_numastat == CONFIG_BOOLEAN_YES || (do_numastat == CONFIG_BOOLEAN_AUTO && numa_node_count >= 2)) { for(m = numa_root; m; m = m->next) { if(m->numastat_filename) { + if(unlikely(!m->numastat_ff)) { m->numastat_ff = procfile_open(m->numastat_filename, " ", PROCFILE_FLAG_DEFAULT); + if(unlikely(!m->numastat_ff)) continue; } @@ -88,38 +96,61 @@ int do_proc_sys_devices_system_node(int update_every, usec_t dt) { if(unlikely(!m->numastat_ff || procfile_lines(m->numastat_ff) < 1 || procfile_linewords(m->numastat_ff, 0) < 1)) continue; - procfile *ff = m->numastat_ff; + if(unlikely(!m->numastat_st)) { + m->numastat_st = rrdset_create_localhost( + "mem" + , m->name + , NULL + , "numa" + , NULL + , "NUMA events" + , "events/s" + , 1000 + , update_every + , RRDSET_TYPE_LINE + ); + + rrdset_flag_set(m->numastat_st, RRDSET_FLAG_DETAIL); + + rrddim_add(m->numastat_st, "numa_hit", "hit", 1, 1, RRD_ALGORITHM_INCREMENTAL); + rrddim_add(m->numastat_st, "numa_miss", "miss", 1, 1, RRD_ALGORITHM_INCREMENTAL); + rrddim_add(m->numastat_st, "local_node", "local", 1, 1, RRD_ALGORITHM_INCREMENTAL); + rrddim_add(m->numastat_st, "numa_foreign", "foreign", 1, 1, RRD_ALGORITHM_INCREMENTAL); + rrddim_add(m->numastat_st, "interleave_hit", "interleave", 1, 1, RRD_ALGORITHM_INCREMENTAL); + rrddim_add(m->numastat_st, "other_node", "other", 1, 1, RRD_ALGORITHM_INCREMENTAL); - RRDSET *st = m->numastat_st; - if(unlikely(!st)) { - st = rrdset_create_localhost("mem", m->name, NULL, "numa", NULL, "NUMA events", "events/s", 1000 - , update_every, RRDSET_TYPE_LINE); - rrdset_flag_set(st, RRDSET_FLAG_DETAIL); - - rrddim_add(st, "local_node", "local", 1, 1, RRD_ALGORITHM_INCREMENTAL); - rrddim_add(st, "numa_foreign", "foreign", 1, 1, RRD_ALGORITHM_INCREMENTAL); - rrddim_add(st, "interleave_hit", "interleave", 1, 1, RRD_ALGORITHM_INCREMENTAL); - rrddim_add(st, "other_node", "other", 1, 1, RRD_ALGORITHM_INCREMENTAL); - - m->numastat_st = st; } - else rrdset_next(st); + else rrdset_next(m->numastat_st); - uint32_t lines = procfile_lines(ff), l; + size_t lines = procfile_lines(m->numastat_ff), l; for(l = 0; l < lines; l++) { - uint32_t words = procfile_linewords(ff, l); + size_t words = procfile_linewords(m->numastat_ff, l); + if(unlikely(words < 2)) { - if(unlikely(words)) error("Cannot read %s numastat line %u. Expected 2 params, read %u.", m->name, l, words); + if(unlikely(words)) + error("Cannot read %s numastat line %zu. Expected 2 params, read %zu.", m->name, l, words); continue; } - char *name = procfile_lineword(ff, l, 0); - char *value = procfile_lineword(ff, l, 1); - if (unlikely(!name || !*name || !value || !*value)) continue; + char *name = procfile_lineword(m->numastat_ff, l, 0); + char *value = procfile_lineword(m->numastat_ff, l, 1); - rrddim_set(st, name, strtoull(value, NULL, 10)); + if (unlikely(!name || !*name || !value || !*value)) + continue; + + uint32_t hash = simple_hash(name); + if(likely( + (hash == hash_numa_hit && !strcmp(name, "numa_hit")) + || (hash == hash_numa_miss && !strcmp(name, "numa_miss")) + || (hash == hash_local_node && !strcmp(name, "local_node")) + || (hash == hash_numa_foreign && !strcmp(name, "numa_foreign")) + || (hash == hash_interleave_hit && !strcmp(name, "interleave_hit")) + || (hash == hash_other_node && !strcmp(name, "other_node")) + )) + rrddim_set(m->numastat_st, name, (collected_number)str2kernel_uint_t(value)); } - rrdset_done(st); + + rrdset_done(m->numastat_st); } } } -- 2.39.2