From b064b79f62434faa076ee211e479f6d5845ef1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 22 Dec 2025 23:57:58 +0100 Subject: [PATCH 1/6] Introduce a "jemalloc-shim" crate This crate basically serves as a hack to properly enable `jemalloc` on Linux and disable it on all other OSes by default. --- Cargo.lock | 13 ++++++++++++- Cargo.toml | 2 ++ polkadot/Cargo.toml | 12 +++--------- polkadot/jemalloc-shim/Cargo.toml | 28 ++++++++++++++++++++++++++++ polkadot/jemalloc-shim/src/lib.rs | 26 ++++++++++++++++++++++++++ polkadot/src/main.rs | 6 ------ 6 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 polkadot/jemalloc-shim/Cargo.toml create mode 100644 polkadot/jemalloc-shim/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ca965102f9170..3e74a0df5d97b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14938,6 +14938,7 @@ dependencies = [ "nix 0.29.0", "polkadot-cli", "polkadot-core-primitives", + "polkadot-jemalloc-shim", "polkadot-node-core-pvf", "polkadot-node-core-pvf-common", "polkadot-node-core-pvf-execute-worker", @@ -14946,7 +14947,6 @@ dependencies = [ "substrate-build-script-utils", "substrate-rpc-client", "tempfile", - "tikv-jemallocator", "tokio", ] @@ -15217,6 +15217,17 @@ dependencies = [ "tracing-gum", ] +[[package]] +name = "polkadot-jemalloc-shim" +version = "1.0.0" +dependencies = [ + "polkadot-cli", + "polkadot-node-core-pvf", + "polkadot-node-core-pvf-prepare-worker", + "polkadot-overseer", + "tikv-jemallocator", +] + [[package]] name = "polkadot-network-bridge" version = "7.0.0" diff --git a/Cargo.toml b/Cargo.toml index 2c7f87d573f14..d89b3f17948c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,6 +159,7 @@ members = [ "polkadot/core-primitives", "polkadot/erasure-coding", "polkadot/erasure-coding/fuzzer", + "polkadot/jemalloc-shim", "polkadot/node/collation-generation", "polkadot/node/core/approval-voting", "polkadot/node/core/approval-voting-parallel", @@ -1115,6 +1116,7 @@ polkadot-core-primitives = { path = "polkadot/core-primitives", default-features polkadot-dispute-distribution = { path = "polkadot/node/network/dispute-distribution", default-features = false } polkadot-erasure-coding = { path = "polkadot/erasure-coding", default-features = false } polkadot-gossip-support = { path = "polkadot/node/network/gossip-support", default-features = false } +polkadot-jemalloc-shim = { path = "polkadot/jemalloc-shim" } polkadot-network-bridge = { path = "polkadot/node/network/bridge", default-features = false } polkadot-node-collation-generation = { path = "polkadot/node/collation-generation", default-features = false } polkadot-node-core-approval-voting = { path = "polkadot/node/core/approval-voting", default-features = false } diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index 74f821e112c79..e5f51feefaa0d 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -67,7 +67,7 @@ path = "src/bin/prepare-worker.rs" [dependencies] color-eyre = { workspace = true } -tikv-jemallocator = { optional = true, features = ["unprefixed_malloc_on_supported_platforms"], workspace = true } +polkadot-jemalloc-shim = { workspace = true } # Crates in our workspace, defined as dependencies so we can pass them feature flags. polkadot-cli = { features = ["rococo-native", "westend-native"], workspace = true, default-features = true } @@ -80,7 +80,7 @@ polkadot-node-core-pvf-common = { workspace = true, default-features = true } polkadot-node-core-pvf-execute-worker = { workspace = true, default-features = true } [target.'cfg(target_os = "linux")'.dependencies] -tikv-jemallocator = { workspace = true, features = ["unprefixed_malloc_on_supported_platforms"] } +polkadot-jemalloc-shim = { workspace = true, features = ["jemalloc-allocator"] } [dev-dependencies] assert_cmd = { workspace = true } @@ -99,13 +99,7 @@ try-runtime = ["polkadot-cli/try-runtime"] fast-runtime = ["polkadot-cli/fast-runtime"] runtime-metrics = ["polkadot-cli/runtime-metrics"] pyroscope = ["polkadot-cli/pyroscope"] -jemalloc-allocator = [ - "dep:tikv-jemallocator", - "polkadot-cli/jemalloc-allocator", - "polkadot-node-core-pvf-prepare-worker/jemalloc-allocator", - "polkadot-node-core-pvf/jemalloc-allocator", - "polkadot-overseer/jemalloc-allocator", -] +jemalloc-allocator = ["polkadot-jemalloc-shim/jemalloc-allocator"] # Generate the metadata hash needed for CheckMetadataHash # in the builtin test runtimes (westend and rococo). diff --git a/polkadot/jemalloc-shim/Cargo.toml b/polkadot/jemalloc-shim/Cargo.toml new file mode 100644 index 0000000000000..7cae140667e06 --- /dev/null +++ b/polkadot/jemalloc-shim/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "polkadot-jemalloc-shim" +version = "1.0.0" +description = "Shim crate to enable jemalloc-allocator feature for polkadot crates" +license.workspace = true +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +tikv-jemallocator = { optional = true, features = ["unprefixed_malloc_on_supported_platforms"], workspace = true } +polkadot-cli = { optional = true, workspace = true } +polkadot-node-core-pvf-prepare-worker = { optional = true, workspace = true } +polkadot-node-core-pvf = { optional = true, workspace = true } +polkadot-overseer = { optional = true, workspace = true } + +[features] +jemalloc-allocator = [ + "dep:tikv-jemallocator", + "polkadot-cli/jemalloc-allocator", + "polkadot-node-core-pvf-prepare-worker/jemalloc-allocator", + "polkadot-node-core-pvf/jemalloc-allocator", + "polkadot-overseer/jemalloc-allocator", +] diff --git a/polkadot/jemalloc-shim/src/lib.rs b/polkadot/jemalloc-shim/src/lib.rs new file mode 100644 index 0000000000000..26ba12fcb070a --- /dev/null +++ b/polkadot/jemalloc-shim/src/lib.rs @@ -0,0 +1,26 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Shim crate to enable `jemalloc-allocator` feature for Polkadot crates. +//! +//! Because [there doesn't exist any easier way right now](https://github.com/rust-lang/cargo/issues/1197), we +//! need an entire crate to handle `jemalloc` enabling/disabling. This way we can enable it by +//! default on Linux, but have it optional on all other OSes. + +/// Sets the global allocator to `jemalloc` when the feature is enabled. +#[cfg(feature = "jemalloc-allocator")] +#[global_allocator] +static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; diff --git a/polkadot/src/main.rs b/polkadot/src/main.rs index 1a96bf8fb00f6..4a41e14d15611 100644 --- a/polkadot/src/main.rs +++ b/polkadot/src/main.rs @@ -20,12 +20,6 @@ use color_eyre::eyre; -/// Global allocator. Changing it to another allocator will require changing -/// `memory_stats::MemoryAllocationTracker`. -#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] -#[global_allocator] -static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; - fn main() -> eyre::Result<()> { color_eyre::install()?; polkadot_cli::run()?; From 09e055967c428b3640c42ba8a2b5aa6fea810403 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 07:56:09 +0000 Subject: [PATCH 2/6] Update from github-actions[bot] running command 'fmt' --- polkadot/jemalloc-shim/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/jemalloc-shim/Cargo.toml b/polkadot/jemalloc-shim/Cargo.toml index 7cae140667e06..53dfae9e4a5d7 100644 --- a/polkadot/jemalloc-shim/Cargo.toml +++ b/polkadot/jemalloc-shim/Cargo.toml @@ -12,11 +12,11 @@ repository.workspace = true workspace = true [dependencies] -tikv-jemallocator = { optional = true, features = ["unprefixed_malloc_on_supported_platforms"], workspace = true } polkadot-cli = { optional = true, workspace = true } -polkadot-node-core-pvf-prepare-worker = { optional = true, workspace = true } polkadot-node-core-pvf = { optional = true, workspace = true } +polkadot-node-core-pvf-prepare-worker = { optional = true, workspace = true } polkadot-overseer = { optional = true, workspace = true } +tikv-jemallocator = { optional = true, features = ["unprefixed_malloc_on_supported_platforms"], workspace = true } [features] jemalloc-allocator = [ From 287f1652926bc06da74303c82da7f6f1f8bf2ad5 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 08:08:04 +0000 Subject: [PATCH 3/6] Update from github-actions[bot] running command 'prdoc --audience node_operator --bump patch' --- prdoc/pr_10709.prdoc | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 prdoc/pr_10709.prdoc diff --git a/prdoc/pr_10709.prdoc b/prdoc/pr_10709.prdoc new file mode 100644 index 0000000000000..fd6139d771e77 --- /dev/null +++ b/prdoc/pr_10709.prdoc @@ -0,0 +1,10 @@ +title: Introduce a "jemalloc-shim" crate +doc: +- audience: Node Operator + description: |- + This crate basically serves as a hack to properly enable `jemalloc` on Linux and disable it on all other OSes by default. +crates: +- name: polkadot + bump: patch +- name: polkadot-jemalloc-shim + bump: patch From 68f13b7c8d868730b0fed302f9be49e6227ff9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 23 Dec 2025 13:33:17 +0100 Subject: [PATCH 4/6] Add it to `umbrella` crate --- umbrella/Cargo.toml | 6 ++++++ umbrella/src/lib.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 6204e38f998b5..6639266d5d96b 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -895,6 +895,7 @@ node = [ "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", + "polkadot-jemalloc-shim", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", @@ -2387,6 +2388,11 @@ default-features = false optional = true path = "../polkadot/node/network/gossip-support" +[dependencies.polkadot-jemalloc-shim] +default-features = false +optional = true +path = "../polkadot/jemalloc-shim" + [dependencies.polkadot-network-bridge] default-features = false optional = true diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index ae0336f9d59eb..9a4169fee8eb5 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -866,6 +866,10 @@ pub use polkadot_erasure_coding; #[cfg(feature = "polkadot-gossip-support")] pub use polkadot_gossip_support; +/// Shim crate to enable jemalloc-allocator feature for polkadot crates. +#[cfg(feature = "polkadot-jemalloc-shim")] +pub use polkadot_jemalloc_shim; + /// The Network Bridge Subsystem — protocol multiplexer for Polkadot. #[cfg(feature = "polkadot-network-bridge")] pub use polkadot_network_bridge; From 8f4b526cff290fa3e6374a14bfa6e5b389e15f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 23 Dec 2025 22:23:37 +0100 Subject: [PATCH 5/6] Adds the shim crate to `polkadot-parachains` and `polkadot-omni-node` --- Cargo.lock | 3 +++ cumulus/polkadot-omni-node/Cargo.toml | 5 +++++ cumulus/polkadot-parachain/Cargo.toml | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 3e74a0df5d97b..d6bb78576e84e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15891,6 +15891,7 @@ version = "0.1.0" dependencies = [ "assert_cmd", "color-eyre", + "polkadot-jemalloc-shim", "polkadot-omni-node-lib", "substrate-build-script-utils", ] @@ -16030,6 +16031,7 @@ dependencies = [ "parachains-common", "penpal-runtime", "people-westend-runtime", + "polkadot-jemalloc-shim", "polkadot-omni-node-lib", "sc-chain-spec", "sc-cli", @@ -16473,6 +16475,7 @@ dependencies = [ "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", + "polkadot-jemalloc-shim", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", diff --git a/cumulus/polkadot-omni-node/Cargo.toml b/cumulus/polkadot-omni-node/Cargo.toml index 4e942ebc41ab4..a21336899afb1 100644 --- a/cumulus/polkadot-omni-node/Cargo.toml +++ b/cumulus/polkadot-omni-node/Cargo.toml @@ -16,8 +16,12 @@ workspace = true color-eyre = { workspace = true } # Local +polkadot-jemalloc-shim = { workspace = true } polkadot-omni-node-lib = { workspace = true, features = ["rococo-native", "westend-native"] } +[target.'cfg(target_os = "linux")'.dependencies] +polkadot-jemalloc-shim = { workspace = true, features = ["jemalloc-allocator"] } + [dev-dependencies] assert_cmd = { workspace = true } @@ -26,6 +30,7 @@ substrate-build-script-utils = { workspace = true, default-features = true } [features] default = [] +jemalloc-allocator = ["polkadot-jemalloc-shim/jemalloc-allocator"] runtime-benchmarks = [ "polkadot-omni-node-lib/runtime-benchmarks", ] diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index e0e4ac573c9a7..8405a77c66e14 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -48,6 +48,7 @@ sp-genesis-builder = { workspace = true, default-features = true } sp-keyring = { workspace = true, default-features = true } # Polkadot +polkadot-jemalloc-shim = { workspace = true } xcm = { workspace = true, default-features = true } # Cumulus @@ -55,6 +56,9 @@ cumulus-client-consensus-aura = { workspace = true } cumulus-primitives-core = { workspace = true, default-features = true } yet-another-parachain-runtime = { workspace = true } +[target.'cfg(target_os = "linux")'.dependencies] +polkadot-jemalloc-shim = { workspace = true, features = ["jemalloc-allocator"] } + [dev-dependencies] assert_cmd = { workspace = true } @@ -63,6 +67,7 @@ substrate-build-script-utils = { workspace = true, default-features = true } [features] default = [] +jemalloc-allocator = ["polkadot-jemalloc-shim/jemalloc-allocator"] runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "parachains-common/runtime-benchmarks", From e762ecc799f6cf77fd2acbb79191e80839654d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 24 Dec 2025 11:20:47 +0100 Subject: [PATCH 6/6] Remove from umbrella crate --- Cargo.lock | 3 --- polkadot/jemalloc-shim/Cargo.toml | 5 ++++- .../node/core/pvf/execute-worker/Cargo.toml | 3 +++ .../node/core/pvf/prepare-worker/Cargo.toml | 3 +++ umbrella/Cargo.toml | 18 ------------------ umbrella/src/lib.rs | 14 -------------- 6 files changed, 10 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6bb78576e84e..56d52039fd8d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16475,7 +16475,6 @@ dependencies = [ "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", - "polkadot-jemalloc-shim", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", @@ -16493,8 +16492,6 @@ dependencies = [ "polkadot-node-core-pvf", "polkadot-node-core-pvf-checker", "polkadot-node-core-pvf-common", - "polkadot-node-core-pvf-execute-worker", - "polkadot-node-core-pvf-prepare-worker", "polkadot-node-core-runtime-api", "polkadot-node-metrics", "polkadot-node-network-protocol", diff --git a/polkadot/jemalloc-shim/Cargo.toml b/polkadot/jemalloc-shim/Cargo.toml index 53dfae9e4a5d7..cb850b5603d4e 100644 --- a/polkadot/jemalloc-shim/Cargo.toml +++ b/polkadot/jemalloc-shim/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "polkadot-jemalloc-shim" version = "1.0.0" -description = "Shim crate to enable jemalloc-allocator feature for polkadot crates" +description = "Shim crate to enable jemalloc-allocator feature for polkadot crates and setting global allocator to jemalloc" license.workspace = true authors.workspace = true edition.workspace = true @@ -11,6 +11,9 @@ repository.workspace = true [lints] workspace = true +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + [dependencies] polkadot-cli = { optional = true, workspace = true } polkadot-node-core-pvf = { optional = true, workspace = true } diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 4df425dfd199b..726cde3243449 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -11,6 +11,9 @@ repository.workspace = true [lints] workspace = true +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + [dependencies] cfg-if = { workspace = true } cpu-time = { workspace = true } diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index cc32086360cd7..a96d20ab35691 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -11,6 +11,9 @@ repository.workspace = true [lints] workspace = true +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + [[bench]] name = "prepare_rococo_runtime" harness = false diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 6639266d5d96b..5fd44713422e9 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -895,7 +895,6 @@ node = [ "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", - "polkadot-jemalloc-shim", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", @@ -913,8 +912,6 @@ node = [ "polkadot-node-core-pvf", "polkadot-node-core-pvf-checker", "polkadot-node-core-pvf-common", - "polkadot-node-core-pvf-execute-worker", - "polkadot-node-core-pvf-prepare-worker", "polkadot-node-core-runtime-api", "polkadot-node-metrics", "polkadot-node-network-protocol", @@ -2388,11 +2385,6 @@ default-features = false optional = true path = "../polkadot/node/network/gossip-support" -[dependencies.polkadot-jemalloc-shim] -default-features = false -optional = true -path = "../polkadot/jemalloc-shim" - [dependencies.polkadot-network-bridge] default-features = false optional = true @@ -2478,16 +2470,6 @@ default-features = false optional = true path = "../polkadot/node/core/pvf/common" -[dependencies.polkadot-node-core-pvf-execute-worker] -default-features = false -optional = true -path = "../polkadot/node/core/pvf/execute-worker" - -[dependencies.polkadot-node-core-pvf-prepare-worker] -default-features = false -optional = true -path = "../polkadot/node/core/pvf/prepare-worker" - [dependencies.polkadot-node-core-runtime-api] default-features = false optional = true diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index 9a4169fee8eb5..a9d26a796038e 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -866,10 +866,6 @@ pub use polkadot_erasure_coding; #[cfg(feature = "polkadot-gossip-support")] pub use polkadot_gossip_support; -/// Shim crate to enable jemalloc-allocator feature for polkadot crates. -#[cfg(feature = "polkadot-jemalloc-shim")] -pub use polkadot_jemalloc_shim; - /// The Network Bridge Subsystem — protocol multiplexer for Polkadot. #[cfg(feature = "polkadot-network-bridge")] pub use polkadot_network_bridge; @@ -946,16 +942,6 @@ pub use polkadot_node_core_pvf_checker; #[cfg(feature = "polkadot-node-core-pvf-common")] pub use polkadot_node_core_pvf_common; -/// Polkadot crate that contains the logic for executing PVFs. Used by the -/// polkadot-execute-worker binary. -#[cfg(feature = "polkadot-node-core-pvf-execute-worker")] -pub use polkadot_node_core_pvf_execute_worker; - -/// Polkadot crate that contains the logic for preparing PVFs. Used by the -/// polkadot-prepare-worker binary. -#[cfg(feature = "polkadot-node-core-pvf-prepare-worker")] -pub use polkadot_node_core_pvf_prepare_worker; - /// Wrapper around the parachain-related runtime APIs. #[cfg(feature = "polkadot-node-core-runtime-api")] pub use polkadot_node_core_runtime_api;