Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCMemoryInfo.MemoryLoadBytes is not implemented on FreeBSD #64935

Closed
wfurt opened this issue Feb 7, 2022 · 9 comments · Fixed by #91524
Closed

GCMemoryInfo.MemoryLoadBytes is not implemented on FreeBSD #64935

wfurt opened this issue Feb 7, 2022 · 9 comments · Fixed by #91524
Labels
area-PAL-coreclr disabled-test The test is disabled in source code against the issue help wanted [up-for-grabs] Good issue for external contributors os-freebsd FreeBSD OS
Milestone

Comments

@wfurt
Copy link
Member

wfurt commented Feb 7, 2022

related to #14537
Because of this, GetGCMemoryInfo test is failing. It is not clear if this impacts just the GCMemoryInfo and test or if that also impacts come other GC operations.

This seems to come from:

void GCToOSInterface::GetMemoryStatus(uint64_t restricted_limit, uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file)

and
uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted)

and that eventually boils to

if (lpBuffer->ullTotalPhys > 0)
{
#ifndef __APPLE__
static volatile bool tryReadMemInfo = true;
if (tryReadMemInfo)
{
// Ensure that we don't try to read the /proc/meminfo in successive calls to the GlobalMemoryStatusEx
// if we have failed to access the file or the file didn't contain the MemAvailable value.
tryReadMemInfo = ReadMemAvailable(&lpBuffer->ullAvailPhys);
}
if (!tryReadMemInfo)
{
// The /proc/meminfo doesn't exist or it doesn't contain the MemAvailable row or the format of the row is invalid
// Fall back to getting the available pages using sysconf.
lpBuffer->ullAvailPhys = sysconf(SYSCONF_PAGES) * sysconf(_SC_PAGE_SIZE);
}
INT64 used_memory = lpBuffer->ullTotalPhys - lpBuffer->ullAvailPhys;
lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys);
#else
vm_size_t page_size;
mach_port_t mach_port;
mach_msg_type_number_t count;
vm_statistics_data_t vm_stats;
mach_port = mach_host_self();
count = sizeof(vm_stats) / sizeof(natural_t);
if (KERN_SUCCESS == host_page_size(mach_port, &page_size))
{
if (KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count))
{
lpBuffer->ullAvailPhys = (int64_t)vm_stats.free_count * (int64_t)page_size;
INT64 used_memory = ((INT64)vm_stats.active_count + (INT64)vm_stats.inactive_count + (INT64)vm_stats.wire_count) * (INT64)page_size;
lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys);
}
}
mach_port_deallocate(mach_task_self(), mach_port);
#endif // __APPLE__
}

while host_statistics() does not seems to be supported on FreeBSD, we may be able to use sysctlt. I don't know exactly what and how but there seems to be info about general memory status.

furt@d13:~/github/wfurt-runtime/src/coreclr $ sysctl -a | grep vm.stats.vm
vm.stats.vm.v_pdpages: 52746896
vm.stats.vm.v_tcached: 0
vm.stats.vm.v_cache_count: 0
vm.stats.vm.v_user_wire_count: 0
vm.stats.vm.v_free_severe: 7741
vm.stats.vm.v_interrupt_free_min: 2
vm.stats.vm.v_pageout_free_min: 34
vm.stats.vm.v_laundry_count: 58
vm.stats.vm.v_inactive_count: 231027
vm.stats.vm.v_inactive_target: 64605
vm.stats.vm.v_active_count: 1954
vm.stats.vm.v_wire_count: 959532
vm.stats.vm.v_free_count: 792657
vm.stats.vm.v_free_min: 12788
vm.stats.vm.v_free_target: 43070
vm.stats.vm.v_free_reserved: 2694
vm.stats.vm.v_page_count: 2018855
vm.stats.vm.v_page_size: 4096
vm.stats.vm.v_kthreadpages: 0
vm.stats.vm.v_rforkpages: 112322
vm.stats.vm.v_vforkpages: 608802
vm.stats.vm.v_forkpages: 792309
vm.stats.vm.v_kthreads: 23
vm.stats.vm.v_rforks: 1368
vm.stats.vm.v_vforks: 17614
vm.stats.vm.v_forks: 16655
vm.stats.vm.v_tfree: 79334088
vm.stats.vm.v_pfree: 34539982
vm.stats.vm.v_dfree: 2398725
vm.stats.vm.v_pdshortfalls: 58
vm.stats.vm.v_pdwakeups: 118
vm.stats.vm.v_reactivated: 684144
vm.stats.vm.v_intrans: 91070
vm.stats.vm.v_vnodepgsout: 271080
vm.stats.vm.v_vnodepgsin: 3647381
vm.stats.vm.v_vnodeout: 17159
vm.stats.vm.v_vnodein: 260117
vm.stats.vm.v_swappgsout: 767544
vm.stats.vm.v_swappgsin: 548901
vm.stats.vm.v_swapout: 44036
vm.stats.vm.v_swapin: 50815
vm.stats.vm.v_ozfod: 5063
vm.stats.vm.v_zfod: 63424950
vm.stats.vm.v_cow_optim: 255
vm.stats.vm.v_cow_faults: 6318711
vm.stats.vm.v_io_faults: 309807
vm.stats.vm.v_vm_faults: 72791650

Some of the entries seems to match the host_info_t.

@wfurt wfurt added disabled-test The test is disabled in source code against the issue os-freebsd FreeBSD OS area-PAL-coreclr labels Feb 7, 2022
@wfurt wfurt added this to the Future milestone Feb 7, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Feb 7, 2022
@wfurt wfurt added the help wanted [up-for-grabs] Good issue for external contributors label Feb 7, 2022
@Thefrank
Copy link
Contributor

Thefrank commented Feb 7, 2022

sysctl might be the quickest (easiest?) way to do this for any BSD-like or Solaris-like system. FreeBSD has vmstat(8) (which basically calls sysctl for that information but can be formatted differently)

thoughts @am11 ?

@am11
Copy link
Member

am11 commented Feb 7, 2022

while host_statistics() does not seems to be supported on FreeBSD

Isn't it so that we are using #ifndef __APPLE__ on Linux, FreeBSD and SunOS and #else (on macOS) is where we are using host_statistics()?

@emaste
Copy link

emaste commented Feb 7, 2022

What do we mean by "available" memory?

Could probably use one of these:

  • v_free_count + v_inactive_count + v_laundry_count
  • ullTotalPhys - v_active_count - v_wire_count

@emaste
Copy link

emaste commented Feb 7, 2022

Background info on memory in FreeBSD: https://wiki.freebsd.org/Memory

@wfurt
Copy link
Member Author

wfurt commented Feb 7, 2022

Yes @am11, but ReadMemAvailable() only parses /proc/meminfo.
I did not look closely what is actually expected. We may look at docs for host_statistics.

@am11
Copy link
Member

am11 commented Feb 7, 2022

Ah, thanks. will take a look. On SunOS, although the procfs is also available, but the difference is that it contains binary files (rather than text files), so it must be failing there as well (we would need to read the contents via read(struct)).

@am11
Copy link
Member

am11 commented Feb 8, 2022

@wfurt, something like this might do the trick:

#if defined(__APPLE__)
// paste existing apple code here

#elif defined(__FreeBSD__)
    size_t inactive_count = 0, cache_count = 0, free_count = 0;
    size_t sz = sizeof(inactive_count);
    sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count, &sz, NULL, 0); 

    sz = sizeof(cache_count);
    sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &sz, NULL, 0); 

    sz = sizeof(free_count);
    sysctlbyname("vm.stats.vm.v_free_count", &free_count, &sz, NULL, 0);

    lpBuffer->ullAvailPhys = (inactive_count + cache_count + free_count) * sysconf(_SC_PAGE_SIZE);

    INT64 used_memory = lpBuffer->ullTotalPhys - lpBuffer->ullAvailPhys;
    lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys);

// TODO: #elif __sun (read binary procfs via struct: https://illumos.org/man/4/proc, as we do in other places)

#else // Linux etc.
// paste existing linux code here

#endif

@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Mar 28, 2022
@Thefrank
Copy link
Contributor

Does this still need to be addressed? If yes, I should have some time this weekend to look over what is missing. If everything is set, can the test be reenabled?

@am11
Copy link
Member

am11 commented Aug 28, 2023

@Thefrank, go for it. I tested the code in a VM as an isolated app. It will help System.GC.GetGCMemoryInfo().MemoryLoadBytes API to report meaningful values and this test:

public static void GetGCMemoryInfo()

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Sep 3, 2023
jkotas pushed a commit that referenced this issue Sep 5, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Sep 5, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Oct 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-PAL-coreclr disabled-test The test is disabled in source code against the issue help wanted [up-for-grabs] Good issue for external contributors os-freebsd FreeBSD OS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants