From 81f0cacf66a72ac649fb61cb28164e7e1ef390d6 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 10 Nov 2016 15:08:08 +0100 Subject: [PATCH] core: prefer RAM allocation in high memory We preserve lower RAM for device drivers with physical memory constraints. If no physical RAM constraint exists, the allocations above 3G (32-bit) or 4G (64-bit) are preferred. --- repos/base/src/core/ram_session_component.cc | 35 ++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/repos/base/src/core/ram_session_component.cc b/repos/base/src/core/ram_session_component.cc index 087be5fc8b..e31d2f38ce 100644 --- a/repos/base/src/core/ram_session_component.cc +++ b/repos/base/src/core/ram_session_component.cc @@ -142,11 +142,32 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attr */ void *ds_addr = 0; bool alloc_succeeded = false; - for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2, - _phys_start, _phys_end).ok()) { - alloc_succeeded = true; - break; + + /* + * If no physical constraint exists, try to allocate physical memory at + * high locations (3G for 32-bit / 4G for 64-bit platforms) in order to + * preserve lower physical regions for device drivers, which may have DMA + * constraints. + */ + if (_phys_start == 0 && _phys_end == ~0UL) { + addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { + if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2, + high_start, _phys_end).ok()) { + alloc_succeeded = true; + break; + } + } + } + + /* apply constraints or re-try because higher memory allocation failed */ + if (!alloc_succeeded) { + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { + if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2, + _phys_start, _phys_end).ok()) { + alloc_succeeded = true; + break; + } } } @@ -157,7 +178,9 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attr * fragmentation could cause a failing allocation. */ if (!alloc_succeeded) { - error("out of physical memory while allocating ", ds_size, " bytes"); + error("out of physical memory while allocating ", ds_size, " bytes ", + "in range [", Hex(_phys_start), "-", Hex(_phys_end), "] - label ", + Cstring(_label)); throw Quota_exceeded(); }