From bc82cce72b74090b8b797d53ca67118542beaa72 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 7 May 2017 22:44:15 +0200 Subject: [PATCH] core: add Platform::max_caps() This method returns the kernel-specific system-global limit of the total number of capabilities. Issue #2398 --- repos/base-fiasco/src/core/include/platform.h | 21 +++++++------ repos/base-foc/src/core/include/platform.h | 2 ++ .../src/include/base/internal/cap_alloc.h | 2 ++ .../src/include/base/internal/cap_map.h | 5 +++ repos/base-hw/src/core/platform.h | 7 +++++ repos/base-linux/src/core/include/platform.h | 31 +++++++++++++------ repos/base-nova/src/core/include/platform.h | 3 ++ repos/base-nova/src/core/platform.cc | 4 ++- repos/base-okl4/src/core/include/platform.h | 24 ++++++++------ .../src/core/include/platform.h | 24 ++++++++------ repos/base-sel4/src/core/include/platform.h | 4 +++ repos/base/src/core/capability_space.cc | 7 ++++- .../base/src/core/include/platform_generic.h | 5 +++ .../include/base/internal/capability_space.h | 5 +++ 14 files changed, 105 insertions(+), 39 deletions(-) diff --git a/repos/base-fiasco/src/core/include/platform.h b/repos/base-fiasco/src/core/include/platform.h index d0df2c30d4..8c2ee23f15 100644 --- a/repos/base-fiasco/src/core/include/platform.h +++ b/repos/base-fiasco/src/core/include/platform.h @@ -16,6 +16,7 @@ #define _CORE__INCLUDE__PLATFORM_H_ #include +#include #include "synced_range_allocator.h" #include "platform_generic.h" @@ -139,15 +140,17 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Range_allocator *core_mem_alloc() { return &_ram_alloc; } - Range_allocator *ram_alloc() { return &_ram_alloc; } - Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } - Range_allocator *io_port_alloc() { return &_io_port_alloc; } - Range_allocator *irq_alloc() { return &_irq_alloc; } - Range_allocator *region_alloc() { return &_region_alloc; } - addr_t vm_start() const { return _vm_start; } - size_t vm_size() const { return _vm_size; } - Rom_fs *rom_fs() { return &_rom_fs; } + Range_allocator *core_mem_alloc() override { return &_ram_alloc; } + Range_allocator *ram_alloc() override { return &_ram_alloc; } + Range_allocator *io_mem_alloc() override { return &_io_mem_alloc; } + Range_allocator *io_port_alloc() override { return &_io_port_alloc; } + Range_allocator *irq_alloc() override { return &_irq_alloc; } + Range_allocator *region_alloc() override { return &_region_alloc; } + addr_t vm_start() const override { return _vm_start; } + size_t vm_size() const override { return _vm_size; } + Rom_fs *rom_fs() override { return &_rom_fs; } + + size_t max_caps() const { return Capability_space::max_caps(); } void wait_for_exit(); }; diff --git a/repos/base-foc/src/core/include/platform.h b/repos/base-foc/src/core/include/platform.h index 3f1766b514..9af71887f2 100644 --- a/repos/base-foc/src/core/include/platform.h +++ b/repos/base-foc/src/core/include/platform.h @@ -158,6 +158,8 @@ namespace Genode { Rom_fs *rom_fs() { return &_rom_fs; } Affinity::Space affinity_space() const; + size_t max_caps() const override { return cap_idx_alloc()->max_caps(); } + void wait_for_exit(); }; } diff --git a/repos/base-foc/src/include/base/internal/cap_alloc.h b/repos/base-foc/src/include/base/internal/cap_alloc.h index 89a77150f2..b5e5977708 100644 --- a/repos/base-foc/src/include/base/internal/cap_alloc.h +++ b/repos/base-foc/src/include/base/internal/cap_alloc.h @@ -134,6 +134,8 @@ namespace Genode { { construct_at >(this); } + + size_t max_caps() const override { return SZ; } }; } diff --git a/repos/base-foc/src/include/base/internal/cap_map.h b/repos/base-foc/src/include/base/internal/cap_map.h index 7a78b8344b..96855bf075 100644 --- a/repos/base-foc/src/include/base/internal/cap_map.h +++ b/repos/base-foc/src/include/base/internal/cap_map.h @@ -113,6 +113,11 @@ namespace Genode { * Redo construction of the object */ virtual void reinit() = 0; + + /** + * Return capacity of allocator + */ + virtual size_t max_caps() const = 0; }; diff --git a/repos/base-hw/src/core/platform.h b/repos/base-hw/src/core/platform.h index b0b547c0d8..48be5e995e 100644 --- a/repos/base-hw/src/core/platform.h +++ b/repos/base-hw/src/core/platform.h @@ -25,6 +25,7 @@ #include #include #include +#include /* core includes */ #include @@ -140,6 +141,12 @@ class Genode::Platform : public Genode::Platform_generic Affinity::Space affinity_space() const { return Affinity::Space(NR_OF_CPUS); } + + /* + * The system-wide maximum number of capabilities is constrained + * by core's local capability space. + */ + size_t max_caps() const override { return Kernel::Pd::max_cap_ids; } }; #endif /* _CORE__PLATFORM_H_ */ diff --git a/repos/base-linux/src/core/include/platform.h b/repos/base-linux/src/core/include/platform.h index b5076e0e94..5519bc53cb 100644 --- a/repos/base-linux/src/core/include/platform.h +++ b/repos/base-linux/src/core/include/platform.h @@ -83,15 +83,28 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Range_allocator *core_mem_alloc() { return &_core_mem_alloc; } - Range_allocator *ram_alloc() { return &_ram_alloc; } - Range_allocator *io_mem_alloc() { return 0; } - Range_allocator *io_port_alloc() { return 0; } - Range_allocator *irq_alloc() { return 0; } - Range_allocator *region_alloc() { return 0; } - addr_t vm_start() const { return 0; } - size_t vm_size() const { return 0; } - Rom_fs *rom_fs() { return 0; } + Range_allocator *core_mem_alloc() override { return &_core_mem_alloc; } + Range_allocator *ram_alloc() override { return &_ram_alloc; } + Range_allocator *io_mem_alloc() override { return 0; } + Range_allocator *io_port_alloc() override { return 0; } + Range_allocator *irq_alloc() override { return 0; } + Range_allocator *region_alloc() override { return 0; } + addr_t vm_start() const override { return 0; } + size_t vm_size() const override { return 0; } + Rom_fs *rom_fs() override { return 0; } + + /* + * On Linux, the maximum number of capabilities is primarily + * constrained by the limited number of file descriptors within + * core. Each dataspace and and each thread consumes one + * descriptor. However, all capabilies managed by the same + * entrypoint share the same file descriptor such that the fd + * limit would be an overly pessimistic upper bound. + * + * Hence, we define the limit somewhat arbitrary on Linux and + * accept that scenarios may break when reaching core's fd limit. + */ + size_t max_caps() const override { return 10000; } void wait_for_exit(); }; diff --git a/repos/base-nova/src/core/include/platform.h b/repos/base-nova/src/core/include/platform.h index 66ead4ea4b..bde2302962 100644 --- a/repos/base-nova/src/core/include/platform.h +++ b/repos/base-nova/src/core/include/platform.h @@ -51,6 +51,8 @@ namespace Genode { addr_t _map_pages(addr_t phys_page, addr_t pages); + size_t _max_caps = 0; + public: /** @@ -72,6 +74,7 @@ namespace Genode { addr_t vm_start() const override { return _vm_base; } size_t vm_size() const override { return _vm_size; } Rom_fs *rom_fs() override { return &_rom_fs; } + size_t max_caps() const override { return _max_caps; } void wait_for_exit() override; bool supports_unmap() override { return true; } diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index 0a32bd99d1..b2ec449dbe 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -642,7 +642,8 @@ Platform::Platform() : } /* add capability selector ranges to map */ - unsigned index = 0x2000; + unsigned const first_index = 0x2000; + unsigned index = first_index; for (unsigned i = 0; i < 32; i++) { void * phys_ptr = 0; @@ -658,6 +659,7 @@ Platform::Platform() : index = range->base() + range->elements(); } + _max_caps = index - first_index; /* add idle ECs to trace sources */ for (unsigned genode_cpu_id = 0; genode_cpu_id < _cpus.width(); genode_cpu_id++) { diff --git a/repos/base-okl4/src/core/include/platform.h b/repos/base-okl4/src/core/include/platform.h index 049bfdcd11..4e72dd383a 100644 --- a/repos/base-okl4/src/core/include/platform.h +++ b/repos/base-okl4/src/core/include/platform.h @@ -24,6 +24,9 @@ #include #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -105,15 +108,16 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Range_allocator *ram_alloc() { return _core_mem_alloc.phys_alloc(); } - Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } - Range_allocator *io_port_alloc() { return &_io_port_alloc; } - Range_allocator *irq_alloc() { return &_irq_alloc; } - Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); } - Range_allocator *core_mem_alloc() { return &_core_mem_alloc; } - addr_t vm_start() const { return _vm_start; } - size_t vm_size() const { return _vm_size; } - Rom_fs *rom_fs() { return &_rom_fs; } + Range_allocator *ram_alloc() override { return _core_mem_alloc.phys_alloc(); } + Range_allocator *io_mem_alloc() override { return &_io_mem_alloc; } + Range_allocator *io_port_alloc() override { return &_io_port_alloc; } + Range_allocator *irq_alloc() override { return &_irq_alloc; } + Range_allocator *region_alloc() override { return _core_mem_alloc.virt_alloc(); } + Range_allocator *core_mem_alloc() override { return &_core_mem_alloc; } + addr_t vm_start() const override { return _vm_start; } + size_t vm_size() const override { return _vm_size; } + Rom_fs *rom_fs() override { return &_rom_fs; } + size_t max_caps() const override { return Capability_space::max_caps(); } void wait_for_exit(); @@ -124,7 +128,7 @@ namespace Genode { ** OKL4-specific platform interface ** **************************************/ - addr_t utcb_base() { return _utcb_base; } + addr_t utcb_base() { return _utcb_base; } }; } diff --git a/repos/base-pistachio/src/core/include/platform.h b/repos/base-pistachio/src/core/include/platform.h index e09ce414e2..d86f2d709d 100644 --- a/repos/base-pistachio/src/core/include/platform.h +++ b/repos/base-pistachio/src/core/include/platform.h @@ -15,8 +15,13 @@ #ifndef _CORE__INCLUDE__PLATFORM_H_ #define _CORE__INCLUDE__PLATFORM_H_ +/* Genode includes */ #include +/* base-internal includes */ +#include + +/* core-local includes */ #include "synced_range_allocator.h" #include "platform_generic.h" #include "platform_thread.h" @@ -136,15 +141,16 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Range_allocator *core_mem_alloc() { return &_ram_alloc; } - Range_allocator *ram_alloc() { return &_ram_alloc; } - Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } - Range_allocator *io_port_alloc() { return &_io_port_alloc; } - Range_allocator *irq_alloc() { return &_irq_alloc; } - Range_allocator *region_alloc() { return &_region_alloc; } - addr_t vm_start() const { return _vm_start; } - size_t vm_size() const { return _vm_size; } - Rom_fs *rom_fs() { return &_rom_fs; } + Range_allocator *core_mem_alloc() override { return &_ram_alloc; } + Range_allocator *ram_alloc() override { return &_ram_alloc; } + Range_allocator *io_mem_alloc() override { return &_io_mem_alloc; } + Range_allocator *io_port_alloc() override { return &_io_port_alloc; } + Range_allocator *irq_alloc() override { return &_irq_alloc; } + Range_allocator *region_alloc() override { return &_region_alloc; } + addr_t vm_start() const override { return _vm_start; } + size_t vm_size() const override { return _vm_size; } + Rom_fs *rom_fs() override { return &_rom_fs; } + size_t max_caps() const override { return Capability_space::max_caps(); } void wait_for_exit(); diff --git a/repos/base-sel4/src/core/include/platform.h b/repos/base-sel4/src/core/include/platform.h index afb9b1e2b2..8f302435b4 100644 --- a/repos/base-sel4/src/core/include/platform.h +++ b/repos/base-sel4/src/core/include/platform.h @@ -198,6 +198,10 @@ class Genode::Platform : public Platform_generic size_t region_alloc_size_at(void * addr) { return (*_core_mem_alloc.virt_alloc())()->size_at(addr); } + size_t max_caps() const override + { + return 1UL << Core_cspace::NUM_CORE_SEL_LOG2; + } }; #endif /* _CORE__INCLUDE__PLATFORM_H_ */ diff --git a/repos/base/src/core/capability_space.cc b/repos/base/src/core/capability_space.cc index be8d5b38a3..ba16260cdf 100644 --- a/repos/base/src/core/capability_space.cc +++ b/repos/base/src/core/capability_space.cc @@ -41,9 +41,11 @@ using namespace Genode; */ namespace { + enum { NUM_LOCAL_CAPS = 64*1024 }; + struct Local_capability_space : - Capability_space_tpl<64*1024, Native_capability::Data> + Capability_space_tpl { }; static Local_capability_space &local_capability_space() @@ -94,6 +96,9 @@ Native_capability Capability_space::import(Rpc_destination dst, Rpc_obj_key key) } +size_t Capability_space::max_caps() { return NUM_LOCAL_CAPS; } + + void Capability_space::print(Output &out, Native_capability::Data const &data) { local_capability_space().print(out, data); diff --git a/repos/base/src/core/include/platform_generic.h b/repos/base/src/core/include/platform_generic.h index dd5e9c3fc6..bd4c02e091 100644 --- a/repos/base/src/core/include/platform_generic.h +++ b/repos/base/src/core/include/platform_generic.h @@ -99,6 +99,11 @@ namespace Genode { { return Affinity::Space(1); } + + /** + * Return system-wide maximum number of capabilities + */ + virtual size_t max_caps() const = 0; }; diff --git a/repos/base/src/include/base/internal/capability_space.h b/repos/base/src/include/base/internal/capability_space.h index 44347c28fc..00d35f9cd8 100644 --- a/repos/base/src/include/base/internal/capability_space.h +++ b/repos/base/src/include/base/internal/capability_space.h @@ -47,6 +47,11 @@ namespace Genode { namespace Capability_space { */ Rpc_obj_key rpc_obj_key(Native_capability::Data const &); + /** + * Return capacity of the capability space + */ + size_t max_caps(); + /** * Print internal capability representation */