aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-12-17 17:58:43 -0500
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2011-07-18 18:43:28 -0400
commitbc7fe1d977734efe6059d6d537b439135ad4a34c (patch)
tree06a437e5cabe7355e0824935b0a8d24d801b6289 /arch
parentdcf7435cfe617c9d9f3dd501d3f5ed4d0b30c218 (diff)
xen/mmu: tune pgtable alloc/release
Make sure the fastpath code is inlined. Batch the page permission change and the pin/unpin, and make sure that it can be batched with any adjacent set_pte/pmd/etc operations. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/xen/mmu.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index eb9112687cee..f987bde77c49 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1497,22 +1497,52 @@ static void __init xen_release_pmd_init(unsigned long pfn)
1497 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 1497 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
1498} 1498}
1499 1499
1500static inline void __pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
1501{
1502 struct multicall_space mcs;
1503 struct mmuext_op *op;
1504
1505 mcs = __xen_mc_entry(sizeof(*op));
1506 op = mcs.args;
1507 op->cmd = cmd;
1508 op->arg1.mfn = pfn_to_mfn(pfn);
1509
1510 MULTI_mmuext_op(mcs.mc, mcs.args, 1, NULL, DOMID_SELF);
1511}
1512
1513static inline void __set_pfn_prot(unsigned long pfn, pgprot_t prot)
1514{
1515 struct multicall_space mcs;
1516 unsigned long addr = (unsigned long)__va(pfn << PAGE_SHIFT);
1517
1518 mcs = __xen_mc_entry(0);
1519 MULTI_update_va_mapping(mcs.mc, (unsigned long)addr,
1520 pfn_pte(pfn, prot), 0);
1521}
1522
1500/* This needs to make sure the new pte page is pinned iff its being 1523/* This needs to make sure the new pte page is pinned iff its being
1501 attached to a pinned pagetable. */ 1524 attached to a pinned pagetable. */
1502static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level) 1525static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,
1526 unsigned level)
1503{ 1527{
1504 struct page *page = pfn_to_page(pfn); 1528 bool pinned = PagePinned(virt_to_page(mm->pgd));
1505 int pinned = PagePinned(virt_to_page(mm->pgd)); 1529
1506
1507 trace_xen_mmu_alloc_ptpage(mm, pfn, level, pinned); 1530 trace_xen_mmu_alloc_ptpage(mm, pfn, level, pinned);
1508 1531
1509 if (pinned) { 1532 if (pinned) {
1533 struct page *page = pfn_to_page(pfn);
1534
1510 SetPagePinned(page); 1535 SetPagePinned(page);
1511 1536
1512 if (!PageHighMem(page)) { 1537 if (!PageHighMem(page)) {
1513 make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn))); 1538 xen_mc_batch();
1539
1540 __set_pfn_prot(pfn, PAGE_KERNEL_RO);
1541
1514 if (level == PT_PTE && USE_SPLIT_PTLOCKS) 1542 if (level == PT_PTE && USE_SPLIT_PTLOCKS)
1515 pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); 1543 __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
1544
1545 xen_mc_issue(PARAVIRT_LAZY_MMU);
1516 } else { 1546 } else {
1517 /* make sure there are no stray mappings of 1547 /* make sure there are no stray mappings of
1518 this page */ 1548 this page */
@@ -1532,7 +1562,7 @@ static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
1532} 1562}
1533 1563
1534/* This should never happen until we're OK to use struct page */ 1564/* This should never happen until we're OK to use struct page */
1535static void xen_release_ptpage(unsigned long pfn, unsigned level) 1565static inline void xen_release_ptpage(unsigned long pfn, unsigned level)
1536{ 1566{
1537 struct page *page = pfn_to_page(pfn); 1567 struct page *page = pfn_to_page(pfn);
1538 bool pinned = PagePinned(page); 1568 bool pinned = PagePinned(page);
@@ -1541,9 +1571,14 @@ static void xen_release_ptpage(unsigned long pfn, unsigned level)
1541 1571
1542 if (pinned) { 1572 if (pinned) {
1543 if (!PageHighMem(page)) { 1573 if (!PageHighMem(page)) {
1574 xen_mc_batch();
1575
1544 if (level == PT_PTE && USE_SPLIT_PTLOCKS) 1576 if (level == PT_PTE && USE_SPLIT_PTLOCKS)
1545 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); 1577 __pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
1546 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 1578
1579 __set_pfn_prot(pfn, PAGE_KERNEL);
1580
1581 xen_mc_issue(PARAVIRT_LAZY_MMU);
1547 } 1582 }
1548 ClearPagePinned(page); 1583 ClearPagePinned(page);
1549 } 1584 }