mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
core: Ignore constraints on allocations if allocator is exhausted
Try to allocate within constraint area first. In case the area is exhausted, try allocation at other memory locations. The motivation for this is to limit DMA allocations to 4GB (since some devices require addresses below 4GB). On some platforms there is little physical RAM in this area (<1GB) and the constrainted area exhausts. In case an IOMMU is present, RAM at higher locations can still be mapped below 4GB, which is done in the platform drivers. issue #4665
This commit is contained in:
parent
77fc2f1e86
commit
0a8d6ddba9
@ -40,16 +40,24 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache)
|
||||
*/
|
||||
Range_allocator::Alloc_result allocated_range = Allocator::Alloc_error::DENIED;
|
||||
|
||||
/*
|
||||
* 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_range.start == 0 && _phys_range.end == ~0UL) {
|
||||
/* apply constraints */
|
||||
if (_phys_range.start != 0 || _phys_range.end != ~0UL) {
|
||||
for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) {
|
||||
allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, _phys_range);
|
||||
if (allocated_range.ok())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If no physical constraint exists or constraints failed, 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 (!allocated_range.ok()) {
|
||||
addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30;
|
||||
Phys_range const range { .start = high_start, .end = _phys_range.end };
|
||||
Phys_range const range { .start = high_start, .end = ~0UL };
|
||||
|
||||
for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) {
|
||||
allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, range);
|
||||
@ -58,7 +66,7 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache)
|
||||
}
|
||||
}
|
||||
|
||||
/* apply constraints, or retry if larger memory allocation failed */
|
||||
/* retry if larger non-constrained memory allocation failed */
|
||||
if (!allocated_range.ok()) {
|
||||
for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) {
|
||||
allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, _phys_range);
|
||||
|
Loading…
x
Reference in New Issue
Block a user