diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc index 2fd75b2e0a..0043158c79 100644 --- a/repos/base-hw/src/core/pager.cc +++ b/repos/base-hw/src/core/pager.cc @@ -22,6 +22,16 @@ using namespace Core; +static unsigned _nr_of_cpus = 0; +static void *_pager_thread_memory = nullptr; + + +void Core::init_pager_thread_per_cpu_memory(unsigned const cpus, void * mem) +{ + _nr_of_cpus = cpus; + _pager_thread_memory = mem; +} + void Core::init_page_fault_handling(Rpc_entrypoint &) { } @@ -78,11 +88,12 @@ void Pager_object::print(Output &out) const Pager_object::Pager_object(Cpu_session_capability cpu_session_cap, Thread_capability thread_cap, addr_t const badge, - Affinity::Location, Session_label const &, + Affinity::Location location, Session_label const &, Cpu_session::Name const &) : Object_pool::Entry(Kernel_object::_cap), - _badge(badge), _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap) + _badge(badge), _location(location), + _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap) { } @@ -90,27 +101,46 @@ Pager_object::Pager_object(Cpu_session_capability cpu_session_cap, ** Pager_entrypoint ** **********************/ -void Pager_entrypoint::dissolve(Pager_object &o) -{ - Kernel::kill_signal_context(Capability_space::capid(o.cap())); - remove(&o); -} - - -Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &) +Pager_entrypoint::Thread::Thread(Affinity::Location cpu) : - Thread(Weight::DEFAULT_WEIGHT, "pager_ep", PAGER_EP_STACK_SIZE, - Type::NORMAL), - + Genode::Thread(Weight::DEFAULT_WEIGHT, "pager_ep", PAGER_EP_STACK_SIZE, cpu), _kobj(_kobj.CALLED_FROM_CORE) { start(); } +void Pager_entrypoint::dissolve(Pager_object &o) +{ + Kernel::kill_signal_context(Capability_space::capid(o.cap())); + + unsigned const cpu = o.location().xpos(); + if (cpu >= _cpus) + error("Invalid location of pager object ", cpu); + else + _threads[cpu].remove(&o); +} + + Pager_capability Pager_entrypoint::manage(Pager_object &o) { - o.start_paging(_kobj); - insert(&o); + unsigned const cpu = o.location().xpos(); + if (cpu >= _cpus) { + error("Invalid location of pager object ", cpu); + } else { + o.start_paging(_threads[cpu]._kobj); + _threads[cpu].insert(&o); + } + return reinterpret_cap_cast(o.cap()); } + + +Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &) +: + _cpus(_nr_of_cpus), + _threads((Thread*)_pager_thread_memory) +{ + for (unsigned i = 0; i < _cpus; i++) + construct_at((void*)&_threads[i], Affinity::Location(i, 0)); +} diff --git a/repos/base-hw/src/core/pager.h b/repos/base-hw/src/core/pager.h index 874dca41d1..6ff4a7d6d4 100644 --- a/repos/base-hw/src/core/pager.h +++ b/repos/base-hw/src/core/pager.h @@ -30,6 +30,8 @@ namespace Core { + class Platform; + /** * Interface used by generic region_map code */ @@ -55,6 +57,8 @@ namespace Core { enum { PAGER_EP_STACK_SIZE = sizeof(addr_t) * 2048 }; extern void init_page_fault_handling(Rpc_entrypoint &); + + void init_pager_thread_per_cpu_memory(unsigned const cpus, void * mem); } @@ -104,6 +108,7 @@ class Core::Pager_object : private Object_pool::Entry, private: unsigned long const _badge; + Affinity::Location _location; Cpu_session_capability _cpu_session_cap; Thread_capability _thread_cap; @@ -130,6 +135,8 @@ class Core::Pager_object : private Object_pool::Entry, */ unsigned long badge() const { return _badge; } + Affinity::Location location() { return _location; } + /** * Resume faulter */ @@ -198,20 +205,40 @@ class Core::Pager_object : private Object_pool::Entry, }; -class Core::Pager_entrypoint : public Object_pool, - public Thread, - private Ipc_pager +class Core::Pager_entrypoint { private: - Kernel_object _kobj; + friend class Platform; + + class Thread : public Object_pool, + public Genode::Thread, + private Ipc_pager + { + private: + + friend class Pager_entrypoint; + + Kernel_object _kobj; + + public: + + explicit Thread(Affinity::Location); + + + /********************** + ** Thread interface ** + **********************/ + + void entry() override; + }; + + unsigned const _cpus; + Thread *_threads; public: - /** - * Constructor - */ - Pager_entrypoint(Rpc_cap_factory &); + explicit Pager_entrypoint(Rpc_cap_factory &); /** * Associate pager object 'obj' with entry point @@ -222,13 +249,6 @@ class Core::Pager_entrypoint : public Object_pool, * Dissolve pager object 'obj' from entry point */ void dissolve(Pager_object &obj); - - - /********************** - ** Thread interface ** - **********************/ - - void entry() override; }; #endif /* _CORE__PAGER_H_ */ diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 33f4c4a65c..5e2cf3a982 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -19,6 +19,7 @@ /* base-hw core includes */ #include +#include #include #include #include @@ -253,6 +254,10 @@ Platform::Platform() ); } + unsigned const cpus = _boot_info().cpus; + size_t size = cpus * sizeof(Pager_entrypoint::Thread); + init_pager_thread_per_cpu_memory(cpus, _core_mem_alloc.alloc(size)); + class Idle_thread_trace_source : public Trace::Source::Info_accessor, private Trace::Control, private Trace::Source diff --git a/repos/base-hw/src/core/region_map_support.cc b/repos/base-hw/src/core/region_map_support.cc index 4f7f4df79d..e69bc7ddb0 100644 --- a/repos/base-hw/src/core/region_map_support.cc +++ b/repos/base-hw/src/core/region_map_support.cc @@ -20,7 +20,7 @@ using namespace Core; -void Pager_entrypoint::entry() +void Pager_entrypoint::Thread::entry() { Untyped_capability cap;