mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
vm_phys: check small blocks to finish allocation
In vm_phys_alloc_queues_contig, in the case that a sequence of max-order blocks are sought to fulfill an allocation, a sequence is ruled out if it does not have enough max-order blocks to satisfy the allocation. However, there may be smaller blocks of free memory that follow the last max-order block in the sequence, and they may be big enough to complete the allocation request, so check for that possibility before giving up on that block sequence. Reviewed by: markj Tested by: pho Differential Revision: https://reviews.freebsd.org/D34724
This commit is contained in:
parent
bafe3b8804
commit
557dc337e6
1 changed files with 21 additions and 3 deletions
|
|
@ -1405,9 +1405,9 @@ vm_phys_alloc_queues_contig(
|
|||
continue;
|
||||
|
||||
/*
|
||||
* Determine if a sufficient number of
|
||||
* subsequent blocks to satisfy the
|
||||
* allocation request are free.
|
||||
* Determine if a series of free oind-blocks
|
||||
* starting here can satisfy the allocation
|
||||
* request.
|
||||
*/
|
||||
do {
|
||||
pa += 1 <<
|
||||
|
|
@ -1416,6 +1416,23 @@ vm_phys_alloc_queues_contig(
|
|||
goto done;
|
||||
} while (VM_NFREEORDER - 1 == seg->first_page[
|
||||
atop(pa - seg->start)].order);
|
||||
|
||||
/*
|
||||
* Determine if an additional series of free
|
||||
* blocks of diminishing size can help to
|
||||
* satisfy the allocation request.
|
||||
*/
|
||||
for (;;) {
|
||||
m = &seg->first_page[
|
||||
atop(pa - seg->start)];
|
||||
if (m->order == VM_NFREEORDER ||
|
||||
pa + (2 << (PAGE_SHIFT + m->order))
|
||||
<= pa_end)
|
||||
break;
|
||||
pa += 1 << (PAGE_SHIFT + m->order);
|
||||
if (pa >= pa_end)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1423,6 +1440,7 @@ vm_phys_alloc_queues_contig(
|
|||
done:
|
||||
for (m = m_ret; m < &m_ret[npages]; m = &m[1 << oind]) {
|
||||
fl = (*queues)[m->pool];
|
||||
oind = m->order;
|
||||
vm_freelist_rem(fl, m, oind);
|
||||
if (m->pool != VM_FREEPOOL_DEFAULT)
|
||||
vm_phys_set_pool(VM_FREEPOOL_DEFAULT, m, oind);
|
||||
|
|
|
|||
Loading…
Reference in a new issue