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:
parent
bd6d78b18e
commit
0dbb5e1696
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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); }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue