Date: Mon, 22 Apr 2013 18:35:05 +0000 (UTC) From: "Cherry G. Mathew" <cherry@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r249772 - projects/amd64_xen_pv/sys/amd64/xen Message-ID: <201304221835.r3MIZ5gw054632@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: cherry Date: Mon Apr 22 18:35:04 2013 New Revision: 249772 URL: http://svnweb.freebsd.org/changeset/base/249772 Log: Add new function to iterate through all p->v mappings in a given pmap. Approved by: gibbs(implicit) Modified: projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.c projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h Modified: projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.c ============================================================================== --- projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.c Mon Apr 22 18:31:39 2013 (r249771) +++ projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.c Mon Apr 22 18:35:04 2013 (r249772) @@ -159,6 +159,8 @@ pv_to_chunk(pv_entry_t pv) #define PC_FREE1 0xfffffffffffffffful #define PC_FREE2 0x000000fffffffffful +static const uint64_t pc_freemask[_NPCM] = { PC_FREE0, PC_FREE1, PC_FREE2 }; + /* * Returns a new PV entry, allocating a new PV chunk from the system when * needed. If this PV chunk allocation fails and a PV list lock pointer was @@ -458,7 +460,8 @@ pmap_pv_vm_page_mapped(pmap_t pmap, vm_p } /* - * Iterate through all mappings, until callback returns 'true' + * Iterate through all va mappings a physical page is part of, until + * callback returns 'true'. * Returns the number of iterations. */ @@ -479,6 +482,47 @@ pmap_pv_iterate(vm_page_t m, pv_cb_t cb) } /* + * Iterate through all pv mappings in a pmap, until callback returns + * 'true'. + * Returns the number of iterations. + */ + +int +pmap_pv_iterate_map(pmap_t pmap, pv_cb_t cb) +{ + int iter = 0; + + int field, idx; + int64_t bit; + uint64_t inuse, bitmask; + pv_entry_t pv; + struct pv_chunk *pc, *npc; + + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + + TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { + iter++; + for (field = 0; field < _NPCM; field++) { + inuse = ~pc->pc_map[field] & pc_freemask[field]; + while (inuse != 0) { + bit = bsfq(inuse); + bitmask = 1UL << bit; + idx = field * 64 + bit; + pv = &pc->pc_pventry[idx]; + inuse &= ~bitmask; + + if (cb(PV_PMAP(pv), pv->pv_va, NULL)) break; + } + if (TAILQ_EMPTY(&pmap->pm_pvchunk)) { + /* Chunks were all freed! Bail. */ + break; + } + } + } + return iter; +} + +/* * Destroy all pv mappings for a given physical page. */ void Modified: projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h ============================================================================== --- projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h Mon Apr 22 18:31:39 2013 (r249771) +++ projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h Mon Apr 22 18:35:04 2013 (r249772) @@ -52,6 +52,7 @@ bool pmap_put_pv_entry(pmap_t pmap, vm_o bool pmap_free_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); pv_entry_t pmap_find_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); int pmap_pv_iterate(vm_page_t m, pv_cb_t cb); +int pmap_pv_iterate_map(pmap_t pmap, pv_cb_t cb); void pmap_pv_page_unmap(vm_page_t m); #endif /* !_MACHINE_PMAP_PV_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304221835.r3MIZ5gw054632>