lib: Memory reporting fails over 2GB
The old style mallinfo() function uses an 'int' to
report memory usage data to the program. Unfortunately
modern architectures can chew through 2gb of memory like a
buzz saw hitting some warm butter, especially in the case
of a memory leak or memory fragmentation.
When a daemon uses more than 2gb of memory, just indicate it's
gotten large and we don't know anymore.
Pre-change behavior:
Robot-1# show memory
System allocator statistics:
Total heap allocated: 16777216 TiB
Holding block headers: 1288 KiB
Used small blocks: 0 bytes
Used ordinary blocks: 535 MiB
Free small blocks: 768 bytes
Free ordinary blocks: 16777216 TiB
Ordinary blocks: 266107
Small blocks: 24
Holding blocks: 2
Post-change behavior:
Robot-1# show memory
System allocator statistics:
Total heap allocated: 1572 KiB
Holding block headers: > 2GB
Used small blocks: 0 bytes
Used ordinary blocks: 1443 KiB
Free small blocks: 32 bytes
Free ordinary blocks: 129 KiB
Ordinary blocks: 2
Small blocks: 1
Holding blocks: 2
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
diff --git a/lib/memory.c b/lib/memory.c
index a9149e1..172ddfc 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -437,41 +437,28 @@
const char *
mtype_memstr (char *buf, size_t len, unsigned long bytes)
{
- unsigned int t, g, m, k;
-
+ unsigned int m, k;
+
/* easy cases */
if (!bytes)
return "0 bytes";
if (bytes == 1)
return "1 byte";
-
- if (sizeof (unsigned long) >= 8)
- /* Hacked to make it not warn on ILP32 machines
- * Shift will always be 40 at runtime. See below too */
- t = bytes >> (sizeof (unsigned long) >= 8 ? 40 : 0);
- else
- t = 0;
- g = bytes >> 30;
+
+ /*
+ * When we pass the 2gb barrier mallinfo() can no longer report
+ * correct data so it just does something odd...
+ * Reporting like Terrabytes of data. Which makes users...
+ * edgy.. yes edgy that's the term for it.
+ * So let's just give up gracefully
+ */
+ if (bytes > 0x7fffffff)
+ return "> 2GB";
+
m = bytes >> 20;
k = bytes >> 10;
-
- if (t > 10)
- {
- /* The shift will always be 39 at runtime.
- * Just hacked to make it not warn on 'smaller' machines.
- * Static compiler analysis should mean no extra code
- */
- if (bytes & (1UL << (sizeof (unsigned long) >= 8 ? 39 : 0)))
- t++;
- snprintf (buf, len, "%4d TiB", t);
- }
- else if (g > 10)
- {
- if (bytes & (1 << 29))
- g++;
- snprintf (buf, len, "%d GiB", g);
- }
- else if (m > 10)
+
+ if (m > 10)
{
if (bytes & (1 << 19))
m++;