summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-06-28 17:35:21 +0200
committerGitHub <noreply@github.com>2021-06-28 17:35:21 +0200
commit54c4b185fac0341a369938445d76fcb199a3ede5 (patch)
treeb03270500919218350ec043755f34321df9df396
parent91bb5e76f2c515febbe067ef4549b847dd3cad2e (diff)
parenta985b7e5be2415e38594ce36f8b7302ea8ed151f (diff)
Merge pull request #18430 from vespa-engine/balder/use-mallinfo-to-report-heap-usage
Use mallinfo to report vespamalloc heap size.
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java1
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.cpp5
-rw-r--r--vespamalloc/src/tests/stacktrace/stacktrace.cpp14
-rw-r--r--vespamalloc/src/vespamalloc/malloc/overload.h26
-rw-r--r--vespamalloc/src/vespamalloc/malloc/vespamalloc.h20
7 files changed, 42 insertions, 30 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
index 760c966a6b2..1743d5f4432 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
@@ -469,6 +469,7 @@ public class VespaMetricSet {
metrics.add(new Metric("content.proton.resource_usage.memory_mappings.max"));
metrics.add(new Metric("content.proton.resource_usage.open_file_descriptors.max"));
metrics.add(new Metric("content.proton.resource_usage.feeding_blocked.max"));
+ metrics.add(new Metric("content.proton.resource_usage.malloc_arena.max"));
metrics.add(new Metric("content.proton.documentdb.attribute.resource_usage.enum_store.average"));
metrics.add(new Metric("content.proton.documentdb.attribute.resource_usage.multi_value.average"));
metrics.add(new Metric("content.proton.documentdb.attribute.resource_usage.feeding_blocked.last")); // TODO: Remove in Vespa 8
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp
index 85b2a7a4b99..c56db96ee8d 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp
+++ b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp
@@ -14,10 +14,11 @@ ResourceUsageMetrics::ResourceUsageMetrics(metrics::MetricSet *parent)
transient_disk("transient_disk", {}, "The relative amount of transient disk needed for running disk index fusion. Max value among all disk indexes (value in the range [0, 1])", this),
memoryMappings("memory_mappings", {}, "The number of mapped memory areas", this),
openFileDescriptors("open_file_descriptors", {}, "The number of open files", this),
- feedingBlocked("feeding_blocked", {}, "Whether feeding is blocked due to resource limits being reached (value is either 0 or 1)", this)
+ feedingBlocked("feeding_blocked", {}, "Whether feeding is blocked due to resource limits being reached (value is either 0 or 1)", this),
+ mallocArena("malloc_arena", {}, "Size of malloc arena", this)
{
}
-ResourceUsageMetrics::~ResourceUsageMetrics() {}
+ResourceUsageMetrics::~ResourceUsageMetrics() = default;
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h
index 038d9149b3b..acadeba8372 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h
+++ b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h
@@ -21,6 +21,7 @@ struct ResourceUsageMetrics : metrics::MetricSet
metrics::LongValueMetric memoryMappings;
metrics::LongValueMetric openFileDescriptors;
metrics::LongValueMetric feedingBlocked;
+ metrics::LongValueMetric mallocArena;
ResourceUsageMetrics(metrics::MetricSet *parent);
~ResourceUsageMetrics();
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
index 26e1bc8b951..d8b5eccb788 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
@@ -40,6 +40,7 @@
#include <vespa/vespalib/util/mmap_file_allocator_factory.h>
#include <vespa/vespalib/util/random.h>
#include <vespa/vespalib/util/size_literals.h>
+#include <malloc.h>
#include <vespa/searchlib/aggregation/forcelink.hpp>
#include <vespa/searchlib/expression/forcelink.hpp>
@@ -763,6 +764,10 @@ Proton::updateMetrics(const metrics::MetricLockGuard &)
metrics.resourceUsage.memoryMappings.set(usageFilter.getMemoryStats().getMappingsCount());
metrics.resourceUsage.openFileDescriptors.set(FastOS_File::count_open_files());
metrics.resourceUsage.feedingBlocked.set((usageFilter.acceptWriteOperation() ? 0.0 : 1.0));
+ struct mallinfo mallocInfo = mallinfo();
+ // Vespamalloc reports arena in 1M blocks as an 'int' is too small.
+ // If we use something else than vespamalloc this must be changed.
+ metrics.resourceUsage.mallocArena.set(uint64_t(mallocInfo.arena) * 1_Mi);
}
{
ContentProtonMetrics::ProtonExecutorMetrics &metrics = _metricsEngine->root().executor;
diff --git a/vespamalloc/src/tests/stacktrace/stacktrace.cpp b/vespamalloc/src/tests/stacktrace/stacktrace.cpp
index e7c53fa5c3f..957f05d9b66 100644
--- a/vespamalloc/src/tests/stacktrace/stacktrace.cpp
+++ b/vespamalloc/src/tests/stacktrace/stacktrace.cpp
@@ -4,6 +4,7 @@
#include <pthread.h>
#include <dlfcn.h>
#include <cassert>
+#include <malloc.h>
void * run(void * arg)
{
@@ -16,7 +17,18 @@ void * run(void * arg)
}
void verify_that_vespamalloc_datasegment_size_exists() {
- assert(dlsym(RTLD_NEXT, "vespamalloc_datasegment_size") != nullptr);
+ struct mallinfo info = mallinfo();
+ printf("Malloc used %dm of memory\n",info.arena);
+ assert(info.arena == 24);
+ assert(info.fordblks == 0);
+ assert(info.fsmblks == 0);
+ assert(info.hblkhd == 0);
+ assert(info.hblks == 0);
+ assert(info.keepcost == 0);
+ assert(info.ordblks == 0);
+ assert(info.smblks == 0);
+ assert(info.uordblks == 0);
+ assert(info.usmblks == 0);
}
int main(int argc, char *argv[])
diff --git a/vespamalloc/src/vespamalloc/malloc/overload.h b/vespamalloc/src/vespamalloc/malloc/overload.h
index f9c51582fb9..ca3a76b705b 100644
--- a/vespamalloc/src/vespamalloc/malloc/overload.h
+++ b/vespamalloc/src/vespamalloc/malloc/overload.h
@@ -5,6 +5,7 @@
#include <errno.h>
#include <new>
#include <stdlib.h>
+#include <malloc.h>
class CreateAllocator
{
@@ -105,9 +106,20 @@ void operator delete[](void* ptr, std::size_t sz, std::align_val_t alignment) no
extern "C" {
-unsigned long vespamalloc_datasegment_size() __attribute__((visibility ("default")));
-unsigned long vespamalloc_datasegment_size() {
- return vespamalloc::_GmemP->dataSegment().dataSize();
+struct mallinfo mallinfo() __THROW __attribute__((visibility ("default")));
+struct mallinfo mallinfo() __THROW {
+ struct mallinfo info;
+ info.arena = (vespamalloc::_GmemP->dataSegment().dataSize() >> 20); // Note reporting in 1M blocks
+ info.ordblks = 0;
+ info.smblks = 0;
+ info.hblks = 0;
+ info.hblkhd = 0;
+ info.usmblks = 0;
+ info.fsmblks = 0;
+ info.uordblks = 0;
+ info.fordblks = 0;
+ info.keepcost = 0;
+ return info;
}
void * malloc(size_t sz) {
@@ -124,8 +136,8 @@ void * realloc(void * ptr, size_t sz)
return vespamalloc::createAllocator()->realloc(ptr, sz);
}
-void* memalign(size_t align, size_t sz) __attribute__((visibility ("default")));
-void* memalign(size_t align, size_t sz)
+void* memalign(size_t align, size_t sz) __THROW __attribute__((visibility ("default")));
+void* memalign(size_t align, size_t sz) __THROW
{
void *ptr(nullptr);
size_t align_1(align - 1);
@@ -137,7 +149,6 @@ void* memalign(size_t align, size_t sz)
}
int posix_memalign(void** ptr, size_t align, size_t sz) __THROW __nonnull((1)) __attribute__((visibility ("default")));
-
int posix_memalign(void** ptr, size_t align, size_t sz) __THROW
{
int retval(0);
@@ -186,7 +197,8 @@ void cfree(void *) __THROW __attribute__((leaf
void __libc_free(void* ptr) __THROW __attribute__((leaf)) ALIAS("free");
void __libc_cfree(void* ptr) __THROW __attribute__((leaf)) ALIAS("cfree");
#endif
-void* __libc_memalign(size_t align, size_t s) ALIAS("memalign");
+struct mallinfo __libc_mallinfo() __THROW ALIAS("mallinfo");
+void* __libc_memalign(size_t align, size_t s) __THROW __attribute__((leaf, malloc, alloc_size(2))) ALIAS("memalign");
int __posix_memalign(void** r, size_t a, size_t s) __THROW __nonnull((1)) ALIAS("posix_memalign");
#undef ALIAS
diff --git a/vespamalloc/src/vespamalloc/malloc/vespamalloc.h b/vespamalloc/src/vespamalloc/malloc/vespamalloc.h
deleted file mode 100644
index 4dbadf8a26e..00000000000
--- a/vespamalloc/src/vespamalloc/malloc/vespamalloc.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-/**
- * Contains the interfaces that vespamalloc offers in addition to the standard
- * allocation interfaces like malloc, calloc, free, new, delete, etc.
- * Use dlsym(RTLD_NEXT, "function_name") to ensure the existence of the interface.
- **/
-
-extern "C" {
-
-/**
- * Reports the amount of memory vespamalloc uses. It is actually the size of the datasegment.
- * This is the peak memory usage during process lifetime, and does not differentiate between malloced or freed memory.
- * This is cheap to call
- **/
-unsigned long vespamalloc_datasegment_size();
-
-}