|
From: BitKeeper B. <ri...@su...> - 2004-08-27 16:01:26
|
ChangeSet 1.1274.1.1, 2004/08/27 14:29:44+01:00, cl...@fr...
Use hypercall batching where possible.
arch/xen/i386/kernel/ldt.c | 5 -
arch/xen/i386/kernel/traps.c | 1
arch/xen/i386/mm/hypervisor.c | 128 +++++++++++++++++++++++++++++-
arch/xen/i386/mm/init.c | 8 -
arch/xen/i386/mm/pgtable.c | 6 +
drivers/xen/blkfront/blkfront.c | 2
include/asm-xen/asm-i386/mmu_context.h | 4
include/asm-xen/asm-i386/pgalloc.h | 2
include/asm-xen/asm-i386/pgtable-2level.h | 6 -
include/asm-xen/asm-i386/pgtable.h | 21 ++--
include/asm-xen/asm-i386/processor.h | 6 -
include/asm-xen/asm-i386/tlbflush.h | 9 --
include/asm-xen/hypervisor.h | 11 ++
13 files changed, 172 insertions(+), 37 deletions(-)
diff -Nru a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/ldt.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/ldt.c 2004-08-27 12:01:22 -04:00
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/ldt.c 2004-08-27 12:01:22 -04:00
@@ -22,8 +22,10 @@
#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
static void flush_ldt(void *null)
{
- if (current->active_mm)
+ if (current->active_mm) {
load_LDT(¤t->active_mm->context);
+ flush_page_update_queue();
+ }
}
#endif
@@ -90,6 +92,7 @@
memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
make_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
PAGE_SIZE);
+ flush_page_update_queue();
return 0;
}
diff -Nru a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/traps.c 2004-08-27 12:01:22 -04:00
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/traps.c 2004-08-27 12:01:22 -04:00
@@ -967,6 +967,7 @@
set_call_gate(&default_ldt[0],lcall7);
set_call_gate(&default_ldt[4],lcall27);
__make_page_readonly(&default_ldt[0]);
+ xen_flush_page_update_queue();
/*
* Should be a barrier for any external CPU state.
diff -Nru a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/hypervisor.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/hypervisor.c 2004-08-27 12:01:22 -04:00
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/hypervisor.c 2004-08-27 12:01:22 -04:00
@@ -28,7 +28,7 @@
#define QUEUE_SIZE 2048
#define pte_offset_kernel pte_offset
#else
-#define QUEUE_SIZE 1
+#define QUEUE_SIZE 128
#endif
static mmu_update_t update_queue[QUEUE_SIZE];
@@ -152,6 +152,12 @@
if ( unlikely(idx == QUEUE_SIZE) ) __flush_page_update_queue();
}
+static inline void increment_index_and_flush(void)
+{
+ idx++;
+ __flush_page_update_queue();
+}
+
void queue_l1_entry_update(pte_t *ptr, unsigned long val)
{
unsigned long flags;
@@ -268,6 +274,126 @@
update_queue[idx].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
update_queue[idx].val = pfn;
increment_index();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+/* queue and flush versions of the above */
+void xen_l1_entry_update(pte_t *ptr, unsigned long val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+#if MMU_UPDATE_DEBUG > 3
+ DEBUG_disallow_pt_read((unsigned long)ptr);
+#endif
+ update_queue[idx].ptr = virt_to_machine(ptr);
+ update_queue[idx].val = val;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_l2_entry_update(pmd_t *ptr, unsigned long val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = virt_to_machine(ptr);
+ update_queue[idx].val = val;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_pt_switch(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = phys_to_machine(ptr);
+ update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_NEW_BASEPTR;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_tlb_flush(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_TLB_FLUSH;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_invlpg(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = MMU_EXTENDED_COMMAND;
+ update_queue[idx].ptr |= ptr & PAGE_MASK;
+ update_queue[idx].val = MMUEXT_INVLPG;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_pgd_pin(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = phys_to_machine(ptr);
+ update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_PIN_L2_TABLE;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_pgd_unpin(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = phys_to_machine(ptr);
+ update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_UNPIN_TABLE;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_pte_pin(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = phys_to_machine(ptr);
+ update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_PIN_L1_TABLE;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_pte_unpin(unsigned long ptr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = phys_to_machine(ptr);
+ update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
+ update_queue[idx].val = MMUEXT_UNPIN_TABLE;
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_set_ldt(unsigned long ptr, unsigned long len)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = MMU_EXTENDED_COMMAND | ptr;
+ update_queue[idx].val = MMUEXT_SET_LDT | (len << MMUEXT_CMD_SHIFT);
+ increment_index_and_flush();
+ spin_unlock_irqrestore(&update_lock, flags);
+}
+
+void xen_machphys_update(unsigned long mfn, unsigned long pfn)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&update_lock, flags);
+ update_queue[idx].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
+ update_queue[idx].val = pfn;
+ increment_index_and_flush();
spin_unlock_irqrestore(&update_lock, flags);
}
diff -Nru a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/init.c 2004-08-27 12:01:22 -04:00
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/init.c 2004-08-27 12:01:22 -04:00
@@ -125,6 +125,7 @@
}
}
+/* NOTE: caller must call flush_page_update_queue() */
void __init wrprotect_bootpt(pgd_t *pgd, void *page, int set)
{
pmd_t *pmd;
@@ -141,6 +142,7 @@
pte_val_ma(*pte) | _PAGE_RW);
}
+/* NOTE: caller must call flush_page_update_queue() */
static void __init protect_bootpt_entries(pgd_t *spgd, pgd_t *dpgd, int set,
int pmdupdate, int pmdset)
{
@@ -163,7 +165,6 @@
}
}
}
- flush_page_update_queue();
}
static inline int is_kernel_text(unsigned long addr)
@@ -575,14 +576,13 @@
protect_bootpt_entries((pgd_t *)start_info.pt_base, swapper_pg_dir,
1, 1, 1);
queue_pgd_pin(__pa(swapper_pg_dir));
- flush_page_update_queue();
load_cr3(swapper_pg_dir);
- __flush_tlb_all();
+ __flush_tlb_all(); /* implicit flush */
queue_pgd_unpin(__pa(start_info.pt_base));
- flush_page_update_queue();
protect_bootpt_entries((pgd_t *)start_info.pt_base, swapper_pg_dir,
0, 1, 0);
wrprotect_bootpt((pgd_t *)start_info.pt_base, swapper_pg_dir, 0);
+ flush_page_update_queue();
#ifdef CONFIG_X86_PAE
/*
diff -Nru a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c 2004-08-27 12:01:22 -04:00
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c 2004-08-27 12:01:22 -04:00
@@ -180,6 +180,7 @@
if (pte) {
clear_page(pte);
__make_page_readonly(pte);
+ xen_flush_page_update_queue();
}
return pte;
}
@@ -204,7 +205,10 @@
#ifdef CONFIG_HIGHPTE
if (pte < highmem_start_page)
#endif
- __make_page_readonly(phys_to_virt(page_to_pseudophys(pte)));
+ {
+ __make_page_readonly(phys_to_virt(page_to_pseudophys(pte)));
+ flush_page_update_queue();
+ }
|