Skip to content

Commit 4c0d2d2

Browse files
authored
memory: switch to the latest tcmalloc for x86_64 builds (#13251)
Signed-off-by: Dmitry Rozhkov <[email protected]>
1 parent a74bd4b commit 4c0d2d2

File tree

18 files changed

+170
-26
lines changed

18 files changed

+170
-26
lines changed

bazel/BUILD

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,37 @@ config_setting(
155155
values = {"define": "tcmalloc=debug"},
156156
)
157157

158+
config_setting(
159+
name = "gperftools_tcmalloc",
160+
values = {"define": "tcmalloc=gperftools"},
161+
)
162+
163+
# As select() can't be nested we need these specialized settings to avoid ambiguity when choosing
164+
# tcmalloc's flavor for x86_64 builds.
165+
config_setting(
166+
name = "disable_tcmalloc_on_linux_x86_64",
167+
values = {
168+
"define": "tcmalloc=disabled",
169+
"cpu": "k8",
170+
},
171+
)
172+
173+
config_setting(
174+
name = "gperftools_tcmalloc_on_linux_x86_64",
175+
values = {
176+
"define": "tcmalloc=gperftools",
177+
"cpu": "k8",
178+
},
179+
)
180+
181+
config_setting(
182+
name = "debug_tcmalloc_on_linux_x86_64",
183+
values = {
184+
"define": "tcmalloc=debug",
185+
"cpu": "k8",
186+
},
187+
)
188+
158189
config_setting(
159190
name = "disable_signal_trace",
160191
values = {"define": "signal_trace=disabled"},

bazel/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,8 @@ The following optional features can be disabled on the Bazel build command-line:
607607
* Google C++ gRPC client with `--define google_grpc=disabled`
608608
* Backtracing on signals with `--define signal_trace=disabled`
609609
* Active stream state dump on signals with `--define signal_trace=disabled` or `--define disable_object_dump_on_signal_trace=disabled`
610-
* tcmalloc with `--define tcmalloc=disabled`
610+
* tcmalloc with `--define tcmalloc=disabled`. Also you can choose Gperftools' implementation of
611+
tcmalloc with `--define tcmalloc=gperftools` which is the default for non-x86 builds.
611612
* deprecated features with `--define deprecated_features=disabled`
612613

613614

@@ -626,7 +627,8 @@ The following optional features can be enabled on the Bazel build command-line:
626627
`--define log_debug_assert_in_release=enabled`. The default behavior is to compile debug assertions out of
627628
release builds so that the condition is not evaluated. This option has no effect in debug builds.
628629
* memory-debugging (scribbling over memory after allocation and before freeing) with
629-
`--define tcmalloc=debug`. Note this option cannot be used with FIPS-compliant mode BoringSSL.
630+
`--define tcmalloc=debug`. Note this option cannot be used with FIPS-compliant mode BoringSSL and
631+
tcmalloc is built from the sources of Gperftools.
630632
* Default [path normalization](https://github.com/envoyproxy/envoy/issues/6435) with
631633
`--define path_normalization_by_default=true`. Note this still could be disable by explicit xDS config.
632634
* Manual stamping via VersionInfo with `--define manual_stamp=manual_stamp`.

bazel/envoy_internal.bzl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ def envoy_copts(repository, test = False):
6060
"//conditions:default": [],
6161
}) + select({
6262
repository + "//bazel:disable_tcmalloc": ["-DABSL_MALLOC_HOOK_MMAP_DISABLE"],
63-
"//conditions:default": ["-DTCMALLOC"],
64-
}) + select({
65-
repository + "//bazel:debug_tcmalloc": ["-DENVOY_MEMORY_DEBUG_ENABLED=1"],
66-
"//conditions:default": [],
63+
repository + "//bazel:disable_tcmalloc_on_linux_x86_64": ["-DABSL_MALLOC_HOOK_MMAP_DISABLE"],
64+
repository + "//bazel:gperftools_tcmalloc": ["-DGPERFTOOLS_TCMALLOC"],
65+
repository + "//bazel:gperftools_tcmalloc_on_linux_x86_64": ["-DGPERFTOOLS_TCMALLOC"],
66+
repository + "//bazel:debug_tcmalloc": ["-DENVOY_MEMORY_DEBUG_ENABLED=1", "-DGPERFTOOLS_TCMALLOC"],
67+
repository + "//bazel:debug_tcmalloc_on_linux_x86_64": ["-DENVOY_MEMORY_DEBUG_ENABLED=1", "-DGPERFTOOLS_TCMALLOC"],
68+
repository + "//bazel:linux_x86_64": ["-DTCMALLOC"],
69+
"//conditions:default": ["-DGPERFTOOLS_TCMALLOC"],
6770
}) + select({
6871
repository + "//bazel:disable_signal_trace": [],
6972
"//conditions:default": ["-DENVOY_HANDLE_SIGNALS"],
@@ -118,6 +121,12 @@ def envoy_stdlib_deps():
118121
def tcmalloc_external_dep(repository):
119122
return select({
120123
repository + "//bazel:disable_tcmalloc": None,
124+
repository + "//bazel:disable_tcmalloc_on_linux_x86_64": None,
125+
repository + "//bazel:debug_tcmalloc": envoy_external_dep_path("gperftools"),
126+
repository + "//bazel:debug_tcmalloc_on_linux_x86_64": envoy_external_dep_path("gperftools"),
127+
repository + "//bazel:gperftools_tcmalloc": envoy_external_dep_path("gperftools"),
128+
repository + "//bazel:gperftools_tcmalloc_on_linux_x86_64": envoy_external_dep_path("gperftools"),
129+
repository + "//bazel:linux_x86_64": envoy_external_dep_path("tcmalloc"),
121130
"//conditions:default": envoy_external_dep_path("gperftools"),
122131
})
123132

bazel/envoy_library.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ load(
2020
def tcmalloc_external_deps(repository):
2121
return select({
2222
repository + "//bazel:disable_tcmalloc": [],
23+
repository + "//bazel:disable_tcmalloc_on_linux_x86_64": [],
24+
repository + "//bazel:debug_tcmalloc": [envoy_external_dep_path("gperftools")],
25+
repository + "//bazel:debug_tcmalloc_on_linux_x86_64": [envoy_external_dep_path("gperftools")],
26+
repository + "//bazel:gperftools_tcmalloc": [envoy_external_dep_path("gperftools")],
27+
repository + "//bazel:gperftools_tcmalloc_on_linux_x86_64": [envoy_external_dep_path("gperftools")],
28+
repository + "//bazel:linux_x86_64": [envoy_external_dep_path("tcmalloc")],
2329
"//conditions:default": [envoy_external_dep_path("gperftools")],
2430
})
2531

bazel/repositories.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def envoy_dependencies(skip_targets = []):
197197
_com_github_google_benchmark()
198198
_com_github_google_jwt_verify()
199199
_com_github_google_libprotobuf_mutator()
200+
_com_github_google_tcmalloc()
200201
_com_github_gperftools_gperftools()
201202
_com_github_grpc_grpc()
202203
_com_github_jbeder_yaml_cpp()
@@ -875,6 +876,16 @@ def _com_github_moonjit_moonjit():
875876
actual = "@envoy//bazel/foreign_cc:moonjit",
876877
)
877878

879+
def _com_github_google_tcmalloc():
880+
_repository_impl(
881+
name = "com_github_google_tcmalloc",
882+
)
883+
884+
native.bind(
885+
name = "tcmalloc",
886+
actual = "@com_github_google_tcmalloc//tcmalloc",
887+
)
888+
878889
def _com_github_gperftools_gperftools():
879890
location = _get_location("com_github_gperftools_gperftools")
880891
http_archive(

bazel/repository_locations.bzl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ DEPENDENCY_REPOSITORIES_SPEC = dict(
241241
last_updated = "2020-08-18",
242242
use_category = ["test_only"],
243243
),
244+
com_github_google_tcmalloc = dict(
245+
project_name = "tcmalloc",
246+
project_desc = "Fast, multi-threaded malloc implementation",
247+
project_url = "https://github.com/google/tcmalloc",
248+
version = "d1311bf409db47c3441d3de6ea07d768c6551dec",
249+
sha256 = "e22444b6544edd81f11c987dd5e482a2e00bbff717badb388779ca57525dad50",
250+
strip_prefix = "tcmalloc-{version}",
251+
urls = ["https://github.com/google/tcmalloc/archive/{version}.tar.gz"],
252+
use_category = ["dataplane_core", "controlplane"],
253+
last_updated = "2020-09-16",
254+
cpe = "N/A",
255+
),
244256
com_github_gperftools_gperftools = dict(
245257
project_name = "gperftools",
246258
project_desc = "tcmalloc and profiling libraries",

ci/do_ci.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ elif [[ "$CI_TARGET" == "bazel.compile_time_options" ]]; then
282282
"--define" "path_normalization_by_default=true"
283283
"--define" "deprecated_features=disabled"
284284
"--define" "use_new_codecs_in_integration_tests=true"
285+
"--define" "tcmalloc=gperftools"
285286
"--define" "zlib=ng")
286287

287288
ENVOY_STDLIB="${ENVOY_STDLIB:-libstdc++}"
@@ -330,7 +331,8 @@ elif [[ "$CI_TARGET" == "bazel.coverage" || "$CI_TARGET" == "bazel.fuzz_coverage
330331

331332
[[ "$CI_TARGET" == "bazel.fuzz_coverage" ]] && export FUZZ_COVERAGE=true
332333

333-
BAZEL_BUILD_OPTIONS="${BAZEL_BUILD_OPTIONS[*]}" test/run_envoy_bazel_coverage.sh "${COVERAGE_TEST_TARGETS[@]}"
334+
# We use custom BAZEL_BUILD_OPTIONS here to cover profiler's code.
335+
BAZEL_BUILD_OPTIONS="${BAZEL_BUILD_OPTIONS[*]} --define tcmalloc=gperftools" test/run_envoy_bazel_coverage.sh "${COVERAGE_TEST_TARGETS[@]}"
334336
collect_build_profile coverage
335337
exit 0
336338
elif [[ "$CI_TARGET" == "bazel.clang_tidy" ]]; then

docs/root/version_history/current.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Minor Behavior Changes
4646
* logging: nghttp2 log messages no longer appear at trace level unless `ENVOY_NGHTTP2_TRACE` is set
4747
in the environment.
4848
* lua: changed the response body returned by `httpCall()` API to raw data. Previously, the returned data was string.
49+
* memory: switched to the `new tcmalloc <https://github.com/google/tcmalloc>`_ for linux_x86_64 builds. The `old tcmalloc <https://github.com/gperftools/gperftools>`_ can still be enabled with the `--define tcmalloc=gperftools` option.
4950
* postgres: changed log format to tokenize fields of Postgres messages.
5051
* router: added transport failure reason to response body when upstream reset happens. After this change, the response body will be of the form `upstream connect error or disconnect/reset before headers. reset reason:{}, transport failure reason:{}`.This behavior may be reverted by setting runtime feature `envoy.reloadable_features.http_transport_failure_reason_in_body` to false.
5152
* router: now consumes all retry related headers to prevent them from being propagated to the upstream. This behavior may be reverted by setting runtime feature `envoy.reloadable_features.consume_all_retry_headers` to false.

source/common/memory/stats.cc

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,52 @@
44

55
#include "common/common/logger.h"
66

7-
#ifdef TCMALLOC
7+
#if defined(TCMALLOC)
8+
9+
#include "tcmalloc/malloc_extension.h"
10+
11+
namespace Envoy {
12+
namespace Memory {
13+
14+
uint64_t Stats::totalCurrentlyAllocated() {
15+
return tcmalloc::MallocExtension::GetNumericProperty("generic.current_allocated_bytes")
16+
.value_or(0);
17+
}
18+
19+
uint64_t Stats::totalCurrentlyReserved() {
20+
// In Google's tcmalloc the semantics of generic.heap_size has
21+
// changed: it doesn't include unmapped bytes.
22+
return tcmalloc::MallocExtension::GetNumericProperty("generic.heap_size").value_or(0) +
23+
tcmalloc::MallocExtension::GetNumericProperty("tcmalloc.pageheap_unmapped_bytes")
24+
.value_or(0);
25+
}
26+
27+
uint64_t Stats::totalThreadCacheBytes() {
28+
return tcmalloc::MallocExtension::GetNumericProperty("tcmalloc.current_total_thread_cache_bytes")
29+
.value_or(0);
30+
}
31+
32+
uint64_t Stats::totalPageHeapFree() {
33+
return tcmalloc::MallocExtension::GetNumericProperty("tcmalloc.pageheap_free_bytes").value_or(0);
34+
}
35+
36+
uint64_t Stats::totalPageHeapUnmapped() {
37+
return tcmalloc::MallocExtension::GetNumericProperty("tcmalloc.pageheap_unmapped_bytes")
38+
.value_or(0);
39+
}
40+
41+
uint64_t Stats::totalPhysicalBytes() {
42+
return tcmalloc::MallocExtension::GetProperties()["generic.physical_memory_used"].value;
43+
}
44+
45+
void Stats::dumpStatsToLog() {
46+
ENVOY_LOG_MISC(debug, "TCMalloc stats:\n{}", tcmalloc::MallocExtension::GetStats());
47+
}
48+
49+
} // namespace Memory
50+
} // namespace Envoy
51+
52+
#elif defined(GPERFTOOLS_TCMALLOC)
853

954
#include "gperftools/malloc_extension.h"
1055

@@ -74,4 +119,4 @@ void Stats::dumpStatsToLog() {}
74119
} // namespace Memory
75120
} // namespace Envoy
76121

77-
#endif // #ifdef TCMALLOC
122+
#endif // #if defined(TCMALLOC)

source/common/memory/utils.cc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,26 @@
33
#include "common/common/assert.h"
44
#include "common/memory/stats.h"
55

6-
#ifdef TCMALLOC
6+
#if defined(TCMALLOC)
7+
#include "tcmalloc/malloc_extension.h"
8+
#elif defined(GPERFTOOLS_TCMALLOC)
79
#include "gperftools/malloc_extension.h"
810
#endif
911

1012
namespace Envoy {
1113
namespace Memory {
1214

15+
namespace {
16+
#if defined(TCMALLOC) || defined(GPERFTOOLS_TCMALLOC)
17+
// TODO(zyfjeff): Make max unfreed memory byte configurable
18+
constexpr uint64_t MAX_UNFREED_MEMORY_BYTE = 100 * 1024 * 1024;
19+
#endif
20+
} // namespace
21+
1322
void Utils::releaseFreeMemory() {
14-
#ifdef TCMALLOC
23+
#if defined(TCMALLOC)
24+
tcmalloc::MallocExtension::ReleaseMemoryToSystem(MAX_UNFREED_MEMORY_BYTE);
25+
#elif defined(GPERFTOOLS_TCMALLOC)
1526
MallocExtension::instance()->ReleaseFreeMemory();
1627
#endif
1728
}
@@ -23,9 +34,7 @@ void Utils::releaseFreeMemory() {
2334
Ref: https://github.com/envoyproxy/envoy/pull/9471#discussion_r363825985
2435
*/
2536
void Utils::tryShrinkHeap() {
26-
#ifdef TCMALLOC
27-
// TODO(zyfjeff): Make max unfreed memory byte configurable
28-
static const uint64_t MAX_UNFREED_MEMORY_BYTE = 100 * 1024 * 1024;
37+
#if defined(TCMALLOC) || defined(GPERFTOOLS_TCMALLOC)
2938
auto total_physical_bytes = Stats::totalPhysicalBytes();
3039
auto allocated_size_by_app = Stats::totalCurrentlyAllocated();
3140

0 commit comments

Comments
 (0)