From 2fa9eb603b12a113dbb9564384d5f9798a79e73e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 20 Sep 2017 08:22:39 -0400 Subject: [PATCH] Memory: clean up interface used to get memory (RAM) size --- .../utils/CalamaresUtilsSystem.cpp | 20 +++++-------- src/libcalamares/utils/CalamaresUtilsSystem.h | 14 +++++++-- .../partition/core/PartitionActions.cpp | 30 ++++++++++--------- .../welcome/checker/RequirementsChecker.cpp | 6 ++-- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 634366e3a..d770967cd 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -230,14 +230,7 @@ System::targetEnvOutput( const QString& command, } -qint64 -System::getPhysicalMemoryB() -{ - return 0; -} - - -qint64 +QPair System::getTotalMemoryB() { #ifdef Q_OS_LINUX @@ -245,20 +238,21 @@ System::getTotalMemoryB() int r = sysinfo( &i ); if (r) - return 0; + return qMakePair(0, 0.0); - return qint64( i.mem_unit ) * i.totalram; + return qMakePair(quint64( i.mem_unit ) * quint64( i.totalram ), 1.1); #elif defined( Q_OS_FREEBSD ) unsigned long memsize; size_t s = sizeof(memsize); int r = sysctlbyname("vm.kmem_size", &memsize, &s, NULL, 0); if (r) - return 0; + return qMakePair(0, 0.0); - return memsize; + return qMakePair(memsize, 1.01); +#else + return qMakePair(0, 0.0); // Unsupported #endif - return 0; // Unsupported } diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.h b/src/libcalamares/utils/CalamaresUtilsSystem.h index bf3acb41c..1ccdfb516 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.h +++ b/src/libcalamares/utils/CalamaresUtilsSystem.h @@ -100,9 +100,19 @@ public: /** * @brief getTotalMemoryB returns the total main memory, in bytes. + * + * Since it is difficult to get the RAM memory size exactly -- either + * by reading information from the DIMMs, which may fail on virtual hosts + * or from asking the kernel, which doesn't report some memory areas -- + * this returns a pair of guessed-size (in bytes) and a "guesstimate factor" + * which says how good the guess is. Generally, assume the *real* memory + * available is size * guesstimate. + * + * If nothing can be found, returns a 0 size and 0 guesstimate. + * + * @return size, guesstimate-factor */ - DLLEXPORT qint64 getTotalMemoryB(); //Always underguessed, but always works on Linux - DLLEXPORT qint64 getPhysicalMemoryB(); //Better guess, doesn't work in VirualBox + DLLEXPORT QPair getTotalMemoryB(); private: static System* s_instance; diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 14e7bf010..cb534fc51 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -59,19 +59,21 @@ constexpr qint64 toGiB( unsigned long long m ) qint64 swapSuggestion( const qint64 availableSpaceB ) { - // swap(mem) = max(2, 2 * mem), if mem < 2 GiB - // = mem, if 2 GiB <= mem < 8 GiB - // = mem / 2, if 8 GIB <= mem < 64 GiB - // = 4 GiB, if mem >= 64 GiB - + /* If suspend-to-disk is demanded, then we always need enough + * swap to write the whole memory to disk -- between 2GB and 8GB + * RAM give proportionally more swap, and from 8GB RAM keep + * swap = RAM. + * + * If suspend-to-disk is not demanded, then ramp up more slowly, + * to 8GB swap at 16GB memory, and then drop to 4GB for "large + * memory" machines, on the assumption that those don't need swap + * because they have tons of memory (or whatever they are doing, + * had better not run into swap). + */ qint64 suggestedSwapSizeB = 0; - qint64 availableRamB = CalamaresUtils::System::instance()->getPhysicalMemoryB(); - qreal overestimationFactor = 1.01; - if ( !availableRamB ) - { - availableRamB = CalamaresUtils::System::instance()->getTotalMemoryB(); - overestimationFactor = 1.10; - } + auto memory = CalamaresUtils::System::instance()->getTotalMemoryB(); + qint64 availableRamB = memory.first; + qreal overestimationFactor = memory.second; bool ensureSuspendToDisk = Calamares::JobQueue::instance()->globalStorage()-> @@ -94,8 +96,8 @@ swapSuggestion( const qint64 availableSpaceB ) suggestedSwapSizeB = qMax( 2_GiB, availableRamB * 2 ); else if ( availableRamB >= 2_GiB && availableRamB < 8_GiB ) suggestedSwapSizeB = availableRamB; - else if ( availableRamB >= 8_GiB && availableRamB < 64_GiB ) - suggestedSwapSizeB = availableRamB / 2; + else if ( availableRamB >= 8_GiB && availableRamB < 16_GiB ) + suggestedSwapSizeB = 8_GiB; else suggestedSwapSizeB = 4_GiB; diff --git a/src/modules/welcome/checker/RequirementsChecker.cpp b/src/modules/welcome/checker/RequirementsChecker.cpp index 29112de84..784535233 100644 --- a/src/modules/welcome/checker/RequirementsChecker.cpp +++ b/src/modules/welcome/checker/RequirementsChecker.cpp @@ -307,9 +307,9 @@ RequirementsChecker::checkEnoughStorage( qint64 requiredSpace ) bool RequirementsChecker::checkEnoughRam( qint64 requiredRam ) { - qint64 availableRam = CalamaresUtils::System::instance()->getPhysicalMemoryB(); - if ( !availableRam ) - availableRam = CalamaresUtils::System::instance()->getTotalMemoryB(); + // Ignore the guesstimate-factor; we get an under-estimate + // which is probably the usable RAM for programs. + quint64 availableRam = CalamaresUtils::System::instance()->getTotalMemoryB().first; return availableRam >= requiredRam * 0.95; // because MemTotal is variable }