* [PATCH 1/3] lguest: speed up PARAVIRT_LAZY_FLUSH handling
@ 2007-05-31 7:23 Rusty Russell
2007-05-31 7:24 ` [PATCH 2/3] lguest: more lazy_hcalls Rusty Russell
0 siblings, 1 reply; 3+ messages in thread
From: Rusty Russell @ 2007-05-31 7:23 UTC (permalink / raw)
To: lkml - Kernel Mailing List; +Cc: Andrew Morton, virtualization
When Zach Amsden added PARAVIRT_LAZY_FLUSH I didn't realize how often
it would get called. We only need to do something if we're actually
in lazy mode.
Before:
Time for one context switch via pipe: 10509 (9863 - 18761)
Time for one Copy-on-Write fault: 71796 (20625 - 207750)
Time to exec client once: 1076218 (1066203 - 1085937)
Time for one fork/exit/wait: 1193125 (574750 - 1197750)
Time for two PTE updates: 10844 (10659 - 20703)
After:
Time for one context switch via pipe: 6745 (6521 - 13966)
Time for one Copy-on-Write fault: 44734 (11468 - 91988)
Time to exec client once: 815984 (801218 - 878218)
Time for one fork/exit/wait: 1023250 (397687 - 1030375)
Time for two PTE updates: 6699 (6475 - 9279)
(Native for comparison):
Time for one context switch via pipe: 4031 (3212 - 4146)
Time for one Copy-on-Write fault: 4402 (4388 - 4426)
Time to exec client once: 343859 (336859 - 349484)
Time for one fork/exit/wait: 120234 (118500 - 136140)
Time for two PTE updates: 2269 (2261 - 2272)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff -r 077496256739 drivers/lguest/lguest.c
--- a/drivers/lguest/lguest.c Thu May 31 16:34:17 2007 +1000
+++ b/drivers/lguest/lguest.c Thu May 31 16:36:23 2007 +1000
@@ -58,9 +58,10 @@ static enum paravirt_lazy_mode lazy_mode
static enum paravirt_lazy_mode lazy_mode;
static void lguest_lazy_mode(enum paravirt_lazy_mode mode)
{
- if (mode == PARAVIRT_LAZY_FLUSH)
- hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
- else {
+ if (mode == PARAVIRT_LAZY_FLUSH) {
+ if (unlikely(lazy_mode != PARAVIRT_LAZY_NONE))
+ hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
+ } else {
lazy_mode = mode;
if (mode == PARAVIRT_LAZY_NONE)
hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 2/3] lguest: more lazy_hcalls 2007-05-31 7:23 [PATCH 1/3] lguest: speed up PARAVIRT_LAZY_FLUSH handling Rusty Russell @ 2007-05-31 7:24 ` Rusty Russell 2007-05-31 7:25 ` [PATCH 3/3] lguest: faster tls switching Rusty Russell 0 siblings, 1 reply; 3+ messages in thread From: Rusty Russell @ 2007-05-31 7:24 UTC (permalink / raw) To: lkml - Kernel Mailing List; +Cc: Andrew Morton, virtualization Some hypercalls can be batched: lazy_hcall is the wrapper which determines this, so it's pretty harmless to use lazy_hcall() instead of hcall(). Before: Time for one context switch via pipe: 6745 (6521 - 13966) After: Time for one context switch via pipe: 5406 (5170 - 7467) Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> --- drivers/lguest/lguest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) =================================================================== --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -225,7 +225,7 @@ static unsigned long current_cr0, curren static unsigned long current_cr0, current_cr3; static void lguest_write_cr0(unsigned long val) { - hcall(LHCALL_TS, val & 8, 0, 0); + lazy_hcall(LHCALL_TS, val & 8, 0, 0); current_cr0 = val; } @@ -247,7 +247,7 @@ static unsigned long lguest_read_cr2(voi static void lguest_write_cr3(unsigned long cr3) { - hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0); + lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0); current_cr3 = cr3; } @@ -287,7 +287,7 @@ static void lguest_set_pte(pte_t *ptep, *ptep = pteval; /* Don't bother with hypercall before initial setup. */ if (current_cr3) - hcall(LHCALL_FLUSH_TLB, 1, 0, 0); + lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); } static void lguest_flush_tlb_single(unsigned long addr) ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 3/3] lguest: faster tls switching 2007-05-31 7:24 ` [PATCH 2/3] lguest: more lazy_hcalls Rusty Russell @ 2007-05-31 7:25 ` Rusty Russell 0 siblings, 0 replies; 3+ messages in thread From: Rusty Russell @ 2007-05-31 7:25 UTC (permalink / raw) To: lkml - Kernel Mailing List; +Cc: Andrew Morton, virtualization 1) When the Guest sets the new TLS entries, we don't need to re-verify the whole GDT. 2) We also don't need to copy all the GDT entries if only the TLS entries have changed. Before: Time for one context switch via pipe: 5406 (5170 - 7467) After: Time for one context switch via pipe: 4916 (4661 - 7004) Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> --- drivers/lguest/core.c | 5 ++++- drivers/lguest/lg.h | 2 ++ drivers/lguest/segments.c | 30 ++++++++++++++++++------------ 3 files changed, 24 insertions(+), 13 deletions(-) diff -r e5e8dfc0fda2 drivers/lguest/core.c --- a/drivers/lguest/core.c Thu May 31 17:04:16 2007 +1000 +++ b/drivers/lguest/core.c Thu May 31 17:12:24 2007 +1000 @@ -278,6 +278,9 @@ static void copy_in_guest_info(struct lg /* Copy all GDT entries but the TSS. */ if (lg->changed & CHANGED_GDT) copy_gdt(lg, pages->state.guest_gdt); + /* If only the TLS entries have changed, copy them. */ + else if (lg->changed & CHANGED_GDT_TLS) + copy_gdt_tls(lg, pages->state.guest_gdt); lg->changed = 0; } diff -r e5e8dfc0fda2 drivers/lguest/lg.h --- a/drivers/lguest/lg.h Thu May 31 17:04:16 2007 +1000 +++ b/drivers/lguest/lg.h Thu May 31 17:10:20 2007 +1000 @@ -115,6 +115,7 @@ struct lguest_pages #define CHANGED_IDT 1 #define CHANGED_GDT 2 +#define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ #define CHANGED_ALL 3 /* The private info the thread maintains about the guest. */ @@ -202,6 +203,7 @@ void load_guest_gdt(struct lguest *lg, u void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num); void guest_load_tls(struct lguest *lg, unsigned long tls_array); void copy_gdt(const struct lguest *lg, struct desc_struct *gdt); +void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt); /* page_tables.c: */ int init_guest_pagetable(struct lguest *lg, unsigned long pgtable); diff -r e5e8dfc0fda2 drivers/lguest/segments.c --- a/drivers/lguest/segments.c Thu May 31 17:04:16 2007 +1000 +++ b/drivers/lguest/segments.c Thu May 31 17:11:46 2007 +1000 @@ -34,11 +34,11 @@ static void check_segment_use(struct lgu kill_guest(lg, "Removed live GDT entry %u", desc); } -static void fixup_gdt_table(struct lguest *lg) +static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(lg->gdt); i++) { + for (i = start; i < end; i++) { /* We never copy these ones to real gdt */ if (ignored_gdt(i)) continue; @@ -86,6 +86,16 @@ void setup_guest_gdt(struct lguest *lg) lg->gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); } +/* This is a fast version for the common case where only the three TLS entries + * have changed. */ +void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt) +{ + unsigned int i; + + for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++) + gdt[i] = lg->gdt[i]; +} + void copy_gdt(const struct lguest *lg, struct desc_struct *gdt) { unsigned int i; @@ -101,7 +111,7 @@ void load_guest_gdt(struct lguest *lg, u kill_guest(lg, "too many gdt entries %i", num); lgread(lg, lg->gdt, table, num * sizeof(lg->gdt[0])); - fixup_gdt_table(lg); + fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->gdt)); lg->changed |= CHANGED_GDT; } @@ -110,6 +120,6 @@ void guest_load_tls(struct lguest *lg, u struct desc_struct *tls = &lg->gdt[GDT_ENTRY_TLS_MIN]; lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES); - fixup_gdt_table(lg); - lg->changed |= CHANGED_GDT; + fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); + lg->changed |= CHANGED_GDT_TLS; } ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-05-31 7:25 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-05-31 7:23 [PATCH 1/3] lguest: speed up PARAVIRT_LAZY_FLUSH handling Rusty Russell 2007-05-31 7:24 ` [PATCH 2/3] lguest: more lazy_hcalls Rusty Russell 2007-05-31 7:25 ` [PATCH 3/3] lguest: faster tls switching Rusty Russell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox