Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking/limiting memory allocator #1192

Merged
merged 62 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
47ecf58
Import changes from archived repo
s0me0ne-unkn0wn Aug 27, 2023
58330de
Fix dependencies
s0me0ne-unkn0wn Aug 30, 2023
aac1da6
Merge branch 'master' into s0me0ne/tracking-allocator
pepoviola Aug 30, 2023
99d4f5e
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 1, 2023
18ef342
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 2, 2023
facd26a
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 12, 2023
3d2146a
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 14, 2023
6ee5ff3
Format manifests
s0me0ne-unkn0wn Sep 14, 2023
f85c753
Make peak allocation value observable
s0me0ne-unkn0wn Sep 15, 2023
c9c0bf8
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 15, 2023
edfa2e1
Enforce memory limits
s0me0ne-unkn0wn Sep 16, 2023
ac5dab4
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 16, 2023
994273a
Fix the node allocator declaration
s0me0ne-unkn0wn Sep 16, 2023
72ded39
`cargo fmt`
s0me0ne-unkn0wn Sep 16, 2023
dfa0daf
Implement abort handler
s0me0ne-unkn0wn Sep 21, 2023
e740b5c
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 21, 2023
48cde3e
Address some discussions
s0me0ne-unkn0wn Sep 21, 2023
acf149e
Remove feature gate
s0me0ne-unkn0wn Sep 21, 2023
6cfeceb
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 21, 2023
c7fa464
Update crate description
s0me0ne-unkn0wn Sep 22, 2023
edeb901
Implement failure callback
s0me0ne-unkn0wn Sep 22, 2023
251ac90
Merge remote-tracking branch 'origin/s0me0ne/tracking-allocator' into…
s0me0ne-unkn0wn Sep 22, 2023
4195806
Address discussions
s0me0ne-unkn0wn Sep 22, 2023
09e5c07
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 22, 2023
02ad536
Fix tests
s0me0ne-unkn0wn Sep 22, 2023
e1a2b63
Fix typo
s0me0ne-unkn0wn Sep 25, 2023
1918d2a
Address discussions
s0me0ne-unkn0wn Sep 26, 2023
b06cb6d
Merge remote-tracking branch 'origin/s0me0ne/tracking-allocator' into…
s0me0ne-unkn0wn Sep 26, 2023
39cf3b7
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 26, 2023
007054a
Address discussions
s0me0ne-unkn0wn Sep 26, 2023
c81e8aa
Try to fix test pipeline
s0me0ne-unkn0wn Sep 26, 2023
5920260
Fix PVF preparation benchmark
s0me0ne-unkn0wn Sep 26, 2023
a37c688
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 26, 2023
96d71c9
Minor fixes
s0me0ne-unkn0wn Sep 27, 2023
30e5236
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 27, 2023
73799fb
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 28, 2023
93b9d61
Eliminate redundant branch
s0me0ne-unkn0wn Sep 28, 2023
8485741
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 28, 2023
7a3875a
Revert "Eliminate redundant branch"
s0me0ne-unkn0wn Sep 28, 2023
83e6b99
Remove redundant todo comment
s0me0ne-unkn0wn Sep 28, 2023
6c6afc8
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Sep 29, 2023
9de0856
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 4, 2023
d6470c5
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 5, 2023
d2d8a60
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 11, 2023
d74aa20
Remove stale file
s0me0ne-unkn0wn Oct 11, 2023
fb40a0d
Merge branch 's0me0ne/tracking-allocator' of github.com:paritytech/po…
s0me0ne-unkn0wn Oct 20, 2023
9c1d920
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 20, 2023
c6be92b
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 23, 2023
8c58a68
Abstract `Spinlock`
s0me0ne-unkn0wn Oct 23, 2023
52578ee
Merge branch 'master' into s0me0ne/tracking-allocator
s0me0ne-unkn0wn Oct 23, 2023
778513c
Update comment
s0me0ne-unkn0wn Oct 29, 2023
9c3ea9b
Add safety comment
s0me0ne-unkn0wn Oct 29, 2023
54686a1
Fix comment formatting
s0me0ne-unkn0wn Oct 29, 2023
07eb6a9
Fix typo
s0me0ne-unkn0wn Oct 29, 2023
e3ca3b6
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Oct 29, 2023
8be6359
Remove unneeded trait bound
s0me0ne-unkn0wn Oct 29, 2023
8b0a722
Remove stale file
s0me0ne-unkn0wn Oct 29, 2023
331ed01
Rename tracking fn
s0me0ne-unkn0wn Nov 1, 2023
7d69a9b
Merge remote-tracking branch 'origin/master' into s0me0ne/tracking-al…
s0me0ne-unkn0wn Nov 1, 2023
10e7443
Fix clippy and tests
s0me0ne-unkn0wn Nov 1, 2023
c3b66f2
Merge branch 'master' into s0me0ne/tracking-allocator
s0me0ne-unkn0wn Nov 1, 2023
e94ddf9
Merge branch 'master' into s0me0ne/tracking-allocator
s0me0ne-unkn0wn Nov 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions polkadot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ polkadot-cli = { path = "cli", features = [
polkadot-node-core-pvf = { path = "node/core/pvf" }
polkadot-node-core-pvf-prepare-worker = { path = "node/core/pvf/prepare-worker" }
polkadot-overseer = { path = "node/overseer" }
tracking-allocator = { path = "node/tracking-allocator", optional = true }

# Needed for worker binaries.
polkadot-node-core-pvf-common = { path = "node/core/pvf/common" }
Expand Down Expand Up @@ -68,6 +69,12 @@ jemalloc-allocator = [
"polkadot-node-core-pvf/jemalloc-allocator",
"polkadot-overseer/jemalloc-allocator",
]
tracking-allocator = [
"dep:tracking-allocator",
"jemalloc-allocator",
"polkadot-node-core-pvf-prepare-worker/tracking-allocator",
"polkadot-node-core-pvf/tracking-allocator",
]

# Enables timeout-based tests supposed to be run only in CI environment as they may be flaky
# when run locally depending on system load
Expand Down
4 changes: 4 additions & 0 deletions polkadot/node/core/pvf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ halt = { package = "test-parachain-halt", path = "../../../parachain/test-parach
[features]
ci-only-tests = []
jemalloc-allocator = [ "polkadot-node-core-pvf-common/jemalloc-allocator" ]
tracking-allocator = [
"polkadot-node-core-pvf-common/tracking-allocator",
"polkadot-node-core-pvf-prepare-worker/tracking-allocator",
]
# This feature is used to export test code to other crates without putting it in the production build.
test-utils = [
"polkadot-node-core-pvf-execute-worker",
Expand Down
1 change: 1 addition & 0 deletions polkadot/node/core/pvf/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ tempfile = "3.3.0"
# Also used for building the puppet worker.
test-utils = []
jemalloc-allocator = []
tracking-allocator = []
3 changes: 3 additions & 0 deletions polkadot/node/core/pvf/common/src/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub struct MemoryStats {
/// `ru_maxrss` from `getrusage`. `None` if an error occurred.
#[cfg(target_os = "linux")]
pub max_rss: Option<i64>,
/// Peak allocation in bytes measured by tracking allocator
#[cfg(feature = "tracking-allocator")]
pub peak_alloc: u64,
s0me0ne-unkn0wn marked this conversation as resolved.
Show resolved Hide resolved
}

/// Statistics of collected memory metrics.
Expand Down
15 changes: 15 additions & 0 deletions polkadot/node/core/pvf/prepare-worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ libc = "0.2.139"
rayon = "1.5.1"
tikv-jemalloc-ctl = { version = "0.5.0", optional = true }
tokio = { version = "1.24.2", features = ["fs", "process"] }
tracking-allocator = { path = "../../../tracking-allocator", optional = true }
tikv-jemallocator = { version = "0.5.0", optional = true }

parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] }

Expand All @@ -36,3 +38,16 @@ jemalloc-allocator = [
"dep:tikv-jemalloc-ctl",
"polkadot-node-core-pvf-common/jemalloc-allocator",
]
tracking-allocator = [
"dep:tikv-jemallocator",
"dep:tracking-allocator",
"polkadot-node-core-pvf-common/tracking-allocator",
]

[dev-dependencies]
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] }
staging-kusama-runtime = { path = "../../../../runtime/kusama" }

[[bench]]
name = "prepare_kusama_runtime"
harness = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// 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 <http://www.gnu.org/licenses/>.

use criterion::{criterion_group, criterion_main, Criterion, SamplingMode};
use polkadot_node_core_pvf_common::{prepare::PrepareJobKind, pvf::PvfPrepData};
use polkadot_node_core_pvf_prepare_worker::{prepare, prevalidate};
use polkadot_primitives::ExecutorParams;
use std::time::Duration;

fn do_prepare_kusama_runtime(pvf: PvfPrepData) {
s0me0ne-unkn0wn marked this conversation as resolved.
Show resolved Hide resolved
let blob = match prevalidate(&pvf.code()) {
Err(err) => panic!("{:?}", err),
Ok(b) => b,
};

match prepare(blob, &pvf.executor_params()) {
Ok(_) => (),
Err(err) => panic!("{:?}", err),
}
}

fn prepare_kusama_runtime(c: &mut Criterion) {
let blob = staging_kusama_runtime::WASM_BINARY.unwrap();
let pvf = match sp_maybe_compressed_blob::decompress(&blob, 64 * 1024 * 1024) {
Ok(code) => PvfPrepData::from_code(
code.into_owned(),
ExecutorParams::default(),
Duration::from_secs(360),
PrepareJobKind::Compilation,
),
Err(e) => {
panic!("Cannot decompress blob: {:?}", e);
},
};

let mut group = c.benchmark_group("kusama");
group.sampling_mode(SamplingMode::Flat);
group.sample_size(20);
group.measurement_time(Duration::from_secs(240));
group.bench_function("prepare Kusama runtime", |b| {
b.iter(|| do_prepare_kusama_runtime(pvf.clone()))
s0me0ne-unkn0wn marked this conversation as resolved.
Show resolved Hide resolved
});
group.finish();
}

criterion_group!(preparation, prepare_kusama_runtime);
criterion_main!(preparation);
28 changes: 27 additions & 1 deletion polkadot/node/core/pvf/prepare-worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ use std::{
};
use tokio::{io, net::UnixStream};

#[cfg(feature = "tracking-allocator")]
use tikv_jemallocator::Jemalloc;
#[cfg(feature = "tracking-allocator")]
use tracking_allocator::TrackingAllocator;
#[cfg(feature = "tracking-allocator")]
#[global_allocator]
static ALLOC: TrackingAllocator<Jemalloc> = TrackingAllocator(Jemalloc);

/// Contains the bytes for a successfully compiled artifact.
pub struct CompiledArtifact(Vec<u8>);

Expand Down Expand Up @@ -168,13 +176,17 @@ pub fn worker_entrypoint(
Arc::clone(&condvar),
WaitOutcome::TimedOut,
)?;

#[cfg(feature = "tracking-allocator")]
ALLOC.start_tracking(executor_params.prechecking_max_memory().map(|v| v as isize));
s0me0ne-unkn0wn marked this conversation as resolved.
Show resolved Hide resolved

// Spawn another thread for preparation.
let prepare_thread = thread::spawn_worker_thread(
"prepare thread",
move || {
// Try to enable landlock.
#[cfg(target_os = "linux")]
let landlock_status = polkadot_node_core_pvf_common::worker::security::landlock::try_restrict_thread()
let landlock_status = polkadot_node_core_pvf_common::worker::security::landlock::try_restrict_thread()
.map(LandlockStatus::from_ruleset_status)
.map_err(|e| e.to_string());
#[cfg(not(target_os = "linux"))]
Expand Down Expand Up @@ -208,6 +220,18 @@ pub fn worker_entrypoint(

let outcome = thread::wait_for_threads(condvar);

#[cfg(feature = "tracking-allocator")]
let peak_alloc = {
let peak = ALLOC.end_tracking();
gum::debug!(
target: LOG_TARGET,
%worker_pid,
"prepare job peak allocation is {} bytes",
peak,
);
peak
};

let result = match outcome {
WaitOutcome::Finished => {
let _ = cpu_time_monitor_tx.send(());
Expand Down Expand Up @@ -240,6 +264,8 @@ pub fn worker_entrypoint(
memory_tracker_stats,
#[cfg(target_os = "linux")]
max_rss: extract_max_rss_stat(max_rss, worker_pid),
#[cfg(feature = "tracking-allocator")]
peak_alloc: peak_alloc as u64,
};

// Log if landlock threw an error.
Expand Down
20 changes: 20 additions & 0 deletions polkadot/node/core/pvf/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ impl Metrics {
metrics.preparation_max_resident.observe(max_resident_kb);
metrics.preparation_max_allocated.observe(max_allocated_kb);
}

#[cfg(feature = "tracking-allocator")]
metrics
.preparation_peak_allocation
.observe((memory_stats.peak_alloc / 1024) as f64);
}
}
}
Expand All @@ -114,6 +119,8 @@ struct MetricsInner {
preparation_max_allocated: prometheus::Histogram,
#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
preparation_max_resident: prometheus::Histogram,
#[cfg(feature = "tracking-allocator")]
preparation_peak_allocation: prometheus::Histogram,
s0me0ne-unkn0wn marked this conversation as resolved.
Show resolved Hide resolved
}

impl metrics::Metrics for Metrics {
Expand Down Expand Up @@ -271,6 +278,19 @@ impl metrics::Metrics for Metrics {
)?,
registry,
)?,
#[cfg(feature = "tracking-allocator")]
preparation_peak_allocation: prometheus::register(
prometheus::Histogram::with_opts(
prometheus::HistogramOpts::new(
"polkadot_pvf_preparation_peak_allocattion",
"peak allocation observed for preparation (in kilobytes)",
).buckets(
prometheus::exponential_buckets(8192.0, 2.0, 10)
.expect("arguments are always valid; qed"),
),
)?,
registry,
)?,
};
Ok(Metrics(Some(inner)))
}
Expand Down
Loading