#!/usr/bin/env python3 import common import lkmc.import_path import thread_pool import shell_helpers from shell_helpers import LF class Main(common.TestCliFunction): def __init__(self): super().__init__( description='''\ Test and benchmark the Linux kernel boot. Use inits that exit immediately. ''' ) self.add_argument( '--size', default=1, type=int, help='''\ See ./test --help for --size. ''' ) def _bench(self, **run_args): run_obj = lkmc.import_path.import_path_main('run') words = [] test_id_args = run_args.copy() del test_id_args['run_id'] for line in run_obj.get_cli(**test_id_args): words.extend(line) test_id = shell_helpers.ShellHelpers().cmd_to_string(words, force_oneline=True) return self.run_test(run_obj, run_args, test_id) def setup(self, env): self.my_thread_pool = thread_pool.ThreadPool( self._bench, handle_output=self.handle_output_function, nthreads=env['nproc'], thread_id_arg='run_id', submit_skip_exit=env['quit_on_fail'], ) def timed_main(self): # TODO bring this benchmark code back to life. Likely should go inside run with an option #gem5_insts() ( # printf "instructions $(./gem5-stat --arch "$1" sim_insts)\n" >> "$self.env['test_boot_benchmark_file']" # newline #) # #qemu_insts() ( # common_arch="$1" # ./qemu-trace2txt --arch "$common_arch" # common_qemu_trace_txt_file="$("$getvar" --arch "$common_arch" qemu_trace_txt_file)" # printf "instructions $(wc -l "${common_qemu_trace_txt_file}" | cut -d' ' -f1)\n" >> "$self.env['test_boot_benchmark_file']" # newline #) # #rm -f "${self.env['test_boot_benchmark_file']}" common_args = self.get_common_args() common_args['ctrl_c_host'] = True common_args['quit_after_boot'] = True # To see it blow up during development. # self.common_args['eval'] = 'insmod /lkmc/panic.ko' if (self.env['emulator'] == 'qemu' or (self.env['emulator'] == 'gem5' and self.env['size'] >= 2)): self.my_thread_pool.submit(common_args) if self.env['host_arch'] == self.env['arch']: # TODO: find out why it fails. if self.env['emulator'] != 'gem5': self.my_thread_pool.submit({**common_args, **{'kvm': True}}) if self.env['emulator'] == 'qemu' and self.env['size'] >= 2: self.my_thread_pool.submit({**common_args, **{'trace': 'exec_tb'}}) if self.env['emulator'] == 'gem5' and self.env['size'] >= 3: if self.env['arch'] == 'x86_64': cpu_types = [ # TODO segfault #'DerivO3CPU' ] elif self.env['is_arm']: cpu_types = [ 'DerivO3CPU', 'HPI', ] for cpu_type in cpu_types: self.my_thread_pool.submit({**common_args, **{ 'extra_emulator_args': [ '--cpu-type', cpu_type, LF, '--caches', LF, '--l2cache', LF, '--l1d_size', '1024kB', LF, '--l1i_size', '1024kB', LF, '--l2_size', '1024kB', LF, '--l3_size', '1024kB', LF, ], }}) if self.env['arch'] == 'aarch64': # Do a fuller testing for aarch64. for build_type in ['debug', 'fast']: self.my_thread_pool.submit({**common_args, **{'gem5_build_type': build_type}}) # Requires patching the executable. # self.my_thread_pool.submit({{**common_args, 'gem5_script': 'biglittle'}}) def teardown(self): self.my_thread_pool.join() self._handle_thread_pool_errors(self.my_thread_pool) return super().teardown() if __name__ == '__main__': Main().cli()