vm: Round up npages and alignment for contig reclamation
When searching for runs to reclaim, we need to ensure that the entire run will be added to the buddy allocator as a single unit. Otherwise, it will not be visible to vm_phys_alloc_contig() as it is currently implemented. This is a problem for allocation requests that are not a power of 2 in size, as with 9KB jumbo mbuf clusters. Reported by: alc Reviewed by: alc MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D28924
This commit is contained in:
parent
c883b6fd8c
commit
0401989282
@ -2972,17 +2972,29 @@ vm_page_reclaim_contig_domain(int domain, int req, u_long npages,
|
|||||||
struct vm_domain *vmd;
|
struct vm_domain *vmd;
|
||||||
vm_paddr_t curr_low;
|
vm_paddr_t curr_low;
|
||||||
vm_page_t m_run, m_runs[NRUNS];
|
vm_page_t m_run, m_runs[NRUNS];
|
||||||
u_long count, reclaimed;
|
u_long count, minalign, reclaimed;
|
||||||
int error, i, options, req_class;
|
int error, i, options, req_class;
|
||||||
|
|
||||||
KASSERT(npages > 0, ("npages is 0"));
|
KASSERT(npages > 0, ("npages is 0"));
|
||||||
KASSERT(powerof2(alignment), ("alignment is not a power of 2"));
|
KASSERT(powerof2(alignment), ("alignment is not a power of 2"));
|
||||||
KASSERT(powerof2(boundary), ("boundary is not a power of 2"));
|
KASSERT(powerof2(boundary), ("boundary is not a power of 2"));
|
||||||
req_class = req & VM_ALLOC_CLASS_MASK;
|
|
||||||
|
/*
|
||||||
|
* The caller will attempt an allocation after some runs have been
|
||||||
|
* reclaimed and added to the vm_phys buddy lists. Due to limitations
|
||||||
|
* of vm_phys_alloc_contig(), round up the requested length to the next
|
||||||
|
* power of two or maximum chunk size, and ensure that each run is
|
||||||
|
* suitably aligned.
|
||||||
|
*/
|
||||||
|
minalign = 1ul << imin(flsl(npages - 1), VM_NFREEORDER - 1);
|
||||||
|
npages = roundup2(npages, minalign);
|
||||||
|
if (alignment < ptoa(minalign))
|
||||||
|
alignment = ptoa(minalign);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The page daemon is allowed to dig deeper into the free page list.
|
* The page daemon is allowed to dig deeper into the free page list.
|
||||||
*/
|
*/
|
||||||
|
req_class = req & VM_ALLOC_CLASS_MASK;
|
||||||
if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT)
|
if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT)
|
||||||
req_class = VM_ALLOC_SYSTEM;
|
req_class = VM_ALLOC_SYSTEM;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user