mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 14:13:09 +00:00
eaf4150c7b
The timer driver on X86 needs CPU quota with highest priority as it frequently has to interrupt the counters to update the PIT. On ARM this makes no difference in the test results as ARM timer drivers, once configured, can sleep until the end of the timeouts. On X86 we raise the error tolerance to 2% (default 1%) to compensate the error caused by the timer. Fixes #1621
263 lines
7.1 KiB
Plaintext
263 lines
7.1 KiB
Plaintext
#
|
|
# Check platform
|
|
#
|
|
# HW is the only kernel that provides appliance of quota to the scheduling.
|
|
#
|
|
assert_spec hw
|
|
|
|
#
|
|
# Build
|
|
#
|
|
|
|
build "core init drivers/timer test/cpu_quota"
|
|
|
|
#
|
|
# Boot image
|
|
#
|
|
|
|
create_boot_directory
|
|
|
|
install_config {
|
|
<config prio_levels="4">
|
|
<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>
|
|
|
|
<start name="test-sync">
|
|
<resource name="RAM" quantum="10M"/>
|
|
<provides><service name="Sync"/></provides>
|
|
</start>
|
|
|
|
<start name="init_1" priority="-1">
|
|
<binary name="init"/>
|
|
<resource name="RAM" quantum="20M"/>
|
|
<resource name="CPU" quantum="10"/>
|
|
<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"/>
|
|
<service name="Timer"/>
|
|
<service name="Sync"/>
|
|
</parent-provides>
|
|
<default-route>
|
|
<any-service><parent/><any-child/></any-service>
|
|
</default-route>
|
|
|
|
<start name="test_slow">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="50"/>
|
|
</start>
|
|
|
|
</config>
|
|
</start>
|
|
|
|
<start name="init_2" priority="-2">
|
|
<binary name="init"/>
|
|
<resource name="RAM" quantum="30M"/>
|
|
<resource name="CPU" quantum="80"/>
|
|
<config prio_levels="2">
|
|
<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"/>
|
|
<service name="Timer"/>
|
|
<service name="Sync"/>
|
|
</parent-provides>
|
|
<default-route>
|
|
<any-service><parent/></any-service>
|
|
</default-route>
|
|
|
|
<start name="test_midl" priority="0">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="25"/>
|
|
</start>
|
|
|
|
<start name="test_fast" priority="-1">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="75"/>
|
|
</start>
|
|
|
|
</config>
|
|
</start>
|
|
|
|
<start name="timer" priority="0">
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="10"/>
|
|
<provides><service name="Timer"/></provides>
|
|
</start>
|
|
|
|
</config>
|
|
}
|
|
|
|
build_boot_image "core init timer test-cpu_quota test-sync"
|
|
|
|
#
|
|
# Execution
|
|
#
|
|
|
|
append qemu_args "-nographic -m 64"
|
|
|
|
run_genode_until ".*done.*\n.*done.*\n.*done.*\n" 100
|
|
|
|
#
|
|
# Conclusion
|
|
#
|
|
set err_cnt 0
|
|
|
|
proc check_counter { name opt cnt total_cnt } {
|
|
|
|
global err_cnt
|
|
set err_str "Good: "
|
|
set err 0.01
|
|
set is 0
|
|
|
|
#
|
|
# On X86, the timer driver uses the PIT with a maximum timeout of 54 ms.
|
|
# Thus, the driver frequently interrupts the counters with highest
|
|
# priority to update the timer. This is why we need a higher error
|
|
# tolerance as for ARM where the driver, once configured, can sleep for
|
|
# the whole test timeout.
|
|
#
|
|
if {[have_spec x86]} { set err 0.02 }
|
|
|
|
if {[expr $total_cnt != 0]} { set is [expr double($cnt) / $total_cnt ] }
|
|
|
|
set is_pc [expr double(round($is * 100000)) / 1000]
|
|
set opt_pc [expr double(round($opt * 100000)) / 1000]
|
|
|
|
if {[expr $is > $opt + $err || $is < $opt - $err]} {
|
|
|
|
set err_str "Bad: "
|
|
set err_cnt [expr $err_cnt + 1]
|
|
}
|
|
puts "$err_str$name received $is_pc % CPU (goal $opt_pc %)"
|
|
}
|
|
|
|
proc check_quota { name opt_sp quota_sp opt quota } {
|
|
|
|
global err_cnt
|
|
if {[expr $quota != $opt]} {
|
|
puts "Bad: $name has quota $quota us (goal $opt us)"
|
|
set err_cnt [expr $err_cnt + 1]
|
|
}
|
|
if {[expr $quota_sp != $opt_sp]} {
|
|
puts "Bad: $name has super period $quota_sp us (goal $opt_sp us)"
|
|
set err_cnt [expr $err_cnt + 1]
|
|
}
|
|
}
|
|
|
|
# pre-define variables if regexp does not match
|
|
set slow_quota ""; set midl_quota ""; set fast_quota ""
|
|
set slow_quota_sp ""; set midl_quota_sp ""; set fast_quota_sp ""
|
|
|
|
regexp {[0-9]+} [regexp -inline {slow. quota [0-9]+} $output] slow_quota
|
|
regexp {[0-9]+} [regexp -inline {midl. quota [0-9]+} $output] midl_quota
|
|
regexp {[0-9]+} [regexp -inline {fast. quota [0-9]+} $output] fast_quota
|
|
|
|
regexp {[0-9]+} [regexp -inline {slow. quota super period [0-9]+} $output] slow_quota_sp
|
|
regexp {[0-9]+} [regexp -inline {midl. quota super period [0-9]+} $output] midl_quota_sp
|
|
regexp {[0-9]+} [regexp -inline {fast. quota super period [0-9]+} $output] fast_quota_sp
|
|
|
|
#
|
|
# We have to consider the rounding errors as the two translations from init to
|
|
# core and then from core to the user are distinct.
|
|
#
|
|
# Slow quota (1000000 * (0x8000 * 5 / 100)) / 0x8000 = 49987
|
|
# Slow quota (1000000 * (0x8000 * 20 / 100)) / 0x8000 = 199981
|
|
# Slow quota (1000000 * (0x8000 * 60 / 100)) / 0x8000 = 599975
|
|
#
|
|
check_quota "Slow test" 1000000 $slow_quota_sp 49987 $slow_quota
|
|
check_quota "Middle test" 1000000 $midl_quota_sp 199981 $midl_quota
|
|
check_quota "Fast test" 1000000 $fast_quota_sp 599975 $fast_quota
|
|
|
|
regexp {[0-9]+} [regexp -inline {slow. counter A [0-9]+} $output] slow_a_cnt
|
|
regexp {[0-9]+} [regexp -inline {midl. counter A [0-9]+} $output] midl_a_cnt
|
|
regexp {[0-9]+} [regexp -inline {fast. counter A [0-9]+} $output] fast_a_cnt
|
|
regexp {[0-9]+} [regexp -inline {slow. counter B [0-9]+} $output] slow_b_cnt
|
|
regexp {[0-9]+} [regexp -inline {midl. counter B [0-9]+} $output] midl_b_cnt
|
|
regexp {[0-9]+} [regexp -inline {fast. counter B [0-9]+} $output] fast_b_cnt
|
|
|
|
set total_cnt [expr $fast_a_cnt + $midl_a_cnt + $slow_a_cnt + $fast_b_cnt + $midl_b_cnt + $slow_b_cnt]
|
|
|
|
#
|
|
# Slow 5.0 % claim + 5.0 % fill = 10 %
|
|
# Stage 1
|
|
# A 0.5 % claim + 2.5 % fill = 3 %
|
|
# B 4.5 % claim + 2.5 % fill = 7 %
|
|
# Stage 2
|
|
# A 5.0 % claim + 5.0 % fill = 10 %
|
|
# Total
|
|
# A 3/4 * 3 + 1/4 * 10 = 4.75 %
|
|
# A 3/4 * 7 + 1/4 * 0 = 5.25 %
|
|
#
|
|
check_counter "Slow counter A" 0.0475 $slow_a_cnt $total_cnt
|
|
check_counter "Slow counter B" 0.0525 $slow_b_cnt $total_cnt
|
|
|
|
#
|
|
# Middle 20 % claim + 5.0 % fill = 25.0 %
|
|
# Stage 1
|
|
# A 2 % claim + 2.5 % fill = 4.5 %
|
|
# B 18 % claim + 2.5 % fill = 20.5 %
|
|
# Stage 2
|
|
# A 20 % claim + 5.0 % fill = 25.0 %
|
|
# Total
|
|
# A 3/4 * 4.5 + 1/4 * 25 = 9.625 %
|
|
# A 3/4 * 20.5 + 1/4 * 0 = 15.375 %
|
|
#
|
|
check_counter "Middle counter A" 0.09625 $midl_a_cnt $total_cnt
|
|
check_counter "Middle counter B" 0.15375 $midl_b_cnt $total_cnt
|
|
|
|
#
|
|
# Fast 60 % claim + 5.0 % fill = 65.0 %
|
|
# Stage 1
|
|
# A 6 % claim + 2.5 % fill = 8.5 %
|
|
# B 54 % claim + 2.5 % fill = 56.5 %
|
|
# Stage 2
|
|
# A 60 % claim + 5.0 % fill = 65.0 %
|
|
# Total
|
|
# A 3/4 * 8.5 + 1/4 * 65 = 22.625 %
|
|
# A 3/4 * 56.5 + 1/4 * 0 = 42.375 %
|
|
#
|
|
check_counter "Fast counter A" 0.22625 $fast_a_cnt $total_cnt
|
|
check_counter "Fast counter B" 0.42375 $fast_b_cnt $total_cnt
|
|
|
|
# final conclusion and return
|
|
if {[expr $err_cnt > 0]} {
|
|
puts "Test failed because of $err_cnt errors"
|
|
exit -1
|
|
}
|
|
puts "Test succeeded"
|