From owner-svn-src-projects@FreeBSD.ORG Mon Apr 22 18:35:05 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id BDBF6820; Mon, 22 Apr 2013 18:35:05 +0000 (UTC) (envelope-from cherry@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 95D641CEF; Mon, 22 Apr 2013 18:35:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3MIZ5Ip054634; Mon, 22 Apr 2013 18:35:05 GMT (envelope-from cherry@svn.freebsd.org) Received: (from cherry@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3MIZ5gw054632; Mon, 22 Apr 2013 18:35:05 GMT (envelope-from cherry@svn.freebsd.org) Message-Id: <201304221835.r3MIZ5gw054632@svn.freebsd.org> From: "Cherry G. Mathew" Date: Mon, 22 Apr 2013 18:35:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r249772 - projects/amd64_xen_pv/sys/amd64/xen X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Apr 2013 18:35:05 -0000 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_ */