@@ -775,27 +775,62 @@ uint64_t uv_get_total_memory(void) {
775775}
776776
777777
778- static uint64_t uv__read_cgroups_uint64 (const char * cgroup , const char * param ) {
779- char filename [256 ];
778+ static uint64_t uv__read_uint64 (const char * filename ) {
780779 char buf [32 ]; /* Large enough to hold an encoded uint64_t. */
781780 uint64_t rc ;
782781
783782 rc = 0 ;
784- snprintf (filename , sizeof (filename ), "/sys/fs/cgroup/%s/%s" , cgroup , param );
785783 if (0 == uv__slurp (filename , buf , sizeof (buf )))
786- sscanf (buf , "%" PRIu64 , & rc );
784+ if (1 != sscanf (buf , "%" PRIu64 , & rc ))
785+ if (0 == strcmp (buf , "max\n" ))
786+ rc = ~0ull ;
787787
788788 return rc ;
789789}
790790
791791
792+ /* This might return 0 if there was a problem getting the memory limit from
793+ * cgroups. This is OK because a return value of 0 signifies that the memory
794+ * limit is unknown.
795+ */
796+ static uint64_t uv__get_constrained_memory_fallback (void ) {
797+ return uv__read_uint64 ("/sys/fs/cgroup/memory/memory.limit_in_bytes" );
798+ }
799+
800+
792801uint64_t uv_get_constrained_memory (void ) {
793- /*
794- * This might return 0 if there was a problem getting the memory limit from
795- * cgroups. This is OK because a return value of 0 signifies that the memory
796- * limit is unknown.
797- */
798- return uv__read_cgroups_uint64 ("memory" , "memory.limit_in_bytes" );
802+ char filename [4097 ];
803+ char buf [1024 ];
804+ uint64_t high ;
805+ uint64_t max ;
806+ char * p ;
807+
808+ if (uv__slurp ("/proc/self/cgroup" , buf , sizeof (buf )))
809+ return uv__get_constrained_memory_fallback ();
810+
811+ /* In the case of cgroupv2, we'll only have a single entry. */
812+ if (memcmp (buf , "0::/" , 4 ))
813+ return uv__get_constrained_memory_fallback ();
814+
815+ p = strchr (buf , '\n' );
816+ if (p != NULL )
817+ * p = '\0' ;
818+
819+ p = buf + 4 ;
820+
821+ snprintf (filename , sizeof (filename ), "/sys/fs/cgroup/%s/memory.max" , p );
822+ max = uv__read_uint64 (filename );
823+
824+ if (max == 0 )
825+ return uv__get_constrained_memory_fallback ();
826+
827+ snprintf (filename , sizeof (filename ), "/sys/fs/cgroup/%s/memory.high" , p );
828+ high = uv__read_uint64 (filename );
829+
830+ if (high == 0 )
831+ return uv__get_constrained_memory_fallback ();
832+
833+ return high < max ? high : max ;
799834}
800835
801836
0 commit comments