core: Added interface to allocate memory from a given NUMA region.

This commit is contained in:
Michael Mueller
2022-10-20 17:00:30 +02:00
parent 953afdaff3
commit 63d6827f16
4 changed files with 66 additions and 1 deletions

View File

@@ -77,6 +77,11 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
{
return call<Rpc_try_alloc>(size, cache);
}
Alloc_result try_alloc(size_t size, Ram_allocator::Numa_id numa_id, Cache cache = CACHED) override
{
return call<Rpc_try_alloc_numa>(size, numa_id, cache);
}
void free(Ram_dataspace_capability ds) override { call<Rpc_free>(ds); }

View File

@@ -284,6 +284,11 @@ struct Genode::Pd_session : Session, Ram_allocator
*/
Ram_quota avail_ram() const { return { ram_quota().value - used_ram().value }; }
/**
* \brief Create new dataspace factory for given NUMA node
* \param
*/
/*****************************************
** Access to kernel-specific interface **
@@ -381,6 +386,7 @@ struct Genode::Pd_session : Session, Ram_allocator
GENODE_RPC(Rpc_used_caps, Cap_quota, used_caps);
GENODE_RPC(Rpc_try_alloc, Alloc_result, try_alloc, size_t, Cache);
GENODE_RPC(Rpc_try_alloc_numa, Alloc_result, try_alloc, size_t, Ram_allocator::Numa_id, Cache);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC_THROW(Rpc_transfer_ram_quota, void, transfer_quota,
GENODE_TYPE_LIST(Out_of_ram, Invalid_session, Undefined_ref_account),
@@ -402,7 +408,7 @@ struct Genode::Pd_session : Session, Ram_allocator
Rpc_alloc_rpc_cap, Rpc_free_rpc_cap, Rpc_address_space,
Rpc_stack_area, Rpc_linker_area, Rpc_ref_account,
Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps,
Rpc_try_alloc, Rpc_free,
Rpc_try_alloc, Rpc_try_alloc_numa, Rpc_free,
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram,
Rpc_native_pd, Rpc_managing_system,
Rpc_dma_addr, Rpc_attach_dma);

View File

@@ -318,6 +318,8 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
Alloc_result try_alloc(size_t, Cache) override;
Alloc_result try_alloc(size_t, Ram_allocator::Numa_id, Cache) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability) const override;

View File

@@ -73,6 +73,58 @@ Pd_session_component::try_alloc(size_t ds_size, Cache cache)
);
}
Ram_allocator::Alloc_result
Pd_session_component::try_alloc(size_t ds_size, Ram_allocator::Numa_id numa_id, Cache cache)
{
/* zero-sized dataspaces are not allowed */
if (!ds_size)
return Alloc_error::DENIED;
/* dataspace allocation granularity is page size */
ds_size = align_addr(ds_size, 12);
using Result = Ram_allocator::Alloc_result;
using Reservation = Genode::Reservation;
/* track quota use */
return _ram_quota_guard().with_reservation<Result>(Ram_quota{ds_size},
[&] (Reservation &ram_reservation) -> Result {
/*
* In the worst case, we need to allocate a new slab block for
* the meta data of the dataspace to be created. Therefore, we
* temporarily withdraw the slab block size here to trigger an
* exception if the account does not have enough room for the meta
* data.
*/
Ram_quota const overhead { Ram_dataspace_factory::SLAB_BLOCK_SIZE };
if (!_ram_quota_guard().have_avail(overhead)) {
ram_reservation.cancel();
return Ram_allocator::Alloc_error::OUT_OF_RAM;
}
/*
* Each dataspace is an RPC object and thereby consumes a
* capability.
*/
return _cap_quota_guard().with_reservation<Result>(Cap_quota{1},
[&] (Genode::Reservation &) -> Result {
return _ram_ds_factory.try_alloc(ds_size, numa_id, cache);
},
[&] () -> Result {
ram_reservation.cancel();
return Ram_allocator::Alloc_error::OUT_OF_CAPS;
}
);
},
[&] () -> Result {
return Ram_allocator::Alloc_error::OUT_OF_RAM;
}
);
}
void Pd_session_component::free(Ram_dataspace_capability ds_cap)
{