master
c 115 lines 3.45 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "windows_plugin.h"
4 #include "windows-internals.h"
5
6 struct netdata_numa {
7 RRDSET *st_numa;
8 RRDDIM *rd_standby;
9 RRDDIM *rd_free_zero;
10
11 COUNTER_DATA standby;
12 COUNTER_DATA free_zero;
13 };
14
15 static DICTIONARY *numa_dict = NULL;
16
17 static void numa_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
18 {
19 struct netdata_numa *d = value;
20
21 d->standby.key = "Standby List MBytes";
22 d->free_zero.key = "Free & Zero Page List MBytes";
23 }
24
25 static void initialize(void)
26 {
27 numa_dict = dictionary_create_advanced(
28 DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct netdata_numa));
29
30 dictionary_register_insert_callback(numa_dict, numa_insert_cb, NULL);
31 }
32
33 static void netdata_numa_chart(struct netdata_numa *nn, int update_every)
34 {
35 if (unlikely(!nn->st_numa)) {
36 char id[RRD_ID_LENGTH_MAX + 1];
37 snprintfz(id, RRD_ID_LENGTH_MAX, "numa_node_%s_mem_usage", windows_shared_buffer);
38
39 nn->st_numa = rrdset_create_localhost(
40 "numa_node_mem_usage",
41 id,
42 NULL,
43 "numa",
44 "mem.numa_node_mem_usage",
45 "NUMA Node Memory Usage",
46 "bytes",
47 PLUGIN_WINDOWS_NAME,
48 "PerflibNUMA",
49 NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO,
50 update_every,
51 RRDSET_TYPE_LINE);
52
53 rrdlabels_add(nn->st_numa->rrdlabels, "node", windows_shared_buffer, RRDLABEL_SRC_AUTO);
54
55 nn->rd_free_zero = rrddim_add(nn->st_numa, "free", NULL, MEGA_FACTOR, 1, RRD_ALGORITHM_ABSOLUTE);
56
57 nn->rd_standby = rrddim_add(nn->st_numa, "standby", NULL, MEGA_FACTOR, 1, RRD_ALGORITHM_ABSOLUTE);
58 }
59
60 rrddim_set_by_pointer(nn->st_numa, nn->rd_free_zero, (collected_number)nn->free_zero.current.Data);
61
62 rrddim_set_by_pointer(nn->st_numa, nn->rd_standby, (collected_number)nn->standby.current.Data);
63
64 rrdset_done(nn->st_numa);
65 }
66
67 static bool do_numa(PERF_DATA_BLOCK *pDataBlock, int update_every)
68 {
69 PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "NUMA Node Memory");
70 if (!pObjectType)
71 return false;
72
73 PERF_INSTANCE_DEFINITION *pi = NULL;
74 for (LONG i = 0; i < pObjectType->NumInstances; i++) {
75 pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
76 if (!pi)
77 break;
78
79 if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
80 strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
81
82 if (strcasecmp(windows_shared_buffer, "_Total") == 0)
83 continue;
84
85 struct netdata_numa *nn = dictionary_set(numa_dict, windows_shared_buffer, NULL, sizeof(*nn));
86
87 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &nn->standby);
88 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &nn->free_zero);
89 netdata_numa_chart(nn, update_every);
90 }
91
92 return true;
93 }
94
95 int do_PerflibNUMA(int update_every, usec_t dt __maybe_unused)
96 {
97 static bool initialized = false;
98
99 if (unlikely(!initialized)) {
100 initialize();
101 initialized = true;
102 }
103
104 DWORD id = RegistryFindIDByName("NUMA Node Memory");
105 if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
106 return -1;
107
108 PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
109 if (!pDataBlock)
110 return -1;
111
112 do_numa(pDataBlock, update_every);
113
114 return 0;
115 }