@@ -245,7 +245,7 @@ static CString getCgroupControllerPath(FILE* cgroupControllerFile, const char* c
245245}
246246
247247
248- static int systemMemoryUsedAsPercentage (FILE* memInfoFile, FILE* zoneInfoFile, CGroupMemoryController* memoryController )
248+ static int systemMemoryUsedAsPercentage (FILE* memInfoFile, FILE* zoneInfoFile)
249249{
250250 if (!memInfoFile || fseek (memInfoFile, 0 , SEEK_SET))
251251 return -1 ;
@@ -288,21 +288,29 @@ static int systemMemoryUsedAsPercentage(FILE* memInfoFile, FILE* zoneInfoFile, C
288288 return -1 ;
289289
290290 int memoryUsagePercentage = ((memoryTotal - memoryAvailable) * 100 ) / memoryTotal;
291- LOG (MemoryPressure, " MemoryPressureMonitor::memory: real (total: %zu kB) (available: %zu kB) (usage: %d%%)" , memoryTotal, memoryAvailable, memoryUsagePercentage);
292- if (memoryController->isActive ()) {
293- memoryTotal = memoryController->getMemoryTotalWithCgroup ();
294- size_t memoryUsage = memoryController->getMemoryUsageWithCgroup ();
295- if (memoryTotal != notSet && memoryUsage != notSet) {
296- int memoryUsagePercentageWithCgroup = 100 * ((float ) memoryUsage / (float ) memoryTotal);
297- LOG (MemoryPressure, " MemoryPressureMonitor::memory: cgroup (total: %zu bytes) (in use: %zu bytes) (usage: %d%%)" , memoryTotal, memoryUsage, memoryUsagePercentageWithCgroup);
298- if (memoryUsagePercentageWithCgroup > memoryUsagePercentage)
299- memoryUsagePercentage = memoryUsagePercentageWithCgroup;
300- }
301- }
302- LOG (MemoryPressure, " MemoryPressureMonitor::memory: (memoryUsagePercentage: %d%%)" , memoryUsagePercentage);
291+ LOG (MemoryPressure, " MemoryPressureMonitor: memory real (memory total=%zu kB) (memory available=%zu kB) (memory usage percentage=%d )" , memoryTotal, memoryAvailable, memoryUsagePercentage);
292+
303293 return memoryUsagePercentage;
304294}
305295
296+ static int containerMemoryUsedAsPercentage (CGroupMemoryController* memoryController)
297+ {
298+ if (!memoryController->isActive ())
299+ return -1 ;
300+
301+ size_t memoryTotal = memoryController->getMemoryTotalWithCgroup ();
302+ size_t memoryUsage = memoryController->getMemoryUsageWithCgroup ();
303+
304+ if (memoryTotal == notSet || memoryUsage == notSet)
305+ return -1 ;
306+
307+ int memoryUsagePercentageWithCgroup = 100 * ((float ) memoryUsage / (float ) memoryTotal);
308+ LOG (MemoryPressure, " MemoryPressureMonitor: memory cgroup (memory total=%zu bytes) (memory usage=%zu bytes) (memory usage percentage=%d bytes)" , memoryTotal, memoryUsage, memoryUsagePercentageWithCgroup);
309+
310+ return memoryUsagePercentageWithCgroup;
311+ }
312+
313+
306314static inline Seconds pollIntervalForUsedMemoryPercentage (int usedPercentage)
307315{
308316 // Use a different poll interval depending on the currently memory used,
@@ -353,30 +361,50 @@ void MemoryPressureMonitor::start()
353361
354362 m_started = true ;
355363
356- Thread::create (" MemoryPressureMonitor" _s, [] {
364+ Thread::create (" MemoryPressureMonitor" _s, [mode = m_mode ] {
357365 FileHandle memInfoFile, zoneInfoFile, cgroupControllerFile;
358366 CGroupMemoryController memoryController = CGroupMemoryController ();
359367 Seconds pollInterval = s_maxPollingInterval;
360368 while (true ) {
361369 sleep (pollInterval);
362370
363- // Cannot operate without this one, retry opening on the next iteration after sleeping.
364- if (!tryOpeningForUnbufferedReading (memInfoFile, s_procMeminfo))
365- continue ;
371+ int usedPercentage = -1 ;
372+ if (mode == Mode::Container || mode == Mode::Higher) {
373+ tryOpeningForUnbufferedReading (cgroupControllerFile, s_procSelfCgroup);
374+
375+ CString cgroupMemoryControllerPath = getCgroupControllerPath (cgroupControllerFile.get (), " memory" );
376+ memoryController.setMemoryControllerPath (cgroupMemoryControllerPath);
377+
378+ usedPercentage = containerMemoryUsedAsPercentage (&memoryController);
379+
380+ // Warn only if we weren't able to get the data and we're in container mode, where it's
381+ // expected to work.
382+ if (usedPercentage == -1 && mode == Mode::Container)
383+ WTFLogAlways (" MemoryPressureMonitor: failed to get the memory usage using cgroup" );
384+ }
366385
367- // The monitor can work without these two, but it will be more precise if thy are eventually opened: keep trying.
368- tryOpeningForUnbufferedReading (zoneInfoFile, s_procZoneinfo);
369- tryOpeningForUnbufferedReading (cgroupControllerFile, s_procSelfCgroup);
386+ if (mode == Mode::System || mode == Mode::Higher) {
387+ // Cannot operate without this one, retry opening on the next iteration after sleeping.
388+ if (!tryOpeningForUnbufferedReading (memInfoFile, s_procMeminfo))
389+ continue ;
390+
391+ tryOpeningForUnbufferedReading (zoneInfoFile, s_procZoneinfo);
392+
393+ int systemUsedPercentage = systemMemoryUsedAsPercentage (memInfoFile.get (), zoneInfoFile.get ());
394+
395+ if (systemUsedPercentage == -1 )
396+ WTFLogAlways (" MemoryPressureMonitor: failed to get the memory usage using real memory" );
397+
398+ usedPercentage = std::max (usedPercentage, systemUsedPercentage);
399+ }
370400
371- CString cgroupMemoryControllerPath = getCgroupControllerPath (cgroupControllerFile.get (), " memory" );
372- memoryController.setMemoryControllerPath (cgroupMemoryControllerPath);
373- int usedPercentage = systemMemoryUsedAsPercentage (memInfoFile.get (), zoneInfoFile.get (), &memoryController);
374401 if (usedPercentage == -1 ) {
375- WTFLogAlways (" Failed to get the memory usage" );
402+ WTFLogAlways (" MemoryPressureMonitor: failed to get the memory usage using any method " );
376403 pollInterval = s_maxPollingInterval;
377404 continue ;
378405 }
379406
407+ LOG (MemoryPressure, " MemoryPressureMonitor: memoryUsagePercentage (%d)" , usedPercentage);
380408 if (usedPercentage >= s_memoryPresurePercentageThreshold) {
381409 bool isCritical = (usedPercentage >= s_memoryPresurePercentageThresholdCritical);
382410 RunLoop::main ().dispatch ([isCritical] {
0 commit comments