2015-03-27 13:05:55 +00:00
|
|
|
#
|
|
|
|
# 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="PD"/>
|
|
|
|
<service name="RM"/>
|
|
|
|
<service name="CPU"/>
|
|
|
|
<service name="LOG"/>
|
|
|
|
</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"/>
|
2015-07-07 15:17:20 +00:00
|
|
|
<resource name="RAM" quantum="20M"/>
|
2015-03-27 13:05:55 +00:00
|
|
|
<resource name="CPU" quantum="10"/>
|
2015-07-07 15:17:20 +00:00
|
|
|
<config>
|
2015-03-27 13:05:55 +00:00
|
|
|
<parent-provides>
|
|
|
|
<service name="ROM"/>
|
|
|
|
<service name="RAM"/>
|
|
|
|
<service name="IRQ"/>
|
|
|
|
<service name="IO_MEM"/>
|
|
|
|
<service name="IO_PORT"/>
|
|
|
|
<service name="PD"/>
|
|
|
|
<service name="RM"/>
|
|
|
|
<service name="CPU"/>
|
|
|
|
<service name="LOG"/>
|
|
|
|
<service name="Timer"/>
|
|
|
|
<service name="Sync"/>
|
|
|
|
</parent-provides>
|
|
|
|
<default-route>
|
|
|
|
<any-service><parent/><any-child/></any-service>
|
|
|
|
</default-route>
|
|
|
|
|
2015-07-07 15:17:20 +00:00
|
|
|
<start name="test_slow">
|
2015-03-27 13:05:55 +00:00
|
|
|
<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"/>
|
2015-07-07 15:17:20 +00:00
|
|
|
<resource name="RAM" quantum="30M"/>
|
2015-03-27 13:05:55 +00:00
|
|
|
<resource name="CPU" quantum="80"/>
|
2015-07-07 15:17:20 +00:00
|
|
|
<config prio_levels="2">
|
2015-03-27 13:05:55 +00:00
|
|
|
<parent-provides>
|
|
|
|
<service name="ROM"/>
|
|
|
|
<service name="RAM"/>
|
|
|
|
<service name="IRQ"/>
|
|
|
|
<service name="IO_MEM"/>
|
|
|
|
<service name="IO_PORT"/>
|
|
|
|
<service name="PD"/>
|
|
|
|
<service name="RM"/>
|
|
|
|
<service name="CPU"/>
|
|
|
|
<service name="LOG"/>
|
|
|
|
<service name="Timer"/>
|
|
|
|
<service name="Sync"/>
|
|
|
|
</parent-provides>
|
|
|
|
<default-route>
|
|
|
|
<any-service><parent/></any-service>
|
|
|
|
</default-route>
|
|
|
|
|
2015-07-07 15:17:20 +00:00
|
|
|
<start name="test_midl" priority="0">
|
2015-03-27 13:05:55 +00:00
|
|
|
<binary name="test-cpu_quota"/>
|
|
|
|
<resource name="RAM" quantum="10M"/>
|
|
|
|
<resource name="CPU" quantum="25"/>
|
|
|
|
</start>
|
|
|
|
|
2015-07-07 15:17:20 +00:00
|
|
|
<start name="test_fast" priority="-1">
|
2015-03-27 13:05:55 +00:00
|
|
|
<binary name="test-cpu_quota"/>
|
|
|
|
<resource name="RAM" quantum="10M"/>
|
|
|
|
<resource name="CPU" quantum="75"/>
|
|
|
|
</start>
|
|
|
|
|
|
|
|
</config>
|
|
|
|
</start>
|
2015-07-07 15:17:20 +00:00
|
|
|
|
|
|
|
<start name="timer" priority="0">
|
|
|
|
<resource name="RAM" quantum="10M"/>
|
|
|
|
<resource name="CPU" quantum="10"/>
|
|
|
|
<provides><service name="Timer"/></provides>
|
|
|
|
</start>
|
|
|
|
|
2015-03-27 13:05:55 +00:00
|
|
|
</config>
|
|
|
|
}
|
|
|
|
|
2016-12-01 18:00:11 +00:00
|
|
|
build_boot_image "core ld.lib.so init timer test-cpu_quota test-sync"
|
2015-03-27 13:05:55 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Execution
|
|
|
|
#
|
|
|
|
|
2015-12-02 11:14:31 +00:00
|
|
|
append qemu_args "-nographic -m 128"
|
2015-03-27 13:05:55 +00:00
|
|
|
|
|
|
|
run_genode_until ".*done.*\n.*done.*\n.*done.*\n" 100
|
|
|
|
|
|
|
|
#
|
|
|
|
# Conclusion
|
|
|
|
#
|
2015-07-03 14:09:01 +00:00
|
|
|
set err_cnt 0
|
2015-03-27 13:05:55 +00:00
|
|
|
|
|
|
|
proc check_counter { name opt cnt total_cnt } {
|
|
|
|
|
2015-07-03 14:09:01 +00:00
|
|
|
global err_cnt
|
2015-12-02 10:56:10 +00:00
|
|
|
set bad 0
|
|
|
|
set class "Good: "
|
|
|
|
set tol 0.01
|
|
|
|
set is 0
|
2015-07-03 14:26:04 +00:00
|
|
|
|
2015-07-07 15:17:20 +00:00
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
#
|
2015-12-02 10:56:10 +00:00
|
|
|
if {[have_spec x86]} { set tol 0.02 }
|
2015-07-07 15:17:20 +00:00
|
|
|
|
2015-12-02 11:11:54 +00:00
|
|
|
#
|
|
|
|
# Zynq is currently tested merely in Qemu and most likely because of
|
|
|
|
# that, the results are less precise.
|
|
|
|
#
|
2017-01-03 12:17:41 +00:00
|
|
|
if {[have_spec zynq]} { set tol 0.03 }
|
2015-12-02 11:11:54 +00:00
|
|
|
|
2015-12-02 12:25:05 +00:00
|
|
|
#
|
|
|
|
# FIXME: There is no reasonable explanation by now why the test results
|
|
|
|
# are less stable on these platforms. We have tried several things that
|
|
|
|
# did not lead to an explanation or improvement:
|
|
|
|
#
|
|
|
|
# * changing the timing parameters of the scheduler
|
|
|
|
# * switching off SMP
|
|
|
|
# * double-checking the speed of userland and kernel timers
|
|
|
|
#
|
2017-01-03 12:17:41 +00:00
|
|
|
if {[have_spec odroid_xu]} { set tol 0.04 }
|
|
|
|
if {[have_spec arndale]} { set tol 0.04 }
|
2015-12-02 12:25:05 +00:00
|
|
|
|
2015-07-03 14:26:04 +00:00
|
|
|
if {[expr $total_cnt != 0]} { set is [expr double($cnt) / $total_cnt ] }
|
|
|
|
|
2015-12-02 10:56:10 +00:00
|
|
|
set err [expr $is - $opt]
|
|
|
|
set is_fmt [format {%0.3f} [expr $is * 100]]
|
|
|
|
set opt_fmt [format {%0.3f} [expr $opt * 100]]
|
|
|
|
set err_fmt [format {%0.3f} [expr $err * 100]]
|
|
|
|
set tol_fmt [format {%0.3f} [expr $tol * 100]]
|
2015-03-27 13:05:55 +00:00
|
|
|
|
2015-12-02 10:56:10 +00:00
|
|
|
if {[expr abs($err) > $tol]} {
|
2015-07-03 14:09:01 +00:00
|
|
|
|
2015-12-02 10:56:10 +00:00
|
|
|
set class "Bad: "
|
2015-07-03 14:09:01 +00:00
|
|
|
set err_cnt [expr $err_cnt + 1]
|
2015-03-27 13:05:55 +00:00
|
|
|
}
|
2015-12-02 10:56:10 +00:00
|
|
|
puts "$class$name received $is_fmt% CPU (goal $opt_fmt% tol $tol_fmt% err $err_fmt%)"
|
2015-03-27 13:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
proc check_quota { name opt_sp quota_sp opt quota } {
|
|
|
|
|
2015-07-03 14:09:01 +00:00
|
|
|
global err_cnt
|
2015-03-27 13:05:55 +00:00
|
|
|
if {[expr $quota != $opt]} {
|
2015-07-03 14:09:01 +00:00
|
|
|
puts "Bad: $name has quota $quota us (goal $opt us)"
|
|
|
|
set err_cnt [expr $err_cnt + 1]
|
2015-03-27 13:05:55 +00:00
|
|
|
}
|
|
|
|
if {[expr $quota_sp != $opt_sp]} {
|
2015-07-03 14:09:01 +00:00
|
|
|
puts "Bad: $name has super period $quota_sp us (goal $opt_sp us)"
|
|
|
|
set err_cnt [expr $err_cnt + 1]
|
2015-03-27 13:05:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-04 09:01:26 +00:00
|
|
|
# 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 ""
|
|
|
|
|
2015-03-27 13:05:55 +00:00
|
|
|
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
|
|
|
|
|
2015-07-03 14:09:01 +00:00
|
|
|
# final conclusion and return
|
|
|
|
if {[expr $err_cnt > 0]} {
|
|
|
|
puts "Test failed because of $err_cnt errors"
|
|
|
|
exit -1
|
|
|
|
}
|
2015-03-27 13:05:55 +00:00
|
|
|
puts "Test succeeded"
|