core: add Platform::max_caps()

This method returns the kernel-specific system-global limit of the total
number of capabilities.

Issue #2398
This commit is contained in:
Norman Feske 2017-05-07 22:44:15 +02:00 committed by Christian Helmuth
parent 82a98065a0
commit bc82cce72b
14 changed files with 105 additions and 39 deletions

View File

@ -16,6 +16,7 @@
#define _CORE__INCLUDE__PLATFORM_H_
#include <base/allocator_avl.h>
#include <base/internal/capability_space.h>
#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();
};

View File

@ -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();
};
}

View File

@ -134,6 +134,8 @@ namespace Genode {
{
construct_at<Cap_index_allocator_tpl<T, SZ> >(this);
}
size_t max_caps() const override { return SZ; }
};
}

View File

@ -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;
};

View File

@ -25,6 +25,7 @@
#include <hw/memory_region.h>
#include <kernel/configuration.h>
#include <kernel/core_interface.h>
#include <kernel/pd.h>
/* core includes */
#include <platform_generic.h>
@ -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_ */

View File

@ -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();
};

View File

@ -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; }

View File

@ -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++) {

View File

@ -24,6 +24,9 @@
#include <core_region_map.h>
#include <core_mem_alloc.h>
/* base-internal includes */
#include <base/internal/capability_space.h>
/* OKL4 includes */
namespace Okl4 { extern "C" {
#include <bootinfo/bootinfo.h>
@ -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; }
};
}

View File

@ -15,8 +15,13 @@
#ifndef _CORE__INCLUDE__PLATFORM_H_
#define _CORE__INCLUDE__PLATFORM_H_
/* Genode includes */
#include <base/allocator_avl.h>
/* base-internal includes */
#include <base/internal/capability_space.h>
/* 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();

View File

@ -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_ */

View File

@ -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<NUM_LOCAL_CAPS, Native_capability::Data>
{ };
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);

View File

@ -99,6 +99,11 @@ namespace Genode {
{
return Affinity::Space(1);
}
/**
* Return system-wide maximum number of capabilities
*/
virtual size_t max_caps() const = 0;
};

View File

@ -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
*/