Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Anthony Liguori
2007-05-30T15:32:23Z

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

Andi Kleen wrote:
> On Wednesday 30 May 2007 16:53:41 Anthony Liguori wrote:
>
>> Subject: [PATCH][PARAVIRT] Eliminate unnecessary CR3 read in TLB flush
>>
>> This patch eliminates the CR3 read (which would cause a VM exit) in the TLB
>> flush path. The patch is based on Ingo Molnar's paravirt series.
>>
>>
>
> This change could be just done generically for the native architecture, couldn't
> it?
>

Sure. It adds a few more cycles onto native though (two memory reads,
and some math). How does the following look?

Regards,

Anthony Liguori

> -Andi
>

[-- Attachment #2: no-read-cr3-on-tlbflush.diff --]
[-- Type: text/x-patch, Size: 2122 bytes --]

Subject: [PATCH] Avoid reading CR3 on TLB flush
From: Anthony Liguori <aliguori@us.ibm.com>

In a virtualized environment, there is significant overhead in reading and
writing control registers. Since we already have the value of CR3 in
current->active_mm->pgd, we can avoid taking the exit on CR3 read when
doing a TLB flush.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Index: kvm/include/asm-i386/tlbflush.h
===================================================================
--- kvm.orig/include/asm-i386/tlbflush.h 2007-05-30 10:22:48.000000000 -0500
+++ kvm/include/asm-i386/tlbflush.h 2007-05-30 10:22:54.000000000 -0500
@@ -14,13 +14,12 @@

#define __native_flush_tlb() \
do { \
- unsigned int tmpreg; \
+ unsigned int cr3 = __pa(current->active_mm->pgd); \
\
__asm__ __volatile__( \
- "movl %%cr3, %0; \n" \
"movl %0, %%cr3; # flush TLB \n" \
- : "=r" (tmpreg) \
- :: "memory"); \
+ :: "r" (cr3) \
+ : "memory"); \
} while (0)

/*
@@ -29,18 +28,18 @@
*/
#define __native_flush_tlb_global() \
do { \
- unsigned int tmpreg, cr4, cr4_orig; \
+ unsigned int cr3 = __pa(current->active_mm->pgd); \
+ unsigned int cr4, cr4_orig; \
\
__asm__ __volatile__( \
- "movl %%cr4, %2; # turn off PGE \n" \
- "movl %2, %1; \n" \
- "andl %3, %1; \n" \
- "movl %1, %%cr4; \n" \
- "movl %%cr3, %0; \n" \
- "movl %0, %%cr3; # flush TLB \n" \
- "movl %2, %%cr4; # turn PGE back on \n" \
- : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \
- : "i" (~X86_CR4_PGE) \
+ "movl %%cr4, %1; # turn off PGE \n" \
+ "movl %1, %0; \n" \
+ "andl %2, %0; \n" \
+ "movl %0, %%cr4; \n" \
+ "movl %3, %%cr3; # flush TLB \n" \
+ "movl %1, %%cr4; # turn PGE back on \n" \
+ : "=&r" (cr4), "=&r" (cr4_orig) \
+ : "i" (~X86_CR4_PGE), "r" (cr3) \
: "memory"); \
} while (0)

[-- Attachment #3: Type: text/plain, Size: 184 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org