4.6 KiB
Count boot instructions
- https://www.quora.com/How-many-instructions-does-a-typical-Linux-kernel-boot-take
- https://github.com/cirosantilli/chat/issues/31
- https://rwmj.wordpress.com/2016/03/17/tracing-qemu-guest-execution/
qemu/docs/tracing.txtandqemu/docs/replay.txt- https://stackoverflow.com/questions/39149446/how-to-use-qemus-simple-trace-backend/46497873#46497873
Best attempt so far:
time ./run -n -e 'init=/poweroff.out' -- -trace exec_tb,file=trace && \
time ./qemu/scripts/simpletrace.py qemu/trace-events trace >trace.txt && \
wc -l trace.txt && \
sed '/0x1000000/q' trace.txt >trace-boot.txt && \
wc -l trace-boot.txt
Notes:
-
-nis a good idea to reduce the chances that you send unwanted non-deterministic mouse or keyboard clicks to the VM. -
-e 'init=/poweroff.out'is crucial as it reduces the instruction count from 40 million to 20 million, so half of the instructions were due to userland programs instead of the boot sequence.Without it, the bulk of the time seems to be spent in setting up the network with
ifupthat gets called from/etc/init.d/S40networkfrom the default Buildroot BusyBox setup.And it becomes even worse if you try to
-net noneas recommended in the 2.7replay.txtdocs, because thenifupwaits for 15 seconds before giving up as per/etc/network/interfaceslinewait-delay 15. -
0x1000000is the address where QEMU puts the Linux kernel at with-kernelin x86.It can be found from:
readelf -e buildroot/output.x86_64~/build/linux-*/vmlinux | grep EntryTODO confirm further. If I try to break there with:
./rungdb *0x1000000but I have no corresponding source line. Also note that this line is not actually the first line, since the kernel messages such as
early console in extract_kernelhave already shown on screen at that point. This does not break at all:./rungdb extract_kernelIt only appears once on every log I've seen so far, checked with
grep 0x1000000 trace.txtThen when we count the instructions that run before the kernel entry point, there is only about 100k instructions, which is insignificant compared to the kernel boot itself.
-
We can also discount the instructions after
initruns by usingreadelfto get the initial address ofinit. One easy way to do that now is to just run:./rungdb-user kernel_module-1.0/user/poweroff.out mainAnd get that from the traces, e.g. if the address is
4003a0, then we search:grep -n 4003a0 trace.txtI have observed a single match for that instruction, so it must be the init, and there were only 20k instructions after it, so the impact is negligible.
This works because we have already done the following with QEMU:
-
./configure --enable-trace-backends=simple. This logs in a binary format to the trace file.It makes 3x execution faster than the default trace backend which logs human readable data to stdout.
This also alters the actual execution, and reduces the instruction count by 10M TODO understand exactly why, possibly due to the
All QSes seenthing. -
the simple QEMU patch mentioned at: https://rwmj.wordpress.com/2016/03/17/tracing-qemu-guest-execution/ of removing the
disablefromexec_tbin thetrace-eventstemplate file in the QEMU source
Possible improvements:
-
to disable networking. Is replacing
initenough?- https://superuser.com/questions/181254/how-do-you-boot-linux-with-networking-disabled
- https://superuser.com/questions/684005/how-does-one-permanently-disable-gnu-linux-networking/1255015#1255015
CONFIG_NET=ndid not significantly reduce instruction, so maybe replacinginitis enough. -
logging with the default backend
loggreatly slows down the CPU, and in particular leads to this during kernel boot:All QSes seen, last rcu_sched kthread activity 5252 (4294901421-4294896169), jiffies_till_next_fqs=1, root ->qsmask 0x0 swapper/0 R running task 0 1 0 0x00000008 ffff880007c03ef8 ffffffff8107aa5d ffff880007c16b40 ffffffff81a3b100 ffff880007c03f60 ffffffff810a41d1 0000000000000000 0000000007c03f20 fffffffffffffedc 0000000000000004 fffffffffffffedc ffffffff00000000 Call Trace: <IRQ> [<ffffffff8107aa5d>] sched_show_task+0xcd/0x130 [<ffffffff810a41d1>] rcu_check_callbacks+0x871/0x880 [<ffffffff810a799f>] update_process_times+0x2f/0x60in which the boot appears to hang for a considerable time.
-
Confirm that the kernel enters at
0x1000000, or where it enters. Once we have this, we can exclude what comes before in the BIOS.