@cryptotaxi247 / netdata-1 / commits / b33416d71

fix os_system_memory() for concurrent use and call it from pulse (#19359)

Costa Tsaousis committed Jan 9, 2025 at 16:23 UTC b33416d713ab2de3302ef99f4582cf5417988703
2 files changed +39 -79
src/daemon/pulse/pulse-daemon-memory.c
+2 -2
@@ -178,8 +178,8 @@ void pulse_daemon_memory_do(bool extended) {
178
179 // ----------------------------------------------------------------------------------------------------------------
180
181 - OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
182 - if (sm.ram_total_bytes) {
181 + OS_SYSTEM_MEMORY sm = os_system_memory(true);
182 + if (sm.ram_total_bytes && dbengine_out_of_memory_protection) {
183 static RRDSET *st_memory_available = NULL;
184 static RRDDIM *rd_available = NULL;
185
src/libnetdata/os/system_memory.c
+37 -77
@@ -82,54 +82,39 @@ static OS_SYSTEM_MEMORY os_system_memory_cgroup_v1(bool query_total_ram __maybe_
82 uint64_t used = 0, inactive = 0;
83
84 if(query_total_ram || sm.ram_total_bytes == 0) {
85 - if (read_txt_file("/sys/fs/cgroup/memory/memory.limit_in_bytes", buf, sizeof(buf)) != 0) {
86 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v1: cannot read /sys/fs/cgroup/memory/memory.limit_in_bytes");
85 + if (read_txt_file("/sys/fs/cgroup/memory/memory.limit_in_bytes", buf, sizeof(buf)) != 0)
86 goto failed;
88 - }
87
90 - sm.ram_total_bytes = strtoull(buf, NULL, 10);
91 - if(!sm.ram_total_bytes) {
92 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v1: /sys/fs/cgroup/memory/memory.limit_in_bytes is zero");
88 + sm.ram_total_bytes = str2ull(buf, NULL);
89 + if(!sm.ram_total_bytes)
90 goto failed;
94 - }
91 }
92
93 buf[0] = '\0';
98 - if (read_txt_file("/sys/fs/cgroup/memory/memory.usage_in_bytes", buf, sizeof(buf)) != 0) {
99 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v1: cannot read /sys/fs/cgroup/memory/memory.usage_in_bytes");
94 + if (read_txt_file("/sys/fs/cgroup/memory/memory.usage_in_bytes", buf, sizeof(buf)) != 0)
95 goto failed;
101 - }
96
103 - used = strtoull(buf, NULL, 10);
104 - if(!used || used > sm.ram_total_bytes) {
105 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v1: used is %llu, total is %llu: used is invalid",
106 -// used, sm.ram_total_bytes);
97 + used = str2ull(buf, NULL);
98 + if(!used || used > sm.ram_total_bytes)
99 goto failed;
108 - }
100
110 - if (read_txt_file("/sys/fs/cgroup/memory.stat", buf, sizeof(buf)) != 0) {
111 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot read /sys/fs/cgroup/memory.stat");
101 + if (read_txt_file("/sys/fs/cgroup/memory.stat", buf, sizeof(buf)) != 0)
102 goto done;
113 - }
103
104 const char *inactive_str = strstr(buf, "total_inactive_file ");
116 - if(!inactive_str) {
117 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot file 'inactive_file ' in /sys/fs/cgroup/memory.stat");
105 + if(!inactive_str)
106 goto done;
119 - }
107 +
108 inactive_str += 20;
109
122 - inactive = strtoull(inactive_str, NULL, 0);
110 + inactive = str2ull(inactive_str, NULL);
111 if(!inactive || inactive > used) {
124 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: inactive is %llu, used is %llu: inactive is invalid",
125 -// inactive, used);
112 inactive = 0;
113 goto done;
114 }
115
116 done:
117 sm.ram_available_bytes = sm.ram_total_bytes - (used - inactive);
132 - os_system_memory_last = sm;
118 return sm;
119
120 failed:
@@ -144,58 +129,43 @@ static OS_SYSTEM_MEMORY os_system_memory_cgroup_v2(bool query_total_ram __maybe_
129 uint64_t used = 0, inactive = 0;
130
131 if(query_total_ram || sm.ram_total_bytes == 0) {
147 - if (read_txt_file("/sys/fs/cgroup/memory.max", buf, sizeof(buf)) != 0) {
148 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot read /sys/fs/cgroup/memory.max");
132 + if (read_txt_file("/sys/fs/cgroup/memory.max", buf, sizeof(buf)) != 0)
133 goto failed;
150 - }
134
135 if(strcmp(buf, "max") == 0)
136 sm.ram_total_bytes = UINT64_MAX;
137 else
155 - sm.ram_total_bytes = strtoull(buf, NULL, 0);
138 + sm.ram_total_bytes = str2ull(buf, NULL);
139
157 - if(!sm.ram_total_bytes) {
158 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: /sys/fs/cgroup/memory.max is zero");
140 + if(!sm.ram_total_bytes)
141 goto failed;
160 - }
142 }
143
144 buf[0] = '\0';
164 - if (read_txt_file("/sys/fs/cgroup/memory.current", buf, sizeof(buf)) != 0) {
165 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot read /sys/fs/cgroup/memory.current");
145 + if (read_txt_file("/sys/fs/cgroup/memory.current", buf, sizeof(buf)) != 0)
146 goto failed;
167 - }
147
169 - used = strtoull(buf, NULL, 0);
170 - if(!used || used > sm.ram_total_bytes) {
171 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: used is %llu, total is %llu: used is invalid",
172 -// used, sm.ram_total_bytes);
148 + used = str2ull(buf, NULL);
149 + if(!used || used > sm.ram_total_bytes)
150 goto failed;
174 - }
151
176 - if (read_txt_file("/sys/fs/cgroup/memory.stat", buf, sizeof(buf)) != 0) {
177 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot read /sys/fs/cgroup/memory.stat");
152 + if (read_txt_file("/sys/fs/cgroup/memory.stat", buf, sizeof(buf)) != 0)
153 goto done;
179 - }
154
155 const char *inactive_str = strstr(buf, "inactive_file ");
182 - if(!inactive_str) {
183 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: cannot file 'inactive_file ' in /sys/fs/cgroup/memory.stat");
156 + if(!inactive_str)
157 goto done;
185 - }
158 +
159 inactive_str += 14;
160
188 - inactive = strtoull(inactive_str, NULL, 0);
161 + inactive = str2ull(inactive_str, NULL);
162 if(!inactive || inactive > used) {
190 -// nd_log(NDLS_DAEMON, NDLP_ERR, "SYSTEM_MEMORY: cgroups v2: inactive is %llu, used is %llu: inactive is invalid",
191 -// inactive, used);
163 inactive = 0;
164 goto done;
165 }
166
167 done:
168 sm.ram_available_bytes = sm.ram_total_bytes - (used - inactive);
198 - os_system_memory_last = sm;
169 return sm;
170
171 failed:
@@ -204,39 +174,28 @@ failed:
174 return sm;
175 }
176
207 -OS_SYSTEM_MEMORY os_system_memory_meminfo(bool query_total_ram __maybe_unused) {
208 - static OS_SYSTEM_MEMORY sm = {0, 0};
209 - static procfile *ff = NULL;
177 +#define MEMINFO_MEMTOTAL "MemTotal:"
178 +#define MEMINFO_MEMAVAILABLE "MemAvailable:"
179
211 - if(unlikely(!ff)) {
212 - ff = procfile_open("/proc/meminfo", ": \t", PROCFILE_FLAG_DEFAULT);
213 - if(unlikely(!ff))
214 - goto failed;
215 - }
180 +static OS_SYSTEM_MEMORY os_system_memory_meminfo(bool query_total_ram __maybe_unused) {
181 + static OS_SYSTEM_MEMORY sm = {0, 0};
182
217 - ff = procfile_readall(ff);
218 - if(unlikely(!ff))
183 + char buf[4096];
184 + if (read_txt_file("/proc/meminfo", buf, sizeof(buf)) != 0)
185 goto failed;
186
221 - bool matched_total = false, matched_available = false;
222 - size_t lines = procfile_lines(ff);
223 - for(size_t line = 0; line < lines ;line++) {
224 - if(!matched_total && strcmp(procfile_lineword(ff, line, 0), "MemTotal") == 0) {
225 - sm.ram_total_bytes = str2ull(procfile_lineword(ff, line, 1), NULL) * 1024;
226 - matched_total = true;
227 - }
187 + char *s = strstr(buf, MEMINFO_MEMTOTAL);
188 + if(!s) goto failed;
189 + s += sizeof(MEMINFO_MEMTOTAL) - 1;
190 + while(isspace((uint8_t)*s)) s++;
191 + sm.ram_total_bytes = str2ull(s, NULL) * 1024;
192
229 - if(!matched_available && strcmp(procfile_lineword(ff, line, 0), "MemAvailable") == 0) {
230 - sm.ram_available_bytes = str2ull(procfile_lineword(ff, line, 1), NULL) * 1024;
231 - matched_available = true;
232 - }
193 + s = strstr(buf, MEMINFO_MEMAVAILABLE);
194 + if(!s) goto failed;
195 + s += sizeof(MEMINFO_MEMAVAILABLE) - 1;
196 + while(isspace((uint8_t)*s)) s++;
197 + sm.ram_available_bytes = str2ull(s, NULL) * 1024;
198
234 - if(matched_total && matched_available)
235 - break;
236 - }
237 -
238 - // we keep ff open to speed up the next calls
239 - os_system_memory_last = sm;
199 return sm;
200
201 failed:
@@ -314,6 +273,7 @@ OS_SYSTEM_MEMORY os_system_memory(bool query_total_ram __maybe_unused) {
273 }
274 }
275
276 + os_system_memory_last = sm;
277 return sm;
278 }
279 #endif