Module Name: src Committed By: cherry Date: Tue May 6 04:26:24 UTC 2014
Modified Files: src/sys/arch/x86/x86: pmap.c src/sys/arch/xen/include: xenpmap.h src/sys/arch/xen/x86: x86_xpmap.c Log Message: Use the hypervisor to copy/zero pages. This saves us the extra overheads of setting up temporary kernel mapping/unmapping. riz@ reports savings of about 2s on a 120s kernel build. To generate a diff of this commit: cvs rdiff -u -r1.181 -r1.182 src/sys/arch/x86/x86/pmap.c cvs rdiff -u -r1.37 -r1.38 src/sys/arch/xen/include/xenpmap.h cvs rdiff -u -r1.52 -r1.53 src/sys/arch/xen/x86/x86_xpmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/pmap.c diff -u src/sys/arch/x86/x86/pmap.c:1.181 src/sys/arch/x86/x86/pmap.c:1.182 --- src/sys/arch/x86/x86/pmap.c:1.181 Wed Nov 6 20:19:03 2013 +++ src/sys/arch/x86/x86/pmap.c Tue May 6 04:26:23 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.181 2013/11/06 20:19:03 mrg Exp $ */ +/* $NetBSD: pmap.c,v 1.182 2014/05/06 04:26:23 cherry Exp $ */ /*- * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. @@ -171,7 +171,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.181 2013/11/06 20:19:03 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.182 2014/05/06 04:26:23 cherry Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -3011,8 +3011,10 @@ pmap_virtual_space(vaddr_t *startp, vadd void pmap_zero_page(paddr_t pa) { -#ifdef __HAVE_DIRECT_MAP +#if defined(__HAVE_DIRECT_MAP) pagezero(PMAP_DIRECT_MAP(pa)); +#elif defined(XEN) + xen_pagezero(pa); #else pt_entry_t *zpte; void *zerova; @@ -3089,11 +3091,13 @@ pmap_pageidlezero(paddr_t pa) void pmap_copy_page(paddr_t srcpa, paddr_t dstpa) { -#ifdef __HAVE_DIRECT_MAP +#if defined(__HAVE_DIRECT_MAP) vaddr_t srcva = PMAP_DIRECT_MAP(srcpa); vaddr_t dstva = PMAP_DIRECT_MAP(dstpa); memcpy((void *)dstva, (void *)srcva, PAGE_SIZE); +#elif defined(XEN) + xen_copy_page(srcpa, dstpa); #else pt_entry_t *spte; pt_entry_t *dpte; @@ -4103,6 +4107,8 @@ pmap_get_physpage(vaddr_t va, int level, panic("pmap_get_physpage: out of memory"); #ifdef __HAVE_DIRECT_MAP pagezero(PMAP_DIRECT_MAP(*paddrp)); +#elif defined(XEN) + xen_pagezero(*paddrp); #else kpreempt_disable(); pmap_pte_set(early_zero_pte, @@ -4110,7 +4116,7 @@ pmap_get_physpage(vaddr_t va, int level, pmap_pte_flush(); pmap_update_pg((vaddr_t)early_zerop); memset(early_zerop, 0, PAGE_SIZE); -#if defined(DIAGNOSTIC) || defined (XEN) +#if defined(DIAGNOSTIC) pmap_pte_set(early_zero_pte, 0); pmap_pte_flush(); #endif /* defined(DIAGNOSTIC) */ Index: src/sys/arch/xen/include/xenpmap.h diff -u src/sys/arch/xen/include/xenpmap.h:1.37 src/sys/arch/xen/include/xenpmap.h:1.38 --- src/sys/arch/xen/include/xenpmap.h:1.37 Sat Jun 30 22:50:36 2012 +++ src/sys/arch/xen/include/xenpmap.h Tue May 6 04:26:24 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: xenpmap.h,v 1.37 2012/06/30 22:50:36 jym Exp $ */ +/* $NetBSD: xenpmap.h,v 1.38 2014/05/06 04:26:24 cherry Exp $ */ /* * @@ -55,6 +55,8 @@ void xen_mcast_tlbflush(kcpuset_t *); void xen_bcast_tlbflush(void); void xen_mcast_invlpg(vaddr_t, kcpuset_t *); void xen_bcast_invlpg(vaddr_t); +void xen_copy_page(paddr_t, paddr_t); +void xen_pagezero(paddr_t); void pmap_xen_resume(void); void pmap_xen_suspend(void); Index: src/sys/arch/xen/x86/x86_xpmap.c diff -u src/sys/arch/xen/x86/x86_xpmap.c:1.52 src/sys/arch/xen/x86/x86_xpmap.c:1.53 --- src/sys/arch/xen/x86/x86_xpmap.c:1.52 Sun Nov 10 01:19:13 2013 +++ src/sys/arch/xen/x86/x86_xpmap.c Tue May 6 04:26:24 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: x86_xpmap.c,v 1.52 2013/11/10 01:19:13 jnemeth Exp $ */ +/* $NetBSD: x86_xpmap.c,v 1.53 2014/05/06 04:26:24 cherry Exp $ */ /* * Copyright (c) 2006 Mathieu Ropert <m...@adviseo.fr> @@ -69,7 +69,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.52 2013/11/10 01:19:13 jnemeth Exp $"); +__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.53 2014/05/06 04:26:24 cherry Exp $"); #include "opt_xen.h" #include "opt_ddb.h" @@ -490,6 +490,35 @@ xen_vcpu_bcast_invlpg(vaddr_t sva, vaddr return; } +/* Copy a page */ +void +xen_copy_page(paddr_t srcpa, paddr_t dstpa) +{ + mmuext_op_t op; + + op.cmd = MMUEXT_COPY_PAGE; + op.arg1.mfn = xpmap_ptom(dstpa) >> PAGE_SHIFT; + op.arg2.src_mfn = xpmap_ptom(srcpa) >> PAGE_SHIFT; + + if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) { + panic(__func__); + } +} + +/* Zero a physical page */ +void +xen_pagezero(paddr_t pa) +{ + mmuext_op_t op; + + op.cmd = MMUEXT_CLEAR_PAGE; + op.arg1.mfn = xpmap_ptom(pa) >> PAGE_SHIFT; + + if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) { + panic(__func__); + } +} + int xpq_update_foreign(paddr_t ptr, pt_entry_t val, int dom) {