test: block benchmarking

This commit is contained in:
Sebastian Sumpf 2015-03-24 15:48:46 +01:00 committed by Christian Helmuth
parent ff12ea01d5
commit 9d4f410988
4 changed files with 212 additions and 225 deletions

View File

@ -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 {
<config>
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="SIGNAL" />
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>}
append_if [have_spec platform_arndale] config {
<start name="platform_drv">
<resource name="RAM" quantum="1M"/>
<provides><service name="Regulator"/></provides>
</start> }
append_if [have_spec acpi] config {
<start name="acpi">
<resource name="RAM" quantum="6M" constrain_phys="yes"/>
<binary name="acpi_drv"/>
<provides>
<service name="PCI"/>
<service name="IRQ" />
</provides>
<route>
<service name="PCI"> <any-child /> </service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>}
append_if [expr ![have_spec acpi] && [have_spec pci]] config {
<start name="pci_drv">
<resource name="RAM" quantum="2M" constrain_phys="yes"/>
<provides><service name="PCI"/></provides>
</start>}
append config {
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
<route>}
append_if [have_spec acpi] config {
<service name="IRQ"><child name="acpi" /></service>}
append config {
<any-service> <parent /> <any-child /></any-service>
</route>
</start>
<start name="ahci">
<binary name="ahci" />
<resource name="RAM" quantum="10M" />
<provides><service name="Block" /></provides>
<route>}
append_if [have_spec acpi] config {
<service name="IRQ"><child name="acpi" /></service>}
append config {
<any-service> <parent /> <any-child /></any-service>
</route>
</start>
<start name="test-blk-cli">
<resource name="RAM" quantum="2M" />
<route>
<service name="Block"><child name="ahci"/></service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>
</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

View File

@ -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 {
<config>
<parent-provides>
@ -56,13 +44,13 @@ set config {
<service name="SIGNAL"/>
</parent-provides>
<default-route>
<any-service><parent/><any-child/></any-service>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>}
</start>
}
append_if [expr ![have_spec acpi] && ![have_spec pci]] config {
<start name="platform_drv">
<resource name="RAM" quantum="1M"/>
@ -71,75 +59,56 @@ append_if [expr ![have_spec acpi] && ![have_spec pci]] config {
append_if [have_spec acpi] config {
<start name="acpi">
<resource name="RAM" quantum="16M" constrain_phys="yes"/>
<resource name="RAM" quantum="6M" constrain_phys="yes"/>
<binary name="acpi_drv"/>
<provides>
<service name="PCI"/>
<service name="IRQ" />
</provides>
<route>
<service name="PCI"> <any-child /> </service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>}
<config>
<policy label="acpi_drv"><pci class="ALL" /></policy>
<policy label="ahci"><pci class="AHCI" /></policy>
</config>
</start>
}
append_if [expr ![have_spec acpi] && [have_spec pci]] config {
<start name="pci_drv">
<resource name="RAM" quantum="3M" constrain_phys="yes"/>
<provides> <service name="PCI"/> </provides>
</start> }
# start driver internal bench with layer 0
append_if [expr $layer == 0] config {
<start name="ahci_bench">
<resource name="RAM" quantum="1G"/>
<provides><service name="Block"/></provides>
</start> }
# start part_blk with layer 2
append_if [expr $layer == 2] config {
<start name="part_blk">
<resource name="RAM" quantum="10M" />
<provides><service name="Block" /></provides>
<route>
<service name="Block"><child name="ahci" /></service>
<any-service><parent/><any-child/></any-service>
</route>
<config>
<policy label="test-block_bench" partition="1"/>
<policy label="ahci"/><pci class="AHCI" /></policy>
</config>
</start> }
# start normal AHCI driver and bench app with layer 1 or 2
append_if [expr ($layer == 1 || $layer == 2)] config {
<start name="ahci">
<resource name="RAM" quantum="10M"/>
<provides><service name="Block"/></provides>}
append_if [expr ($layer == 1 || $layer == 2) && [have_spec acpi]] config {
<route>
<service name="IRQ"><child name="acpi" /></service>
<any-service><parent/><any-child/></any-service>
</route>}
append_if [expr ($layer == 1 || $layer == 2)] config {
</start>
<start name="test-block_bench">
<resource name="RAM" quantum="1G"/> }
# if layer is 2 route block requests of bench app to part_blk
append_if [expr $layer == 2] config {
<route>
<service name="Block"><child name="part_blk" /></service>
<any-service><parent/><any-child/></any-service>
</route> }
# end start node of bench app if layer 1 or 2
append_if [expr ($layer == 1 || $layer == 2)] config {
</start> }
# end config
append config {
<start name="ahci">
<binary name="ahci_drv" />
<resource name="RAM" quantum="10M" />
<provides><service name="Block" /></provides>
<config>
<policy label="test-ahci" device="0" />
</config>
</start>
<start name="test-ahci">
<binary name="test-blk-bench" />
<resource name="RAM" quantum="5M" />
<config>
<libc stdout="/dev/log">
<vfs>
<dir name="dev"> <log/> </dir>
</vfs>
</libc>
</config>
<route>
<service name="Block"><child name="ahci"/></service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>
</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

View File

@ -0,0 +1,158 @@
#include <base/allocator_avl.h>
#include <block_session/connection.h>
#include <os/server.h>
#include <timer_session/connection.h>
#include <stdio.h>
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<Throughput> _disp_ack;
Signal_rpc_member<Throughput> _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);
}
}

View File

@ -0,0 +1,3 @@
TARGET = test-blk-bench
SRC_CC = main.cc
LIBS = base server libc