aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/paravirt.h
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2007-10-16 14:51:29 -0400
committerJeremy Fitzhardinge <jeremy@goop.org>2007-10-16 14:51:29 -0400
commit8965c1c0950d459d99b8b81dfc1ab02e3d2cfb08 (patch)
tree50ad53453562c7dc50afa866d52345bd6e820bef /include/asm-x86/paravirt.h
parent93b1eab3d29e7ea32ee583de3362da84db06ded8 (diff)
paravirt: clean up lazy mode handling
Currently, the set_lazy_mode pv_op is overloaded with 5 functions: 1. enter lazy cpu mode 2. leave lazy cpu mode 3. enter lazy mmu mode 4. leave lazy mmu mode 5. flush pending batched operations This complicates each paravirt backend, since it needs to deal with all the possible state transitions, handling flushing, etc. In particular, flushing is quite distinct from the other 4 functions, and seems to just cause complication. This patch removes the set_lazy_mode operation, and adds "enter" and "leave" lazy mode operations on mmu_ops and cpu_ops. All the logic associated with enter and leaving lazy states is now in common code (basically BUG_ONs to make sure that no mode is current when entering a lazy mode, and make sure that the mode is current when leaving). Also, flush is handled in a common way, by simply leaving and re-entering the lazy mode. The result is that the Xen, lguest and VMI lazy mode implementations are much simpler. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Cc: Andi Kleen <ak@suse.de> Cc: Zach Amsden <zach@vmware.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Avi Kivity <avi@qumranet.com> Cc: Anthony Liguory <aliguori@us.ibm.com> Cc: "Glauber de Oliveira Costa" <glommer@gmail.com> Cc: Jun Nakajima <jun.nakajima@intel.com>
Diffstat (limited to 'include/asm-x86/paravirt.h')
-rw-r--r--include/asm-x86/paravirt.h52
1 files changed, 33 insertions, 19 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 19726e12051e..f59d370c5df4 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -25,15 +25,6 @@ struct tss_struct;
25struct mm_struct; 25struct mm_struct;
26struct desc_struct; 26struct desc_struct;
27 27
28/* Lazy mode for batching updates / context switch */
29enum paravirt_lazy_mode {
30 PARAVIRT_LAZY_NONE = 0,
31 PARAVIRT_LAZY_MMU = 1,
32 PARAVIRT_LAZY_CPU = 2,
33 PARAVIRT_LAZY_FLUSH = 3,
34};
35
36
37/* general info */ 28/* general info */
38struct pv_info { 29struct pv_info {
39 unsigned int kernel_rpl; 30 unsigned int kernel_rpl;
@@ -64,9 +55,10 @@ struct pv_init_ops {
64}; 55};
65 56
66 57
67struct pv_misc_ops { 58struct pv_lazy_ops {
68 /* Set deferred update mode, used for batching operations. */ 59 /* Set deferred update mode, used for batching operations. */
69 void (*set_lazy_mode)(enum paravirt_lazy_mode mode); 60 void (*enter)(void);
61 void (*leave)(void);
70}; 62};
71 63
72struct pv_time_ops { 64struct pv_time_ops {
@@ -131,6 +123,8 @@ struct pv_cpu_ops {
131 /* These two are jmp to, not actually called. */ 123 /* These two are jmp to, not actually called. */
132 void (*irq_enable_sysexit)(void); 124 void (*irq_enable_sysexit)(void);
133 void (*iret)(void); 125 void (*iret)(void);
126
127 struct pv_lazy_ops lazy_mode;
134}; 128};
135 129
136struct pv_irq_ops { 130struct pv_irq_ops {
@@ -244,6 +238,8 @@ struct pv_mmu_ops {
244#ifdef CONFIG_HIGHPTE 238#ifdef CONFIG_HIGHPTE
245 void *(*kmap_atomic_pte)(struct page *page, enum km_type type); 239 void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
246#endif 240#endif
241
242 struct pv_lazy_ops lazy_mode;
247}; 243};
248 244
249/* This contains all the paravirt structures: we get a convenient 245/* This contains all the paravirt structures: we get a convenient
@@ -252,7 +248,6 @@ struct pv_mmu_ops {
252struct paravirt_patch_template 248struct paravirt_patch_template
253{ 249{
254 struct pv_init_ops pv_init_ops; 250 struct pv_init_ops pv_init_ops;
255 struct pv_misc_ops pv_misc_ops;
256 struct pv_time_ops pv_time_ops; 251 struct pv_time_ops pv_time_ops;
257 struct pv_cpu_ops pv_cpu_ops; 252 struct pv_cpu_ops pv_cpu_ops;
258 struct pv_irq_ops pv_irq_ops; 253 struct pv_irq_ops pv_irq_ops;
@@ -262,7 +257,6 @@ struct paravirt_patch_template
262 257
263extern struct pv_info pv_info; 258extern struct pv_info pv_info;
264extern struct pv_init_ops pv_init_ops; 259extern struct pv_init_ops pv_init_ops;
265extern struct pv_misc_ops pv_misc_ops;
266extern struct pv_time_ops pv_time_ops; 260extern struct pv_time_ops pv_time_ops;
267extern struct pv_cpu_ops pv_cpu_ops; 261extern struct pv_cpu_ops pv_cpu_ops;
268extern struct pv_irq_ops pv_irq_ops; 262extern struct pv_irq_ops pv_irq_ops;
@@ -953,37 +947,57 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
953} 947}
954#endif /* CONFIG_X86_PAE */ 948#endif /* CONFIG_X86_PAE */
955 949
950/* Lazy mode for batching updates / context switch */
951enum paravirt_lazy_mode {
952 PARAVIRT_LAZY_NONE,
953 PARAVIRT_LAZY_MMU,
954 PARAVIRT_LAZY_CPU,
955};
956
957enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
958void paravirt_enter_lazy_cpu(void);
959void paravirt_leave_lazy_cpu(void);
960void paravirt_enter_lazy_mmu(void);
961void paravirt_leave_lazy_mmu(void);
962void paravirt_leave_lazy(enum paravirt_lazy_mode mode);
963
956#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE 964#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE
957static inline void arch_enter_lazy_cpu_mode(void) 965static inline void arch_enter_lazy_cpu_mode(void)
958{ 966{
959 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_CPU); 967 PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);
960} 968}
961 969
962static inline void arch_leave_lazy_cpu_mode(void) 970static inline void arch_leave_lazy_cpu_mode(void)
963{ 971{
964 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_NONE); 972 PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
965} 973}
966 974
967static inline void arch_flush_lazy_cpu_mode(void) 975static inline void arch_flush_lazy_cpu_mode(void)
968{ 976{
969 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_FLUSH); 977 if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) {
978 arch_leave_lazy_cpu_mode();
979 arch_enter_lazy_cpu_mode();
980 }
970} 981}
971 982
972 983
973#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE 984#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
974static inline void arch_enter_lazy_mmu_mode(void) 985static inline void arch_enter_lazy_mmu_mode(void)
975{ 986{
976 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_MMU); 987 PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter);
977} 988}
978 989
979static inline void arch_leave_lazy_mmu_mode(void) 990static inline void arch_leave_lazy_mmu_mode(void)
980{ 991{
981 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_NONE); 992 PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
982} 993}
983 994
984static inline void arch_flush_lazy_mmu_mode(void) 995static inline void arch_flush_lazy_mmu_mode(void)
985{ 996{
986 PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_FLUSH); 997 if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) {
998 arch_leave_lazy_mmu_mode();
999 arch_enter_lazy_mmu_mode();
1000 }
987} 1001}
988 1002
989void _paravirt_nop(void); 1003void _paravirt_nop(void);