From 702382ac8b5385ce15f807016582b54793141c4b Mon Sep 17 00:00:00 2001 From: Dan Callaghan Date: Mon, 13 Jul 2015 15:06:59 +1000 Subject: [PATCH 18/26] guess memory size from memory hotplug info (#694) --- src/core/Makefile | 2 +- src/core/mem.cc | 35 +++++++++++++++++++++++++++++++++-- src/core/sysfs.cc | 16 ++++++++++++++++ src/core/sysfs.h | 2 ++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/core/Makefile b/src/core/Makefile index 2d95a80..884a963 100644 --- a/src/core/Makefile +++ b/src/core/Makefile @@ -39,7 +39,7 @@ main.o: device-tree.h pci.h pcmcia.h pcmcia-legacy.h ide.h scsi.h spd.h main.o: network.h isapnp.h fb.h usb.h sysfs.h display.h parisc.h cpufreq.h main.o: ideraid.h mounts.h smp.h abi.h s390.h virtio.h pnp.h vio.h print.o: print.h hw.h options.h version.h osutils.h config.h -mem.o: version.h config.h mem.h hw.h +mem.o: version.h config.h mem.h hw.h sysfs.h dmi.o: version.h config.h dmi.h hw.h osutils.h device-tree.o: version.h device-tree.h hw.h osutils.h cpuinfo.o: version.h cpuinfo.h hw.h osutils.h diff --git a/src/core/mem.cc b/src/core/mem.cc index 686cc16..72bfb35 100644 --- a/src/core/mem.cc +++ b/src/core/mem.cc @@ -5,9 +5,10 @@ * sources: * - the size of /proc/kcore * - the value returned by the sysconf libc function + * - the sum of sizes of kernel hotplug memory blocks * - the sum of sizes of individual memory banks * - * NOTE: Except in last case, this guess can be widely inaccurate, as the + * NOTE: In the first two cases this guess can be widely inaccurate, as the * kernel itself limits the memory addressable by userspace processes. * Because of that, this module reports the biggest value found if it can't * access the size of individual memory banks (information filled in by other @@ -17,6 +18,7 @@ #include "version.h" #include "config.h" +#include "sysfs.h" #include "mem.h" #include #include @@ -52,6 +54,31 @@ static unsigned long long get_sysconf_size() } +static unsigned long long get_hotplug_size() +{ + vector < sysfs::entry > entries = sysfs::entries_by_bus("memory"); + + if (entries.empty()) + return 0; + + unsigned long long memblocksize = + sysfs::entry::byPath("/system/memory").hex_attr("block_size_bytes"); + if (memblocksize == 0) + return 0; + + unsigned long long totalsize = 0; + for (vector < sysfs::entry >::iterator it = entries.begin(); + it != entries.end(); ++it) + { + const sysfs::entry & e = *it; + if (e.string_attr("online") != "1") + continue; + totalsize += memblocksize; + } + return totalsize; +} + + static unsigned long long count_memorybanks_size(hwNode & n) { hwNode *memory = n.getChild("core/memory"); @@ -93,9 +120,11 @@ bool scan_memory(hwNode & n) hwNode *memory = n.getChild("core/memory"); unsigned long long logicalmem = 0; unsigned long long kcore = 0; + unsigned long long hotplug_size = 0; logicalmem = get_sysconf_size(); kcore = get_kcore_size(); + hotplug_size = get_hotplug_size(); count_memorybanks_size(n); claim_memory(n); @@ -127,7 +156,9 @@ bool scan_memory(hwNode & n) if (memory->getSize() > logicalmem) // we already have a value return true; - if ((logicalmem == 0) + if (hotplug_size > logicalmem) + memory->setSize(hotplug_size); + else if ((logicalmem == 0) || ((kcore > logicalmem) && (kcore < 2 * logicalmem))) memory->setSize(kcore); else diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc index fb7f2bb..d17d33d 100644 --- a/src/core/sysfs.cc +++ b/src/core/sysfs.cc @@ -239,6 +239,13 @@ entry entry::byClass(string devclass, string devname) } +entry entry::byPath(string path) +{ + entry e(fs.path + "/devices" + path); + return e; +} + + entry::entry(const string & devpath) { This = new entry_i; @@ -318,6 +325,15 @@ string entry::string_attr(const string & name, const string & def) const } +unsigned long long entry::hex_attr(const string & name, unsigned long long def) const +{ + string val = string_attr(name, ""); + if (val.empty()) + return def; + return strtoull(val.c_str(), NULL, 16); +} + + vector < string > entry::multiline_attr(const string & name) const { vector < string > lines; diff --git a/src/core/sysfs.h b/src/core/sysfs.h index 7ceb395..a6d69ed 100644 --- a/src/core/sysfs.h +++ b/src/core/sysfs.h @@ -15,6 +15,7 @@ namespace sysfs static entry byBus(string devbus, string devname); static entry byClass(string devclass, string devname); + static entry byPath(string path); entry & operator =(const entry &); entry(const entry &); @@ -28,6 +29,7 @@ namespace sysfs entry parent() const; string name_in_class(const string &) const; string string_attr(const string & name, const string & def = "") const; + unsigned long long hex_attr(const string & name, unsigned long long def = 0) const; vector < string > multiline_attr(const string & name) const; struct entry_i * This; -- 2.10.2