From a062ba6dd2e4c1e9e2a5cb3249a205735e8e5a2f Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 14 Nov 2018 15:06:52 +0100 Subject: [PATCH] base: add tlb shootdown test metric to smp test Fix #3041 --- repos/base/run/smp.run | 18 ++++++++- repos/base/src/test/smp/main.cc | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/repos/base/run/smp.run b/repos/base/run/smp.run index e6828a3428..8f33b3f296 100644 --- a/repos/base/run/smp.run +++ b/repos/base/run/smp.run @@ -5,6 +5,10 @@ # \author Alexander Boettcher # +if { [get_cmd_switch --autopilot] && [have_include "power_on/qemu"] } { + puts "Run script does not support autopilot mode on Qemu" + exit 0 +} build "core init test/smp" @@ -31,8 +35,6 @@ install_config { build_boot_image "core ld.lib.so init test-smp" if {[have_include "power_on/qemu"]} { - if {[get_cmd_switch --autopilot]} { exit 0 } - # in general we want to have at least 2 CPUs set want_cpus 2 @@ -108,3 +110,15 @@ for {set r 0} {$r <= $rounds} {incr r} { } compare_output_to $good_string puts "Affinity test: passed" + +set output $original_output +grep_output {no RM attachment } +unify_output {pf_addr=0x[a-f0-9]+} "ADDR" +unify_output {pf_ip=0x[a-f0-9]+} "IP" +set good_string "" +for {set r 1} {$r < $cpus} {incr r} { + append good_string {no RM attachment (READ ADDR IP from pager_object: pd='init -> test-smp' thread='tlb_thread')} + append good_string "\n" +} +compare_output_to $good_string +puts "TLB test: passed" diff --git a/repos/base/src/test/smp/main.cc b/repos/base/src/test/smp/main.cc index 1cc774689b..d3e56e2535 100644 --- a/repos/base/src/test/smp/main.cc +++ b/repos/base/src/test/smp/main.cc @@ -13,6 +13,7 @@ */ /* Genode includes */ +#include #include #include #include @@ -243,6 +244,73 @@ namespace Affinity_test { } } +namespace Tlb_shootdown_test { + + struct Thread : Genode::Thread, Genode::Noncopyable + { + enum { STACK_SIZE = sizeof(long)*2048 }; + + unsigned cpu_idx; + volatile unsigned * values; + Genode::Lock barrier; + + void entry() + { + Genode::log("TLB: thread started on CPU ", cpu_idx); + values[cpu_idx] = 1; + barrier.unlock(); + + for (; values[cpu_idx] == 1;) ; + + Genode::raw("Unforseeable crosstalk effect!"); + } + + Thread(Genode::Env &env, Location location, unsigned idx, + volatile unsigned * values) + : Genode::Thread(env, Name("tlb_thread"), STACK_SIZE, location, + Weight(), env.cpu()), + cpu_idx(idx), values(values), barrier(Genode::Lock::LOCKED) { + start(); } + + /* + * Noncopyable + */ + Thread(Thread const&); + Thread &operator = (Thread const &); + }; + + void execute(Genode::Env &env, Genode::Heap & heap, + Genode::Affinity::Space & cpus) + { + using namespace Genode; + + log("TLB: --- test started ---"); + + enum { DS_SIZE = 4096 }; + Genode::Attached_ram_dataspace * ram_ds = + new (heap) Genode::Attached_ram_dataspace(env.ram(), env.rm(), + DS_SIZE); + + /* get some memory for the thread objects */ + Thread ** threads = new (heap) Thread*[cpus.total()]; + + /* construct the thread objects */ + for (unsigned i = 1; i < cpus.total(); i++) + threads[i] = new (heap) Thread(env, cpus.location_of_index(i), i, + ram_ds->local_addr()); + + /* wait until all threads are up and running */ + for (unsigned i = 1; i < cpus.total(); i++) threads[i]->barrier.lock(); + + log("TLB: all threads are up and running..."); + destroy(heap, ram_ds); + log("TLB: ram dataspace destroyed, all will fault..."); + for (unsigned i = 1; i < cpus.total(); i++) destroy(heap, threads[i]); + destroy(heap, threads); + + log("TLB: --- test finished ---"); + } +} void Component::construct(Genode::Env & env) { using namespace Genode; @@ -257,6 +325,7 @@ void Component::construct(Genode::Env & env) Mp_server_test::execute(env, heap, cpus); Affinity_test::execute(env, heap, cpus); + Tlb_shootdown_test::execute(env, heap, cpus); log("--- SMP testsuite finished ---"); }