Skip to content

Commit 1721f18

Browse files
committed
gem5: track build and run variants separately with -M and -N
Otherwise, checking out branches is too insane, as it does not update the worktrees, even though the gem5/gem5 module was updated. gem5: expose build types, document debug builds. simultaneous runs: store stdout and stderr on a file to allow running all from a single terminal on the background cleanly.
1 parent 71e927e commit 1721f18

File tree

10 files changed

+122
-34
lines changed

10 files changed

+122
-34
lines changed

README.adoc

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,8 +1154,8 @@ The default run id is `0`.
11541154
This method also allows us to keep run outputs in separate directories for later inspection, e.g.:
11551155

11561156
....
1157-
./run -aA -g -n 0
1158-
./run -aA -g -n 1
1157+
./run -aA -g -n 0 &>/dev/null &
1158+
./run -aA -g -n 1 &>/dev/null &
11591159
....
11601160

11611161
produces two separate `m5out` directories:
@@ -1165,6 +1165,13 @@ less out/aarch64/gem5/default/0/m5out
11651165
less out/aarch64/gem5/default/1/m5out
11661166
....
11671167

1168+
and the gem5 host executable stdout and stderr can be found at:
1169+
1170+
....
1171+
less out/aarch64/gem5/default/0/termout.txt
1172+
less out/aarch64/gem5/default/1/termout.txt
1173+
....
1174+
11681175
You can also add a prefix to the build ID before a period:
11691176

11701177
....
@@ -1194,6 +1201,8 @@ Like <<cpu-architecture>>, you will need to pass the `-n` option to anything tha
11941201
./rungdb -n 1
11951202
....
11961203

1204+
To run multiple gem5 checkouts, see: <<gem5-simultaneous-runs-with-build-variants>>.
1205+
11971206
Implementation note: we create multiple namespaces for two things:
11981207

11991208
* run output directory
@@ -5108,7 +5117,7 @@ gem5 full system:
51085117

51095118
....
51105119
printf 'm5 exit' > data/readfile
5111-
./run -aa -g -F 'm5 checkpoint;m5 readfile > a.sh;sh a.sh'
5120+
./run -aa -g -F '/gem5.sh'
51125121
printf 'm5 resetstats;dhrystone 100000;m5 exit' > data/readfile
51135122
time ./run -aa -gu -- -r 1
51145123
....
@@ -5517,7 +5526,7 @@ arch=aarch64
55175526
# Generate a checkpoint after Linux boots.
55185527
# The boot takes a while, be patient young Padawan.
55195528
printf 'm5 exit' > data/readfile
5520-
./run -a "$arch" -g -F '/5 checkpoint;m5 readfile > a.sh;sh a.sh'
5529+
./run -a "$arch" -g -F '/gem5.sh'
55215530
55225531
# Restore the checkpoint, and run the benchmark with parameter 1.000.
55235532
# We skip the boot completely, saving time!
@@ -6172,7 +6181,7 @@ This integer value is just pure `fs.py` sugar, the backend at `m5.instantiate` j
61726181

61736182
You want to automate running several tests from a single pristine post-boot state.
61746183

6175-
The problem is that after the checkpoint, the memory and disk states are fixed, so you can't for example:
6184+
The problem is that boot takes forever, and after the checkpoint, the memory and disk states are fixed, so you can't for example:
61766185

61776186
* hack up an existing rc script, since the disk is fixed
61786187
* inject new kernel boot command line options, since those have already been put into memory by the bootloader
@@ -6188,10 +6197,12 @@ printf 'echo "second benchmark";m5 exit' > data/readfile
61886197
./run -a aarch64 -g -- -r 1
61896198
....
61906199

6191-
Other possibilities include:
6200+
Since this is such a common setup, we provide helper for it at: link:rootfs_overlay/gem5.sh[rootfs_overlay/gem5.sh].
6201+
6202+
Other loophole possibilities include:
61926203

61936204
* <<9p>>
6194-
* create multiple disk images, and mount the benchmark one
6205+
* link:https://stackoverflow.com/questions/50862906/how-to-attach-multiple-disk-images-in-a-simulation-with-gem5-fs-py/51037661#51037661[create multiple disk images], and mount the benchmark from on one of them
61956206
* `expect` as mentioned at: https://stackoverflow.com/questions/7013137/automating-telnet-session-using-bash-scripts
61966207
+
61976208
....
@@ -6798,28 +6809,69 @@ Analogous to the <<linux-kernel-build-variants>> but with the `-M` option instea
67986809
....
67996810
./build -g
68006811
git -C gem5/gem5 checkout some-branch
6801-
./build -M some-branch -g
6812+
./build -g -M some-branch
68026813
git -C gem5/gem5 checkout -
68036814
./run -g
6815+
git -C gem5/gem5 checkout some-branch
68046816
./run -M some-branch -g
68056817
....
68066818

6807-
Since we control the gem5 build however, unlike Linux which uses Buildroot, we make it awesomer, and use `git worktree` instead of a mere `rsync` for the copy.
6819+
Don't forget however that gem5 has Python scripts in its source code tree, and that those must match the source code of a given build.
68086820

6809-
It works like this:
6821+
Therefore, you can't forget to checkout to the sources to that of the corresponding build before running, unless you explicitly tell gem5 to use a non-default source tree with `-N`.
68106822

6811-
* when you don't pass the `-M` option, which is the same as the `-M default` variant, we use the source code from under the `gem5/gem5` submodule for the build
6812-
* otherwise, if you pass `-M some-branch`, we generate a git worktree checkout under `data/gem5/some-branch`, with branch name `wt/some-branch`.
6813-
+
6814-
The initial revision for that worktree is whatever `gem5/gem5` is currently points to.
6815-
+
6816-
However, if the worktree already exists, we leave it untouched.
6817-
+
6818-
Therefore, you can safely go to that directory and edit the source there without fear that it will get deleted.
6823+
This becomes inevitable when you want to launch <<gem5-simultaneous-runs-with-build-variants>>.
6824+
6825+
===== gem5 simultaneous runs with build variants
6826+
6827+
In order to checkout multiple gem5 builds and run them simultaneously, you also need to use the `-N`:
6828+
6829+
....
6830+
./build -g
6831+
git -C gem5/gem5 checkout some-branch
6832+
./build -g -M some-branch -N some-branch
6833+
git -C gem5/gem5 checkout -
6834+
./run -g -n 0 &>/dev/null &
6835+
./run -g -M some-branch -N some-branch -n 1 &>/dev/null &
6836+
....
6837+
6838+
The `-N <woktree-id>` determines the location of the gem5 tree to be used for both:
6839+
6840+
* the input C files of the build at build time
6841+
* the Python scripts to be used at runtime
6842+
6843+
The difference between `-M` and `-N` is that `-M` specifies the gem5 build output directory, while `-N` specifies the source input directory.
6844+
6845+
When `-N` is not given, source tree under `gem5/gem5` is used.
6846+
6847+
If `-N <worktree-id>` is given, the directory used is `data/gem5/<worktree-id>`, and:
6848+
6849+
* if that directory does not exist, create a `git worktree` at a branch `wt/<worktree-id>` on current commit of `gem5/gem5` there.
68196850
+
6820-
The `wt/` branch name prefix stands for `WorkTree`, and is done to allow us to checkout to a test `some-branch` branch under `gem5/gem5` and still use `-M some-branch`, without aconflict for the worktree branch.
6851+
The `wt/` branch name prefix stands for `WorkTree`, and is done to allow us to checkout to a test `some-branch` branch under `gem5/gem5` and still use `-N some-branch`, without conflict for the worktree branch, which can only be checked out once.
6852+
* otherwise, leave that worktree untouched, without updating it
6853+
6854+
`-N` is only required if you have multiple gem5 checkouts, e.g. it would not be required for multiple builds of the same tree, e.g. a <<gem5-debug-build>> and a non-debug one.
6855+
6856+
===== gem5 debug build
6857+
6858+
Built and run `gem5.debug`, which has optimizations turned off unlike the default `gem5.opt`:
6859+
6860+
....
6861+
./build -aA -g -M debug -t debug
6862+
./run -aA -g -M debug -t debug
6863+
....
6864+
6865+
`-M` is optional just to prevent it from overwriting the `opt` build.
6866+
6867+
A Linux kernel boot was about 14 times slower than opt at 71e927e63bda6507d5a528f22c78d65099bdf36f between the commands:
6868+
6869+
....
6870+
./run -aA -E 'm5 exit' -g -L v4.16
6871+
./run -aA -E 'm5 exit' -g -M debug -t debug -L v4.16
6872+
....
68216873

6822-
All build outputs end up at: `out/common/gem5/<variant>` regardless.
6874+
Therefore the performance different is very big, making debug mode almost unusable.
68236875

68246876
==== Generic package build variants
68256877

build

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ post_script_args=
2121
qemu_sdl='--enable-sdl --with-sdlabi=2.0'
2222
suffix=
2323
v=0
24-
while getopts 'a:B:b:C:c:fGgj:hIiK:kL:lM:p:qSs:v' OPT; do
24+
while getopts 'a:B:b:C:c:fGgj:hIiK:kL:lM:p:qSst::v' OPT; do
2525
case "$OPT" in
2626
a)
2727
arch="$OPTARG"
@@ -98,6 +98,9 @@ BR2_TARGET_ROOTFS_INITRAMFS=n
9898
s)
9999
suffix="$OPTARG"
100100
;;
101+
t)
102+
common_gem5_build_type="$OPTARG"
103+
;;
101104
v)
102105
v=1
103106
;;
@@ -220,8 +223,9 @@ env \\
220223
make \\
221224
O='${buildroot_out_dir}' \\
222225
HOST_QEMU_OPTS='--enable-debug --enable-trace-backends=simple ${qemu_sdl}' \\
223-
GEM5_LKMC_SRCDIR="$common_gem5_src_dir" \\
226+
GEM5_LKMC_GEM5_BUILD_TYPE="$common_gem5_build_type" \\
224227
GEM5_LKMC_OUTDIR="$common_gem5_out_dir" \\
228+
GEM5_LKMC_SRCDIR="$common_gem5_src_dir" \\
225229
V='${v}' \\
226230
${extra_make_args} \
227231
all \\

build-usage.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@
2626
Mnemonic: `fast`.
2727
|`-g` | |Enable gem5 build or force its rebuild.
2828
|`-h` | |Show this help message.
29-
|`-L` | |Linux kernel build variant.
29+
|`-L` |`VARIANT` |Linux kernel build variant.
3030
|`-I` | |Enable initramfs for the current build.
3131
|`-i` | |Enable initrd for the current build.
3232
|`-K` |`KERNEL_CONFIG_FILE` |Use `KERNEL_CONFIG_FILE` as the exact Linux kernel
3333
configuration. Ignore the default kernel config fragments,
3434
but still add options explicitly passed with `-C` and `-c`.
3535
on top of it.
36+
|`-M` |`VARIANT` |gem5 build variant.
3637
|`-p` | |Pass extra arguments to the `rootfs_post_build_script`.
3738
|`-S` | |Don't build QEMU with SDL support.
3839
Graphics such as X11 won't work, only the terminal.

common

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,28 @@ set_common_vars() {
6969
common_images_dir="${buildroot_out_dir}/images"
7070
host_dir="${buildroot_out_dir}/host"
7171
common_qemu_run_dir="${out_arch_dir}/qemu/${common_run_id}"
72+
common_qemu_termout_file="${common_qemu_run_dir}/termout.txt"
7273
common_linux_custom_dir="${build_dir}/linux-custom"
7374
common_linux_variant_dir="${common_linux_custom_dir}.${linux_variant}"
7475
common_vmlinux="${common_linux_variant_dir}/vmlinux"
75-
if [ "$gem5_variant" = default ]; then
76-
common_gem5_src_dir="${root_dir}/gem5/gem5"
76+
if [ -n "$common_gem5_worktree" ]; then
77+
common_gem5_src_dir="${common_gem5_non_default_src_root_dir}/${common_gem5_worktree}"
7778
else
78-
common_gem5_src_dir="${common_gem5_non_default_src_root_dir}/${gem5_variant}"
79+
common_gem5_src_dir="${root_dir}/gem5/gem5"
7980
fi
8081
common_gem5_out_dir="${common_dir}/gem5/${gem5_variant}"
8182
common_gem5_m5term="${common_gem5_out_dir}/m5term"
8283
common_gem5_build_dir="${common_gem5_out_dir}/build"
8384
common_gem5_system_dir="${common_gem5_out_dir}/system"
8485
common_gem5_run_dir="${out_arch_dir}/gem5/${gem5_variant}/${common_run_id}"
86+
common_gem5_termout_file="${common_gem5_run_dir}/termout.txt"
8587
common_m5out_dir="${common_gem5_run_dir}/m5out"
8688
if "$gem5"; then
8789
common_run_dir="$common_gem5_run_dir"
90+
common_termout_file="$common_gem5_termout_file"
8891
else
8992
common_run_dir="$common_qemu_run_dir"
93+
common_termout_file="$common_qemu_termout_file"
9094
fi
9195
common_trace_txt_file="${common_m5out_dir}/trace.txt"
9296
case "$arch" in
@@ -136,8 +140,10 @@ data_dir="${root_dir}/data"
136140
p9_dir="${data_dir}/9p"
137141
readfile_file="${data_dir}/readfile"
138142
common_dir="${out_dir}/common"
143+
common_gem5_build_type=opt
139144
common_gem5_default_src_dir="${root_dir}/gem5/gem5"
140145
common_gem5_non_default_src_root_dir="${data_dir}/gem5"
146+
common_gem5_worktree=
141147
common_gem5_variant=default
142148
common_run_id=0
143149
f="${data_dir}/cli"

gem5-bench-cache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ if "$generate_checkpoints"; then
6868
# Create the checkpoints after the kernel boot.
6969
rm -rf "${common_m5out_dir}"/cpt.*;
7070
printf 'm5 exit' > "${readfile_file}"
71-
cpt_cmd="-E 'm5 checkpoint;m5 readfile > a.sh;sh a.sh'"
71+
cpt_cmd="-E '/gem5.sh'"
7272
# 1
7373
./eeval "$cmd $cpt_cmd"
7474
# RESTORE_INVESTIGATION

gem5/build

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#!/usr/bin/env bash
22
set -eux
33
arch=x86_64
4+
build_type=opt
45
cross_compile=
56
j=
67
outdir="$(pwd)"
7-
while getopts a:c:j:o: OPT; do
8+
while getopts a:c:j:o:t: OPT; do
89
case "$OPT" in
910
a)
1011
arch="$OPTARG"
@@ -18,6 +19,12 @@ while getopts a:c:j:o: OPT; do
1819
o)
1920
outdir="$OPTARG"
2021
;;
22+
t)
23+
build_type="$OPTARG"
24+
;;
25+
?)
26+
exit 2
27+
;;
2128
esac
2229
done
2330
shift "$(($OPTIND - 1))"
@@ -30,15 +37,15 @@ disks_dir="${system_dir}/disks"
3037
mkdir -p "$binaries_dir" "$disks_dir"
3138
export PATH="/usr/lib/ccache:${PATH}"
3239
if [ "$arch" = x86_64 ]; then
33-
scons -j "$j" --ignore-style "${outdir}/build/X86/gem5.opt"
40+
scons -j "$j" --ignore-style "${outdir}/build/X86/gem5.${build_type}"
3441
f="${disks_dir}/linux-bigswap2.img"
3542
dd if=/dev/zero of="$f" bs=1024 count=65536
3643
mkswap "$f"
3744
# This file must always be present, despite --kernel overriding that default and selecting the kernel.
3845
# I'm not even joking. No one has ever built x86 gem5 without the magic dist dir present.
3946
touch "${binaries_dir}/x86_64-vmlinux-2.6.22.9"
4047
elif [ "$arch" = arm ] || [ "$arch" = aarch64 ]; then
41-
scons -j "$j" --ignore-style "${outdir}/build/ARM/gem5.opt"
48+
scons -j "$j" --ignore-style "${outdir}/build/ARM/gem5.${build_type}"
4249
make -C ./system/arm/dt/
4350
mkdir -p "${system_dir}/arm/dt"
4451
# || true in case they are the same directory.

gem5/external.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ endif
1616

1717
define GEM5_BUILD_CMDS
1818
# TODO cannot pass "-c '$(TARGET_CROSS)'" here because the ARM build uses aarch64 for the bootloader...
19-
cd '$(GEM5_LKMC_SRCDIR)' && '$(GEM5_SITE)/build' -a '$(ARCH)' -j '$(BR2_JLEVEL)' -o '$(GEM5_LKMC_OUTDIR)'
19+
cd '$(GEM5_LKMC_SRCDIR)' && '$(GEM5_SITE)/build' -a '$(ARCH)' -j '$(BR2_JLEVEL)' -o '$(GEM5_LKMC_OUTDIR)' -t '$(GEM5_LKMC_GEM5_BUILD_TYPE)'
2020

2121
# TODO cannot use TARGET_CONFIGURE_OPTS here because it overrides the CFLAGS on m5,
2222
# which have an include. We should patch gem5 to add a += instead of = there.

rootfs_overlay/gem5.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
m5 checkpoint
3+
script=/tmp/readfile
4+
m5 readfile > "$script"
5+
if [ -s "$script" ]; then
6+
sh "$script"
7+
fi

run

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ trace_enabled=false
3636
# just to prevent QEMU from emitting a warning that '' is not valid.
3737
trace_type=pr_manager_run
3838
vnc=
39-
while getopts a:c:DdE:e:F:f:G:ghIiKkL:M:m:n:PT:U:uVX:x OPT; do
39+
while getopts a:c:DdE:e:F:f:G:ghIiKkL:M:m:N:n:PT:t:U:uVX:x OPT; do
4040
case "$OPT" in
4141
a)
4242
arch="$OPTARG"
@@ -100,6 +100,9 @@ while getopts a:c:DdE:e:F:f:G:ghIiKkL:M:m:n:PT:U:uVX:x OPT; do
100100
m)
101101
memory="$OPTARG"
102102
;;
103+
N)
104+
common_gem5_worktree="$OPTARG"
105+
;;
103106
n)
104107
common_run_id="$OPTARG"
105108
;;
@@ -110,6 +113,9 @@ while getopts a:c:DdE:e:F:f:G:ghIiKkL:M:m:n:PT:U:uVX:x OPT; do
110113
trace_enabled=true
111114
trace_type="$OPTARG"
112115
;;
116+
t)
117+
common_gem5_build_type="$OPTARG"
118+
;;
113119
U)
114120
tmux_args="$OPTARG"
115121
;;
@@ -188,7 +194,7 @@ if "$gem5"; then
188194
gem5_common="\
189195
M5_PATH='${common_gem5_system_dir}' \\
190196
${debug_vm} \
191-
'${common_gem5_build_dir}/${gem5_arch}/gem5.opt' \\
197+
'${common_gem5_build_dir}/${gem5_arch}/gem5.${common_gem5_build_type}' \\
192198
--debug-file=trace.txt \\
193199
${gem5opts} \
194200
-d '${common_m5out_dir}' \\
@@ -356,4 +362,7 @@ if "$tmux"; then
356362
eval "./tmu ./rungdb -a '${arch} -L ${common_linux_variant}' -n ${common_run_id} ${tmux_args}"
357363
fi
358364
fi
365+
cmd="${cmd} \\
366+
|& tee ${common_termout_file} \
367+
"
359368
"${root_dir}/eeval" "$cmd" "${common_run_dir}/run.sh"

run-usage.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@
3636
|`-i` | |Run with initrd.
3737
|`-K` | |Use KVM. Only works if guest arch == host arch.
3838
|`-k` | |Enable KGDB.
39-
|`-L` | |Linux kernel build variant.
39+
|`-L` |`VARIANT` |Linux kernel build variant.
40+
|`-M` |`VARIANT` |gem5 build output variant.
4041
|`-m` | |Set the memory size of the guest. E.g.: `-m 512M`. Default: `256M`.
4142
The default is the minimum amount that boots all archs without extra
4243
options added. Anything lower will lead some arch to fail to boot.
4344
Any
45+
|`-N` |`VARIANT` |gem5 source input variant.
4446
|`-n` | |Run ID.
4547
|`-P` | |Run the downloaded prebuilt images.
4648
|`-T` |`TRACE_TYPES` |Set trace events to be enabled.

0 commit comments

Comments
 (0)