From a652cb5110c962a74806c4b14adc559c2eba6d88 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 14 Aug 2013 21:19:11 +0200 Subject: [PATCH] Apply affinity subspacing to session requests --- base/include/base/affinity.h | 16 +++++++++ base/include/base/child.h | 11 ++++++ base/run/affinity_subspace.run | 63 ++++++++++++++++++++++++++++++++++ base/src/base/child/child.cc | 5 ++- os/include/init/child.h | 26 ++++++++++++++ 5 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 base/run/affinity_subspace.run diff --git a/base/include/base/affinity.h b/base/include/base/affinity.h index 1f95f935c..8e05ff900 100644 --- a/base/include/base/affinity.h +++ b/base/include/base/affinity.h @@ -69,6 +69,11 @@ namespace Genode { unsigned height() const { return _height; } unsigned total() const { return _width*_height; } + Space multiply(Space const &other) const + { + return Space(_width*other.width(), _height*other.height()); + } + /** * Return location of a single CPU of specified index */ @@ -110,6 +115,17 @@ namespace Genode { unsigned width() const { return _width; } unsigned height() const { return _height; } bool valid() const { return _width*_height > 0; } + + Location multiply_position(Space const &space) const + { + return Location(_xpos*space.width(), _ypos*space.height(), + _width, _height); + } + + Location transpose(int dx, int dy) const + { + return Location(_xpos + dx, _ypos + dy, _width, _height); + } }; private: diff --git a/base/include/base/child.h b/base/include/base/child.h index 37479e35d..a5e43c8e0 100644 --- a/base/include/base/child.h +++ b/base/include/base/child.h @@ -73,6 +73,17 @@ namespace Genode { Server * /*server*/) { return false; } + /** + * Apply session affinity policy + * + * \param affinity affinity passed along with a session request + * \return affinity subordinated to the child policy + */ + virtual Affinity filter_session_affinity(Affinity const &affinity) + { + return affinity; + } + /** * Unregister services that had been provided by the child */ diff --git a/base/run/affinity_subspace.run b/base/run/affinity_subspace.run new file mode 100644 index 000000000..3e34fb996 --- /dev/null +++ b/base/run/affinity_subspace.run @@ -0,0 +1,63 @@ +# +# \brief Test to affinity subspacing +# \author Norman Feske +# + +if {[have_spec platform_pbxa9] || (![have_spec nova] && ![have_spec foc])} { + puts "Platform is unsupported." + exit 0 +} + + +build "core init test/affinity" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +append qemu_args " -nographic -m 64 -smp 8,cores=8 " + +build_boot_image "core init test-affinity" + +run_genode_until {.*Detected 2x1 CPUs.*} 60 + +puts "Test succeeded" + diff --git a/base/src/base/child/child.cc b/base/src/base/child/child.cc index ed8d3a12b..97b17bf3a 100644 --- a/base/src/base/child/child.cc +++ b/base/src/base/child/child.cc @@ -257,6 +257,9 @@ Session_capability Child::session(Parent::Service_name const &name, strncpy(_args, args.string(), sizeof(_args)); _policy->filter_session_args(name.string(), _args, sizeof(_args)); + /* filter session affinity */ + Affinity const filtered_affinity = _policy->filter_session_affinity(affinity); + /* transfer the quota donation from the child's account to ourself */ size_t ram_quota = Arg_string::find_arg(_args, "ram_quota").long_value(0); @@ -274,7 +277,7 @@ Session_capability Child::session(Parent::Service_name const &name, /* create session */ Session_capability cap; - try { cap = service->session(_args, affinity); } + try { cap = service->session(_args, filtered_affinity); } catch (Service::Invalid_args) { throw Service_denied(); } catch (Service::Unavailable) { throw Service_denied(); } catch (Service::Quota_exceeded) { throw Quota_exceeded(); } diff --git a/os/include/init/child.h b/os/include/init/child.h index f008c3dcd..84e90a88f 100644 --- a/os/include/init/child.h +++ b/os/include/init/child.h @@ -658,6 +658,32 @@ namespace Init { _pd_args_policy. filter_session_args(service, args, args_len); } + Genode::Affinity filter_session_affinity(Genode::Affinity const &session_affinity) + { + using namespace Genode; + + /* check if no valid affinity space was specified */ + if (session_affinity.space().total() == 0) + return session_affinity; + + Affinity::Space const &session_space = session_affinity.space(); + Affinity::Location const &session_location = session_affinity.location(); + + Affinity::Space const &child_space = _resources.affinity.space(); + Affinity::Location const &child_location = _resources.affinity.location(); + + /* scale resolution of resulting space */ + Affinity::Space space(child_space.multiply(session_space)); + + /* subordinate session affinity to child affinity subspace */ + Affinity::Location location(child_location + .multiply_position(session_space) + .transpose(session_location.xpos(), + session_location.ypos())); + + return Affinity(space, location); + } + bool announce_service(const char *service_name, Genode::Root_capability root, Genode::Allocator *alloc,