Skip to content

Commit 3748ffb

Browse files
Add 'benchmark' configuration
This patch adds a new configuration for each platform called 'benchmark'. The purpose of this is to enable Microkit systems to leverage the benchmark configuration of seL4 that tracks things like kernel entries and CPU utilisation. This also exports the PMU to user-space. This is not ideal, which is why [RFC-16](seL4/rfcs#22) exists. However, we need to be able to do benchmarking for projects like the seL4 Device Driver Framework in the meantime. It may take a while to get the RFC approved and implemented which is why we are adding this 'temporary' configuration. Signed-off-by: Ivan Velickovic <i.velickovic@unsw.edu.au>
1 parent b5eef17 commit 3748ffb

File tree

7 files changed

+88
-11
lines changed

7 files changed

+88
-11
lines changed

README.md

+2-8
Original file line numberDiff line numberDiff line change
@@ -185,18 +185,12 @@ The currently supported configurations are:
185185

186186
* release
187187
* debug
188+
* benchmark
188189

189190
## Supported Boards
190191

191192
For documentation on each supported board see the [manual](https://github.com/seL4/microkit/blob/main/docs/manual.md#board-support-packages-bsps).
192193

193194
## Supported Configurations
194195

195-
## Release
196-
197-
In release configuration the loader, kernel and monitor do *not* perform any direct serial output.
198-
199-
200-
## Debug
201-
202-
The debug configuration includes basic print output form the loader, kernel and monitor.
196+
For documentation on each supported board see the [manual](https://github.com/seL4/microkit/blob/main/docs/manual.md#configurations-config).

build_sdk.py

+9
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ class ConfigInfo:
187187
"KernelVerificationBuild": False
188188
}
189189
),
190+
ConfigInfo(
191+
name="benchmark",
192+
debug=False,
193+
kernel_options={
194+
"KernelArmExportPMUUser": True,
195+
"KernelDebugBuild": False,
196+
"KernelBenchmarks": "track_utilisation"
197+
},
198+
),
190199
)
191200

192201

docs/manual.md

+19-2
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,8 @@ handler via the `fault` entry point. It is then up to the parent to decide how t
313313
Microkit is distributed as a software development kit (SDK).
314314

315315
The SDK includes support for one or more *boards*.
316-
Two *configurations* are supported for each board: *debug* and *release*.
317-
The *debug* configuration includes a debug build of the seL4 kernel to allow console debug output using the kernel's UART driver.
316+
Three *configurations* are supported for each board: *debug*, *release*, and *benchmark*.
317+
See [the Configurations section](#config) for more details.
318318

319319
The SDK contains:
320320

@@ -337,6 +337,23 @@ The Microkit tool should be invoked by the system build process to transform a s
337337

338338
The ELF files provided as program images should be standard ELF files and have been linked against the provided libmicrokit.
339339

340+
## Configurations {#config}
341+
342+
## Debug
343+
344+
The *debug* configuration includes a debug build of the seL4 kernel to allow console debug output using the kernel's UART driver.
345+
346+
## Release
347+
348+
The *release* configuration is a release build of the seL4 kernel and is intended for production builds. The loader, monitor, and
349+
kernel do *not* perform any serial output.
350+
351+
## Benchmark
352+
353+
The *benchmark* configuration uses a build of the seL4 kernel that exports the hardware's performance monitoring unit (PMU) to PDs.
354+
The kernel also tracks information about CPU utilisation. This benchmark configuration exists due a limitation of the seL4 kernel
355+
and is intended to be removed once [RFC-16 is implemented](https://github.com/seL4/rfcs/pull/22).
356+
340357
## System Requirements
341358

342359
The Microkit tool requires Linux (x86-64), macOS (x86-64 or AArch64).

libmicrokit/include/microkit.h

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ typedef unsigned int microkit_child;
1616
typedef seL4_MessageInfo_t microkit_msginfo;
1717

1818
#define MONITOR_EP 5
19+
/* Only valid in the 'benchmark' configuration */
20+
#define TCB_CAP 6
1921
#define BASE_OUTPUT_NOTIFICATION_CAP 10
2022
#define BASE_ENDPOINT_CAP 74
2123
#define BASE_IRQ_CAP 138

tool/microkit/src/main.rs

+26
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const FAULT_EP_CAP_IDX: u64 = 2;
3333
const VSPACE_CAP_IDX: u64 = 3;
3434
const REPLY_CAP_IDX: u64 = 4;
3535
const MONITOR_EP_CAP_IDX: u64 = 5;
36+
const TCB_CAP_IDX: u64 = 6;
3637

3738
const BASE_OUTPUT_NOTIFICATION_CAP: u64 = 10;
3839
const BASE_OUTPUT_ENDPOINT_CAP: u64 = BASE_OUTPUT_NOTIFICATION_CAP + 64;
@@ -2058,6 +2059,30 @@ fn build_system(kernel_config: &Config,
20582059
}));
20592060
}
20602061

2062+
// In the benchmark configuration, we allow PDs to access their own TCB.
2063+
// This is necessary for accessing kernel's benchmark API.
2064+
if kernel_config.benchmark {
2065+
let mut tcb_cap_copy_invocation = Invocation::new(InvocationArgs::CnodeCopy {
2066+
cnode: cnode_objs[0].cap_addr,
2067+
dest_index: TCB_CAP_IDX,
2068+
dest_depth: PD_CAP_BITS,
2069+
src_root: root_cnode_cap,
2070+
src_obj: pd_tcb_objs[0].cap_addr,
2071+
src_depth: kernel_config.cap_address_bits,
2072+
rights: Rights::All as u64,
2073+
});
2074+
tcb_cap_copy_invocation.repeat(system.protection_domains.len() as u32, InvocationArgs::CnodeCopy {
2075+
cnode: 1,
2076+
dest_index: 0,
2077+
dest_depth: 0,
2078+
src_root: 0,
2079+
src_obj: 1,
2080+
src_depth: 0,
2081+
rights: 0,
2082+
});
2083+
system_invocations.push(tcb_cap_copy_invocation);
2084+
}
2085+
20612086
// Set VSpace and CSpace
20622087
let num_set_space_invocations = system.protection_domains.len() + virtual_machines.len();
20632088
let mut set_space_invocation = Invocation::new(InvocationArgs::TcbSetSpace {
@@ -2499,6 +2524,7 @@ fn main() -> Result<(), String> {
24992524
fan_out_limit: json_str_as_u64(&kernel_config_json, "RETYPE_FAN_OUT_LIMIT")?,
25002525
arm_pa_size_bits: 40,
25012526
hypervisor: json_str_as_bool(&kernel_config_json, "ARM_HYPERVISOR_SUPPORT")?,
2527+
benchmark: args.config == "benchmark",
25022528
};
25032529

25042530
match kernel_config.arch {

tool/microkit/src/sel4.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct Config {
4848
pub fan_out_limit: u64,
4949
pub hypervisor: bool,
5050
pub arm_pa_size_bits: usize,
51+
pub benchmark: bool,
5152
}
5253

5354
pub enum Arch {
@@ -584,6 +585,15 @@ impl Invocation {
584585
arg_strs.push(Invocation::fmt_field("attr", attr));
585586
(page, cap_lookup.get(&page).unwrap().as_str())
586587
}
588+
InvocationArgs::CnodeCopy { cnode, dest_index, dest_depth, src_root, src_obj, src_depth, rights } => {
589+
arg_strs.push(Invocation::fmt_field("dest_index", dest_index));
590+
arg_strs.push(Invocation::fmt_field("dest_depth", dest_depth));
591+
arg_strs.push(Invocation::fmt_field_cap("src_root", src_root, cap_lookup));
592+
arg_strs.push(Invocation::fmt_field_cap("src_obj", src_obj, cap_lookup));
593+
arg_strs.push(Invocation::fmt_field("src_depth", src_depth));
594+
arg_strs.push(Invocation::fmt_field("rights", rights));
595+
(cnode, cap_lookup.get(&cnode).unwrap().as_str())
596+
}
587597
InvocationArgs::CnodeMint { cnode, dest_index, dest_depth, src_root, src_obj, src_depth, rights, badge } => {
588598
arg_strs.push(Invocation::fmt_field("dest_index", dest_index));
589599
arg_strs.push(Invocation::fmt_field("dest_depth", dest_depth));
@@ -628,7 +638,8 @@ impl Invocation {
628638
InvocationLabel::IrqSetIrqHandler => "IRQ Handler",
629639
InvocationLabel::ArmPageTableMap => "Page Table",
630640
InvocationLabel::ArmPageMap => "Page",
631-
InvocationLabel::CnodeMint => "CNode",
641+
InvocationLabel::CnodeMint |
642+
InvocationLabel::CnodeCopy => "CNode",
632643
InvocationLabel::SchedControlConfigureFlags => "SchedControl",
633644
InvocationLabel::ArmVcpuSetTcb => "VCPU",
634645
_ => panic!("Internal error: unexpected label when getting object type '{:?}'", self.label)
@@ -649,6 +660,7 @@ impl Invocation {
649660
InvocationLabel::IrqSetIrqHandler => "SetNotification",
650661
InvocationLabel::ArmPageTableMap |
651662
InvocationLabel::ArmPageMap => "Map",
663+
InvocationLabel::CnodeCopy => "Copy",
652664
InvocationLabel::CnodeMint => "Mint",
653665
InvocationLabel::SchedControlConfigureFlags => "ConfigureFlags",
654666
InvocationLabel::ArmVcpuSetTcb => "VCPUSetTcb",
@@ -672,6 +684,7 @@ impl InvocationArgs {
672684
InvocationArgs::IrqHandlerSetNotification { .. } => InvocationLabel::IrqSetIrqHandler,
673685
InvocationArgs::PageTableMap { .. } => InvocationLabel::ArmPageTableMap,
674686
InvocationArgs::PageMap { .. } => InvocationLabel::ArmPageMap,
687+
InvocationArgs::CnodeCopy { .. } => InvocationLabel::CnodeCopy,
675688
InvocationArgs::CnodeMint { .. } => InvocationLabel::CnodeMint,
676689
InvocationArgs::SchedControlConfigureFlags { .. } => InvocationLabel::SchedControlConfigureFlags,
677690
InvocationArgs::ArmVcpuSetTcb { .. } => InvocationLabel::ArmVcpuSetTcb,
@@ -728,6 +741,12 @@ impl InvocationArgs {
728741
vec![vspace]
729742
),
730743
InvocationArgs::PageMap { page, vspace, vaddr, rights, attr } => (page, vec![vaddr, rights, attr], vec![vspace]),
744+
InvocationArgs::CnodeCopy { cnode, dest_index, dest_depth, src_root, src_obj, src_depth, rights } =>
745+
(
746+
cnode,
747+
vec![dest_index, dest_depth, src_obj, src_depth, rights],
748+
vec![src_root]
749+
),
731750
InvocationArgs::CnodeMint { cnode, dest_index, dest_depth, src_root, src_obj, src_depth, rights, badge } =>
732751
(
733752
cnode,
@@ -822,6 +841,15 @@ pub enum InvocationArgs {
822841
rights: u64,
823842
attr: u64,
824843
},
844+
CnodeCopy {
845+
cnode: u64,
846+
dest_index: u64,
847+
dest_depth: u64,
848+
src_root: u64,
849+
src_obj: u64,
850+
src_depth: u64,
851+
rights: u64,
852+
},
825853
CnodeMint {
826854
cnode: u64,
827855
dest_index: u64,

tool/microkit/tests/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const DEFAULT_KERNEL_CONFIG: sel4::Config = sel4::Config {
1717
fan_out_limit: 256,
1818
hypervisor: true,
1919
arm_pa_size_bits: 40,
20+
benchmark: false,
2021
};
2122

2223
const DEFAULT_PLAT_DESC: sysxml::PlatformDescription = sysxml::PlatformDescription::new(&DEFAULT_KERNEL_CONFIG);

0 commit comments

Comments
 (0)