]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4435: memory: add shell commands for jemalloc heap profiling
authorAkhilesh MY (amuttuva) <amuttuva@cisco.com>
Wed, 11 Sep 2024 12:39:34 +0000 (12:39 +0000)
committerShanmugam S (shanms) <shanms@cisco.com>
Wed, 11 Sep 2024 12:39:34 +0000 (12:39 +0000)
Merge in SNORT/snort3 from ~AMUTTUVA/snort3:jemalloc_cli to master

Squashed commit of the following:

commit 6a36e76117b05b637cebb0d17997627f9e045d6e
Author: Akhilesh MY <amuttuva@cisco.com>
Date:   Thu Sep 5 10:47:53 2024 -0400

    memory: add shell commands for jemalloc heap profiling

src/main.cc
src/main.h
src/main/snort_module.cc
src/memory/heap_interface.cc
src/memory/heap_interface.h
src/memory/memory_cap.cc
src/memory/memory_cap.h

index d6928f46b34890ad010adce50f217ec40d422d14..86c059c50d38616a039644d2b36774633266881c 100644 (file)
@@ -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<std::string, clear_counter_type_t> 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);
index b13c38206ea23355357e1f6be91bf6eb355a2927..958be816ef64239f02962556785e13e756d66d26 100644 (file)
@@ -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);
index 3479104b44d48f034c021adc4b342058277af0da..00607006a080979409375ac37703d1b0c57b9680 100644 (file)
@@ -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" },
index 88dbd345fff63a242f3cf6eb11ebd0198b8cd620..924d74e2f14094cfab302620a05843dde3b73280 100644 (file)
@@ -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
 //--------------------------------------------------------------------------
index 895ef374f08bd69f0233c7996fd6b69c0b911a9d..703a790f4c7576dc160a5dbc8407aaf529872961 100644 (file)
@@ -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:
index a157f3f978bc63a89e4d6eceeef58f8ed459eb29..caba863861e506493b59c84c9896e800c1a8ba66 100644 (file)
@@ -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
 
index 590267e88d0359979d4f774ff589fe3f627da221..1bc0759010ce75517768128885e7bdc6a990f890 100644 (file)
@@ -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