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

Merge Preparation: Latest IC with Graph Copy #4630

Merged
merged 23 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ab4d3b5
Adjust to new system API
luc-blaeser May 29, 2024
27a89c6
Merge branch 'luc/stable-heap64' into luc/port64-latest-ic
luc-blaeser Jul 8, 2024
492287b
Port to latest IC 64-bit system API
luc-blaeser Jul 10, 2024
b582aa1
Update to new IC with Wasm64
luc-blaeser Jul 10, 2024
cc59a6a
Updating nix hashes
github-actions[bot] Jul 10, 2024
c264488
Update IC dependency (Wasm64 enabled)
luc-blaeser Jul 10, 2024
4e5aa71
Merge branch 'luc/port64-latest-ic' of https://github.com/dfinity/mot…
luc-blaeser Jul 10, 2024
6d7fc98
Update expected test results
luc-blaeser Jul 11, 2024
941163c
Fix migration test
luc-blaeser Jul 11, 2024
a83f5c3
Use latest `drun`
luc-blaeser Jul 23, 2024
51e8571
Adjust expected test results
luc-blaeser Jul 23, 2024
bb91280
Updating nix hashes
github-actions[bot] Jul 23, 2024
3b279fa
Merge branch 'luc/stable-heap64' into luc/port64-latest-ic
luc-blaeser Jul 23, 2024
f32c7bf
Merge branch 'luc/port64-latest-ic' of https://github.com/dfinity/mot…
luc-blaeser Jul 23, 2024
5cf93f4
Update expected test results
luc-blaeser Jul 24, 2024
98087ce
Fix `drun` nix build for Linux
luc-blaeser Jul 24, 2024
06b0423
Disable DTS in `drun`, refactor `drun` patches
luc-blaeser Jul 24, 2024
845ceb5
Merge branch 'luc/port64-latest-ic' into luc/graph-copy-latest-ic
luc-blaeser Jul 25, 2024
f7564e4
Update expected test results for new `drun`
luc-blaeser Jul 25, 2024
b8a4212
Limiting amount of stable memory accessed per graph copy increment
luc-blaeser Jul 26, 2024
d9c6d5b
Reformat
luc-blaeser Jul 26, 2024
f84b5fc
Merge branch 'luc/graph-copy-on-stable-heap64' into luc/graph-copy-la…
luc-blaeser Aug 19, 2024
c2266e6
Adjust expected test result
luc-blaeser Aug 19, 2024
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
4 changes: 2 additions & 2 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ let
};
})

# Rust 1.69
# Rust stable
(self: super: let
rust-channel = self.moz_overlay.rustChannelOf { date = "2023-04-20"; channel = "stable"; };
rust-channel = self.moz_overlay.rustChannelOf { version = "1.78.0"; channel = "stable"; };
in {
rustPlatform_moz_stable = self.makeRustPlatform {
rustc = rust-channel.rust;
Expand Down
67 changes: 60 additions & 7 deletions nix/drun.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pkgs:
{ drun =
pkgs.rustPlatform.buildRustPackage {
pkgs.rustPlatform_moz_stable.buildRustPackage {
name = "drun";

src = pkgs.sources.ic;
Expand All @@ -19,12 +19,10 @@ pkgs:
lockFile = "${pkgs.sources.ic}/Cargo.lock";
outputHashes = {
"build-info-0.0.27" = "sha256-SkwWwDNrTsntkNiCv6rsyTFGazhpRDnKtVzPpYLKF9U=";
"derive_more-0.99.8-alpha.0" = "sha256-tEsfYC9oCAsDjinCsUDgRg3q6ruvayuA1lRmsEP9cys=";
"ic-btc-interface-0.1.0" = "sha256-JoVg1t62C2FIe0la1oQzidybLj1CyAQy80gkRh/MTn0=";
"ic-btc-test-utils-0.1.0" = "sha256-VecEMFjoeiRi0VgJ9CeDoOzdyJbJNiZ5MBmiV1+b7As=";
"icrc1-test-env-0.1.1" = "sha256-yWJF+KM8l65Nr0pwR9QeltkqbHDzOLNPVnLhf1mRukQ=";
"cloudflare-0.11.0" = "sha256-bJYiypmDI4KEy/VWt/7UcOv+g2CZLb9qUA9c1xlLxhM=";
"ic-agent-0.36.0" = "sha256-vDONIVjz0cwVgiszVRIjTKcqRUMHdVwTURflAMqmzHM=";
"icrc1-test-env-0.1.1" = "sha256-2PB7e64Owin/Eji3k8UoeWs+pfDfOOTaAyXjvjOZ/4g=";
"jsonrpc-0.12.1" = "sha256-3FtdZlt2PqVDkE5iKWYIp1eiIELsaYlUPRSP2Xp8ejM=";
"libssh2-sys-0.2.23" = "sha256-9Hb7CnPF+lxrVO1NAhS7EXcPVWZutJXr6UWxpptzk4U=";
"lmdb-rkv-0.14.99" = "sha256-5WcUzapkrc/s3wCBNCuUDhtbp17n67rTbm2rx0qtITg=";
};
};
Expand All @@ -43,9 +41,64 @@ pkgs:

for file in lib_sources {
EOF

cd -

# Disable DTS for `drun`
patch rs/config/src/subnet_config.rs << EOF
@@ -290,9 +290,9 @@ impl SchedulerConfig {
}

pub fn system_subnet() -> Self {
- let max_instructions_per_message_without_dts = NumInstructions::from(50 * B);
+ let max_instructions_per_message_without_dts =
+ MAX_INSTRUCTIONS_PER_MESSAGE_WITHOUT_DTS * SYSTEM_SUBNET_FACTOR;
let max_instructions_per_install_code = NumInstructions::from(1_000 * B);
- let max_instructions_per_slice = NumInstructions::from(10 * B);
Self {
scheduler_cores: NUMBER_OF_EXECUTION_THREADS,
max_paused_executions: MAX_PAUSED_EXECUTIONS,
@@ -300,20 +300,19 @@ impl SchedulerConfig {
// TODO(RUN-993): Enable heap delta rate limiting for system subnets.
// Setting initial reserve to capacity effectively disables the rate limiting.
heap_delta_initial_reserve: SUBNET_HEAP_DELTA_CAPACITY,
- // Round limit is set to allow on average 2B instructions.
- // See also comment about \`MAX_INSTRUCTIONS_PER_ROUND\`.
- max_instructions_per_round: max_instructions_per_message_without_dts
- .max(max_instructions_per_slice)
- + NumInstructions::from(2 * B),
+ max_instructions_per_round: MAX_INSTRUCTIONS_PER_ROUND * SYSTEM_SUBNET_FACTOR,
+ // Effectively disable DTS on system subnets.
max_instructions_per_message: max_instructions_per_message_without_dts,
max_instructions_per_message_without_dts,
- max_instructions_per_slice,
+ // Effectively disable DTS on system subnets.
+ max_instructions_per_slice: max_instructions_per_message_without_dts,
instruction_overhead_per_execution: INSTRUCTION_OVERHEAD_PER_EXECUTION,
instruction_overhead_per_canister: INSTRUCTION_OVERHEAD_PER_CANISTER,
instruction_overhead_per_canister_for_finalization:
INSTRUCTION_OVERHEAD_PER_CANISTER_FOR_FINALIZATION,
max_instructions_per_install_code,
- max_instructions_per_install_code_slice: max_instructions_per_slice,
+ // Effectively disable DTS on system subnets.
+ max_instructions_per_install_code_slice: max_instructions_per_install_code,
max_heap_delta_per_iteration: MAX_HEAP_DELTA_PER_ITERATION * SYSTEM_SUBNET_FACTOR,
max_message_duration_before_warn_in_seconds:
MAX_MESSAGE_DURATION_BEFORE_WARN_IN_SECONDS,
EOF

# static linking of libunwind fails under nix Linux
patch rs/monitoring/backtrace/build.rs << EOF
@@ -1,8 +1,2 @@
fn main() {
- if std::env::var("TARGET").unwrap() == "x86_64-unknown-linux-gnu" {
- println!("cargo:rustc-link-lib=static=unwind");
- println!("cargo:rustc-link-lib=static=unwind-ptrace");
- println!("cargo:rustc-link-lib=static=unwind-x86_64");
- println!("cargo:rustc-link-lib=dylib=lzma");
- }
}
EOF

mkdir -p .cargo
cat > .cargo/config.toml << EOF
[target.x86_64-apple-darwin]
Expand Down
10 changes: 5 additions & 5 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
"version": "3.2.25"
},
"ic": {
"branch": "pull/143/head",
"branch": "luc/latest-ic-wasm64-test",
"description": "Internet Computer blockchain source: the client/replica software run by nodes",
"homepage": "",
"owner": "dfinity",
"owner": "luc-blaeser",
"repo": "ic",
"rev": "31f02c1b08aef1c6ee4c1b6bb9d25c21c5a4ff41",
"sha256": "04k278900kv082axrgv6vga0n8sw6c3lcc9298ih9gjyx8hanfb1",
"rev": "7921f5f3dc0d9fb774e3222f8ff6b1c00a086f1a",
"sha256": "1ykawbpaqnf1y508vh81m30p813ykmnbffxc3p0hw0p0k1ynq6zz",
"type": "tarball",
"url": "https://github.com/dfinity/ic/archive/31f02c1b08aef1c6ee4c1b6bb9d25c21c5a4ff41.tar.gz",
"url": "https://github.com/luc-blaeser/ic/archive/7921f5f3dc0d9fb774e3222f8ff6b1c00a086f1a.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ic-hs": {
Expand Down
23 changes: 13 additions & 10 deletions rts/motoko-rts/src/stabilization/deserialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use self::{scan_stack::ScanStack, stable_memory_access::StableMemoryAccess};

use super::{
clear_stable_memory,
graph_copy::{limit::InstructionLimit, GraphCopy},
graph_copy::{limit::ExecutionLimit, GraphCopy},
layout::{deserialize, StableValue},
moc_stabilization_instruction_limit,
};
Expand All @@ -25,7 +25,7 @@ pub struct Deserialization {
stable_start: u64,
stable_size: u64,
stable_root: Option<Value>,
limit: InstructionLimit,
limit: ExecutionLimit,
clear_position: u64,
}

Expand Down Expand Up @@ -62,7 +62,7 @@ impl Deserialization {
pub fn start<M: Memory>(mem: &mut M, stable_start: u64, stable_size: u64) -> Deserialization {
let from_space = StableMemoryAccess::open(stable_start, stable_size);
let scan_stack = unsafe { ScanStack::new(mem) };
let limit = InstructionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let limit = ExecutionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let mut deserialization = Deserialization {
from_space,
scan_stack,
Expand Down Expand Up @@ -114,6 +114,13 @@ impl Deserialization {
fn stable_end(&self) -> u64 {
self.stable_start.checked_add(self.stable_size).unwrap()
}

fn processed_memory(&self) -> u64 {
let deserialized_memory = unsafe { deserialized_size() as u64 };
debug_assert!(self.clear_position >= self.stable_start);
let cleared_memory = self.clear_position - self.stable_start;
deserialized_memory + cleared_memory
}
}

impl GraphCopy<StableValue, Value, u32> for Deserialization {
Expand Down Expand Up @@ -195,16 +202,12 @@ impl GraphCopy<StableValue, Value, u32> for Deserialization {
}

fn time_over(&mut self) -> bool {
let deserialized_memory = unsafe { deserialized_size() as u64 };
debug_assert!(self.clear_position >= self.stable_start);
let cleared_memory = self.clear_position - self.stable_start;
let processed_memory = deserialized_memory + cleared_memory;
self.limit.is_exceeded(processed_memory)
self.limit.is_exceeded(self.processed_memory())
}

fn reset_time(&mut self) {
let limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(limit);
let instruction_limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(instruction_limit, self.processed_memory());
}
}

Expand Down
54 changes: 38 additions & 16 deletions rts/motoko-rts/src/stabilization/graph_copy/limit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
use crate::{constants::KB, stabilization::ic0_performance_counter};
use crate::{
constants::{GB, KB},
stabilization::ic0_performance_counter,
};

/// Instruction limit for the graph copy increment.
/// Monitoring the message instruction counter.
/// Maximum amount of memory that is processed per increment.
/// The IC configures a maximum of 2 GB of stable memory that can
/// be accessed per message. We keep a conservative reserve of 1 GB.
const MEMORY_PROCESSING_LIMIT_PER_INCREMENT: u64 = GB as u64;

/// Execution limit for the graph copy increment.
/// Monitoring the message instruction counter and
/// the amount of processed memory.
/// The latter is relevant to avoid exceeding the limit
/// of how much stable memory be accessed in a message.
/// Optimization: Avoiding frequent repeated calls to
/// `ic0_performance_counter()` as this incurs 200
/// instructions itself.
Expand All @@ -18,11 +29,13 @@ use crate::{constants::KB, stabilization::ic0_performance_counter};
/// Once the limit has been exceeded, the heuristics
/// continuously returns exceeded until the monitoring
/// is reset.
pub struct InstructionLimit {
pub struct ExecutionLimit {
/// Instruction counter at the beginning of the measurement.
start: u64,
initial_instruction_counter: u64,
/// Limit of processed instructions since measurment start.
limit: u64,
instruction_limit: u64,
/// Amount of processed memory before the measurement.
initial_processed_memory: u64,
// Only used for sporadic synchronization heuristics:
/// Number of `is_exceeded` calls since the last instruction
/// counter synchronization.
Expand All @@ -34,25 +47,33 @@ pub struct InstructionLimit {
exceeded: bool,
}

impl InstructionLimit {
impl ExecutionLimit {
/// Threshold on the number of `is_exceeded` calls since the
/// last instruction counter synchronization.
const CALL_THRESHOLD: usize = 1_000;
/// Threshold on the amount of processed memory since the last
/// instruction counter synchronization.
const MEMORY_THRESHOLD: u64 = 256 * KB as u64;

pub fn new(limit: u64) -> InstructionLimit {
InstructionLimit {
start: Self::instruction_counter(),
limit,
pub fn new(instruction_limit: u64) -> ExecutionLimit {
ExecutionLimit {
initial_instruction_counter: Self::instruction_counter(),
instruction_limit,
initial_processed_memory: 0,
call_counter: 0,
last_processed: 0,
exceeded: false,
}
}

pub fn is_exceeded(&mut self, processed_memory: u64) -> bool {
debug_assert!(self.initial_processed_memory <= processed_memory);
// Check the memory limit.
if processed_memory - self.initial_processed_memory > MEMORY_PROCESSING_LIMIT_PER_INCREMENT
{
return true;
}
// Check the instruction limit.
// Sporadic instruction counter synchronization, see above.
self.call_counter += 1;
if processed_memory >= self.last_processed.saturating_add(Self::MEMORY_THRESHOLD)
Expand All @@ -63,15 +84,16 @@ impl InstructionLimit {
self.last_processed = processed_memory;
// Check actual instruction counter.
let current = Self::instruction_counter();
debug_assert!(self.start <= current);
let elapsed = current - self.start;
self.exceeded = elapsed > self.limit;
debug_assert!(self.initial_instruction_counter <= current);
let elapsed = current - self.initial_instruction_counter;
self.exceeded = elapsed > self.instruction_limit;
}
self.exceeded
}

pub fn reset(&mut self, limit: u64) {
*self = Self::new(limit);
pub fn reset(&mut self, instruction_limit: u64, processed_memory: u64) {
*self = Self::new(instruction_limit);
self.initial_processed_memory = processed_memory;
}

fn instruction_counter() -> u64 {
Expand Down
16 changes: 10 additions & 6 deletions rts/motoko-rts/src/stabilization/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use crate::{
use self::stable_memory_stream::{ScanStream, StableMemoryStream};

use super::{
graph_copy::{limit::InstructionLimit, GraphCopy},
graph_copy::{limit::ExecutionLimit, GraphCopy},
layout::{scan_serialized, StableToSpace, StableValue},
moc_stabilization_instruction_limit, DUMMY_VALUE,
};

pub struct Serialization {
to_space: StableMemoryStream,
limit: InstructionLimit,
limit: ExecutionLimit,
array_slice: Option<ArraySlice>,
}

Expand Down Expand Up @@ -65,7 +65,7 @@ impl Serialization {
/// The start is followed by a series of copy increments before the serialization is completed.
pub fn start<M: Memory>(mem: &mut M, root: Value, stable_start: u64) -> Serialization {
let to_space = StableMemoryStream::open(stable_start);
let limit = InstructionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let limit = ExecutionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let mut serialization = Serialization {
limit,
to_space,
Expand Down Expand Up @@ -115,6 +115,10 @@ impl Serialization {
pub fn set_array_slice(&mut self, slice: ArraySlice) {
self.array_slice = Some(slice);
}

fn processed_memory(&self) -> u64 {
self.serialized_data_length()
}
}

impl GraphCopy<Value, StableValue, u32> for Serialization {
Expand Down Expand Up @@ -183,12 +187,12 @@ impl GraphCopy<Value, StableValue, u32> for Serialization {
}

fn time_over(&mut self) -> bool {
self.limit.is_exceeded(self.serialized_data_length())
self.limit.is_exceeded(self.processed_memory())
}

fn reset_time(&mut self) {
let limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(limit);
let instruction_limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(instruction_limit, self.processed_memory());
}
}

Expand Down
Loading