Compare commits

..

9 Commits

20 changed files with 416 additions and 95 deletions

View File

@@ -25,8 +25,13 @@ namespace Ealan { struct Habitat_connection; }
struct Ealan::Habitat_connection : Genode::Connection<Ealan::Habitat_session>, Habitat_client
{
Habitat_connection(Genode::Env &env, Genode::Affinity &affinity, Label const &label = Label())
: Connection<Habitat_session>(env, label, Genode::Ram_quota { RAM_QUOTA }, affinity, Args("")), Habitat_client(cap()) {}
Habitat_connection(Genode::Env &env, Genode::Affinity &affinity,
Label const &label = Label())
: Connection<Habitat_session>(env, label, Genode::Ram_quota{RAM_QUOTA}, affinity,
Args("")),
Habitat_client(cap())
{
}
Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) override {
return Habitat_client::create_cell(pd_cap, affinity, prio, label, is_brick);

View File

@@ -298,9 +298,15 @@ namespace Tukija {
ALWAYS_INLINE
inline uint8_t create_cell(mword_t pd, uint8_t prio, mword_t &cip, mword_t &dst)
inline uint8_t create_cell(mword_t pd, mword_t hsel, uint8_t prio, mword_t &cip, mword_t &dst)
{
return syscall_5(TUKIJA_CREATE_CELL, prio, pd, dst, cip);
return syscall_5(TUKIJA_CREATE_CELL, prio, pd, hsel, dst, cip);
}
ALWAYS_INLINE
inline uint8_t create_habitat(mword_t sel, mword_t dst)
{
return syscall_1(TUKIJA_CREATE_HABITAT, 0, sel, dst);
}
ALWAYS_INLINE
@@ -424,6 +430,12 @@ namespace Tukija {
return syscall_0(TUKIJA_CELL_CTRL, op, pd);
}
ALWAYS_INLINE
inline uint8_t map_tip(mword_t pd)
{
return syscall_0(TUKIJA_MAP_TIP, 0, pd);
}
ALWAYS_INLINE
inline uint8_t release(Tukija::Resource_type type, Tukija::Release_op op = Tukija::Release_op::RELEASE)
{

View File

@@ -57,26 +57,28 @@ namespace Tukija {
* NOVA system-call IDs
*/
enum Syscall {
NOVA_CALL = 0x0,
NOVA_REPLY = 0x1,
NOVA_CREATE_PD = 0x2,
NOVA_CREATE_EC = 0x3,
NOVA_CREATE_SC = 0x4,
NOVA_CREATE_PT = 0x5,
NOVA_CREATE_SM = 0x6,
NOVA_REVOKE = 0x7,
NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */
NOVA_EC_CTRL = 0x9,
NOVA_SC_CTRL = 0xa,
NOVA_PT_CTRL = 0xb,
NOVA_SM_CTRL = 0xc,
NOVA_ASSIGN_PCI = 0xd,
NOVA_ASSIGN_GSI = 0xe,
NOVA_PD_CTRL = 0xf,
TUKIJA_CREATE_CELL = 0x10,
TUKIJA_ALLOCATE = 0x11,
TUKIJA_CELL_CTRL = 0x12,
TUKIJA_RELEASE = 0x13,
NOVA_CALL = 0x0,
NOVA_REPLY = 0x1,
NOVA_CREATE_PD = 0x2,
NOVA_CREATE_EC = 0x3,
NOVA_CREATE_SC = 0x4,
NOVA_CREATE_PT = 0x5,
NOVA_CREATE_SM = 0x6,
NOVA_REVOKE = 0x7,
NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */
NOVA_EC_CTRL = 0x9,
NOVA_SC_CTRL = 0xa,
NOVA_PT_CTRL = 0xb,
NOVA_SM_CTRL = 0xc,
NOVA_ASSIGN_PCI = 0xd,
NOVA_ASSIGN_GSI = 0xe,
NOVA_PD_CTRL = 0xf,
TUKIJA_CREATE_CELL = 0x10,
TUKIJA_ALLOCATE = 0x11,
TUKIJA_CELL_CTRL = 0x12,
TUKIJA_RELEASE = 0x13,
TUKIJA_MAP_TIP = 0x14,
TUKIJA_CREATE_HABITAT = 0x15
};
/**
@@ -135,7 +137,11 @@ namespace Tukija {
inline mword_t bit_cpu(unsigned const cpu) const {
return cpu % CPUS_PER_VALUE;
}
inline mword_t values()
{
return sizeof(raw) / sizeof(raw[0]);
}
public:
inline explicit Cpuset(mword_t const v)
{
@@ -182,6 +188,16 @@ namespace Tukija {
}
}
unsigned first_cpu()
{
long cpu = -1;
for (unsigned i = 0; i < values(); i++) {
cpu = bit_scan_forward(raw[i]);
if (cpu != -1) break;
}
return static_cast<unsigned>(cpu);
}
unsigned count()
{
unsigned count = 0;
@@ -200,6 +216,17 @@ namespace Tukija {
}
};
/**
* @brief Habitat Information page
*
*/
struct Habitat_info_page
{
alignas(64) Cpuset reserved_cores{0};
alignas(64) Cpuset current_cores{0};
alignas(64) bool resizable{false};
};
/**
* Cell information pages
*
@@ -300,6 +327,25 @@ namespace Tukija {
Genode::Affinity::Location loc = Genode::Thread::myself()->affinity();
return location_to_index(loc);
}
Genode::Affinity::Location kernel_cpu_to_location(unsigned cpu)
{
unsigned idx = 0;
for (; idx < 256; idx++) {
if (idx_to_phys_cpu_id[idx] == cpu)
break;
}
if (idx >= habitat_affinity.total())
return Genode::Affinity::Location();
unsigned y = idx / habitat_affinity.width();
unsigned x = ((idx - y) / habitat_affinity.height() - location.xpos()) %
habitat_affinity.width();
return Genode::Affinity::Location(x,y);
}
/**
* @brief Return the worker information structure for the workers at the given location

View File

@@ -15,6 +15,8 @@
#define _CORE__INCLUDE__CELL_COMPONENT_H_
/* Genode includes */
#include "base/affinity.h"
#include "tukija/stdint.h"
#include <base/rpc_server.h>
#include <base/session_label.h>
#include <pd_session/client.h>
@@ -49,7 +51,8 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
Genode::Region_map &_rm;
Genode::Pd_session_capability _pd_cap;
Genode::Pd_session_client _pd;
Genode::Tukija_native_pd_client _native_pd;
Genode::Tukija_native_pd_client _native_pd;
Genode::Affinity _habitat;
Tukija::Cip *_cip{nullptr};
@@ -83,8 +86,14 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
public:
Cell_component(Genode::Pd_session_capability pd_cap, Genode::uint16_t prio, Genode::Affinity &affinity, Genode::Rpc_entrypoint &ep, Genode::Region_map &rm, Genode::Session_label const &label, bool is_brick) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()), _is_brick(is_brick) {
Tukija::mword_t cell_pd_sel = _native_pd.sel();
Cell_component(Genode::Pd_session_capability pd_cap, Genode::uint16_t prio,
Genode::Affinity &affinity, Genode::Rpc_entrypoint &ep,
Genode::Region_map &rm, Genode::Session_label const &label, bool is_brick,
Tukija::mword_t habitat_sel, Genode::Affinity habitat_affinity)
: _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap),
_native_pd(_pd.native_pd()), _habitat(habitat_affinity), _is_brick(is_brick)
{
Tukija::mword_t cell_pd_sel = _native_pd.sel();
Tukija::mword_t cip_phys = 0;
/* Allocate a region map for mapping the CIP of this new cell.
@@ -101,7 +110,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
* a page frame for the CIP. The CIP will then be mapped by the kernel using the
* supplied virtual address from the previously allocated region map.
*/
if (Tukija::create_cell(cell_pd_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt)) {
if (Tukija::create_cell(cell_pd_sel, habitat_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt)) {
Genode::error("Failed to create cell at Tukija.");
throw Cell_creation_error();
}
@@ -127,9 +136,9 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
_map_location_to_kernel(Genode::Affinity(affinity.space(), Genode::Affinity::Location(0,0,affinity.space().width(), affinity.space().height())));
_ep.manage(this);
}
}
~Cell_component()
~Cell_component()
{
Genode::log("Destroying Cell session");
Core::platform().region_alloc().free(_cip);
@@ -147,10 +156,11 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
void update(Genode::Affinity &affinity) override {
/* TODO: implement */
Genode::log("Changing cell ", _session_label,"'s affinity to ", affinity);
_cip->cores_reserved.clear();
_cip->cores_reserved.clear();
if (_cip->cores_reserved.count() != 0)
Genode::error("Failed clearing reserved cores");
_calculate_mask_for_location(&_cip->cores_reserved, affinity.location());
_calculate_mask_for_location(&_cip->cores_reserved, affinity.location().transpose(_habitat.location().xpos(), _habitat.location().ypos()));
Genode::log(_session_label, "'s cores: ", _cip->cores_reserved);
Tukija::cell_ctrl(_native_pd.sel(), Tukija::Cell_control::UPDATE_AFFINITY);
}

View File

@@ -1,6 +1,8 @@
#ifndef __CORE_HABITAT_ROOT_H
#define __CORE_HABITAT_ROOT_H
#include "base/affinity.h"
#include "platform_generic.h"
#include <root/component.h>
#include <base/log.h>
@@ -20,6 +22,8 @@ namespace Core {
Habitat_session_component *_create_session(char const *args, Genode::Affinity const &affinity) override {
Genode::log("Creating new habitat ", affinity);
size_t ram_quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
@@ -31,6 +35,10 @@ namespace Core {
throw Genode::Service_denied();
}
Genode::Affinity::Location session_location =
affinity.scale_to(Core::platform().affinity_space());
return new (md_alloc()) Habitat_session_component(
*this->ep(),
session_resources_from_args(args),
@@ -38,7 +46,7 @@ namespace Core {
session_diag_from_args(args),
_ram_alloc,
_local_rm,
affinity);
Genode::Affinity(Core::platform().affinity_space(), session_location));
}
void _upgrade_session(Habitat_session_component *habitat, const char *args) override

View File

@@ -13,6 +13,14 @@
#ifndef _CORE__HABITAT_SESSION_COMPONENT_H_
#define _CORE__HABITAT_SESSION_COMPONENT_H_
#include "base/affinity.h"
#include "base/ram_allocator.h"
#include "base/stdint.h"
#include "dataspace_component.h"
#include "platform_generic.h"
#include "region_map/region_map.h"
#include "tukija/stdint.h"
#include "tukija/syscall-generic.h"
#include <base/rpc_server.h>
#include <base/env.h>
#include <base/allocator.h>
@@ -24,7 +32,7 @@
#include <tukija_native_pd/client.h>
#include <pd_session/client.h>
#include <cell_component.h>
#include <tukija/cap_map.h>
#include <nova_util.h>
@@ -34,29 +42,68 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
{
private:
Genode::Region_map &_local_rm;
Genode::Affinity const &_affinity;
Genode::Affinity const _affinity;
Genode::Session_label const &_label;
Genode::Constrained_ram_allocator _ram_alloc;
Genode::Sliced_heap _md_alloc;
Genode::Rpc_entrypoint &_ep;
Genode::List<Ealan::Cell_component> _managed_cells { };
Genode::List<Ealan::Cell_component> _managed_cells{};
Genode::addr_t _id_base;
Tukija::Habitat_info_page *haip{};
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Location &loc)
Genode::addr_t _sel() const { return _id_base; }
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Location &location)
{
const_cast<Genode::Affinity::Location&>(loc).for_each(
const_cast<Genode::Affinity::Location&>(location).for_each(
[&](Genode::Affinity::Location const &location)
{
unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location);
coreset->set(kernel_cpu);
});
}
}
Habitat_session_component(const Habitat_session_component &);
Habitat_session_component& operator=(const Habitat_session_component&);
public:
Habitat_session_component(Genode::Rpc_entrypoint &ep, Genode::Session::Resources const &resources, Genode::Session_label const &label, Genode::Session::Diag const &diag, Genode::Ram_allocator &ram, Genode::Region_map &rm, Genode::Affinity const &affinity) : Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag), _local_rm(rm), _affinity(affinity), _label(label), _ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm), _ep(ep) {}
Habitat_session_component(Genode::Rpc_entrypoint &ep,
Genode::Session::Resources const &resources,
Genode::Session_label const &label,
Genode::Session::Diag const &diag, Genode::Ram_allocator &ram,
Genode::Region_map &rm, Genode::Affinity const &affinity)
: Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag),
_local_rm(rm), _affinity(affinity), _label(label),
_ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm),
_ep(ep), _id_base(cap_map().insert(1))
{
Core::platform().region_alloc().alloc_aligned(Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result([&](void *ptr) { haip = static_cast<Tukija::Habitat_info_page*>(ptr); }, [&](Genode::Range_allocator::Alloc_error) { haip = nullptr; });
if (!haip) { Genode::error("Failed to allocate Habitat Info Page"); }
Tukija::create_habitat(_sel(), reinterpret_cast<Tukija::mword_t>(haip));
_calculate_mask_for_location(&haip->reserved_cores, _affinity.location());
Genode::log("Created habitat: ", haip->reserved_cores);
}
Ealan::Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, [[maybe_unused]] Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) override {
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label, is_brick);
Genode::log("Habitat ", _affinity);
Genode::log(haip->reserved_cores);
Genode::Affinity::Location location = affinity.location().transpose(
_affinity.location().xpos(), _affinity.location().ypos());
Genode::Affinity session_affinity(Core::platform().affinity_space(), location);
Genode::log(label, ": ", affinity, "->", session_affinity);
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, session_affinity, _ep, _local_rm, label, is_brick, _sel(), _affinity);
_managed_cells.insert(cell);

View File

@@ -158,6 +158,11 @@ void Pager_object::_page_fault_handler(Pager_object &obj)
/* lookup fault address and decide what to do */
unsigned error = (obj.pager(ipc_pager) == Pager_object::Pager_result::STOP);
if (ipc_pager.fault_addr() >= reinterpret_cast<Genode::addr_t>(Tukija::Tip::tip())) {
Genode::error("TIP is not mapped.");
Tukija::map_tip(obj.pd_sel());
}
/* don't open receive window for pager threads */
if (utcb.crd_rcv.value())
nova_die();

View File

@@ -40,7 +40,7 @@ Platform_pd::Platform_pd(Allocator &, char const *label, signed, bool)
log("Creating PD for <", label, "> with cap selector ", _pd_sel);
/* create task */
enum { KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE = 2, UPPER_LIMIT_PAGES = 192 };
enum { KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE = 2, UPPER_LIMIT_PAGES = 1024 };
uint8_t res = Tukija::create_pd(_pd_sel, platform_specific().core_pd_sel(),
Tukija::Obj_crd(),
KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE,

View File

@@ -93,6 +93,13 @@ class Genode::Affinity
return Affinity::Space(node.attribute_value("width", 0U),
node.attribute_value("height", 0U));
}
template <typename FUNC> void for_each(const FUNC &f)
{
for (unsigned i = 0; i < total(); i++) {
f(location_of_index(i));
}
}
};

View File

@@ -267,7 +267,7 @@ Cpu_session_component::Cpu_session_component(Rpc_entrypoint &session_ep,
_thread_alloc(_md_alloc), _priority(0),
/* map affinity to a location within the physical affinity space */
_location(affinity.scale_to(platform().affinity_space())),
_location(affinity.location()),
_trace_sources(trace_sources),
_trace_control_area(_ram_alloc, local_rm),

View File

@@ -12,6 +12,7 @@
#ifndef __INCLUDE__EALANOS__MEMORY__SUPERBLOCK_H_
#define __INCLUDE__EALANOS__MEMORY__SUPERBLOCK_H_
#include "base/log.h"
#include <ealanos/util/lifo_queue.h>
#include <base/stdint.h>
#include <base/ram_allocator.h>
@@ -92,23 +93,28 @@ class Ealan::Memory::Superblock : public Hyperblock
alignas(64) Genode::addr_t _start{0}; /* Start address of the blocks */
public:
Superblock(Genode::size_t sz) : _size_class(sz)
Superblock(Genode::size_t sz, bool debug=false) : _size_class(sz)
{
if (_size_class > SIZE) {
Genode::error("Size class ", _size_class, " is bigger than superblock size ", SIZE);
}
/*Genode::log("Superblock SIZE=", SIZE, " BASE=", BASE, " this at ", this);
Genode::log("Block metadata size is ", sizeof(Block));
Genode::log("Size class of superblock is ", _size_class);
Genode::log("Superblock ends at ", reinterpret_cast<void*>(_end));
Genode::log("Capacity is ", capacity());
Genode::log("-------------------");*/
Genode::addr_t end = reinterpret_cast<Genode::addr_t>(this) + SIZE - sizeof(Block) - _size_class;
if (debug) {
Genode::log("Superblock SIZE=", SIZE, " BASE=", BASE, " this at ", this);
Genode::log("Block metadata size is ", sizeof(Block));
Genode::log("Size class of superblock is ", _size_class);
Genode::log("Superblock ends at ", reinterpret_cast<void*>(end));
Genode::log("Capacity is ", capacity());
Genode::log("-------------------");
}
for (Genode::addr_t block = reinterpret_cast<Genode::addr_t>(&_start); block < end; block += sizeof(Block) + _size_class) {
Block *b = reinterpret_cast<Block *>(block);
b->_superblock = this;
_blocks.enqueue(b);
if (debug)
Genode::log("Enqueued block ", b);
}
}
@@ -123,24 +129,22 @@ class Ealan::Memory::Superblock : public Hyperblock
if (block)
return reinterpret_cast<Block*>(reinterpret_cast<Genode::addr_t>(block)+64);
/*if (block != nullptr) {
if (block->reserve(this)) {
__atomic_compare_exchange_n(&last_freed_block, &block, nullptr, false,
__ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
return reinterpret_cast<void*>(reinterpret_cast<Genode::addr_t>(block)+64);
}
if (block->reserve(this)) {
__atomic_compare_exchange_n(&last_freed_block, &block, nullptr, false,
__ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
return reinterpret_cast<void*>(reinterpret_cast<Genode::addr_t>(block)+64);
}
}
Block *block = reinterpret_cast<Block *>(&_start);
Block *end = reinterpret_cast<Block *>(reinterpret_cast<Genode::addr_t>(this) + SIZE - 64);
while (block < end) {
Genode::addr_t next = reinterpret_cast<Genode::addr_t>(block) + sizeof(Block) + _size_class;
if (block->_superblock == nullptr) {
if (block->reserve(this)) {
return reinterpret_cast<void *>(reinterpret_cast<Genode::addr_t>(block) +
64);
}
}
block = reinterpret_cast<Block *>(next);
Block *end = reinterpret_cast<Block *>(reinterpret_cast<Genode::addr_t>(this) + SIZE -
64); while (block < end) { Genode::addr_t next = reinterpret_cast<Genode::addr_t>(block)
+ sizeof(Block) + _size_class; if (block->_superblock == nullptr) { if
(block->reserve(this)) { return reinterpret_cast<void
*>(reinterpret_cast<Genode::addr_t>(block) + 64);
}
}
block = reinterpret_cast<Block *>(next);
}*/
return nullptr;
}
@@ -179,8 +183,10 @@ class Ealan::Memory::Superblock : public Hyperblock
Block *b = reinterpret_cast<Block *>(reinterpret_cast<Genode::addr_t>(ptr) - 64);
Block *end = reinterpret_cast<Block *>(reinterpret_cast<Genode::addr_t>(this) + SIZE);
if (b > --end)
return;
/*if (b > --end && b < reinterpret_cast<Block *>(this)) {
Genode::warning("freeing Block that does not belong to this superblock");
return;
}*/
_blocks.enqueue(b);
}

View File

@@ -0,0 +1,142 @@
set build_components {
core init hoitaja timer lib/ld lib/libm lib/libc lib/stdcxx lib/vfs app/allocating_cell
}
build $build_components
create_boot_directory
install_config {
<config prio_levels="32">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Habitat"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<affinity-space width="64" height="1"/>
<default caps="500"/>
<start name="timer" brick="yes">
<resource name="RAM" quantum="16M"/>
<affinity xpos="0" ypos="0" width="1" height="1"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="habitat_a" caps="1500" managing_system="yes" brick="yes">
<resource name="RAM" quantum="128G"/>
<affinity xpos="32" width="32" height="1" ypos="0"/>
<binary name="hoitaja"/>
<route>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
<config prio_levels="32" verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<affinity-space width="32" height="1"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="500"/>
<start name="allocating_cell">
<binary name="allocating_cell"/>
<resource name="RAM" quantum="128M"/>
<config start_with="63" end_with="63" calls="300">
<vfs> <dir name="dev">
<log/>
<inline name="rtc">2022-07-20 14:30</inline>
</dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
</config>
</start>
</config>
</start>
<start name="habitat_b" caps="1500" managing_system="yes" brick="yes">
<resource name="RAM" quantum="128G"/>
<affinity xpos="0" width="32" height="1" ypos="0"/>
<binary name="hoitaja"/>
<route>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
<config prio_levels="32" verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<affinity-space width="32" height="1"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="500"/>
<start name="allocating_cell">
<binary name="allocating_cell"/>
<resource name="RAM" quantum="128M"/>
<config start_with="63" end_with="63" calls="300">
<vfs> <dir name="dev">
<log/>
<inline name="rtc">2022-07-20 14:30</inline>
</dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
</config>
</start>
</config>
</start>
</config>
}
build_boot_image [build_artifacts]
append qemu_args " -nographic "
set succeeded 0
set failed 0
for {set i 0} { $i < 3000 } { incr i } {
if { ! [catch {run_genode_until ".*Changing cell timer\'s affinity to .*0,0,64.*" 60} result ] } {
incr succeeded
puts "\n $succeeded of 3000 succeeded"
kill_spawned $qemu_spawn_id
} else {
incr failed
kill_spawned $qemu_spawn_id
}
}
puts "\n $succeeded of $i succeeded. $failed of $i failed."

View File

@@ -691,22 +691,24 @@ Genode::Affinity Sandbox::Child::filter_session_affinity(Affinity const &session
if (session_affinity.space().total() == 0)
return Affinity(child_space, child_location);
Affinity::Space const &session_space = session_affinity.space();
//Affinity::Space const &session_space = session_affinity.space();
Affinity::Location const &session_location = session_affinity.location();
/* scale resolution of resulting space */
Affinity::Space space(child_space.multiply(session_space));
Affinity::Location child_session(child_location.xpos(), child_location.ypos(),
child_location.width() * session_location.width(),
child_location.height() * session_location.height());
/* scale resolution of resulting space */
//Affinity::Space space(child_space.multiply(session_space));
Affinity::Location child_session(child_location.xpos(), child_location.ypos(),
session_location.width(),
session_location.height() );
/* subordinate session affinity to child affinity subspace */
Affinity::Location location(child_session
.multiply_position(session_space)
.transpose(session_location.xpos() * child_location.width(),
session_location.ypos() * child_location.height()));
//.multiply_position(session_space)
.transpose(session_location.xpos() ,
session_location.ypos() ));
return Affinity(space, location);
return Affinity(child_space, location);
}

View File

@@ -79,8 +79,15 @@ class Hoitaja::Core_allocator
Genode::log("Resource coefficient: ", _resource_coeff);
unsigned int cores_share = _calculate_resource_share(priority);
unsigned int xpos = _cores_for_cells - cores_share;
if (xpos <= 0) {
xpos = 1;
cores_share -= 1;
}
return Genode::Affinity::Location( _cores_for_cells-cores_share, 0, cores_share, 1 ); /* always use the core_share last cores, for now */
return Genode::Affinity::Location( xpos, 0, cores_share, 1 ); /* always use the core_share last cores, for now */
}
void free_cores_from_cell(::Sandbox::Child &cell)
@@ -116,10 +123,17 @@ class Hoitaja::Core_allocator
if (*xpos - static_cast<int>(cores_share) <= *lower_limit) {
cores_share-= *lower_limit; // Save one core for Hoitaja
}
}
Genode::Affinity::Location location(*xpos - cores_share, resources.affinity.location().ypos(), cores_share, resources.affinity.location().height());
unsigned int new_xpos = *xpos - cores_share;
if (!new_xpos) {
new_xpos = 1;
cores_share -= 1;
}
Genode::Affinity::Location location(new_xpos, resources.affinity.location().ypos(), cores_share, resources.affinity.location().height());
Genode::log(cell.name(), ": ", location);
/*if (resources.affinity.location() != location) { // Only update, if location has actually changed
cell.update_affinity(Genode::Affinity(resources.affinity.space(), location));
}

View File

@@ -467,7 +467,7 @@ bool Genode::Sandbox::Library::ready_to_create_child(Start_model::Name const
if (_affinity_space.constructed() && !_core_allocator.constructed()) {
log("Creating new core allocator for ", _affinity_space->total(), " cores.");
_core_allocator.construct(*_affinity_space, _prio_levels);
_habitat.construct(_env, Affinity(*_affinity_space, Affinity::Location(0,0)));
_habitat.construct(_env, Affinity(*_affinity_space, Affinity::Location(0,0, _affinity_space->width(), _affinity_space->height())));
}
Affinity::Location allocation = _core_allocator->allocate_cores_for_cell(start_node);

View File

@@ -7,6 +7,7 @@
LIBC_PORT_DIR := $(call select_from_ports,libc)
LIBC_DIR := $(LIBC_PORT_DIR)/src/lib/libc
LIBC_REP_DIR := $(realpath $(call select_from_repositories,include/libc-genode)/../..)
EALAN_REP_DIR := $(realpath $(call select_from_repositories,ealanos))
# local libc includes
INC_DIR += $(LIBC_DIR)/lib/libc/locale
@@ -14,6 +15,7 @@ INC_DIR += $(LIBC_DIR)/lib/libc/include
INC_DIR += $(LIBC_DIR)/lib/libc/stdio
INC_DIR += $(LIBC_DIR)/lib/libc/net
INC_DIR += $(LIBC_DIR)/contrib/gdtoa
INC_DIR += $(EALAN_REP_DIR)/include
#CC_OPT += -DGENODE_RELEASE

View File

@@ -15,6 +15,8 @@
#define _LIBC__INTERNAL__INIT_H_
/* Genode includes */
#include "pd_session/pd_session.h"
#include "region_map/region_map.h"
#include <base/env.h>
#include <base/heap.h>
#include <util/xml_node.h>
@@ -98,7 +100,7 @@ namespace Libc {
/**
* Malloc allocator
*/
void init_malloc(Genode::Allocator &);
void init_malloc(Genode::Pd_session &pd , Genode::Region_map &rm);
void init_malloc_cloned(Clone_connection &);
void reinit_malloc(Genode::Allocator &);

View File

@@ -45,6 +45,7 @@
#include <internal/atexit.h>
#include <internal/rtc.h>
namespace Libc {
class Kernel;
class Main_blockade;

View File

@@ -500,7 +500,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
} else {
_malloc_heap.construct(*_malloc_ram, _env.rm());
init_malloc(*_malloc_heap);
init_malloc(_env.pd(), _env.rm());
}
init_fork(_env, _fd_alloc, _libc_env, _heap, *_malloc_heap, _pid, *this,

View File

@@ -13,6 +13,8 @@
*/
/* Genode includes */
#include "pd_session/pd_session.h"
#include "region_map/region_map.h"
#include <base/env.h>
#include <base/log.h>
#include <base/slab.h>
@@ -30,6 +32,7 @@ extern "C" {
#include <internal/init.h>
#include <internal/clone_session.h>
#include <internal/errno.h>
#include <ealanos/memory/hamstraaja.h>
namespace Libc {
@@ -83,7 +86,7 @@ class Libc::Malloc
SLAB_START = 5, /* 32 bytes (log2) */
SLAB_STOP = 11, /* 2048 bytes (log2) */
NUM_SLABS = (SLAB_STOP - SLAB_START) + 1,
DEFAULT_ALIGN = 16
DEFAULT_ALIGN = 64
};
struct Metadata
@@ -232,10 +235,11 @@ class Libc::Malloc
using namespace Libc;
using Hamsterer = Ealan::Memory::Hamstraaja<32, 2048>;
//static Malloc *mallocator;
static Malloc *mallocator;
static Hamsterer *mallocator;
extern "C" void *malloc(size_t size)
{
@@ -267,13 +271,21 @@ extern "C" void *realloc(void *ptr, size_t size)
return nullptr;
}
return mallocator->realloc(ptr, size);
void *new_addr = mallocator->alloc(size);
if (new_addr) {
::memcpy(new_addr, ptr, size);
free(ptr);
}
return new_addr;
//return mallocator->realloc(ptr, size);
}
int posix_memalign(void **memptr, size_t alignment, size_t size)
{
*memptr = mallocator->alloc(size, alignment);
*memptr = mallocator->aligned_alloc(size, alignment);
if (!*memptr)
return Errno(ENOMEM);
@@ -283,19 +295,19 @@ int posix_memalign(void **memptr, size_t alignment, size_t size)
/* space for singleton object w/o destructor */
static long _malloc_obj[(sizeof(Malloc) + sizeof(long))/sizeof(long)];
static long _malloc_obj[(sizeof(Hamsterer) + sizeof(long))/sizeof(long)];
void Libc::init_malloc(Genode::Allocator &heap)
void Libc::init_malloc(Genode::Pd_session &pd, Genode::Region_map &rm)
{
mallocator = construct_at<Malloc>(_malloc_obj, heap);
mallocator = construct_at<Hamsterer>(_malloc_obj, pd, rm);
}
void Libc::init_malloc_cloned(Clone_connection &clone_connection)
{
clone_connection.object_content(_malloc_obj);
mallocator = (Malloc *)_malloc_obj;
mallocator = (Hamsterer *)_malloc_obj;
}