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

Function vm_phys_alloc_npages

freebsd/vm/vm_phys.c:726–792  ·  view source on GitHub ↗

* Tries to allocate the specified number of pages from the specified pool * within the specified domain. Returns the actual number of allocated pages * and a pointer to each page through the array ma[]. * * The returned pages may not be physically contiguous. However, in contrast * to performing multiple, back-to-back calls to vm_phys_alloc_pages(..., 0), * calling this function once to al

Source from the content-addressed store, hash-verified

724 * The free page queues for the specified domain must be locked.
725 */
726int
727vm_phys_alloc_npages(int domain, int pool, int npages, vm_page_t ma[])
728{
729 struct vm_freelist *alt, *fl;
730 vm_page_t m;
731 int avail, end, flind, freelist, i, need, oind, pind;
732
733 KASSERT(domain >= 0 && domain < vm_ndomains,
734 ("vm_phys_alloc_npages: domain %d is out of range", domain));
735 KASSERT(pool < VM_NFREEPOOL,
736 ("vm_phys_alloc_npages: pool %d is out of range", pool));
737 KASSERT(npages <= 1 << (VM_NFREEORDER - 1),
738 ("vm_phys_alloc_npages: npages %d is out of range", npages));
739 vm_domain_free_assert_locked(VM_DOMAIN(domain));
740 i = 0;
741 for (freelist = 0; freelist < VM_NFREELIST; freelist++) {
742 flind = vm_freelist_to_flind[freelist];
743 if (flind < 0)
744 continue;
745 fl = vm_phys_free_queues[domain][flind][pool];
746 for (oind = 0; oind < VM_NFREEORDER; oind++) {
747 while ((m = TAILQ_FIRST(&fl[oind].pl)) != NULL) {
748 vm_freelist_rem(fl, m, oind);
749 avail = 1 << oind;
750 need = imin(npages - i, avail);
751 for (end = i + need; i < end;)
752 ma[i++] = m++;
753 if (need < avail) {
754 /*
755 * Return excess pages to fl. Its
756 * order [0, oind) queues are empty.
757 */
758 vm_phys_enq_range(m, avail - need, fl,
759 1);
760 return (npages);
761 } else if (i == npages)
762 return (npages);
763 }
764 }
765 for (oind = VM_NFREEORDER - 1; oind >= 0; oind--) {
766 for (pind = 0; pind < VM_NFREEPOOL; pind++) {
767 alt = vm_phys_free_queues[domain][flind][pind];
768 while ((m = TAILQ_FIRST(&alt[oind].pl)) !=
769 NULL) {
770 vm_freelist_rem(alt, m, oind);
771 vm_phys_set_pool(pool, m, oind);
772 avail = 1 << oind;
773 need = imin(npages - i, avail);
774 for (end = i + need; i < end;)
775 ma[i++] = m++;
776 if (need < avail) {
777 /*
778 * Return excess pages to fl.
779 * Its order [0, oind) queues
780 * are empty.
781 */
782 vm_phys_enq_range(m, avail -
783 need, fl, 1);

Callers 1

vm_page_zone_importFunction · 0.85

Calls 4

vm_freelist_remFunction · 0.85
iminFunction · 0.85
vm_phys_enq_rangeFunction · 0.85
vm_phys_set_poolFunction · 0.85

Tested by

no test coverage detected