From 85f140400ddca54a59bdf87aadbbf18b15e0bc99 Mon Sep 17 00:00:00 2001 From: Stephan Dollberg Date: Fri, 31 May 2024 09:43:43 +0100 Subject: [PATCH 1/2] cpu_profiler: prealloc result buffers Preallocated result buffers at startup to avoid oversized allocs later down the line. (cherry picked from commit 01bd46455f1a31b8f7a2745730af498ee0ce3d5d) --- src/v/resource_mgmt/cpu_profiler.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/v/resource_mgmt/cpu_profiler.cc b/src/v/resource_mgmt/cpu_profiler.cc index 1afb3f9c8068..bb5610f449e0 100644 --- a/src/v/resource_mgmt/cpu_profiler.cc +++ b/src/v/resource_mgmt/cpu_profiler.cc @@ -36,6 +36,14 @@ cpu_profiler::cpu_profiler( , _sample_period(std::move(sample_period)) { _enabled.watch([this] { on_enabled_change(); }); _sample_period.watch([this] { on_sample_period_change(); }); + + for (size_t i = 0; i < number_of_results_buffers; i++) { + _results_buffers.emplace_back( + 0, + std::vector{}, + ss::lowres_clock::time_point::min()); + _results_buffers.back().samples.reserve(ss::max_number_of_traces); + } } ss::future<> cpu_profiler::start() { From bfcf345877141fee14bafa9b3d71ce7bd37cded2 Mon Sep 17 00:00:00 2001 From: Stephan Dollberg Date: Thu, 6 Jun 2024 12:19:30 +0100 Subject: [PATCH 2/2] cpu_profiler: Use stream_range_as_array in debug endpoint Avoids serializing everything to a single giant string (and hence causing oversized allocs). Note this still serializes the internal vector to a single string but I am working on a fix for that in seastar. (cherry picked from commit 69b215dd0ab5381fc4fd009fa23a6d4f4c284ded) --- src/v/redpanda/admin/debug.cc | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/v/redpanda/admin/debug.cc b/src/v/redpanda/admin/debug.cc index 169c70861c9a..da121e238c62 100644 --- a/src/v/redpanda/admin/debug.cc +++ b/src/v/redpanda/admin/debug.cc @@ -27,6 +27,7 @@ #include "redpanda/admin/api-doc/debug.json.hh" #include "redpanda/admin/server.h" #include "redpanda/admin/util.h" +#include "resource_mgmt/cpu_profiler.h" #include "serde/rw/rw.h" #include "storage/kvstore.h" @@ -542,23 +543,23 @@ admin_server::cpu_profile_handler(std::unique_ptr req) { *wait_ms, shard_id); } - std::vector response{ - profiles.size()}; - for (size_t i = 0; i < profiles.size(); i++) { - response[i].shard_id = profiles[i].shard; - response[i].dropped_samples = profiles[i].dropped_samples; - - for (auto& sample : profiles[i].samples) { - ss::httpd::debug_json::cpu_profile_sample s; - s.occurrences = sample.occurrences; - s.user_backtrace = sample.user_backtrace; - - response[i].samples.push(s); - } - } - co_return co_await ss::make_ready_future( - std::move(response)); + ss::json::stream_range_as_array( + lw_shared_container(std::move(profiles)), + [](const resources::cpu_profiler::shard_samples& profile) { + ss::httpd::debug_json::cpu_profile_shard_samples ret; + ret.shard_id = profile.shard; + ret.dropped_samples = profile.dropped_samples; + + for (auto& sample : profile.samples) { + ss::httpd::debug_json::cpu_profile_sample s; + s.occurrences = sample.occurrences; + s.user_backtrace = sample.user_backtrace; + + ret.samples.push(s); + } + return ret; + })); } ss::future