Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static uint64_t read_cpufreq(unsigned int cpunum);

int uv__platform_loop_init(uv_loop_t* loop) {

loop->inotify_fd = -1;
loop->inotify_watchers = NULL;

Expand Down Expand Up @@ -811,29 +811,48 @@ uint64_t uv_get_constrained_memory(void) {
uint64_t high;
uint64_t max;
char* p;
char* p_end;

if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
return uv__get_constrained_memory_fallback();

/* In the case of cgroupv2, we'll only have a single entry. */
if (memcmp(buf, "0::/", 4))
return uv__get_constrained_memory_fallback();
if (0 == memcmp(buf, "0::/", 4)) {
p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';

p = buf + 4;

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.max", p);
max = uv__read_uint64(filename);

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.high", p);
high = uv__read_uint64(filename);
} else {
p = strchr(buf, ':');
while (p != NULL && memcmp(p, ":memory:", 8)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh wait, I realise this isn't how cgroups work...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think it is correct? But it would be good for someone who understands these things to check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take it slurm creates a cgroup subtree? On my cgroupv1 system, the limit sits at /sys/fs/cgroup/memory directly. It'd be useful to add a comment here about what you're doing, that's easier to review than to parse C code 🙂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that appears to be how cgroupv1 works, e.g. https://unix.stackexchange.com/a/621576

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently we're still missing something though, as on my cgroup1 system with Docker, I can't access even the memory subgroup listed in /proc/self/cgroup.

p = strchr(p, '\n');
p = strchr(p, ':');
}
if (p == NULL)
return uv__get_constrained_memory_fallback();

p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';
p = p + 8;
p_end = strchr(p, '\n');
if (p_end != NULL)
*p_end = '\0';

p = buf + 4;
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/memory/%s/memory.limit_in_bytes", p);
max = uv__read_uint64(filename);

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.max", p);
max = uv__read_uint64(filename);
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/memory/%s/memory.soft_limit_in_bytes", p);
high = uv__read_uint64(filename);
}

if (max == 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (max == 0 || high == 0)

return uv__get_constrained_memory_fallback();

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.high", p);
high = uv__read_uint64(filename);

if (high == 0)
return uv__get_constrained_memory_fallback();

Expand Down