MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vm_reserv_alloc_contig

Function vm_reserv_alloc_contig

freebsd/vm/vm_reserv.c:625–815  ·  view source on GitHub ↗

* Allocates a contiguous set of physical pages of the given size "npages" * from existing or newly created reservations. All of the physical pages * must be at or above the given physical address "low" and below the given * physical address "high". The given value "alignment" determines the * alignment of the first physical page in the set. If the given value * "boundary" is non-zero, then

Source from the content-addressed store, hash-verified

623 * The object must be locked.
624 */
625vm_page_t
626vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain,
627 int req, vm_page_t mpred, u_long npages, vm_paddr_t low, vm_paddr_t high,
628 u_long alignment, vm_paddr_t boundary)
629{
630 struct vm_domain *vmd;
631 vm_paddr_t pa, size;
632 vm_page_t m, m_ret, msucc;
633 vm_pindex_t first, leftcap, rightcap;
634 vm_reserv_t rv;
635 u_long allocpages, maxpages, minpages;
636 int i, index, n;
637
638 VM_OBJECT_ASSERT_WLOCKED(object);
639 KASSERT(npages != 0, ("vm_reserv_alloc_contig: npages is 0"));
640
641 /*
642 * Is a reservation fundamentally impossible?
643 */
644 if (pindex < VM_RESERV_INDEX(object, pindex) ||
645 pindex + npages > object->size)
646 return (NULL);
647
648 /*
649 * All reservations of a particular size have the same alignment.
650 * Assuming that the first page is allocated from a reservation, the
651 * least significant bits of its physical address can be determined
652 * from its offset from the beginning of the reservation and the size
653 * of the reservation.
654 *
655 * Could the specified index within a reservation of the smallest
656 * possible size satisfy the alignment and boundary requirements?
657 */
658 pa = VM_RESERV_INDEX(object, pindex) << PAGE_SHIFT;
659 if ((pa & (alignment - 1)) != 0)
660 return (NULL);
661 size = npages << PAGE_SHIFT;
662 if (((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0)
663 return (NULL);
664
665 /*
666 * Look for an existing reservation.
667 */
668 rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
669 if (rv != NULL) {
670 KASSERT(object != kernel_object || rv->domain == domain,
671 ("vm_reserv_alloc_contig: domain mismatch"));
672 index = VM_RESERV_INDEX(object, pindex);
673 /* Does the allocation fit within the reservation? */
674 if (index + npages > VM_LEVEL_0_NPAGES)
675 return (NULL);
676 domain = rv->domain;
677 vmd = VM_DOMAIN(domain);
678 vm_reserv_lock(rv);
679 /* Handle reclaim race. */
680 if (rv->object != object)
681 goto out;
682 m = &rv->pages[index];

Callers 1

Calls 11

vm_reserv_from_objectFunction · 0.85
popmap_is_setFunction · 0.85
vm_domain_allocateFunction · 0.85
vm_reserv_populateFunction · 0.85
vm_reserv_from_pageFunction · 0.85
vm_phys_alloc_contigFunction · 0.85
ulmaxFunction · 0.85
vm_domain_freecnt_incFunction · 0.85
vm_page_domainFunction · 0.85
vm_reserv_insertFunction · 0.85
ulminFunction · 0.85

Tested by

no test coverage detected