From: Akhilesh MY (amuttuva) Date: Wed, 11 Sep 2024 12:39:34 +0000 (+0000) Subject: Pull request #4435: memory: add shell commands for jemalloc heap profiling X-Git-Tag: 3.3.7.0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e637b1f62137d6e20178158763385df86f555af9;p=thirdparty%2Fsnort3.git Pull request #4435: memory: add shell commands for jemalloc heap profiling Merge in SNORT/snort3 from ~AMUTTUVA/snort3:jemalloc_cli to master Squashed commit of the following: commit 6a36e76117b05b637cebb0d17997627f9e045d6e Author: Akhilesh MY Date: Thu Sep 5 10:47:53 2024 -0400 memory: add shell commands for jemalloc heap profiling --- diff --git a/src/main.cc b/src/main.cc index d6928f46b..86c059c50 100644 --- a/src/main.cc +++ b/src/main.cc @@ -86,6 +86,8 @@ const struct timespec main_sleep = { 0, 1000000 }; // 0.001 sec static const char* prompt = "o\")~ "; +static const uint64_t def_prof_sample = 19; + static const std::map counter_name_to_id = { {"daq", clear_counter_type_t::TYPE_DAQ}, @@ -369,6 +371,34 @@ int main_dump_heap_stats(lua_State* L) return 0; } +int main_heap_profile(lua_State* L) +{ + ControlConn* ctrlcon = ControlConn::query_from_lua(L); + if ( L ) + { + const bool enable = luaL_opt(L,lua_toboolean, 1, false); + const uint64_t sample_rate = luaL_optint(L, 2, def_prof_sample); + memory::MemoryCap::heap_profile_config(enable, sample_rate); + + memory::MemoryCap::show_heap_profile_config(ctrlcon); + } + return 0; +} + +int main_dump_heap_profile(lua_State* L) +{ + ControlConn* ctrlcon = ControlConn::query_from_lua(L); + memory::MemoryCap::dump_heap_profile(ctrlcon); + return 0; +} + +int main_show_heap_profile(lua_State* L) +{ + ControlConn* ctrlcon = ControlConn::query_from_lua(L); + memory::MemoryCap::show_heap_profile_config(ctrlcon); + return 0; +} + int convert_counter_type(const char* type) { auto it = counter_name_to_id.find(type); diff --git a/src/main.h b/src/main.h index b13c38206..958be816e 100644 --- a/src/main.h +++ b/src/main.h @@ -30,6 +30,9 @@ int main_delete_inspector(lua_State* = nullptr); int main_dump_stats(lua_State* = nullptr); int main_log_command(lua_State* = nullptr); int main_dump_heap_stats(lua_State* = nullptr); +int main_heap_profile(lua_State* = nullptr); +int main_dump_heap_profile(lua_State* = nullptr); +int main_show_heap_profile(lua_State* = nullptr); int main_reset_stats(lua_State* = nullptr); int main_set_watchdog_params(lua_State* = nullptr); int main_rotate_stats(lua_State* = nullptr); diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index 3479104b4..00607006a 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -125,6 +125,15 @@ static const Parameter reset_stat_param[] = { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +static const Parameter s_heap_params[] = +{ + { "enable", Parameter::PT_BOOL, nullptr, nullptr, + "enable/disable jemalloc tracking" }, + { "sample_rate", Parameter::PT_INT, "0:max32", nullptr, + "average interval(log base 2) between memory profile dumps, as measured in bytes of allocation activity" }, + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + static const Command snort_cmds[] = { { "set_watchdog_params", main_set_watchdog_params, s_watchdog, "set watchdog parameters" }, @@ -135,6 +144,9 @@ static const Command snort_cmds[] = { "dump_stats", main_dump_stats, nullptr, "show summary statistics" }, { "dump_heap_stats", main_dump_heap_stats, nullptr, "show heap statistics" }, + { "heap_profile", main_heap_profile, s_heap_params, "jemalloc memory tracking configuration"}, + { "dump_heap_profile", main_dump_heap_profile, nullptr, "dump jemalloc memory profile"}, + { "show_heap_profile", main_show_heap_profile, nullptr, "show jemalloc memory profiling configuration"}, { "reset_stats", main_reset_stats, reset_stat_param, "clear summary statistics. " "Type can be: daq|module|appid|file_id|snort|ha|all. reset_stats() without a parameter clears all statistics."}, { "rotate_stats", main_rotate_stats, nullptr, "roll perfmonitor log files" }, diff --git a/src/memory/heap_interface.cc b/src/memory/heap_interface.cc index 88dbd345f..924d74e2f 100644 --- a/src/memory/heap_interface.cc +++ b/src/memory/heap_interface.cc @@ -52,6 +52,10 @@ class JemallocInterface : public HeapInterface void print_stats(ControlConn*) override; void get_aux_counts(uint64_t&, uint64_t&, uint64_t&, uint64_t&) override; + + void profile_config(bool enable, uint64_t sample_rate) override; + void dump_profile(ControlConn*) override; + void show_profile_config(ControlConn*) override; }; static size_t stats_mib[2], mib_len = 2; @@ -132,6 +136,55 @@ void JemallocInterface::get_aux_counts(uint64_t& all, uint64_t& act, uint64_t& r mallctl("stats.retained", (void*)&ret, &sz, nullptr, 0); } +void JemallocInterface::profile_config(bool enable, uint64_t sample_rate) +{ + bool en = enable; + int ret = mallctl("prof.active", nullptr, nullptr, &en, sizeof(bool)); + if ( ret ) + snort::LogMessage("Error in setting jemalloc profile config : %d", ret); + + if ( enable ) + { + size_t sample = sample_rate; + ret = mallctl("prof.reset", nullptr, nullptr, &sample, sizeof(size_t)); + if ( ret ) + snort::LogMessage("Error in setting jemalloc sample rate : %d", ret); + } +} + +void JemallocInterface::dump_profile(ControlConn* ctrlcon) +{ + int ret = mallctl("prof.dump", nullptr, nullptr, nullptr, 0); + if ( ret ) + snort::LogMessage("Error in dumping jemalloc profile : %d", ret); + else + ctrlcon->respond("Jemalloc memory profile dumped\n"); +} + +void JemallocInterface::show_profile_config(ControlConn* ctrlcon) +{ + bool enable = false; + size_t sz = sizeof(enable); + int ret = mallctl("prof.active", &enable, &sz, nullptr, 0); + if ( ret ) + snort::LogMessage("Error in getting jemalloc profiling config : %d", ret); + + if ( enable ) + { + size_t sample = 0; + sz = sizeof(sample); + ret = mallctl("prof.lg_sample", &sample, &sz, nullptr, 0); + if ( ret ) + snort::LogMessage("Error in getting jemalloc sample rate : %d", ret); + + ctrlcon->respond("Jemalloc memory profiling is enabled with sample rate %lu\n", sample); + } + else + { + ctrlcon->respond("Jemalloc memory profiling is disabled\n"); + } +} + //-------------------------------------------------------------------------- #else // disabled interface //-------------------------------------------------------------------------- diff --git a/src/memory/heap_interface.h b/src/memory/heap_interface.h index 895ef374f..703a790f4 100644 --- a/src/memory/heap_interface.h +++ b/src/memory/heap_interface.h @@ -42,6 +42,10 @@ public: virtual void get_aux_counts(uint64_t& app_all, uint64_t& active, uint64_t& resident, uint64_t& retained) { app_all = active = resident = retained = 0; } + virtual void profile_config(bool, uint64_t) { } + virtual void dump_profile(ControlConn*) { } + virtual void show_profile_config(ControlConn*) { } + static HeapInterface* get_instance(); protected: diff --git a/src/memory/memory_cap.cc b/src/memory/memory_cap.cc index a157f3f97..caba86386 100644 --- a/src/memory/memory_cap.cc +++ b/src/memory/memory_cap.cc @@ -351,5 +351,21 @@ void MemoryCap::dump_mem_stats(ControlConn* ctrlcon) { heap->print_stats(ctrlcon); } + +void MemoryCap::heap_profile_config(bool enable, uint64_t sample_rate) +{ + heap->profile_config(enable, sample_rate); +} + +void MemoryCap::dump_heap_profile(ControlConn* ctrlcon) +{ + heap->dump_profile(ctrlcon); +} + +void MemoryCap::show_heap_profile_config(ControlConn* ctrlcon) +{ + heap->show_profile_config(ctrlcon); +} + } // namespace memory diff --git a/src/memory/memory_cap.h b/src/memory/memory_cap.h index 590267e88..1bc075901 100644 --- a/src/memory/memory_cap.h +++ b/src/memory/memory_cap.h @@ -85,6 +85,9 @@ public: static void update_pegs(); static void dump_mem_stats(ControlConn*); + static void heap_profile_config(bool enable, uint64_t sample_rate); + static void dump_heap_profile(ControlConn*); + static void show_heap_profile_config(ControlConn*); #if defined(REG_TEST) || defined(UNIT_TEST) static void test_main_check(); #endif