mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
test: block benchmarking
This commit is contained in:
parent
ff12ea01d5
commit
9d4f410988
@ -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
|
@ -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
|
||||
|
158
repos/os/src/test/blk/bench/main.cc
Normal file
158
repos/os/src/test/blk/bench/main.cc
Normal 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);
|
||||
}
|
||||
}
|
3
repos/os/src/test/blk/bench/target.mk
Normal file
3
repos/os/src/test/blk/bench/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-blk-bench
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server libc
|
Loading…
x
Reference in New Issue
Block a user