* Allocate a contiguous set of physical pages of the given size * "npages" from the free lists. 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 the set of physical page
| 1360 | * "alignment" and "boundary" must be a power of two. |
| 1361 | */ |
| 1362 | vm_page_t |
| 1363 | vm_phys_alloc_contig(int domain, u_long npages, vm_paddr_t low, vm_paddr_t high, |
| 1364 | u_long alignment, vm_paddr_t boundary) |
| 1365 | { |
| 1366 | vm_paddr_t pa_end, pa_start; |
| 1367 | vm_page_t m_run; |
| 1368 | struct vm_phys_seg *seg; |
| 1369 | int segind; |
| 1370 | |
| 1371 | KASSERT(npages > 0, ("npages is 0")); |
| 1372 | KASSERT(powerof2(alignment), ("alignment is not a power of 2")); |
| 1373 | KASSERT(powerof2(boundary), ("boundary is not a power of 2")); |
| 1374 | vm_domain_free_assert_locked(VM_DOMAIN(domain)); |
| 1375 | if (low >= high) |
| 1376 | return (NULL); |
| 1377 | m_run = NULL; |
| 1378 | for (segind = vm_phys_nsegs - 1; segind >= 0; segind--) { |
| 1379 | seg = &vm_phys_segs[segind]; |
| 1380 | if (seg->start >= high || seg->domain != domain) |
| 1381 | continue; |
| 1382 | if (low >= seg->end) |
| 1383 | break; |
| 1384 | if (low <= seg->start) |
| 1385 | pa_start = seg->start; |
| 1386 | else |
| 1387 | pa_start = low; |
| 1388 | if (high < seg->end) |
| 1389 | pa_end = high; |
| 1390 | else |
| 1391 | pa_end = seg->end; |
| 1392 | if (pa_end - pa_start < ptoa(npages)) |
| 1393 | continue; |
| 1394 | m_run = vm_phys_alloc_seg_contig(seg, npages, low, high, |
| 1395 | alignment, boundary); |
| 1396 | if (m_run != NULL) |
| 1397 | break; |
| 1398 | } |
| 1399 | return (m_run); |
| 1400 | } |
| 1401 | |
| 1402 | /* |
| 1403 | * Allocate a run of contiguous physical pages from the free list for the |
no test coverage detected