* Scan physical memory between the specified addresses "low" and "high" for a * run of contiguous physical pages that satisfy the specified conditions, and * return the lowest page in the run. The specified "alignment" determines * the alignment of the lowest physical page in the run. If the specified * "boundary" is non-zero, then the run of physical pages cannot span a * physical address
| 1233 | * be a power of two. |
| 1234 | */ |
| 1235 | vm_page_t |
| 1236 | vm_phys_scan_contig(int domain, u_long npages, vm_paddr_t low, vm_paddr_t high, |
| 1237 | u_long alignment, vm_paddr_t boundary, int options) |
| 1238 | { |
| 1239 | vm_paddr_t pa_end; |
| 1240 | vm_page_t m_end, m_run, m_start; |
| 1241 | struct vm_phys_seg *seg; |
| 1242 | int segind; |
| 1243 | |
| 1244 | KASSERT(npages > 0, ("npages is 0")); |
| 1245 | KASSERT(powerof2(alignment), ("alignment is not a power of 2")); |
| 1246 | KASSERT(powerof2(boundary), ("boundary is not a power of 2")); |
| 1247 | if (low >= high) |
| 1248 | return (NULL); |
| 1249 | for (segind = 0; segind < vm_phys_nsegs; segind++) { |
| 1250 | seg = &vm_phys_segs[segind]; |
| 1251 | if (seg->domain != domain) |
| 1252 | continue; |
| 1253 | if (seg->start >= high) |
| 1254 | break; |
| 1255 | if (low >= seg->end) |
| 1256 | continue; |
| 1257 | if (low <= seg->start) |
| 1258 | m_start = seg->first_page; |
| 1259 | else |
| 1260 | m_start = &seg->first_page[atop(low - seg->start)]; |
| 1261 | if (high < seg->end) |
| 1262 | pa_end = high; |
| 1263 | else |
| 1264 | pa_end = seg->end; |
| 1265 | if (pa_end - VM_PAGE_TO_PHYS(m_start) < ptoa(npages)) |
| 1266 | continue; |
| 1267 | m_end = &seg->first_page[atop(pa_end - seg->start)]; |
| 1268 | m_run = vm_page_scan_contig(npages, m_start, m_end, |
| 1269 | alignment, boundary, options); |
| 1270 | if (m_run != NULL) |
| 1271 | return (m_run); |
| 1272 | } |
| 1273 | return (NULL); |
| 1274 | } |
| 1275 | |
| 1276 | /* |
| 1277 | * Set the pool for a contiguous, power of two-sized set of physical pages. |
no test coverage detected