diff --git a/repos/os/run/ahci.run b/repos/os/run/ahci.run deleted file mode 100644 index c30925e6c2..0000000000 --- a/repos/os/run/ahci.run +++ /dev/null @@ -1,141 +0,0 @@ -if {![have_spec x86] && ![have_spec platform_arndale]} { - puts "\nThe AHCI driver supports x86 architecture and Arndale only\n" - exit 0 -} - -# -# Build -# - -set build_components { core init drivers/timer drivers/ahci test/blk/cli } - -lappend_if [have_spec acpi] build_components drivers/acpi -lappend_if [have_spec pci] build_components drivers/pci -lappend_if [have_spec pci] build_components drivers/pci/device_pd -lappend_if [have_spec platform_arndale] build_components drivers/platform - -build $build_components - -create_boot_directory - -# -# Generate config -# - -set config { - - - - - - - - - - - - - - - - - } - -append_if [have_spec platform_arndale] config { - - - - } - -append_if [have_spec acpi] config { - - - - - - - - - - - - } - -append_if [expr ![have_spec acpi] && [have_spec pci]] config { - - - - } - -append config { - - - - } - -append_if [have_spec acpi] config { - } - -append config { - - - - - - - - } - -append_if [have_spec acpi] config { - } - -append config { - - - - - - - - - - -} - -install_config $config - -# -# Boot modules -# - -set boot_modules { core init timer ahci test-blk-cli } - -lappend_if [have_spec pci] boot_modules pci_drv -lappend_if [have_spec acpi] boot_modules acpi_drv -lappend_if [have_spec nova] boot_modules pci_device_pd -lappend_if [have_spec platform_arndale] boot_modules platform_drv - -build_boot_image $boot_modules - -# -# Qemu -# - -set disk_image "bin/block.img" - -append qemu_args " -m 64 -nographic " -append qemu_args " -drive id=disk,file=$disk_image,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -boot d" - -if { [file exists $disk_image] == 0 } then { - # create random block device file - puts "creating disk image \"$disk_image\"" - catch { - exec dd if=/dev/urandom of=$disk_image bs=512 count=20480 - } -} - -# -# Test -# - -run_genode_until "Tests finished successfully.*\n" 50 diff --git a/repos/os/run/ahci_bench.run b/repos/os/run/ahci_bench.run index cc67e7ba8a..5f2fd5b840 100644 --- a/repos/os/run/ahci_bench.run +++ b/repos/os/run/ahci_bench.run @@ -1,18 +1,6 @@ -# -# Select benchmark layer -# -# 0: driver internal -# 1: native Genode app -# 2: native Genode app with partition manager -# -set layer 0 - -# driver-internal benchmark is special -if {[expr ($layer == 0)] && ![have_spec platform_arndale]} { - puts "Driver-internal benchmark (layer 0) only supported on Arndale." - exit 0 -} +set mke2fs [check_installed mke2fs] +set dd [check_installed dd] # # Build @@ -22,24 +10,24 @@ set build_components { drivers/timer drivers/ahci drivers/platform + test/blk/bench } -lappend_if [expr ($layer == 1 || $layer == 2)] build_components test/block_bench -lappend_if [expr ($layer == 2)] build_components server/part_blk - lappend_if [have_spec acpi] build_components drivers/acpi -lappend_if [have_spec pci] build_components drivers/pci/device_pd lappend_if [have_spec pci] build_components drivers/pci build $build_components +# +# Build EXT2-file-system image +# +catch { exec $dd if=/dev/zero of=bin/ext2.raw bs=1M count=16 } +catch { exec $mke2fs -F bin/ext2.raw } create_boot_directory # -# Config +# Generate config # - -# basic config for all layers set config { @@ -56,13 +44,13 @@ set config { - + - } - + +} append_if [expr ![have_spec acpi] && ![have_spec pci]] config { @@ -71,75 +59,56 @@ append_if [expr ![have_spec acpi] && ![have_spec pci]] config { append_if [have_spec acpi] config { - + - - } + + + + + +} append_if [expr ![have_spec acpi] && [have_spec pci]] config { - } - -# start driver internal bench with layer 0 -append_if [expr $layer == 0] config { - - - - } - -# start part_blk with layer 2 -append_if [expr $layer == 2] config { - - - - - - - - + } -# start normal AHCI driver and bench app with layer 1 or 2 -append_if [expr ($layer == 1 || $layer == 2)] config { - - - } - -append_if [expr ($layer == 1 || $layer == 2) && [have_spec acpi]] config { - - - - } - -append_if [expr ($layer == 1 || $layer == 2)] config { - - - } - -# if layer is 2 route block requests of bench app to part_blk -append_if [expr $layer == 2] config { - - - - } - -# end start node of bench app if layer 1 or 2 -append_if [expr ($layer == 1 || $layer == 2)] config { - } - -# end config append config { + + + + + + + + + + + + + + + + + + + + + + + + } install_config $config @@ -147,20 +116,18 @@ install_config $config # # Boot modules # - -set boot_modules { core init timer } +set boot_modules { core init timer ahci_drv test-blk-bench libc.lib.so + ld.lib.so } lappend_if [expr ![have_spec acpi] && ![have_spec pci]] boot_modules platform_drv lappend_if [have_spec pci] boot_modules pci_drv -lappend_if [have_spec pci] boot_modules pci_device_pd +lappend_if [have_spec nova] boot_modules pci_device_pd lappend_if [have_spec acpi] boot_modules acpi_drv -lappend_if [expr ($layer == 0)] boot_modules ahci_bench -lappend_if [expr ($layer == 1 || $layer == 2)] boot_modules ahci -lappend_if [expr ($layer == 1 || $layer == 2)] boot_modules test-block_bench -lappend_if [expr ($layer == 2)] boot_modules part_blk - build_boot_image $boot_modules -run_genode_until forever +append qemu_args " -nographic -m 256 " +append qemu_args " -drive id=disk,file=bin/ext2.raw,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -boot d" +append qemu_args " -drive id=cd,file=[run_dir]/../ahci_bench.iso,if=none,media=cdrom -device ide-cd,drive=cd,bus=ahci.1" +run_genode_until "Done\n" 100 diff --git a/repos/os/src/test/blk/bench/main.cc b/repos/os/src/test/blk/bench/main.cc new file mode 100644 index 0000000000..95b8aa23e9 --- /dev/null +++ b/repos/os/src/test/blk/bench/main.cc @@ -0,0 +1,158 @@ +#include +#include +#include +#include + +#include + +using namespace Genode; + +enum { + TEST_WRITE = false, + TEST_SIZE = 1024 * 1024 * 1024, + REQUEST_SIZE = 8 * 512, + TX_BUFFER = Block::Session::TX_QUEUE_SIZE * REQUEST_SIZE +}; + + +namespace Test { + class Throughput; + struct Main; +} + + +class Test::Throughput +{ + private: + + Allocator_avl _alloc{env()->heap() }; + Block::Connection _session { &_alloc, TX_BUFFER }; + Timer::Connection _timer; + + Signal_rpc_member _disp_ack; + Signal_rpc_member _disp_submit; + bool _read_done = false; + bool _write_done = false; + + unsigned long _start = 0; + unsigned long _stop = 0; + size_t _bytes = 0; + Block::sector_t _current = 0; + + size_t _blk_size; + Block::sector_t _blk_count; + + void _submit() + { + static size_t count = REQUEST_SIZE / _blk_size; + + try { + while (_session.tx()->ready_to_submit()) { + Block::Packet_descriptor p( + _session.tx()->alloc_packet(REQUEST_SIZE), + !_read_done ? Block::Packet_descriptor::READ : Block::Packet_descriptor::WRITE, + _current, count); + + _session.tx()->submit_packet(p); + + /* increment for next read */ + _current += count; + if (_current + count >= _blk_count) + _current = 0; + } + } catch (...) { } + } + + void _ready_to_submit(unsigned) + { + _submit(); + } + + void _ack_avail(unsigned) + { + while (_session.tx()->ack_avail()) { + + Block::Packet_descriptor p = _session.tx()->get_acked_packet(); + if (!p.succeeded()) + PERR("Packet error: block: %llu count: %zu", p.block_number(), p.block_count()); + + if (!_read_done || (_read_done && p.operation() == Block::Packet_descriptor::WRITE)) + _bytes += p.size(); + + _session.tx()->release_packet(p); + } + + if (_bytes >= TEST_SIZE) { + _finish(); + return; + } + + _submit(); + } + + void _finish() + { + if (_read_done && (_write_done || !TEST_WRITE)) + return; + + _stop = _timer.elapsed_ms(); + ::printf("%s %zu KB in %lu ms (%.02f MB/s)\n", + !_read_done ? "Read" : "Wrote", + _bytes / 1024, _stop - _start, + ((double)_bytes / (1024 * 1024)) / ((double)(_stop - _start) / 1000)); + + + /* start write */ + if (!_read_done ) { + _read_done = true; + _start = _timer.elapsed_ms(); + _bytes = 0; + _current = 0; + if (TEST_WRITE) + _submit(); + else + ::printf("Done\n"); + } else if (!_write_done && TEST_WRITE) { + _write_done = true; + ::printf("Done\n"); + } + } + + public: + + Throughput(Server::Entrypoint &ep) + : _disp_ack(ep, *this, &Throughput::_ack_avail), + _disp_submit(ep, *this, &Throughput::_ready_to_submit) + { + _session.tx_channel()->sigh_ack_avail(_disp_ack); + _session.tx_channel()->sigh_ready_to_submit(_disp_submit); + + Block::Session::Operations blk_ops; + _session.info(&_blk_count, &_blk_size, &blk_ops); + + PWRN("block count %llu size %zu", _blk_count, _blk_size); + PINF("read/write %u KB ...", TEST_SIZE / 1024); + _start = _timer.elapsed_ms(); + _submit(); + } +}; + + +struct Test::Main +{ + Main(Server::Entrypoint &ep) + { + new (env()->heap()) Throughput(ep); + } +}; + + +namespace Server { + char const *name() { return "block_bench_ep"; }; + size_t stack_size() { return 2*1024*sizeof(long); } + + void construct(Entrypoint &ep) + { + static Test::Main server(ep); + } +} diff --git a/repos/os/src/test/blk/bench/target.mk b/repos/os/src/test/blk/bench/target.mk new file mode 100644 index 0000000000..cfb1b61bb0 --- /dev/null +++ b/repos/os/src/test/blk/bench/target.mk @@ -0,0 +1,3 @@ +TARGET = test-blk-bench +SRC_CC = main.cc +LIBS = base server libc