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

Function vm_phys_unfree_page

freebsd/vm/vm_phys.c:1295–1350  ·  view source on GitHub ↗

* Search for the given physical page "m" in the free lists. If the search * succeeds, remove "m" from the free lists and return TRUE. Otherwise, return * FALSE, indicating that "m" is not in the free lists. * * The free page queues must be locked. */

Source from the content-addressed store, hash-verified

1293 * The free page queues must be locked.
1294 */
1295boolean_t
1296vm_phys_unfree_page(vm_page_t m)
1297{
1298 struct vm_freelist *fl;
1299 struct vm_phys_seg *seg;
1300 vm_paddr_t pa, pa_half;
1301 vm_page_t m_set, m_tmp;
1302 int order;
1303
1304 /*
1305 * First, find the contiguous, power of two-sized set of free
1306 * physical pages containing the given physical page "m" and
1307 * assign it to "m_set".
1308 */
1309 seg = &vm_phys_segs[m->segind];
1310 vm_domain_free_assert_locked(VM_DOMAIN(seg->domain));
1311 for (m_set = m, order = 0; m_set->order == VM_NFREEORDER &&
1312 order < VM_NFREEORDER - 1; ) {
1313 order++;
1314 pa = m->phys_addr & (~(vm_paddr_t)0 << (PAGE_SHIFT + order));
1315 if (pa >= seg->start)
1316 m_set = &seg->first_page[atop(pa - seg->start)];
1317 else
1318 return (FALSE);
1319 }
1320 if (m_set->order < order)
1321 return (FALSE);
1322 if (m_set->order == VM_NFREEORDER)
1323 return (FALSE);
1324 KASSERT(m_set->order < VM_NFREEORDER,
1325 ("vm_phys_unfree_page: page %p has unexpected order %d",
1326 m_set, m_set->order));
1327
1328 /*
1329 * Next, remove "m_set" from the free lists. Finally, extract
1330 * "m" from "m_set" using an iterative algorithm: While "m_set"
1331 * is larger than a page, shrink "m_set" by returning the half
1332 * of "m_set" that does not contain "m" to the free lists.
1333 */
1334 fl = (*seg->free_queues)[m_set->pool];
1335 order = m_set->order;
1336 vm_freelist_rem(fl, m_set, order);
1337 while (order > 0) {
1338 order--;
1339 pa_half = m_set->phys_addr ^ (1 << (PAGE_SHIFT + order));
1340 if (m->phys_addr < pa_half)
1341 m_tmp = &seg->first_page[atop(pa_half - seg->start)];
1342 else {
1343 m_tmp = m_set;
1344 m_set = &seg->first_page[atop(pa_half - seg->start)];
1345 }
1346 vm_freelist_add(fl, m_tmp, order, 0);
1347 }
1348 KASSERT(m_set == m, ("vm_phys_unfree_page: fatal inconsistency"));
1349 return (TRUE);
1350}
1351
1352/*

Callers 1

vm_page_blacklist_addFunction · 0.85

Calls 2

vm_freelist_remFunction · 0.85
vm_freelist_addFunction · 0.85

Tested by

no test coverage detected