Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Few fixes : 1. Check real memory size to find memory limit 2. working…
Browse files Browse the repository at this point in the history
… set size value needs to be multiplied by pagesize to get value in bytes
  • Loading branch information
rahul committed Mar 21, 2017
1 parent a4d892d commit 391e8d3
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 54 deletions.
52 changes: 26 additions & 26 deletions src/gc/unix/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Module Name:
#include <cstdint>
#include <cstddef>
#include <cassert>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Expand All @@ -26,7 +27,6 @@ Module Name:
#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
#define PROC_STATM_FILENAME "/proc/self/statm"
#define MEM_LIMIT_FILENAME "/memory.limit_in_bytes"
#define MEM_SWAP_LIMIT_FILENAME "/memory.memsw.limit_in_bytes"
#define _countof(_array) (sizeof(_array)/sizeof(_array[0]))

class CGroup
Expand Down Expand Up @@ -63,19 +63,6 @@ class CGroup
return ReadMemoryValueFromFile(mem_limit_filename, val);
}

bool GetSwapMemoryLimit(size_t *val)
{
char memsw_limit_filename[MAX_PATH];

if (m_memory_cgroup_path[0] == 0)
return false;

strcpy(memsw_limit_filename, m_memory_cgroup_path);
strncat(memsw_limit_filename, MEM_SWAP_LIMIT_FILENAME,
MAX_PATH-strlen(memsw_limit_filename)-1);
return ReadMemoryValueFromFile(memsw_limit_filename, val);
}

private:
bool FindMemoryHierarchyMount(char* mountpath, size_t mountpathsize)
{
Expand Down Expand Up @@ -245,27 +232,33 @@ class CGroup
size_t GetRestrictedPhysicalMemoryLimit()
{
CGroup cgroup;
size_t result;
size_t physical_memory_limit;
size_t swap_memory_limit;

if (!cgroup.GetPhysicalMemoryLimit(&physical_memory_limit))
physical_memory_limit = SIZE_T_MAX;
if (cgroup.GetSwapMemoryLimit(&swap_memory_limit))
{
assert(swap_memory_limit >= physical_memory_limit);
result = swap_memory_limit;
}
else
result = physical_memory_limit;

struct rlimit curr_rlimit;
size_t rlimit_soft_limit = RLIM_INFINITY;
if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0)
{
rlimit_soft_limit = curr_rlimit.rlim_cur;
}
result = (result < rlimit_soft_limit) ? result : rlimit_soft_limit;
return result;
physical_memory_limit = (physical_memory_limit < rlimit_soft_limit) ?
physical_memory_limit : rlimit_soft_limit;

// Ensure that limit is not greater than real memory size
size_t pages = (size_t) sysconf(_SC_PHYS_PAGES);
if (pages != -1)
{
long pageSize = sysconf(_SC_PAGE_SIZE);
if (pageSize != -1)
{
physical_memory_limit = (physical_memory_limit < pages * pageSize)?
physical_memory_limit : pages * pageSize;
}
}

return physical_memory_limit;
}

bool GetWorkingSetSize(size_t* val)
Expand All @@ -281,7 +274,14 @@ bool GetWorkingSetSize(size_t* val)
if (file != NULL && getline(&line, &linelen, file) != -1)
{
if (sscanf(line, "%*s %zu %*s %*s %*s %*s %*s", val) == 1)
result = true;
{
long pageSize = sysconf(_SC_PAGE_SIZE);
if (pageSize != -1)
{
*val = *val * pageSize;
result = true;
}
}
}

if (file)
Expand Down
2 changes: 1 addition & 1 deletion src/gc/unix/gcenv.unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available
// We do this only when we have the total physical memory available.
if (total > 0 && GetWorkingSetSize(&used))
{
available = total - used;
available = total > used ? total-used : 0;
load = (uint32_t)((used * 100) / total);
}

Expand Down
50 changes: 24 additions & 26 deletions src/pal/src/misc/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Module Name:
SET_DEFAULT_DEBUG_CHANNEL(MISC);
#include "pal/palinternal.h"
#include <sys/resource.h>
#include "pal/virtual.h"

#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo"
#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
#define PROC_STATM_FILENAME "/proc/self/statm"
#define MEM_LIMIT_FILENAME "/memory.limit_in_bytes"
#define MEM_SWAP_LIMIT_FILENAME "/memory.memsw.limit_in_bytes"

class CGroup
{
Expand Down Expand Up @@ -54,17 +54,6 @@ class CGroup
strcat_s(mem_limit_filename, MAX_PATH, MEM_LIMIT_FILENAME);
return ReadMemoryValueFromFile(mem_limit_filename, val);
}
bool GetSwapMemoryLimit(size_t *val)
{
char memsw_limit_filename[MAX_PATH];

if (m_memory_cgroup_path[0] == 0)
return false;

strcpy_s(memsw_limit_filename, MAX_PATH, m_memory_cgroup_path);
strcat_s(memsw_limit_filename, MAX_PATH, MEM_SWAP_LIMIT_FILENAME);
return ReadMemoryValueFromFile(memsw_limit_filename, val);
}
private:
bool FindMemoryHierarchyMount(char* mountpath, size_t mountpathsize)
{
Expand Down Expand Up @@ -217,35 +206,40 @@ class CGroup
}
};


size_t
PALAPI
PAL_GetRestrictedPhysicalMemoryLimit()
{
CGroup cgroup;
size_t result;
size_t physical_memory_limit;
size_t swap_memory_limit;

if (!cgroup.GetPhysicalMemoryLimit(&physical_memory_limit))
physical_memory_limit = SIZE_T_MAX;
if (cgroup.GetSwapMemoryLimit(&swap_memory_limit))
{
_ASSERTE(swap_memory_limit >= physical_memory_limit);
result = swap_memory_limit;
}
else
result = physical_memory_limit;

struct rlimit curr_rlimit;
size_t rlimit_soft_limit = (size_t)RLIM_INFINITY;
if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0)
{
rlimit_soft_limit = curr_rlimit.rlim_cur;
}
result = min(result, rlimit_soft_limit);
physical_memory_limit = min(physical_memory_limit, rlimit_soft_limit);

if(result == SIZE_T_MAX)
result = 0;
return result;
// Ensure that limit is not greater than real memory size
size_t pages = (size_t) sysconf(_SC_PHYS_PAGES);
if (pages != -1)
{
long pageSize = sysconf(_SC_PAGE_SIZE);
if (pageSize != -1)
{
physical_memory_limit = min(physical_memory_limit,
pages * pageSize);
}
}

if(physical_memory_limit == SIZE_T_MAX)
physical_memory_limit = 0;
return physical_memory_limit;
}

BOOL
Expand All @@ -262,8 +256,12 @@ PAL_GetWorkingSetSize(size_t* val)
FILE* file = fopen(PROC_STATM_FILENAME, "r");
if (file != NULL && getline(&line, &linelen, file) != -1)
{
if (sscanf_s(line, "%*s %zu %*s %*s %*s %*s %*s", val) == 1)
int x = sscanf_s(line, "%*s %llu %*s %*s %*s %*s %*s", val);
if(x==1)
{
*val = *val * VIRTUAL_PAGE_SIZE;
result = true;
}
}

if (file)
Expand Down
7 changes: 6 additions & 1 deletion src/vm/gcenv.os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,12 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available
if (memory_load)
*memory_load = (uint32_t)((float)workingSetSize * 100.0 / (float)restricted_limit);
if (available_physical)
*available_physical = restricted_limit - workingSetSize;
{
if(workingSetSize > restricted_limit)
*available_physical = 0;
else
*available_physical = restricted_limit - workingSetSize;
}
// Available page file doesn't mean much when physical memory is restricted since
// we don't know how much of it is available to this process so we are not going to
// bother to make another OS call for it.
Expand Down

0 comments on commit 391e8d3

Please sign in to comment.