vm_session: support to trace vCPU

Issue #3111
This commit is contained in:
Alexander Boettcher
2019-04-17 14:16:27 +02:00
committed by Christian Helmuth
parent dca144f2ee
commit 05fa063068
22 changed files with 189 additions and 70 deletions

View File

@@ -17,8 +17,12 @@
/* Genode includes */
#include <base/allocator_guard.h>
#include <base/rpc_server.h>
#include <vm_session/vm_session.h>
#include <trace/control_area.h>
#include <trace/source_registry.h>
namespace Genode { class Vm_session_component; }
class Genode::Vm_session_component
@@ -33,7 +37,12 @@ class Genode::Vm_session_component
typedef Constrained_ram_allocator Con_ram_allocator;
typedef Allocator_avl_tpl<Rm_region> Avl_region;
class Vcpu : public List<Vcpu>::Element {
class Vcpu : private List<Vcpu>::Element,
public Trace::Source::Info_accessor
{
friend class List<Vcpu>;
friend class Vm_session_component;
public:
@@ -43,17 +52,23 @@ class Genode::Vm_session_component
Constrained_ram_allocator &_ram_alloc;
Cap_quota_guard &_cap_alloc;
Trace::Source_registry &_trace_sources;
Ram_dataspace_capability _ds_cap { };
addr_t _sel_sm_ec_sc;
addr_t _vm_pt_cnt { 0 };
Vcpu_id const _id;
State _state { INIT };
Affinity::Location const _location;
Session_label const &_label;
public:
Vcpu(Constrained_ram_allocator &ram_alloc,
Cap_quota_guard &cap_alloc,
Vcpu_id const id);
Vcpu_id const id, Affinity::Location const,
Session_label const &,
Trace::Control_area &,
Trace::Source_registry &);
~Vcpu();
@@ -70,17 +85,55 @@ class Genode::Vm_session_component
void alive() { _state = ALIVE; };
static addr_t invalid() { return ~0UL; }
/********************************************
** Trace::Source::Info_accessor interface **
********************************************/
Trace::Source::Info trace_source_info() const override;
private:
struct Trace_control_slot
{
unsigned index = 0;
Trace::Control_area &_trace_control_area;
Trace_control_slot(Trace::Control_area &trace_control_area)
: _trace_control_area(trace_control_area)
{
if (!_trace_control_area.alloc(index))
throw Out_of_ram();
}
~Trace_control_slot()
{
_trace_control_area.free(index);
}
Trace::Control &control()
{
return *_trace_control_area.at(index);
}
};
Trace_control_slot _trace_control_slot;
Trace::Source _trace_source { *this, _trace_control_slot.control() };
};
Rpc_entrypoint &_ep;
Con_ram_allocator _constrained_md_ram_alloc;
Sliced_heap _heap;
Avl_region _map { &_heap };
addr_t _pd_sel { 0 };
unsigned _id_alloc { 0 };
unsigned _priority;
Rpc_entrypoint &_ep;
Trace::Control_area _trace_control_area;
Trace::Source_registry &_trace_sources;
Con_ram_allocator _constrained_md_ram_alloc;
Sliced_heap _heap;
Avl_region _map { &_heap };
addr_t _pd_sel { 0 };
unsigned _id_alloc { 0 };
unsigned _priority;
Session_label const _session_label;
List<Vcpu> _vcpus { };
List<Vcpu> _vcpus { };
Vcpu * _lookup(Vcpu_id const vcpu_id)
{
@@ -104,7 +157,8 @@ class Genode::Vm_session_component
using Cap_quota_guard::upgrade;
Vm_session_component(Rpc_entrypoint &, Resources, Label const &,
Diag, Ram_allocator &ram, Region_map &, unsigned);
Diag, Ram_allocator &ram, Region_map &, unsigned,
Trace::Source_registry &);
~Vm_session_component();
/*********************************

View File

@@ -20,12 +20,13 @@
/*
* Add x86 specific services
*/
void Genode::platform_add_local_services(Rpc_entrypoint &ep,
Sliced_heap &heap,
Registry<Service> &services)
void Genode::platform_add_local_services(Rpc_entrypoint &ep,
Sliced_heap &heap,
Registry<Service> &services,
Trace::Source_registry &trace_sources)
{
static Vm_root vm_root(ep, heap, core_env().ram_allocator(),
core_env().local_rm());
core_env().local_rm(), trace_sources);
static Core_service<Vm_session_component> vm(services, vm_root);
static Io_port_root io_root(*core_env().pd_session(),

View File

@@ -37,12 +37,20 @@ enum { CAP_RANGE_LOG2 = 2, CAP_RANGE = 1 << CAP_RANGE_LOG2 };
Vm_session_component::Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
Cap_quota_guard &cap_alloc,
Vcpu_id const id)
Vcpu_id const id,
Affinity::Location const location,
Session_label const &label,
Trace::Control_area &trace_control_area,
Trace::Source_registry &trace_sources)
:
_ram_alloc(ram_alloc),
_cap_alloc(cap_alloc),
_trace_sources(trace_sources),
_sel_sm_ec_sc(invalid()),
_id(id)
_id(id),
_location(location),
_label(label),
_trace_control_slot(trace_control_area)
{
/* account caps required to setup vCPU */
_cap_alloc.withdraw(Cap_quota{CAP_RANGE});
@@ -63,10 +71,14 @@ Vm_session_component::Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
cap_map().remove(_sel_sm_ec_sc, CAP_RANGE_LOG2);
throw;
}
_trace_sources.insert(&_trace_source);
}
Vm_session_component::Vcpu::~Vcpu()
{
_trace_sources.remove(&_trace_source);
if (_ds_cap.valid())
_ram_alloc.free(_ds_cap);
@@ -85,6 +97,19 @@ addr_t Vm_session_component::Vcpu::new_pt_id()
return MAX_VM_EXITS * _id.id + _vm_pt_cnt ++;
}
Genode::Trace::Source::Info Vm_session_component::Vcpu::trace_source_info() const
{
Genode::uint64_t sc_time = 0;
uint8_t res = Nova::sc_ctrl(sc_sel(), sc_time);
if (res != Nova::NOVA_OK)
warning("sc_ctrl failed res=", res);
return { _label, String<5>("vCPU"),
Trace::Execution_time(sc_time, sc_time),
_location };
}
static Nova::uint8_t map_async_caps(Nova::Obj_crd const src,
Nova::Obj_crd const dst,
@@ -132,13 +157,16 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
return;
/* lookup vmm pd and cpu location of handler thread in VMM */
addr_t kernel_cpu_id = 0;
addr_t kernel_cpu_id = 0;
Affinity::Location vcpu_location;
auto lambda = [&] (Cpu_thread_component *ptr) {
if (!ptr)
return Vcpu::invalid();
Cpu_thread_component &thread = *ptr;
vcpu_location = thread.platform_thread().affinity();
addr_t genode_cpu_id = thread.platform_thread().affinity().xpos();
kernel_cpu_id = platform_specific().kernel_cpu_id(genode_cpu_id);
@@ -153,7 +181,11 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
/* allocate vCPU object */
Vcpu &vcpu = *new (_heap) Vcpu(_constrained_md_ram_alloc,
_cap_quota_guard(),
Vcpu_id {_id_alloc});
Vcpu_id {_id_alloc},
vcpu_location,
_session_label,
_trace_control_area,
_trace_sources);
/* we ran out of caps in core */
if (!vcpu.ds_cap().valid())
@@ -273,18 +305,21 @@ Genode::Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu
Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
Resources resources,
Label const &,
Label const &label,
Diag,
Ram_allocator &ram,
Region_map &local_rm,
unsigned const priority)
unsigned const priority,
Trace::Source_registry &trace_sources)
:
Ram_quota_guard(resources.ram_quota),
Cap_quota_guard(resources.cap_quota),
_ep(ep),
_trace_control_area(ram, local_rm), _trace_sources(trace_sources),
_constrained_md_ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()),
_heap(_constrained_md_ram_alloc, local_rm),
_priority(scale_priority(priority, "VM session"))
_priority(scale_priority(priority, "VM session")),
_session_label(label)
{
_cap_quota_guard().withdraw(Cap_quota{1});