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

Function pmap_ts_referenced

freebsd/arm/arm/pmap-v6.c:5303–5405  ·  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

5301 * to pmap_is_modified().
5302 */
5303int
5304pmap_ts_referenced(vm_page_t m)
5305{
5306 struct md_page *pvh;
5307 pv_entry_t pv, pvf;
5308 pmap_t pmap;
5309 pt1_entry_t *pte1p, opte1;
5310 pt2_entry_t *pte2p, opte2;
5311 vm_paddr_t pa;
5312 int rtval = 0;
5313
5314 KASSERT((m->oflags & VPO_UNMANAGED) == 0,
5315 ("%s: page %p is not managed", __func__, m));
5316 pa = VM_PAGE_TO_PHYS(m);
5317 pvh = pa_to_pvh(pa);
5318 rw_wlock(&pvh_global_lock);
5319 sched_pin();
5320 if ((m->flags & PG_FICTITIOUS) != 0 ||
5321 (pvf = TAILQ_FIRST(&pvh->pv_list)) == NULL)
5322 goto small_mappings;
5323 pv = pvf;
5324 do {
5325 pmap = PV_PMAP(pv);
5326 PMAP_LOCK(pmap);
5327 pte1p = pmap_pte1(pmap, pv->pv_va);
5328 opte1 = pte1_load(pte1p);
5329 if (pte1_is_dirty(opte1)) {
5330 /*
5331 * Although "opte1" is mapping a 1MB page, because
5332 * this function is called at a 4KB page granularity,
5333 * we only update the 4KB page under test.
5334 */
5335 vm_page_dirty(m);
5336 }
5337 if ((opte1 & PTE1_A) != 0) {
5338 /*
5339 * Since this reference bit is shared by 256 4KB pages,
5340 * it should not be cleared every time it is tested.
5341 * Apply a simple "hash" function on the physical page
5342 * number, the virtual section number, and the pmap
5343 * address to select one 4KB page out of the 256
5344 * on which testing the reference bit will result
5345 * in clearing that bit. This function is designed
5346 * to avoid the selection of the same 4KB page
5347 * for every 1MB page mapping.
5348 *
5349 * On demotion, a mapping that hasn't been referenced
5350 * is simply destroyed. To avoid the possibility of a
5351 * subsequent page fault on a demoted wired mapping,
5352 * always leave its reference bit set. Moreover,
5353 * since the section is wired, the current state of
5354 * its reference bit won't affect page replacement.
5355 */
5356 if ((((pa >> PAGE_SHIFT) ^ (pv->pv_va >> PTE1_SHIFT) ^
5357 (uintptr_t)pmap) & (NPTE2_IN_PG - 1)) == 0 &&
5358 !pte1_is_wired(opte1)) {
5359 pte1_clear_bit(pte1p, PTE1_A);
5360 pmap_tlb_flush(pmap, pv->pv_va);

Callers

nothing calls this directly

Calls 15

pa_to_pvhFunction · 0.85
sched_pinFunction · 0.85
pmap_pte1Function · 0.85
pte1_loadFunction · 0.85
pte1_is_dirtyFunction · 0.85
vm_page_dirtyFunction · 0.85
pte1_is_wiredFunction · 0.85
pte1_clear_bitFunction · 0.85
pmap_tlb_flushFunction · 0.85
pte1_is_linkFunction · 0.85
pmap_pte2_quickFunction · 0.85
pte2_loadFunction · 0.85

Tested by

no test coverage detected