Propagate 'Range_allocator::alloc_aligned' errors

This patch reflects eventual allocation errors in a more specific way to
the caller of 'alloc_aligned', in particular out-of-metadata and
out-of-memory are considered as different conditions.

Related to issue #526.
This commit is contained in:
Norman Feske 2012-11-28 22:50:08 +01:00
parent bd6d78b18e
commit 0dbb5e1696
39 changed files with 133 additions and 89 deletions

View File

@ -56,7 +56,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session,
{ {
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
if (!irq_alloc || (irq_number == -1)|| if (!irq_alloc || (irq_number == -1)||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { irq_alloc->alloc_addr(1, irq_number).is_error()) {
PERR("unavailable IRQ %lx requested", irq_number); PERR("unavailable IRQ %lx requested", irq_number);
return; return;
} }

View File

@ -46,7 +46,7 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
/* find appropriate region for mapping */ /* find appropriate region for mapping */
void *local_base = 0; void *local_base = 0;
if (!platform()->region_alloc()->alloc_aligned(size, &local_base, alignment)) if (platform()->region_alloc()->alloc_aligned(size, &local_base, alignment).is_error())
return 0; return 0;
/* call sigma0 for I/O region */ /* call sigma0 for I/O region */

View File

@ -99,7 +99,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session,
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
if (irq_number == -1 || !irq_alloc || if (irq_number == -1 || !irq_alloc ||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { irq_alloc->alloc_addr(1, irq_number).is_error()) {
PERR("Unavailable IRQ %lx requested", irq_number); PERR("Unavailable IRQ %lx requested", irq_number);
throw Root::Invalid_args(); throw Root::Invalid_args();
} }

View File

@ -35,7 +35,7 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
/* find appropriate region for mapping */ /* find appropriate region for mapping */
void *local_base = 0; void *local_base = 0;
if (!platform()->region_alloc()->alloc_aligned(size, &local_base, alignment)) if (platform()->region_alloc()->alloc_aligned(size, &local_base, alignment).is_error())
return 0; return 0;
if (!map_local_io(base, (addr_t)local_base, size >> get_page_size_log2())) { if (!map_local_io(base, (addr_t)local_base, size >> get_page_size_log2())) {

View File

@ -52,7 +52,7 @@ namespace Genode
void * kernel_pd; void * kernel_pd;
Range_allocator * ram = platform()->ram_alloc(); Range_allocator * ram = platform()->ram_alloc();
assert(ram->alloc_aligned(Kernel::pd_size(), &kernel_pd, assert(ram->alloc_aligned(Kernel::pd_size(), &kernel_pd,
Kernel::pd_alignm_log2())); Kernel::pd_alignm_log2()).is_ok())
/* create kernel object */ /* create kernel object */
_id = Kernel::new_pd(kernel_pd); _id = Kernel::new_pd(kernel_pd);

View File

@ -45,8 +45,8 @@ namespace Genode {
{ {
addr_t addr; addr_t addr;
if (_ds_size() > *ram_quota || if (_ds_size() > *ram_quota ||
!_ram_alloc->alloc_aligned(_ds_size(), (void**)&addr, _ram_alloc->alloc_aligned(_ds_size(), (void**)&addr,
get_page_size_log2())) get_page_size_log2()).is_error())
throw Root::Quota_exceeded(); throw Root::Quota_exceeded();
*ram_quota -= _ds_size(); *ram_quota -= _ds_size();
return addr; return addr;

View File

@ -53,7 +53,7 @@ Irq_session_component::Irq_session_component(Cap_session * cap_session,
/* allocate IRQ */ /* allocate IRQ */
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
if (irq_number == -1 || !irq_alloc || if (irq_number == -1 || !irq_alloc ||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { irq_alloc->alloc_addr(1, irq_number).is_error()) {
PERR("Unavailable IRQ %lu requested", irq_number); PERR("Unavailable IRQ %lu requested", irq_number);
throw Root::Invalid_args(); throw Root::Invalid_args();
} }

View File

@ -72,7 +72,7 @@ Platform_thread::Platform_thread(const char * name,
/* create UTCB for a core thread */ /* create UTCB for a core thread */
Range_allocator * const ram = platform()->ram_alloc(); Range_allocator * const ram = platform()->ram_alloc();
assert(ram->alloc_aligned(sizeof(Native_utcb), (void **)&_phys_utcb, assert(ram->alloc_aligned(sizeof(Native_utcb), (void **)&_phys_utcb,
MIN_MAPPING_SIZE_LOG2)); MIN_MAPPING_SIZE_LOG2).is_ok());
_virt_utcb = _phys_utcb; _virt_utcb = _phys_utcb;
/* common constructor parts */ /* common constructor parts */

View File

@ -72,7 +72,7 @@ void Ipc_pager::resolve_and_wait_for_fault()
{ {
/* try to get some natural aligned space */ /* try to get some natural aligned space */
void * space; void * space;
assert(platform()->ram_alloc()->alloc_aligned(1<<sl2, &space, sl2)); assert(platform()->ram_alloc()->alloc_aligned(1<<sl2, &space, sl2).is_ok());
/* try to translate again with extra space */ /* try to translate again with extra space */
sl2 = tlb->insert_translation(_mapping.virt_address, sl2 = tlb->insert_translation(_mapping.virt_address,

View File

@ -98,8 +98,8 @@ class Context_area_ram_session : public Ram_session
/* allocate physical memory */ /* allocate physical memory */
size = round_page(size); size = round_page(size);
void *phys_base; void *phys_base;
if (!platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, if (platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base,
get_page_size_log2())) { get_page_size_log2()).is_error()) {
PERR("could not allocate backing store for new context"); PERR("could not allocate backing store for new context");
return Ram_dataspace_capability(); return Ram_dataspace_capability();
} }

View File

@ -44,8 +44,8 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session,
_attached(false) _attached(false)
{ {
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
if (!_irq_alloc || (irq_number == -1)|| if (!_irq_alloc || (irq_number == -1) ||
_irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) _irq_alloc->alloc_addr(1, irq_number).is_error())
{ {
PERR("unavailable IRQ %lx requested", irq_number); PERR("unavailable IRQ %lx requested", irq_number);
return; return;

View File

@ -60,11 +60,11 @@ Genode::Thread_base::Context * Roottask::physical_context(Genode::Native_thread_
if(!_context[tid]) { if(!_context[tid]) {
/* Allocate new context */ /* Allocate new context */
if(!Genode::platform_specific()-> if (Genode::platform_specific()
core_mem_alloc()-> ->core_mem_alloc()
alloc_aligned(aligned_size, ->alloc_aligned(aligned_size,
(void**)&_context[tid], (void**)&_context[tid],
CONTEXT_PAGE_SIZE_LOG2)) CONTEXT_PAGE_SIZE_LOG2).is_error())
{ {
PERR("Allocate memory for a new stack- and misc-area failed"); PERR("Allocate memory for a new stack- and misc-area failed");
return 0; return 0;
@ -185,7 +185,7 @@ void Genode::Platform::_optimize_init_img_rom(long int & base, size_t const & si
/* Search for location where text-segment would be mapable /* Search for location where text-segment would be mapable
* with pages of size INIT_TEXT_SEGM_ALIGN */ * with pages of size INIT_TEXT_SEGM_ALIGN */
if (_core_mem_alloc.alloc_aligned(size + 2*INIT_TEXT_SEGM_ALIGN, if (_core_mem_alloc.alloc_aligned(size + 2*INIT_TEXT_SEGM_ALIGN,
(void**)&base, INIT_TEXT_SEGM_ALIGN_LOG2)) (void**)&base, INIT_TEXT_SEGM_ALIGN_LOG2).is_ok())
{ {
/* Found better location so move */ /* Found better location so move */
base = base + INIT_TEXT_SEGM_ALIGN - ELF_HEADER_SIZE; base = base + INIT_TEXT_SEGM_ALIGN - ELF_HEADER_SIZE;

View File

@ -64,11 +64,11 @@ Kernel::Utcb* Genode::physical_utcb(Native_thread_id tid)
} }
if(!phys_utcb[tid]) { if(!phys_utcb[tid]) {
if (!platform_specific()-> if (platform_specific()->
core_mem_alloc()-> core_mem_alloc()->
alloc_aligned(sizeof(Kernel::Utcb), alloc_aligned(sizeof(Kernel::Utcb),
(void**)&phys_utcb[tid], (void**)&phys_utcb[tid],
Kernel::Utcb::ALIGNMENT_LOG2)) Kernel::Utcb::ALIGNMENT_LOG2).is_error())
{ {
PERR("Allocate memory for a new UTCB failed"); PERR("Allocate memory for a new UTCB failed");
return 0; return 0;

View File

@ -4,7 +4,7 @@ SPEC_BASE_DIR = $(REP_DIR)/src/base
SRC_CC = \ SRC_CC = \
context_area.cc context_area.cc \
core_rm_session.cc \ core_rm_session.cc \
cpu_session_component.cc \ cpu_session_component.cc \
dataspace_component.cc \ dataspace_component.cc \

View File

@ -43,8 +43,8 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
/* allocate range in core's virtual address space */ /* allocate range in core's virtual address space */
void *virt_addr; void *virt_addr;
if (!platform()->region_alloc()->alloc_aligned(page_rounded_size, if (platform()->region_alloc()->alloc_aligned(page_rounded_size,
&virt_addr, alignment)) { &virt_addr, alignment).is_error()) {
PERR("Could not allocate virtual address range in core of size %zd\n", PERR("Could not allocate virtual address range in core of size %zd\n",
page_rounded_size); page_rounded_size);
return 0; return 0;

View File

@ -63,7 +63,7 @@ void Ram_session_component::_clear_ds(Dataspace_component *ds)
size_t align_log2 = log2(ds->size()); size_t align_log2 = log2(ds->size());
for (; align_log2 >= get_page_size_log2(); align_log2--) { for (; align_log2 >= get_page_size_log2(); align_log2--) {
if (platform()->region_alloc()->alloc_aligned(page_rounded_size, if (platform()->region_alloc()->alloc_aligned(page_rounded_size,
&virt_addr, align_log2)) { &virt_addr, align_log2).is_ok()) {
virt_alloc_succeeded = true; virt_alloc_succeeded = true;
break; break;
} }

View File

@ -83,11 +83,10 @@ addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
/* find appropriate region for mapping */ /* find appropriate region for mapping */
void *result = 0; void *result = 0;
platform()->region_alloc()->alloc_aligned(size, &result, alignment); if (platform()->region_alloc()->alloc_aligned(size, &result, alignment).is_error())
local_base = (addr_t)result;
if (!local_base)
PERR("alloc_aligned failed!"); PERR("alloc_aligned failed!");
local_base = (addr_t)result;
} }
if (verbose) if (verbose)

View File

@ -110,7 +110,7 @@ Irq_session_component::Irq_session_component(Cap_session *cap_session,
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
if (irq_number == -1 || !irq_alloc || if (irq_number == -1 || !irq_alloc ||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) { irq_alloc->alloc_addr(1, irq_number).is_error()) {
PERR("unavailable IRQ %lx requested", irq_number); PERR("unavailable IRQ %lx requested", irq_number);
/* FIXME error condition -> exception */ /* FIXME error condition -> exception */

View File

@ -132,6 +132,23 @@ namespace Genode {
*/ */
virtual int remove_range(addr_t base, size_t size) = 0; virtual int remove_range(addr_t base, size_t size) = 0;
/**
* Return value of allocation functons
*
* 'OK' on success, or
* 'OUT_OF_METADATA' if meta-data allocation failed, or
* 'RANGE_CONFLICT' if no fitting address range is found
*/
struct Alloc_return
{
enum Value { OK = 0, OUT_OF_METADATA = -1, RANGE_CONFLICT = -2 };
Value const value;
Alloc_return(Value value) : value(value) { }
bool is_ok() const { return value == OK; }
bool is_error() const { return !is_ok(); }
};
/** /**
* Allocate block * Allocate block
* *
@ -140,11 +157,8 @@ namespace Genode {
* undefined in the error case * undefined in the error case
* \param align alignment of new block specified * \param align alignment of new block specified
* as the power of two * as the power of two
* \return true on success
*/ */
virtual bool alloc_aligned(size_t size, void **out_addr, int align = 0) = 0; virtual Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0) = 0;
enum Alloc_return { ALLOC_OK = 0, OUT_OF_METADATA = -1, RANGE_CONFLICT = -2 };
/** /**
* Allocate block at address * Allocate block at address

View File

@ -215,7 +215,7 @@ namespace Genode {
int add_range(addr_t base, size_t size); int add_range(addr_t base, size_t size);
int remove_range(addr_t base, size_t size); int remove_range(addr_t base, size_t size);
bool alloc_aligned(size_t size, void **out_addr, int align = 0); Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0);
Alloc_return alloc_addr(size_t size, addr_t addr); Alloc_return alloc_addr(size_t size, addr_t addr);
void free(void *addr); void free(void *addr);
size_t avail(); size_t avail();
@ -227,7 +227,7 @@ namespace Genode {
*************************/ *************************/
bool alloc(size_t size, void **out_addr) { bool alloc(size_t size, void **out_addr) {
return Allocator_avl_base::alloc_aligned(size, out_addr); } return (Allocator_avl_base::alloc_aligned(size, out_addr).is_ok()); }
void free(void *addr, size_t) { free(addr); } void free(void *addr, size_t) { free(addr); }

View File

@ -71,6 +71,27 @@ namespace Genode {
return (addr_t)0; return (addr_t)0;
} }
Pager_capability add_client(Thread_capability thread)
{
bool try_again = false;
do {
try {
return Rm_session_client::add_client(thread);
} catch (Rm_session::Out_of_metadata) {
/* give up if the error occurred a second time */
if (try_again)
break;
PINF("upgrade quota donation for Env::RM session");
env()->parent()->upgrade(_cap, "ram_quota=8K");
try_again = true;
}
} while (try_again);
return Pager_capability();
}
}; };
class Expanding_ram_session_client : public Ram_session_client class Expanding_ram_session_client : public Ram_session_client

View File

@ -208,7 +208,7 @@ namespace Genode {
return _alloc.remove_range(base, size); return _alloc.remove_range(base, size);
} }
bool alloc_aligned(size_t size, void **out_addr, int align = 0) Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0)
{ {
Lock::Guard lock_guard(*_lock); Lock::Guard lock_guard(*_lock);
return _alloc.alloc_aligned(size, out_addr, align); return _alloc.alloc_aligned(size, out_addr, align);

View File

@ -100,7 +100,6 @@ namespace Genode {
class Out_of_metadata : public Attach_failed { }; class Out_of_metadata : public Attach_failed { };
class Invalid_thread : public Exception { }; class Invalid_thread : public Exception { };
class Out_of_memory : public Exception { };
/** /**
* Destructor * Destructor
@ -156,7 +155,7 @@ namespace Genode {
* *
* \param thread thread that will be paged * \param thread thread that will be paged
* \throw Invalid_thread * \throw Invalid_thread
* \throw Out_of_memory * \throw Out_of_metadata
* \return capability to be used for handling page faults * \return capability to be used for handling page faults
* *
* This method must be called at least once to establish a valid * This method must be called at least once to establish a valid
@ -191,7 +190,7 @@ namespace Genode {
Dataspace_capability, size_t, off_t, bool, Local_addr, bool); Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
GENODE_RPC(Rpc_detach, void, detach, Local_addr); GENODE_RPC(Rpc_detach, void, detach, Local_addr);
GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
GENODE_TYPE_LIST(Invalid_thread, Out_of_memory), GENODE_TYPE_LIST(Invalid_thread, Out_of_metadata),
Thread_capability); Thread_capability);
GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
GENODE_RPC(Rpc_state, State, state); GENODE_RPC(Rpc_state, State, state);

View File

@ -247,11 +247,11 @@ int Allocator_avl_base::remove_range(addr_t base, size_t size)
} }
bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align) Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align)
{ {
Block *dst1, *dst2; Block *dst1, *dst2;
if (!_alloc_two_blocks_metadata(&dst1, &dst2)) if (!_alloc_two_blocks_metadata(&dst1, &dst2))
return false; return Alloc_return(Alloc_return::OUT_OF_METADATA);
/* find best fitting block */ /* find best fitting block */
Block *b = _addr_tree.first(); Block *b = _addr_tree.first();
@ -260,7 +260,7 @@ bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align)
if (!b) { if (!b) {
_md_alloc->free(dst1, sizeof(Block)); _md_alloc->free(dst1, sizeof(Block));
_md_alloc->free(dst2, sizeof(Block)); _md_alloc->free(dst2, sizeof(Block));
return false; return Alloc_return(Alloc_return::RANGE_CONFLICT);
} }
/* calculate address of new (aligned) block */ /* calculate address of new (aligned) block */
@ -273,12 +273,12 @@ bool Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align)
Block *new_block = _alloc_block_metadata(); Block *new_block = _alloc_block_metadata();
if (!new_block) { if (!new_block) {
_md_alloc->free(new_block, sizeof(Block)); _md_alloc->free(new_block, sizeof(Block));
return false; return Alloc_return(Alloc_return::OUT_OF_METADATA);
} }
_add_block(new_block, new_addr, size, Block::USED); _add_block(new_block, new_addr, size, Block::USED);
*out_addr = reinterpret_cast<void *>(new_addr); *out_addr = reinterpret_cast<void *>(new_addr);
return true; return Alloc_return(Alloc_return::OK);
} }
@ -286,11 +286,11 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t
{ {
/* sanity check */ /* sanity check */
if (!_sum_in_range(addr, size)) if (!_sum_in_range(addr, size))
return Range_allocator::RANGE_CONFLICT; return Alloc_return(Alloc_return::RANGE_CONFLICT);
Block *dst1, *dst2; Block *dst1, *dst2;
if (!_alloc_two_blocks_metadata(&dst1, &dst2)) if (!_alloc_two_blocks_metadata(&dst1, &dst2))
return Range_allocator::OUT_OF_METADATA; return Alloc_return(Alloc_return::OUT_OF_METADATA);
/* find block at specified address */ /* find block at specified address */
Block *b = _addr_tree.first(); Block *b = _addr_tree.first();
@ -301,7 +301,7 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t
{ {
_md_alloc->free(dst1, sizeof(Block)); _md_alloc->free(dst1, sizeof(Block));
_md_alloc->free(dst2, sizeof(Block)); _md_alloc->free(dst2, sizeof(Block));
return Range_allocator::RANGE_CONFLICT; return Alloc_return(Alloc_return::RANGE_CONFLICT);
} }
/* remove new block from containing block */ /* remove new block from containing block */
@ -311,11 +311,11 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_addr(size_t size, addr_t
Block *new_block = _alloc_block_metadata(); Block *new_block = _alloc_block_metadata();
if (!new_block) { if (!new_block) {
_md_alloc->free(new_block, sizeof(Block)); _md_alloc->free(new_block, sizeof(Block));
return Range_allocator::OUT_OF_METADATA; return Alloc_return(Alloc_return::OUT_OF_METADATA);
} }
_add_block(new_block, addr, size, Block::USED); _add_block(new_block, addr, size, Block::USED);
return Range_allocator::ALLOC_OK; return Alloc_return(Alloc_return::OK);
} }

View File

@ -61,7 +61,7 @@ int Heap::Dataspace_pool::expand(size_t size, Range_allocator *alloc)
alloc->add_range((addr_t)local_addr, size); alloc->add_range((addr_t)local_addr, size);
/* now that we have new backing store, allocate Dataspace structure */ /* now that we have new backing store, allocate Dataspace structure */
if (!alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2)) { if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).is_error()) {
PWRN("could not allocate meta data - this should never happen"); PWRN("could not allocate meta data - this should never happen");
return -1; return -1;
} }
@ -84,7 +84,7 @@ int Heap::quota_limit(size_t new_quota_limit)
bool Heap::_try_local_alloc(size_t size, void **out_addr) bool Heap::_try_local_alloc(size_t size, void **out_addr)
{ {
if (!_alloc.alloc_aligned(size, out_addr, 2)) if (_alloc.alloc_aligned(size, out_addr, 2).is_error())
return false; return false;
_quota_used += size; _quota_used += size;

View File

@ -142,8 +142,8 @@ class Context_area_ram_session : public Ram_session
/* allocate physical memory */ /* allocate physical memory */
size = round_page(size); size = round_page(size);
void *phys_base; void *phys_base;
if (!platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base, if (platform_specific()->ram_alloc()->alloc_aligned(size, &phys_base,
get_page_size_log2())) { get_page_size_log2()).is_error()) {
PERR("could not allocate backing store for new context"); PERR("could not allocate backing store for new context");
return Ram_dataspace_capability(); return Ram_dataspace_capability();
} }

View File

@ -208,7 +208,7 @@ class Genode::Irq_proxy : public THREAD,
return static_cast<PROXY *>(p); return static_cast<PROXY *>(p);
/* try to create proxy */ /* try to create proxy */
if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error())
return 0; return 0;
PROXY *new_proxy = new (env()->heap()) PROXY(irq_number); PROXY *new_proxy = new (env()->heap()) PROXY(irq_number);

View File

@ -51,16 +51,16 @@ Io_mem_session_component::_prepare_io_mem(const char *args,
} }
/* allocate region */ /* allocate region */
switch (_io_mem_alloc->alloc_addr(req_size, req_base)) { switch (_io_mem_alloc->alloc_addr(req_size, req_base).value) {
case Range_allocator::RANGE_CONFLICT: case Range_allocator::Alloc_return::RANGE_CONFLICT:
PERR("I/O memory [%lx,%lx) not available", base, base + size); PERR("I/O memory [%lx,%lx) not available", base, base + size);
return Dataspace_attr(); return Dataspace_attr();
case Range_allocator::OUT_OF_METADATA: case Range_allocator::Alloc_return::OUT_OF_METADATA:
PERR("I/O memory allocator ran out of meta data"); PERR("I/O memory allocator ran out of meta data");
return Dataspace_attr(); return Dataspace_attr();
case Range_allocator::ALLOC_OK: break; case Range_allocator::Alloc_return::OK: break;
} }
/* request local mapping */ /* request local mapping */

View File

@ -145,7 +145,7 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, bool cache
void *ds_addr = 0; void *ds_addr = 0;
bool alloc_succeeded = false; bool alloc_succeeded = false;
for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) {
if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2)) { if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2).is_ok()) {
alloc_succeeded = true; alloc_succeeded = true;
break; break;
} }

View File

@ -350,15 +350,15 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
/* allocate region for attachment */ /* allocate region for attachment */
void *r = 0; void *r = 0;
if (use_local_addr) { if (use_local_addr) {
switch (_map.alloc_addr(size, local_addr)) { switch (_map.alloc_addr(size, local_addr).value) {
case Range_allocator::OUT_OF_METADATA: case Range_allocator::Alloc_return::OUT_OF_METADATA:
throw Out_of_metadata(); throw Out_of_metadata();
case Range_allocator::RANGE_CONFLICT: case Range_allocator::Alloc_return::RANGE_CONFLICT:
throw Region_conflict(); throw Region_conflict();
case Range_allocator::ALLOC_OK: case Range_allocator::Alloc_return::OK:
r = local_addr; r = local_addr;
break; break;
} }
@ -381,8 +381,15 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
continue; continue;
/* try allocating the align region */ /* try allocating the align region */
if (_map.alloc_aligned(size, &r, align_log2)) Range_allocator::Alloc_return alloc_return =
_map.alloc_aligned(size, &r, align_log2);
if (alloc_return.is_ok())
break; break;
else if (alloc_return.value == Range_allocator::Alloc_return::OUT_OF_METADATA) {
_map.free(r);
throw Out_of_metadata();
}
} }
if (align_log2 < get_page_size_log2()) { if (align_log2 < get_page_size_log2()) {
@ -569,7 +576,7 @@ Pager_capability Rm_session_component::add_client(Thread_capability thread)
Rm_client *cl; Rm_client *cl;
try { cl = new(&_client_slab) Rm_client(this, badge); } try { cl = new(&_client_slab) Rm_client(this, badge); }
catch (Allocator::Out_of_memory) { throw Out_of_memory(); } catch (Allocator::Out_of_memory) { throw Out_of_metadata(); }
_clients.insert(cl); _clients.insert(cl);

View File

@ -102,13 +102,13 @@ Io_port_session_component::Io_port_session_component(Range_allocator *io_port_al
unsigned size = Arg_string::find_arg(args, "io_port_size").ulong_value(0); unsigned size = Arg_string::find_arg(args, "io_port_size").ulong_value(0);
/* allocate region (also checks out-of-bounds regions) */ /* allocate region (also checks out-of-bounds regions) */
switch (io_port_alloc->alloc_addr(size, base)) { switch (io_port_alloc->alloc_addr(size, base).value) {
case Range_allocator::RANGE_CONFLICT: case Range_allocator::Alloc_return::RANGE_CONFLICT:
PERR("I/O port [%x,%x) not available", base, base + size); PERR("I/O port [%x,%x) not available", base, base + size);
throw Root::Invalid_args(); throw Root::Invalid_args();
case Range_allocator::OUT_OF_METADATA: case Range_allocator::Alloc_return::OUT_OF_METADATA:
PERR("I/O port allocator ran out of meta data"); PERR("I/O port allocator ran out of meta data");
/* /*
@ -117,7 +117,7 @@ Io_port_session_component::Io_port_session_component(Range_allocator *io_port_al
*/ */
throw Root::Invalid_args(); throw Root::Invalid_args();
case Range_allocator::ALLOC_OK: break; case Range_allocator::Alloc_return::OK: break;
} }
if (verbose) if (verbose)

View File

@ -59,7 +59,10 @@ void __attribute__((constructor)) init()
extern "C" void *alloc_memblock(size_t size, size_t align) extern "C" void *alloc_memblock(size_t size, size_t align)
{ {
void *ptr; void *ptr;
allocator()->alloc_aligned(size, &ptr, log2(align)); if (allocator()->alloc_aligned(size, &ptr, log2(align)).is_error()) {
PERR("memory allocation failed in alloc_memblock");
return 0;
};
return ptr; return ptr;
} }

View File

@ -172,7 +172,7 @@ namespace Genode {
void *alloc(size_t size, int zone = -1, int align = 2) void *alloc(size_t size, int zone = -1, int align = 2)
{ {
void *addr; void *addr;
if (!_range.alloc_aligned(size, &addr, align)) { if (_range.alloc_aligned(size, &addr, align).is_error()) {
PERR("Memory allocation of %zu bytes failed", size); PERR("Memory allocation of %zu bytes failed", size);
return 0; return 0;
} }

View File

@ -52,7 +52,7 @@ File_descriptor *File_descriptor_allocator::alloc(Plugin *plugin,
if (addr == ANY_FD) if (addr == ANY_FD)
alloc_ok = Allocator_avl_base::alloc(1, reinterpret_cast<void**>(&addr)); alloc_ok = Allocator_avl_base::alloc(1, reinterpret_cast<void**>(&addr));
else else
alloc_ok = (Allocator_avl_base::alloc_addr(1, addr) == ALLOC_OK); alloc_ok = (Allocator_avl_base::alloc_addr(1, addr).is_ok());
if (!alloc_ok) { if (!alloc_ok) {
PERR("could not allocate libc_fd %d%s", PERR("could not allocate libc_fd %d%s",

View File

@ -162,7 +162,7 @@ int Libc::Mem_alloc_impl::Dataspace_pool::expand(size_t size, Range_allocator *a
alloc->add_range((addr_t)local_addr, size); alloc->add_range((addr_t)local_addr, size);
/* now that we have new backing store, allocate Dataspace structure */ /* now that we have new backing store, allocate Dataspace structure */
if (!alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2)) { if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).is_error()) {
PWRN("could not allocate meta data - this should never happen"); PWRN("could not allocate meta data - this should never happen");
return -1; return -1;
} }
@ -182,7 +182,7 @@ void *Libc::Mem_alloc_impl::alloc(size_t size, size_t align_log2)
/* try allocation at our local allocator */ /* try allocation at our local allocator */
void *out_addr = 0; void *out_addr = 0;
if (_alloc.alloc_aligned(size, &out_addr, align_log2)) if (_alloc.alloc_aligned(size, &out_addr, align_log2).is_ok())
return out_addr; return out_addr;
/* /*
@ -208,7 +208,7 @@ void *Libc::Mem_alloc_impl::alloc(size_t size, size_t align_log2)
} }
/* allocate originally requested block */ /* allocate originally requested block */
return _alloc.alloc_aligned(size, &out_addr, align_log2) ? out_addr : 0; return _alloc.alloc_aligned(size, &out_addr, align_log2).is_ok() ? out_addr : 0;
} }

View File

@ -72,8 +72,9 @@ namespace Nic {
return 0; return 0;
} }
bool alloc_aligned(Genode::size_t size, void **out_addr, int) { Alloc_return alloc_aligned(Genode::size_t size, void **out_addr, int) {
return alloc(size, out_addr); } return alloc(size, out_addr) ? Alloc_return::OK
: Alloc_return::RANGE_CONFLICT; }
bool alloc(Genode::size_t size, void **out_addr) bool alloc(Genode::size_t size, void **out_addr)
{ {
@ -120,8 +121,8 @@ namespace Nic {
int remove_range(Genode::addr_t, Genode::size_t) { return 0;} int remove_range(Genode::addr_t, Genode::size_t) { return 0;}
Genode::size_t avail() { return 0; } Genode::size_t avail() { return 0; }
bool valid_addr(Genode::addr_t) { return 0; } bool valid_addr(Genode::addr_t) { return 0; }
Genode::Range_allocator::Alloc_return alloc_addr(Genode::size_t, Genode::addr_t) { Alloc_return alloc_addr(Genode::size_t, Genode::addr_t) {
return OUT_OF_METADATA; } return Alloc_return(Alloc_return::OUT_OF_METADATA); }
}; };
}; };

View File

@ -577,7 +577,7 @@ class Packet_stream_source : private Packet_stream_base
Packet_descriptor alloc_packet(Genode::size_t size, int align = POLICY::Packet_descriptor::PACKET_ALIGNMENT) Packet_descriptor alloc_packet(Genode::size_t size, int align = POLICY::Packet_descriptor::PACKET_ALIGNMENT)
{ {
void *base = 0; void *base = 0;
if (!_packet_alloc->alloc_aligned(size, &base, align)) if (_packet_alloc->alloc_aligned(size, &base, align).is_error())
throw Packet_alloc_failed(); throw Packet_alloc_failed();
return Packet_descriptor((Genode::off_t)base, size); return Packet_descriptor((Genode::off_t)base, size);

View File

@ -115,7 +115,7 @@ extern "C" void dde_kit_pgtab_set_region_with_size(void *virt, dde_kit_addr_t ph
map = virt_to_phys_map(); map = virt_to_phys_map();
region = Mem_region(reinterpret_cast<addr_t>(virt), size, phys); region = Mem_region(reinterpret_cast<addr_t>(virt), size, phys);
if (map->alloc_addr(size, reinterpret_cast<addr_t>(virt)) == Range_allocator::ALLOC_OK) if (map->alloc_addr(size, reinterpret_cast<addr_t>(virt)).is_ok())
map->metadata(virt, region); map->metadata(virt, region);
else else
PWRN("virt->phys mapping for [%lx,%lx) failed", PWRN("virt->phys mapping for [%lx,%lx) failed",
@ -125,7 +125,7 @@ extern "C" void dde_kit_pgtab_set_region_with_size(void *virt, dde_kit_addr_t ph
map = phys_to_virt_map(); map = phys_to_virt_map();
region = Mem_region(phys, size, reinterpret_cast<addr_t>(virt)); region = Mem_region(phys, size, reinterpret_cast<addr_t>(virt));
if (map->alloc_addr(size, phys) == Range_allocator::ALLOC_OK) if (map->alloc_addr(size, phys).is_ok())
map->metadata(reinterpret_cast<void *>(phys), region); map->metadata(reinterpret_cast<void *>(phys), region);
else else
PWRN("phys->virt mapping for [%lx,%lx) failed", phys, phys + size); PWRN("phys->virt mapping for [%lx,%lx) failed", phys, phys + size);

View File

@ -61,9 +61,9 @@ namespace Genode {
{ {
addr_t addr = vaddr; addr_t addr = vaddr;
if (addr && (_range.alloc_addr(size, addr) != Range_allocator::ALLOC_OK)) if (addr && (_range.alloc_addr(size, addr).is_error()))
throw Region_conflict(); throw Region_conflict();
else if (!addr && !_range.alloc_aligned(size, (void **)&addr, 12)) else if (!addr && _range.alloc_aligned(size, (void **)&addr, 12).is_error())
throw Region_conflict(); throw Region_conflict();
return addr; return addr;