From 7e421d78a9eaf6c677345c5b02d9bcf9cd8be2b9 Mon Sep 17 00:00:00 2001 From: Zengran Zhang Date: Fri, 18 Jan 2019 20:09:52 +0800 Subject: [PATCH] osd,mon,mds: support get|set tcmalloc release rate Signed-off-by: Zengran Zhang --- doc/man/8/ceph.rst | 18 ++++++++++++++++-- src/mds/MDSDaemon.cc | 3 +++ src/mon/Monitor.cc | 3 +++ src/osd/OSD.cc | 16 ++++++++++++---- src/perfglue/disabled_heap_profiler.cc | 4 ++++ src/perfglue/heap_profiler.cc | 22 ++++++++++++++++++++++ src/perfglue/heap_profiler.h | 4 ++++ 7 files changed, 64 insertions(+), 6 deletions(-) diff --git a/doc/man/8/ceph.rst b/doc/man/8/ceph.rst index 5f080dcb5d7d4..a165e64404580 100644 --- a/doc/man/8/ceph.rst +++ b/doc/man/8/ceph.rst @@ -27,7 +27,7 @@ Synopsis | **ceph** **health** *{detail}* -| **ceph** **heap** [ *dump* \| *start_profiler* \| *stop_profiler* \| *release* \| *stats* ] ... +| **ceph** **heap** [ *dump* \| *start_profiler* \| *stop_profiler* \| *release* \| *get_release_rate* \| *set_release_rate* \| *stats* ] ... | **ceph** **injectargs** ** [ **... ] @@ -323,8 +323,22 @@ Show heap usage info (available only if compiled with tcmalloc) Usage:: - ceph heap dump|start_profiler|stop_profiler|release|stats + ceph heap dump|start_profiler|stop_profiler|stats +Subcommand ``release`` to make TCMalloc to releases no-longer-used memory back to the kernel at once. + +Usage:: + + ceph heap release + +Subcommand ``(get|set)_release_rate`` get or set the TCMalloc memory release rate. TCMalloc releases +no-longer-used memory back to the kernel gradually. the rate controls how quickly this happens. +Increase this setting to make TCMalloc to return unused memory more frequently. 0 means never return +memory to system, 1 means wait for 1000 pages after releasing a page to system. It is ``1.0`` by default.. + +Usage:: + + ceph heap get_release_rate|set_release_rate {} injectargs ---------- diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 7aadfd43aff2d..fe70afeaaf6f2 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -838,6 +838,9 @@ int MDSDaemon::_handle_command( cmd_getval(cct, cmdmap, "heapcmd", heapcmd); vector heapcmd_vec; get_str_vec(heapcmd, heapcmd_vec); + string value; + if (cmd_getval(cct, cmdmap, "value", value)) + heapcmd_vec.push_back(value); ceph_heap_profiler_handle_command(heapcmd_vec, ds); } } else if (prefix == "cpu_profiler") { diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 5c7a92017791a..2856018beaf68 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -3652,6 +3652,9 @@ void Monitor::handle_command(MonOpRequestRef op) // XXX 1-element vector, change at callee or make vector here? vector heapcmd_vec; get_str_vec(heapcmd, heapcmd_vec); + string value; + if (cmd_getval(g_ceph_context, cmdmap, "value", value)) + heapcmd_vec.push_back(value); ceph_heap_profiler_handle_command(heapcmd_vec, ds); rdata.append(ds); rs = ""; diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 5ba037bba153f..b6f1f6453f0a1 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -3128,7 +3128,8 @@ void OSD::final_init() r = admin_socket->register_command( "heap", "heap " \ - "name=heapcmd,type=CephString", + "name=heapcmd,type=CephString " \ + "name=value,type=CephString,req=false", asok_hook, "show heap usage info (available only if " "compiled with tcmalloc)"); @@ -6208,8 +6209,10 @@ COMMAND("bench " \ "osd", "rw") COMMAND("flush_pg_stats", "flush pg stats", "osd", "rw") COMMAND("heap " \ - "name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \ - "show heap usage info (available only if compiled with tcmalloc)", \ + "name=heapcmd,type=CephChoices,strings="\ + "dump|start_profiler|stop_profiler|release|get_release_rate|set_release_rate|stats " \ + "name=value,type=CephString,req=false", + "show heap usage info (available only if compiled with tcmalloc)", "osd", "rw") COMMAND("debug dump_missing " \ "name=filename,type=CephFilepath", @@ -10805,10 +10808,15 @@ int heap(CephContext& cct, const cmdmap_t& cmdmap, Formatter& f, if (!cmd_getval(&cct, cmdmap, "heapcmd", cmd)) { os << "unable to get value for command \"" << cmd << "\""; return -EINVAL; - } + } std::vector cmd_vec; get_str_vec(cmd, cmd_vec); + + string val; + if (cmd_getval(&cct, cmdmap, "value", val)) { + cmd_vec.push_back(val); + } ceph_heap_profiler_handle_command(cmd_vec, os); diff --git a/src/perfglue/disabled_heap_profiler.cc b/src/perfglue/disabled_heap_profiler.cc index 238ab4ad83c73..e2293afd26582 100644 --- a/src/perfglue/disabled_heap_profiler.cc +++ b/src/perfglue/disabled_heap_profiler.cc @@ -21,6 +21,10 @@ void ceph_heap_profiler_stats(char *buf, int length) { return; } void ceph_heap_release_free_memory() { return; } +double ceph_heap_get_release_rate() { return 0; } + +void ceph_heap_set_release_rate(double value) { return; } + bool ceph_heap_profiler_running() { return false; } void ceph_heap_profiler_start() { return; } diff --git a/src/perfglue/heap_profiler.cc b/src/perfglue/heap_profiler.cc index aceee55909f5c..c5cdbb4ee9627 100644 --- a/src/perfglue/heap_profiler.cc +++ b/src/perfglue/heap_profiler.cc @@ -52,6 +52,16 @@ void ceph_heap_release_free_memory() MallocExtension::instance()->ReleaseFreeMemory(); } +double ceph_heap_get_release_rate() +{ + return MallocExtension::instance()->GetMemoryReleaseRate(); +} + +void ceph_heap_set_release_rate(double val) +{ + MallocExtension::instance()->SetMemoryReleaseRate(val); +} + bool ceph_heap_get_numeric_property( const char *property, size_t *value) { @@ -153,6 +163,18 @@ void ceph_heap_profiler_handle_command(const std::vector& cmd, } else if (cmd.size() == 1 && cmd[0] == "release") { ceph_heap_release_free_memory(); out << g_conf()->name << " releasing free RAM back to system."; + } else if (cmd.size() == 1 && cmd[0] == "get_release_rate") { + out << g_conf()->name << " release rate: " + << std::setprecision(4) << ceph_heap_get_release_rate() << "\n"; + } else if (cmd.size() == 2 && cmd[0] == "set_release_rate") { + try { + double val = std::stod(cmd[1]); + ceph_heap_set_release_rate(val); + out << g_conf()->name << " release rate changed to: " + << std::setprecision(4) << ceph_heap_get_release_rate() << "\n"; + } catch (...) { + out << g_conf()->name << " *** need an numerical value. "; + } } else #endif if (cmd.size() == 1 && cmd[0] == "stats") { diff --git a/src/perfglue/heap_profiler.h b/src/perfglue/heap_profiler.h index 75fba8ac33820..1eacb462022e3 100644 --- a/src/perfglue/heap_profiler.h +++ b/src/perfglue/heap_profiler.h @@ -35,6 +35,10 @@ void ceph_heap_profiler_stats(char *buf, int length); void ceph_heap_release_free_memory(); +double ceph_heap_get_release_rate(); + +void ceph_heap_get_release_rate(double value); + bool ceph_heap_profiler_running(); void ceph_heap_profiler_start(); -- 2.39.5