* Allocate a run of contiguous physical pages from the free list for the * specified segment. */
| 1404 | * specified segment. |
| 1405 | */ |
| 1406 | static vm_page_t |
| 1407 | vm_phys_alloc_seg_contig(struct vm_phys_seg *seg, u_long npages, |
| 1408 | vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary) |
| 1409 | { |
| 1410 | struct vm_freelist *fl; |
| 1411 | vm_paddr_t pa, pa_end, size; |
| 1412 | vm_page_t m, m_ret; |
| 1413 | u_long npages_end; |
| 1414 | int oind, order, pind; |
| 1415 | |
| 1416 | KASSERT(npages > 0, ("npages is 0")); |
| 1417 | KASSERT(powerof2(alignment), ("alignment is not a power of 2")); |
| 1418 | KASSERT(powerof2(boundary), ("boundary is not a power of 2")); |
| 1419 | vm_domain_free_assert_locked(VM_DOMAIN(seg->domain)); |
| 1420 | /* Compute the queue that is the best fit for npages. */ |
| 1421 | order = flsl(npages - 1); |
| 1422 | /* Search for a run satisfying the specified conditions. */ |
| 1423 | size = npages << PAGE_SHIFT; |
| 1424 | for (oind = min(order, VM_NFREEORDER - 1); oind < VM_NFREEORDER; |
| 1425 | oind++) { |
| 1426 | for (pind = 0; pind < VM_NFREEPOOL; pind++) { |
| 1427 | fl = (*seg->free_queues)[pind]; |
| 1428 | TAILQ_FOREACH(m_ret, &fl[oind].pl, listq) { |
| 1429 | /* |
| 1430 | * Is the size of this allocation request |
| 1431 | * larger than the largest block size? |
| 1432 | */ |
| 1433 | if (order >= VM_NFREEORDER) { |
| 1434 | /* |
| 1435 | * Determine if a sufficient number of |
| 1436 | * subsequent blocks to satisfy the |
| 1437 | * allocation request are free. |
| 1438 | */ |
| 1439 | pa = VM_PAGE_TO_PHYS(m_ret); |
| 1440 | pa_end = pa + size; |
| 1441 | if (pa_end < pa) |
| 1442 | continue; |
| 1443 | for (;;) { |
| 1444 | pa += 1 << (PAGE_SHIFT + |
| 1445 | VM_NFREEORDER - 1); |
| 1446 | if (pa >= pa_end || |
| 1447 | pa < seg->start || |
| 1448 | pa >= seg->end) |
| 1449 | break; |
| 1450 | m = &seg->first_page[atop(pa - |
| 1451 | seg->start)]; |
| 1452 | if (m->order != VM_NFREEORDER - |
| 1453 | 1) |
| 1454 | break; |
| 1455 | } |
| 1456 | /* If not, go to the next block. */ |
| 1457 | if (pa < pa_end) |
| 1458 | continue; |
| 1459 | } |
| 1460 | |
| 1461 | /* |
| 1462 | * Determine if the blocks are within the |
| 1463 | * given range, satisfy the given alignment, |
no test coverage detected