From owner-svn-src-projects@FreeBSD.ORG Mon Mar 25 13:03:25 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 0917C379; Mon, 25 Mar 2013 13:03:25 +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 EF91EBF7; Mon, 25 Mar 2013 13:03:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r2PD3OH2019460; Mon, 25 Mar 2013 13:03:24 GMT (envelope-from cherry@svn.freebsd.org) Received: (from cherry@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r2PD3OOZ019458; Mon, 25 Mar 2013 13:03:24 GMT (envelope-from cherry@svn.freebsd.org) Message-Id: <201303251303.r2PD3OOZ019458@svn.freebsd.org> From: "Cherry G. Mathew" Date: Mon, 25 Mar 2013 13:03:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r248701 - 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, 25 Mar 2013 13:03:25 -0000 Author: cherry Date: Mon Mar 25 13:03:24 2013 New Revision: 248701 URL: http://svnweb.freebsd.org/changeset/base/248701 Log: Add a two functions to pmap_pv tracking: i) To run a callback on every iterated entry ii) To free a pv entry and it's associated chunk (from amd64/amd64/pmap.c) 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 Mar 25 12:38:45 2013 (r248700) +++ projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.c Mon Mar 25 13:03:24 2013 (r248701) @@ -168,6 +168,58 @@ pv_to_chunk(pv_entry_t pv) #include #include + + +static void +free_pv_chunk(struct pv_chunk *pc) +{ + vm_page_t m; + + mtx_lock(&pv_chunks_mutex); + TAILQ_REMOVE(&pv_chunks, pc, pc_lru); + mtx_unlock(&pv_chunks_mutex); + PV_STAT(atomic_subtract_int(&pv_entry_spare, _NPCPV)); + PV_STAT(atomic_subtract_int(&pc_chunk_count, 1)); + PV_STAT(atomic_add_int(&pc_chunk_frees, 1)); + /* entire chunk is free, return it */ + m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc)); + pmap_kremove((vm_offset_t)pc); + dump_drop_page(m->phys_addr); + vm_page_unwire(m, 0); + vm_page_free(m); +} + +/* + * free the pv_entry back to the free list + */ +static void +free_pv_entry(pmap_t pmap, pv_entry_t pv) +{ + struct pv_chunk *pc; + int idx, field, bit; + + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + PV_STAT(atomic_add_long(&pv_entry_frees, 1)); + PV_STAT(atomic_add_int(&pv_entry_spare, 1)); + PV_STAT(atomic_subtract_long(&pv_entry_count, 1)); + pc = pv_to_chunk(pv); + idx = pv - &pc->pc_pventry[0]; + field = idx / 64; + bit = idx % 64; + pc->pc_map[field] |= 1ul << bit; + if (pc->pc_map[0] != PC_FREE0 || pc->pc_map[1] != PC_FREE1 || + pc->pc_map[2] != PC_FREE2) { + /* 98% of the time, pc is already at the head of the list. */ + if (__predict_false(pc != TAILQ_FIRST(&pmap->pm_pvchunk))) { + TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list); + TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list); + } + return; + } + TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list); + free_pv_chunk(pc); +} + pv_entry_t pmap_get_pv_entry(pmap_t pmap) { @@ -281,6 +333,7 @@ pmap_free_pv_entry(pmap_t pmap, vm_offse TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { if (pmap == PV_PMAP(pv) && va == pv->pv_va) { TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + free_pv_entry(pmap, pv); found = true; break; } @@ -384,3 +437,40 @@ pmap_pv_vm_page_mapped(pmap_t pmap, vm_p (VM_MAX_KERNEL_ADDRESS + 1)) ? false : true; } + +/* + * Iterate through all mappings, until callback returns 'true' + * Returns the number of iterations. + */ + +int +pmap_pv_iterate(vm_page_t m, pv_cb_t cb) +{ + int iter = 0; + pv_entry_t next_pv, pv; + + rw_wlock(&pvh_global_lock); + + TAILQ_FOREACH_SAFE(pv, &m->md.pv_list, pv_list, next_pv) { + iter++; + if (cb(PV_PMAP(pv), pv->pv_va, m)) break; + } + rw_wunlock(&pvh_global_lock); + return iter; +} + +/* + * Destroy all pv mappings for a given physical page. + */ +void +pmap_pv_page_unmap(vm_page_t m) +{ + pv_entry_t pv, next_pv; + + rw_wlock(&pvh_global_lock); + TAILQ_FOREACH_SAFE(pv, &m->md.pv_list, pv_list, next_pv) { + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + } + rw_wunlock(&pvh_global_lock); + return; +} Modified: projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h ============================================================================== --- projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h Mon Mar 25 12:38:45 2013 (r248700) +++ projects/amd64_xen_pv/sys/amd64/xen/pmap_pv.h Mon Mar 25 13:03:24 2013 (r248701) @@ -36,6 +36,12 @@ #ifndef _MACHINE_PMAP_PV_H_ #define _MACHINE_PMAP_PV_H_ +/* + * Used as a callback when iterating through multiple pmaps + * If the callback returns 'true', iteration is stopped. + */ +typedef bool pv_cb_t(pmap_t pmap, vm_offset_t va, vm_page_t m) ; + void pmap_pv_init(void); void pmap_pv_pmap_init(pmap_t pmap); void pmap_pv_vm_page_init(vm_page_t m); @@ -45,5 +51,7 @@ pv_entry_t pmap_get_pv_entry(pmap_t pmap void pmap_put_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); 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); +void pmap_pv_page_unmap(vm_page_t m); #endif /* !_MACHINE_PMAP_PV_H_ */