* Free a contiguous, arbitrarily sized set of physical pages, without * merging across set boundaries. * * The free page queues must be locked. */
| 1145 | * The free page queues must be locked. |
| 1146 | */ |
| 1147 | void |
| 1148 | vm_phys_enqueue_contig(vm_page_t m, u_long npages) |
| 1149 | { |
| 1150 | struct vm_freelist *fl; |
| 1151 | struct vm_phys_seg *seg; |
| 1152 | vm_page_t m_end; |
| 1153 | int order; |
| 1154 | |
| 1155 | /* |
| 1156 | * Avoid unnecessary coalescing by freeing the pages in the largest |
| 1157 | * possible power-of-two-sized subsets. |
| 1158 | */ |
| 1159 | vm_domain_free_assert_locked(vm_pagequeue_domain(m)); |
| 1160 | seg = &vm_phys_segs[m->segind]; |
| 1161 | fl = (*seg->free_queues)[m->pool]; |
| 1162 | m_end = m + npages; |
| 1163 | /* Free blocks of increasing size. */ |
| 1164 | while ((order = max_order(m)) < VM_NFREEORDER - 1 && |
| 1165 | m + (1 << order) <= m_end) { |
| 1166 | KASSERT(seg == &vm_phys_segs[m->segind], |
| 1167 | ("%s: page range [%p,%p) spans multiple segments", |
| 1168 | __func__, m_end - npages, m)); |
| 1169 | vm_freelist_add(fl, m, order, 1); |
| 1170 | m += 1 << order; |
| 1171 | } |
| 1172 | /* Free blocks of maximum size. */ |
| 1173 | while (m + (1 << order) <= m_end) { |
| 1174 | KASSERT(seg == &vm_phys_segs[m->segind], |
| 1175 | ("%s: page range [%p,%p) spans multiple segments", |
| 1176 | __func__, m_end - npages, m)); |
| 1177 | vm_freelist_add(fl, m, order, 1); |
| 1178 | m += 1 << order; |
| 1179 | } |
| 1180 | /* Free blocks of diminishing size. */ |
| 1181 | while (m < m_end) { |
| 1182 | KASSERT(seg == &vm_phys_segs[m->segind], |
| 1183 | ("%s: page range [%p,%p) spans multiple segments", |
| 1184 | __func__, m_end - npages, m)); |
| 1185 | order = flsl(m_end - m) - 1; |
| 1186 | vm_freelist_add(fl, m, order, 1); |
| 1187 | m += 1 << order; |
| 1188 | } |
| 1189 | } |
| 1190 | |
| 1191 | /* |
| 1192 | * Free a contiguous, arbitrarily sized set of physical pages. |
no test coverage detected