mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Introducing new topology service to query NUMA information from within a component.
This commit is contained in:
22
repos/base/include/topo_session/capability.h
Normal file
22
repos/base/include/topo_session/capability.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* \brief Topo-session capability type
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalanOS, witch is based on Genode OS framework
|
||||
* distributed under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <base/capability.h>
|
||||
#include <topo_session/topo_session.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
typedef Capability<Topo_session> Topo_session_capability;
|
||||
} // namespace Genode
|
||||
40
repos/base/include/topo_session/client.h
Normal file
40
repos/base/include/topo_session/client.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* \brief Client-side topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <topo_session/capability.h>
|
||||
#include <topo_session/node.h>
|
||||
#include <base/rpc_client.h>
|
||||
#include <base/affinity.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Topo_session_client;
|
||||
struct Node;
|
||||
}
|
||||
|
||||
struct Genode::Topo_session_client : Rpc_client<Topo_session>
|
||||
{
|
||||
explicit Topo_session_client(Topo_session_capability session)
|
||||
: Rpc_client<Topo_session>(session) { }
|
||||
|
||||
Node *node_affinity_of(Affinity::Location &loc) override {
|
||||
return call<Rpc_node_affinity>(loc);
|
||||
}
|
||||
|
||||
unsigned node_count() override {
|
||||
return call<Rpc_node_count>();
|
||||
}
|
||||
};
|
||||
46
repos/base/include/topo_session/connection.h
Normal file
46
repos/base/include/topo_session/connection.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <topo_session/client.h>
|
||||
#include <topo_session/node.h>
|
||||
#include <base/connection.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Topo_connection;
|
||||
}
|
||||
|
||||
struct Genode::Topo_connection : Connection<Topo_session>, Topo_session_client
|
||||
{
|
||||
enum
|
||||
{
|
||||
RAM_QUOTA = 8192
|
||||
};
|
||||
|
||||
Topo_connection(Env &env, const char *label = "", Affinity const &affinity = Affinity())
|
||||
:
|
||||
Connection<Topo_session>(env,
|
||||
session(env.parent(), affinity, "ram_quota=%u, cap_quota=%u, label=\"%s\"", RAM_QUOTA, CAP_QUOTA, label)),
|
||||
Topo_session_client(cap()) {}
|
||||
|
||||
Node *node_affinity_of(Affinity::Location &loc) override {
|
||||
return Topo_session_client::node_affinity_of(loc);
|
||||
}
|
||||
|
||||
unsigned node_count() override {
|
||||
return Topo_session_client::node_count();
|
||||
}
|
||||
};
|
||||
42
repos/base/include/topo_session/node.h
Normal file
42
repos/base/include/topo_session/node.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* \brief Representation of a NUMA node
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Node;
|
||||
}
|
||||
|
||||
struct Genode::Node : List<Node>::Element
|
||||
{
|
||||
/* ID presented to component */
|
||||
unsigned _id;
|
||||
|
||||
unsigned _core_count;
|
||||
List<Node> neighbours;
|
||||
|
||||
/* Physical NUMA node ID */
|
||||
unsigned _native_id;
|
||||
|
||||
Node(unsigned id, unsigned native_id) : _id(id), _core_count(0), neighbours(), _native_id(native_id) {}
|
||||
|
||||
unsigned native_id() { return _native_id; }
|
||||
unsigned id() { return _id; }
|
||||
unsigned core_count() { return _core_count; }
|
||||
void core_count(unsigned count) { _core_count = count; }
|
||||
void increment_core_count() { _core_count++; }
|
||||
};
|
||||
52
repos/base/include/topo_session/topo_session.h
Normal file
52
repos/base/include/topo_session/topo_session.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <session/session.h>
|
||||
#include <base/affinity.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Topo_session;
|
||||
struct Topo_session_client;
|
||||
struct Node;
|
||||
}
|
||||
|
||||
struct Genode::Topo_session : Session
|
||||
{
|
||||
/**
|
||||
* \nooapi
|
||||
*
|
||||
*/
|
||||
static const char *service_name() { return "TOPO"; }
|
||||
|
||||
enum
|
||||
{
|
||||
CAP_QUOTA = 2
|
||||
};
|
||||
|
||||
typedef Topo_session_client Client;
|
||||
|
||||
virtual ~Topo_session() { }
|
||||
|
||||
virtual Node *node_affinity_of(Affinity::Location &) = 0;
|
||||
virtual unsigned node_count() = 0;
|
||||
|
||||
GENODE_RPC(Rpc_node_affinity, Node*, node_affinity_of, Affinity::Location &);
|
||||
GENODE_RPC(Rpc_node_count, unsigned, node_count);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_node_affinity, Rpc_node_count);
|
||||
};
|
||||
67
repos/base/src/core/include/topo_root.h
Normal file
67
repos/base/src/core/include/topo_root.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* \brief Topology service root component
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <root/component.h>
|
||||
|
||||
#include <topo_session_component.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Topo_root : public Root_component<Topo_session_component>
|
||||
{
|
||||
private:
|
||||
Ram_allocator &_ram_alloc;
|
||||
Region_map &_local_rm;
|
||||
|
||||
protected:
|
||||
|
||||
Topo_session_component *_create_session(char const *args, Affinity const &affinity) override {
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
|
||||
if (ram_quota < Trace::Control_area::SIZE)
|
||||
throw Insufficient_ram_quota();
|
||||
|
||||
if (!affinity.valid())
|
||||
throw Service_denied();
|
||||
|
||||
return new (md_alloc())
|
||||
Topo_session_component(*this->ep(),
|
||||
session_resources_from_args(args),
|
||||
session_label_from_args(args),
|
||||
session_diag_from_args(args),
|
||||
_ram_alloc, _local_rm,
|
||||
const_cast<Affinity&>(affinity));
|
||||
}
|
||||
|
||||
void _upgrade_session(Topo_session_component *topo, const char *args) override
|
||||
{
|
||||
topo->upgrade(ram_quota_from_args(args));
|
||||
topo->upgrade(cap_quota_from_args(args));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Topo_root(Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Rpc_entrypoint &session_ep,
|
||||
Allocator &md_alloc)
|
||||
:
|
||||
Root_component<Topo_session_component>(&session_ep, &md_alloc),
|
||||
_ram_alloc(ram_alloc), _local_rm(local_rm)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
61
repos/base/src/core/include/topo_session_component.h
Normal file
61
repos/base/src/core/include/topo_session_component.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/session_object.h>
|
||||
#include <base/affinity.h>
|
||||
#include <base/heap.h>
|
||||
#include <topo_session/topo_session.h>
|
||||
#include <topo_session/node.h>
|
||||
|
||||
namespace Genode {
|
||||
class Topo_session_component;
|
||||
}
|
||||
|
||||
class Genode::Topo_session_component : public Session_object<Topo_session>
|
||||
{
|
||||
private:
|
||||
Genode::Affinity &_affinity;
|
||||
Sliced_heap _md_alloc;
|
||||
|
||||
Node ***_node_affinities;
|
||||
unsigned _node_count;
|
||||
|
||||
public:
|
||||
Topo_session_component(Rpc_entrypoint &session_ep,
|
||||
Resources const &resources,
|
||||
Label const &label,
|
||||
Diag const &diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Affinity &affinity
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Topology session interface
|
||||
*/
|
||||
|
||||
Node *node_affinity_of(Affinity::Location &loc) override
|
||||
{
|
||||
return _node_affinities[loc.xpos()][loc.ypos()];
|
||||
}
|
||||
|
||||
unsigned node_count() override
|
||||
{
|
||||
return _node_count;
|
||||
}
|
||||
};
|
||||
58
repos/base/src/core/topo_session_component.cc
Normal file
58
repos/base/src/core/topo_session_component.cc
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
#include <topo_session_component.h>
|
||||
#include <platform_generic.h>
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Topo_session_component::Topo_session_component(Rpc_entrypoint &session_ep,
|
||||
Resources const &resources,
|
||||
Label const &label,
|
||||
Diag const &diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Affinity &affinity)
|
||||
:
|
||||
Session_object(session_ep, resources, label, diag),
|
||||
_md_alloc(ram_alloc, local_rm),
|
||||
_affinity(affinity)
|
||||
{
|
||||
const unsigned height = affinity.space().height();
|
||||
unsigned width = affinity.space().width();
|
||||
unsigned curr_node_id = 0;
|
||||
Node *node_created[] = new (_md_alloc) Node *[64]();
|
||||
|
||||
_node_affinities = new (_md_alloc) Node **[width];
|
||||
|
||||
|
||||
for (unsigned x = 0; x < width; x++) {
|
||||
_node_affinities[x] = new (_md_alloc) Node *[height];
|
||||
for (unsigned y = 0; y < height; y++) {
|
||||
|
||||
Affinity::Location loc = Affinity::Location(x, y);
|
||||
unsigned cpu_id = platform_specific().kernel_cpu_id(loc);
|
||||
unsigned native_id = platform_specific().domain_of_cpu(cpu_id);
|
||||
|
||||
if (!node_created[node_id]) {
|
||||
_node_affinities[x][y] = new (_md_alloc) Node(curr_node_id, native_id);
|
||||
_node_affinities[x][y]->increment_core_count();
|
||||
_node_count++;
|
||||
} else {
|
||||
(_node_affinities[x][y] = node_created[native_id])->increment_core_count();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user