Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.

Commit aa86b14

Browse files
committed
Make memory util more fair between baseline/rackscale benches; prepare to use hugepages for qemu memory (not done yet)
1 parent d6dbc4d commit aa86b14

File tree

4 files changed

+79
-63
lines changed

4 files changed

+79
-63
lines changed

kernel/src/arch/x86_64/rackscale/registration.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::memory::backends::AllocatorStatistics;
2020
use crate::memory::mcache::MCache;
2121
use crate::memory::shmem_affinity::mid_to_shmem_affinity;
2222
use crate::memory::{Frame, PAddr, LARGE_PAGE_SIZE};
23-
use crate::transport::shmem::get_affinity_shmem;
23+
use crate::transport::shmem::{get_affinity_shmem, get_affinity_shmem_by_mid};
2424

2525
#[derive(Debug, Default)]
2626
pub(crate) struct ClientRegistrationRequest {
@@ -117,6 +117,16 @@ pub(crate) fn register_client(hdr: &mut RPCHeader, payload: &mut [u8]) -> Result
117117
}
118118
};
119119

120+
// Make sure the controller and the client are seeing the same shmem addresses.
121+
{
122+
let shmem_region = get_affinity_shmem_by_mid(req.mid);
123+
assert_eq!(
124+
shmem_region.base.as_u64(),
125+
req.shmem_region_base,
126+
"Controller did not assign shmem region the same address as the client"
127+
);
128+
}
129+
120130
// Create shmem memory manager
121131
let frame = Frame::new(
122132
PAddr::from(req.shmem_region_base),

kernel/tests/s11_rackscale_benchmarks.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ fn rackscale_fxmark_benchmark(transport: RackscaleTransport) {
117117
test.controller_match_fn = controller_match_fn;
118118
test.transport = transport;
119119
test.use_affinity_shmem = cfg!(feature = "affinity-shmem");
120+
test.use_qemu_huge_pages = cfg!(feature = "affinity-shmem");
120121
test.file_name = file_name.clone();
121122
test.arg = Some(config);
122123

@@ -144,9 +145,7 @@ fn rackscale_fxmark_benchmark(transport: RackscaleTransport) {
144145
cmd_fn,
145146
baseline_timeout_fn: timeout_fn,
146147
rackscale_timeout_fn: timeout_fn,
147-
controller_mem_fn: mem_fn,
148-
client_mem_fn: mem_fn,
149-
baseline_mem_fn: mem_fn,
148+
mem_fn,
150149
};
151150

152151
if cfg!(feature = "baseline") {
@@ -284,6 +283,7 @@ fn rackscale_vmops_benchmark(transport: RackscaleTransport, benchtype: VMOpsBenc
284283
test.controller_match_fn = controller_match_fn;
285284
test.transport = transport;
286285
test.use_affinity_shmem = cfg!(feature = "affinity-shmem");
286+
test.use_qemu_huge_pages = cfg!(feature = "affinity-shmem");
287287
test.file_name = file_name.clone();
288288
test.arg = Some(benchtype);
289289

@@ -308,9 +308,7 @@ fn rackscale_vmops_benchmark(transport: RackscaleTransport, benchtype: VMOpsBenc
308308
cmd_fn,
309309
baseline_timeout_fn,
310310
rackscale_timeout_fn,
311-
controller_mem_fn: mem_fn,
312-
client_mem_fn: mem_fn,
313-
baseline_mem_fn: mem_fn,
311+
mem_fn,
314312
};
315313

316314
if cfg!(feature = "baseline") {
@@ -411,6 +409,7 @@ fn s11_rackscale_shmem_leveldb_benchmark() {
411409
test.controller_match_fn = controller_match_fn;
412410
test.transport = RackscaleTransport::Shmem;
413411
test.use_affinity_shmem = cfg!(feature = "affinity-shmem");
412+
test.use_qemu_huge_pages = cfg!(feature = "affinity-shmem");
414413
test.file_name = file_name.to_string();
415414
test.arg = Some(config);
416415
test.run_dhcpd_for_baseline = true;
@@ -440,9 +439,7 @@ fn s11_rackscale_shmem_leveldb_benchmark() {
440439
cmd_fn,
441440
baseline_timeout_fn,
442441
rackscale_timeout_fn,
443-
controller_mem_fn: mem_fn,
444-
client_mem_fn: mem_fn,
445-
baseline_mem_fn: mem_fn,
442+
mem_fn,
446443
};
447444

448445
if cfg!(feature = "baseline") {
@@ -601,6 +598,7 @@ fn rackscale_memcached_benchmark(transport: RackscaleTransport) {
601598
test.transport = transport;
602599
test.shmem_size *= 2;
603600
test.use_affinity_shmem = cfg!(feature = "affinity-shmem");
601+
test.use_qemu_huge_pages = cfg!(feature = "affinity-shmem");
604602
test.file_name = file_name.to_string();
605603
test.arg = Some(config);
606604
test.run_dhcpd_for_baseline = true;
@@ -630,9 +628,7 @@ fn rackscale_memcached_benchmark(transport: RackscaleTransport) {
630628
cmd_fn,
631629
baseline_timeout_fn,
632630
rackscale_timeout_fn,
633-
controller_mem_fn: mem_fn,
634-
client_mem_fn: mem_fn,
635-
baseline_mem_fn: mem_fn,
631+
mem_fn,
636632
};
637633

638634
if cfg!(feature = "baseline") {
@@ -682,6 +678,7 @@ fn rackscale_monetdb_benchmark(transport: RackscaleTransport) {
682678
test.controller_match_fn = controller_match_fn;
683679
test.transport = transport;
684680
test.use_affinity_shmem = cfg!(feature = "affinity-shmem");
681+
test.use_qemu_huge_pages = cfg!(feature = "affinity-shmem");
685682
test.file_name = file_name.to_string();
686683
test.arg = None;
687684
test.run_dhcpd_for_baseline = true;
@@ -710,9 +707,7 @@ fn rackscale_monetdb_benchmark(transport: RackscaleTransport) {
710707
cmd_fn,
711708
baseline_timeout_fn,
712709
rackscale_timeout_fn,
713-
controller_mem_fn: mem_fn,
714-
client_mem_fn: mem_fn,
715-
baseline_mem_fn: mem_fn,
710+
mem_fn,
716711
};
717712

718713
if cfg!(feature = "baseline") {

kernel/testutils/src/rackscale_runner.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,12 @@ where
5858
built: Built<'static>,
5959
/// Timeout for the controller process
6060
pub controller_timeout: u64,
61-
/// Amount of non-shmem QEMU memory given to the controller
62-
pub controller_memory: usize,
6361
/// Function that is called after the controller is spawned to match output of the controller process
6462
pub controller_match_fn: RackscaleMatchFn<T>,
6563
/// Timeout for each client process
6664
pub client_timeout: u64,
67-
/// Amount of non-shmem QEMU memory given to each client
68-
pub client_memory: usize,
65+
/// Amount of non-shmem QEMU memory given to each QEMU instance
66+
pub memory: usize,
6967
/// Function that is called after each client is spawned to match output of the client process
7068
pub client_match_fn: RackscaleMatchFn<T>,
7169
/// Number of client machines to spawn
@@ -90,6 +88,8 @@ where
9088
pub arg: Option<T>,
9189
/// Run DHCPD in baseline test
9290
pub run_dhcpd_for_baseline: bool,
91+
/// Huge huge pages for qemu memory. This requires pre-alloc'ing them on the host before running.
92+
pub use_qemu_huge_pages: bool,
9393
}
9494

9595
impl<T: Clone + Send + 'static> RackscaleRun<T> {
@@ -109,11 +109,10 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
109109

110110
RackscaleRun {
111111
controller_timeout: 60_000,
112-
controller_memory: 1024,
113112
controller_match_fn: blank_match_fn,
114113
client_timeout: 60_000,
115-
client_memory: 1024,
116114
client_match_fn: blank_match_fn,
115+
memory: 1024,
117116
kernel_test,
118117
built,
119118
num_clients: 1,
@@ -127,6 +126,7 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
127126
cmd: "".to_string(),
128127
arg: None,
129128
run_dhcpd_for_baseline: false,
129+
use_qemu_huge_pages: false,
130130
}
131131
}
132132

@@ -186,10 +186,11 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
186186
let controller_placement_cores = placement_cores.clone();
187187
let state = self.clone();
188188
let controller_tx_build_timer = tx_build_timer_mut.clone();
189+
let use_large_pages = self.use_qemu_huge_pages;
189190
let controller = std::thread::Builder::new()
190191
.name("Controller".to_string())
191192
.spawn(move || {
192-
let cmdline_controller =
193+
let mut cmdline_controller =
193194
RunnerArgs::new_with_build(&controller_kernel_test, &state.built)
194195
.timeout(state.controller_timeout)
195196
.transport(state.transport)
@@ -200,12 +201,16 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
200201
.no_network_setup()
201202
.workers(state.num_clients + 1)
202203
.use_vmxnet3()
203-
.memory(state.controller_memory)
204+
.memory(state.memory)
204205
.nodes(1)
205206
.cores(controller_cores)
206207
.node_offset(controller_placement_cores[0].0)
207208
.setaffinity(controller_placement_cores[0].1.clone());
208209

210+
if use_large_pages {
211+
cmdline_controller = cmdline_controller.large_pages().prealloc();
212+
}
213+
209214
let mut output = String::new();
210215
let qemu_run = || -> Result<WaitStatus> {
211216
let mut p = spawn_nrk(&cmdline_controller)?;
@@ -287,10 +292,11 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
287292
let client_placement_cores = placement_cores.clone();
288293
let state = self.clone();
289294
let client_tx_build_timer = tx_build_timer_mut.clone();
295+
let use_large_pages = self.use_qemu_huge_pages;
290296
let client = std::thread::Builder::new()
291297
.name(format!("Client{}", i + 1))
292298
.spawn(move || {
293-
let cmdline_client =
299+
let mut cmdline_client =
294300
RunnerArgs::new_with_build(&client_kernel_test, &state.built)
295301
.timeout(state.client_timeout)
296302
.transport(state.transport)
@@ -301,14 +307,18 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
301307
.no_network_setup()
302308
.workers(state.num_clients + 1)
303309
.cores(state.cores_per_client)
304-
.memory(state.client_memory)
310+
.memory(state.memory)
305311
.nobuild() // Use single build for all for consistency
306312
.use_vmxnet3()
307313
.cmd(&client_cmd)
308314
.nodes(1)
309315
.node_offset(client_placement_cores[i + 1].0)
310316
.setaffinity(client_placement_cores[i + 1].1.clone());
311317

318+
if use_large_pages {
319+
cmdline_client = cmdline_client.large_pages().prealloc();
320+
}
321+
312322
let mut output = String::new();
313323
let qemu_run = || -> Result<WaitStatus> {
314324
let mut p = spawn_nrk(&cmdline_client)?;
@@ -425,16 +435,20 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
425435
setup_network(self.num_clients + 1);
426436
}
427437

428-
let cmdline_baseline = RunnerArgs::new_with_build(&self.kernel_test, &self.built)
438+
let mut cmdline_baseline = RunnerArgs::new_with_build(&self.kernel_test, &self.built)
429439
.timeout(self.controller_timeout)
430-
.memory(self.controller_memory)
440+
.memory(self.memory)
431441
.workers(1)
432442
.cores(self.cores_per_client * self.num_clients)
433443
.cmd(&self.cmd)
434444
.no_network_setup()
435445
.nodes(self.num_clients)
436446
.setaffinity(all_placement_cores);
437447

448+
if self.use_qemu_huge_pages {
449+
cmdline_baseline = cmdline_baseline.large_pages().prealloc();
450+
}
451+
438452
let mut output = String::new();
439453
let mut qemu_run = || -> Result<WaitStatus> {
440454
let dhcpd_server = if self.run_dhcpd_for_baseline {
@@ -472,12 +486,8 @@ pub struct RackscaleBench<T: Clone + Send + 'static> {
472486
pub rackscale_timeout_fn: fn(usize) -> u64,
473487
// Function to calculate the timeout. Takes as argument number of application cores
474488
pub baseline_timeout_fn: fn(usize) -> u64,
475-
// Function to calculate controller (and baseline) memory. Takes as argument number of application cores and is_smoke
476-
pub controller_mem_fn: fn(usize, bool) -> usize,
477-
// Function to calculate client memory. Takes as argument number of application cores and is_smoke
478-
pub client_mem_fn: fn(usize, bool) -> usize,
479-
// Function to calculate baseline nros memory. Takes as argument number of application cores and is_smoke
480-
pub baseline_mem_fn: fn(usize, bool) -> usize,
489+
// Function to calculate memory (excpeting controller memory). Takes as argument number of application cores and is_smoke
490+
pub mem_fn: fn(usize, bool) -> usize,
481491
}
482492

483493
impl<T: Clone + Send + 'static> RackscaleBench<T> {
@@ -565,11 +575,11 @@ impl<T: Clone + Send + 'static> RackscaleBench<T> {
565575

566576
// Caclulate memory for each component
567577
if !is_baseline {
568-
test_run.controller_memory = (self.controller_mem_fn)(total_cores, is_smoke);
569-
test_run.client_memory = (self.client_mem_fn)(total_cores, is_smoke);
578+
test_run.memory = ((self.mem_fn)(total_cores, is_smoke) / test_run.num_clients)
579+
- test_run.shmem_size;
580+
assert!(test_run.memory > 0);
570581
} else {
571-
test_run.controller_memory = (self.baseline_mem_fn)(total_cores, is_smoke);
572-
test_run.client_memory = test_run.controller_memory;
582+
test_run.memory = (self.mem_fn)(total_cores, is_smoke);
573583
}
574584

575585
if is_baseline {

0 commit comments

Comments
 (0)