mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
Apply affinity subspacing to session requests
This commit is contained in:
parent
a4066c358e
commit
a652cb5110
@ -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:
|
||||
|
@ -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
|
||||
*/
|
||||
|
63
base/run/affinity_subspace.run
Normal file
63
base/run/affinity_subspace.run
Normal file
@ -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 {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="CPU"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<affinity-space width="2" />
|
||||
<default-route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</default-route>
|
||||
<start name="init">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<!-- assign the right half of the available CPUs -->
|
||||
<affinity xpos="1" width="1" />
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="CPU"/>
|
||||
<service name="RM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</default-route>
|
||||
<!-- assign the leftmost half of CPUs to test-affinity -->
|
||||
<affinity-space width="2" />
|
||||
<start name="test-affinity">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<affinity xpos="0" width="1" />
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
</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"
|
||||
|
@ -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(); }
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user