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