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

Function pmap_ts_referenced

freebsd/arm64/arm64/pmap.c:5500–5649  ·  view source on GitHub ↗

* pmap_ts_referenced: * * Return a count of reference bits for a page, clearing those bits. * It is not necessary for every reference bit to be cleared, but it * is necessary that 0 only be returned when there are truly no * reference bits set. * * As an optimization, update the page's dirty field if a modified bit is * found while counting reference bits. This opportunistic update can be

Source from the content-addressed store, hash-verified

5498 * to pmap_is_modified().
5499 */
5500int
5501pmap_ts_referenced(vm_page_t m)
5502{
5503 struct md_page *pvh;
5504 pv_entry_t pv, pvf;
5505 pmap_t pmap;
5506 struct rwlock *lock;
5507 pd_entry_t *pde, tpde;
5508 pt_entry_t *pte, tpte;
5509 vm_offset_t va;
5510 vm_paddr_t pa;
5511 int cleared, lvl, md_gen, not_cleared, pvh_gen;
5512 struct spglist free;
5513
5514 KASSERT((m->oflags & VPO_UNMANAGED) == 0,
5515 ("pmap_ts_referenced: page %p is not managed", m));
5516 SLIST_INIT(&free);
5517 cleared = 0;
5518 pa = VM_PAGE_TO_PHYS(m);
5519 lock = PHYS_TO_PV_LIST_LOCK(pa);
5520 pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : page_to_pvh(m);
5521 rw_wlock(lock);
5522retry:
5523 not_cleared = 0;
5524 if ((pvf = TAILQ_FIRST(&pvh->pv_list)) == NULL)
5525 goto small_mappings;
5526 pv = pvf;
5527 do {
5528 if (pvf == NULL)
5529 pvf = pv;
5530 pmap = PV_PMAP(pv);
5531 if (!PMAP_TRYLOCK(pmap)) {
5532 pvh_gen = pvh->pv_gen;
5533 rw_wunlock(lock);
5534 PMAP_LOCK(pmap);
5535 rw_wlock(lock);
5536 if (pvh_gen != pvh->pv_gen) {
5537 PMAP_UNLOCK(pmap);
5538 goto retry;
5539 }
5540 }
5541 va = pv->pv_va;
5542 pde = pmap_pde(pmap, pv->pv_va, &lvl);
5543 KASSERT(pde != NULL, ("pmap_ts_referenced: no l1 table found"));
5544 KASSERT(lvl == 1,
5545 ("pmap_ts_referenced: invalid pde level %d", lvl));
5546 tpde = pmap_load(pde);
5547 KASSERT((tpde & ATTR_DESCR_MASK) == L1_TABLE,
5548 ("pmap_ts_referenced: found an invalid l1 table"));
5549 pte = pmap_l1_to_l2(pde, pv->pv_va);
5550 tpte = pmap_load(pte);
5551 if (pmap_pte_dirty(pmap, tpte)) {
5552 /*
5553 * Although "tpte" is mapping a 2MB page, because
5554 * this function is called at a 4KB page granularity,
5555 * we only update the 4KB page under test.
5556 */
5557 vm_page_dirty(m);

Callers

nothing calls this directly

Calls 8

page_to_pvhFunction · 0.85
pmap_l1_to_l2Function · 0.85
pmap_pte_dirtyFunction · 0.85
vm_page_dirtyFunction · 0.85
pmap_l2_to_l3Function · 0.85
vm_page_free_pages_toqFunction · 0.85
pmap_pdeFunction · 0.70
pmap_invalidate_pageFunction · 0.70

Tested by

no test coverage detected