diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-04-24 03:26:50 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-05-08 18:55:24 -0400 |
commit | a789ed5fb6d0256c4177c2cc27e06520ddbe4d4c (patch) | |
tree | afdbb0c64c15ec522eae260949bfec02df2291b2 | |
parent | b80119bb35a49a4e8dbfb9708872adfd5cf38dee (diff) |
xen: cache cr0 value to avoid trap'n'emulate for read_cr0
stts() is implemented in terms of read_cr0/write_cr0 to update the
state of the TS bit. This happens during context switch, and so
is fairly performance critical. Rather than falling back to
a trap-and-emulate native read_cr0, implement our own by caching
the last-written value from write_cr0 (the TS bit is the only one
we really care about).
Impact: optimise Xen context switches
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
-rw-r--r-- | arch/x86/xen/enlighten.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e9df942aa14..0a1700a2be9 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -658,10 +658,26 @@ static void xen_clts(void) | |||
658 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 658 | xen_mc_issue(PARAVIRT_LAZY_CPU); |
659 | } | 659 | } |
660 | 660 | ||
661 | static DEFINE_PER_CPU(unsigned long, xen_cr0_value); | ||
662 | |||
663 | static unsigned long xen_read_cr0(void) | ||
664 | { | ||
665 | unsigned long cr0 = percpu_read(xen_cr0_value); | ||
666 | |||
667 | if (unlikely(cr0 == 0)) { | ||
668 | cr0 = native_read_cr0(); | ||
669 | percpu_write(xen_cr0_value, cr0); | ||
670 | } | ||
671 | |||
672 | return cr0; | ||
673 | } | ||
674 | |||
661 | static void xen_write_cr0(unsigned long cr0) | 675 | static void xen_write_cr0(unsigned long cr0) |
662 | { | 676 | { |
663 | struct multicall_space mcs; | 677 | struct multicall_space mcs; |
664 | 678 | ||
679 | percpu_write(xen_cr0_value, cr0); | ||
680 | |||
665 | /* Only pay attention to cr0.TS; everything else is | 681 | /* Only pay attention to cr0.TS; everything else is |
666 | ignored. */ | 682 | ignored. */ |
667 | mcs = xen_mc_entry(0); | 683 | mcs = xen_mc_entry(0); |
@@ -847,7 +863,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { | |||
847 | 863 | ||
848 | .clts = xen_clts, | 864 | .clts = xen_clts, |
849 | 865 | ||
850 | .read_cr0 = native_read_cr0, | 866 | .read_cr0 = xen_read_cr0, |
851 | .write_cr0 = xen_write_cr0, | 867 | .write_cr0 = xen_write_cr0, |
852 | 868 | ||
853 | .read_cr4 = native_read_cr4, | 869 | .read_cr4 = native_read_cr4, |