summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsys.cpp
diff options
context:
space:
mode:
authorRoger Luedecke <roger.luedecke@gmail.com>2026-09-15 15:11:36 -0700
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-09-16 21:03:26 +0300
commit8802e40a411aa9d28d8193aa0f0d2bad238b2f2f (patch)
tree7fdfdd56e75ed015b4779d6180bceaabb5d56343 /indra/llcommon/llsys.cpp
parentcb35e21dca397c25ebf0ec0414552c622f548939 (diff)
Fix Linux available memory reporting to use MemAvailable instead of get_avphys_pages()
On Linux, get_avphys_pages() maps to sysconf(_SC_AVPHYS_PAGES) which returns only completely unallocated pages (MemFree). The Linux kernel eagerly uses spare physical RAM for disk caching (buff/cache). When active disk caching fills memory, MemFree routinely hovers between 200-500 MB even when gigabytes of memory are available. This caused the viewer's memory budget logic to falsely report low system memory (<256 MB), repeatedly triggering emergency texture downrezzing loops and dynamic draw-distance halving. Replace get_avphys_pages() in LLMemoryInfo::updateAvailableMemory() with a fast, non-allocating single fread of MemAvailable: from /proc/meminfo (available on Linux >= 3.14), with fallback to get_avphys_pages().
Diffstat (limited to 'indra/llcommon/llsys.cpp')
-rw-r--r--indra/llcommon/llsys.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index bc38b72004..8ebb45ca66 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -853,8 +853,33 @@ void LLMemoryInfo::updateAvailableMemory()
}
#elif LL_LINUX
- U64 phys = U64(getpagesize()) * U64(get_avphys_pages());
- LLMemory::sAvailPhysicalMemInKB = U64Bytes(phys);
+ bool found_available = false;
+ LLFILE* fp = LLFile::fopen(MEMINFO_FILE, LLFILE_MODE("rb"));
+ if (fp)
+ {
+ char buff[2048];
+ size_t nbytes = fread(buff, 1, sizeof(buff) - 1, fp);
+ buff[nbytes] = '\0';
+ fclose(fp);
+
+ char* memp = strstr(buff, "MemAvailable:");
+ if (memp)
+ {
+ unsigned long long mem_avail_kb = 0;
+ if (sscanf(memp, "MemAvailable: %llu", &mem_avail_kb) == 1)
+ {
+ LLMemory::sAvailPhysicalMemInKB = U32Kilobytes(mem_avail_kb);
+ found_available = true;
+ }
+ }
+ }
+
+ if (!found_available)
+ {
+ // Fallback for pre-3.14 kernels or container environments without MemAvailable
+ U64 phys = U64(getpagesize()) * U64(get_avphys_pages());
+ LLMemory::sAvailPhysicalMemInKB = U64Bytes(phys);
+ }
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.