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