diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-15 08:15:53 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-16 08:20:31 -0500 |
commit | 6dbde3530850d4d8bfc1b6bd4006d92786a2787f (patch) | |
tree | 08c6dd55e860827311b889e2ecfe3de9f51421a0 /arch/x86/xen | |
parent | 004aa322f855a765741d9437a98dd8fe2e4f32a6 (diff) |
percpu: add optimized generic percpu accessors
It is an optimization and a cleanup, and adds the following new
generic percpu methods:
percpu_read()
percpu_write()
percpu_add()
percpu_sub()
percpu_and()
percpu_or()
percpu_xor()
and implements support for them on x86. (other architectures will fall
back to a default implementation)
The advantage is that for example to read a local percpu variable,
instead of this sequence:
return __get_cpu_var(var);
ffffffff8102ca2b: 48 8b 14 fd 80 09 74 mov -0x7e8bf680(,%rdi,8),%rdx
ffffffff8102ca32: 81
ffffffff8102ca33: 48 c7 c0 d8 59 00 00 mov $0x59d8,%rax
ffffffff8102ca3a: 48 8b 04 10 mov (%rax,%rdx,1),%rax
We can get a single instruction by using the optimized variants:
return percpu_read(var);
ffffffff8102ca3f: 65 48 8b 05 91 8f fd mov %gs:0x7efd8f91(%rip),%rax
I also cleaned up the x86-specific APIs and made the x86 code use
these new generic percpu primitives.
tj: * fixed generic percpu_sub() definition as Roel Kluin pointed out
* added percpu_and() for completeness's sake
* made generic percpu ops atomic against preemption
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r-- | arch/x86/xen/enlighten.c | 14 | ||||
-rw-r--r-- | arch/x86/xen/irq.c | 8 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/multicalls.h | 2 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 2 |
5 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 312414ef9365..75b94139e1f2 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -695,17 +695,17 @@ static void xen_write_cr0(unsigned long cr0) | |||
695 | 695 | ||
696 | static void xen_write_cr2(unsigned long cr2) | 696 | static void xen_write_cr2(unsigned long cr2) |
697 | { | 697 | { |
698 | x86_read_percpu(xen_vcpu)->arch.cr2 = cr2; | 698 | percpu_read(xen_vcpu)->arch.cr2 = cr2; |
699 | } | 699 | } |
700 | 700 | ||
701 | static unsigned long xen_read_cr2(void) | 701 | static unsigned long xen_read_cr2(void) |
702 | { | 702 | { |
703 | return x86_read_percpu(xen_vcpu)->arch.cr2; | 703 | return percpu_read(xen_vcpu)->arch.cr2; |
704 | } | 704 | } |
705 | 705 | ||
706 | static unsigned long xen_read_cr2_direct(void) | 706 | static unsigned long xen_read_cr2_direct(void) |
707 | { | 707 | { |
708 | return x86_read_percpu(xen_vcpu_info.arch.cr2); | 708 | return percpu_read(xen_vcpu_info.arch.cr2); |
709 | } | 709 | } |
710 | 710 | ||
711 | static void xen_write_cr4(unsigned long cr4) | 711 | static void xen_write_cr4(unsigned long cr4) |
@@ -718,12 +718,12 @@ static void xen_write_cr4(unsigned long cr4) | |||
718 | 718 | ||
719 | static unsigned long xen_read_cr3(void) | 719 | static unsigned long xen_read_cr3(void) |
720 | { | 720 | { |
721 | return x86_read_percpu(xen_cr3); | 721 | return percpu_read(xen_cr3); |
722 | } | 722 | } |
723 | 723 | ||
724 | static void set_current_cr3(void *v) | 724 | static void set_current_cr3(void *v) |
725 | { | 725 | { |
726 | x86_write_percpu(xen_current_cr3, (unsigned long)v); | 726 | percpu_write(xen_current_cr3, (unsigned long)v); |
727 | } | 727 | } |
728 | 728 | ||
729 | static void __xen_write_cr3(bool kernel, unsigned long cr3) | 729 | static void __xen_write_cr3(bool kernel, unsigned long cr3) |
@@ -748,7 +748,7 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3) | |||
748 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | 748 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); |
749 | 749 | ||
750 | if (kernel) { | 750 | if (kernel) { |
751 | x86_write_percpu(xen_cr3, cr3); | 751 | percpu_write(xen_cr3, cr3); |
752 | 752 | ||
753 | /* Update xen_current_cr3 once the batch has actually | 753 | /* Update xen_current_cr3 once the batch has actually |
754 | been submitted. */ | 754 | been submitted. */ |
@@ -764,7 +764,7 @@ static void xen_write_cr3(unsigned long cr3) | |||
764 | 764 | ||
765 | /* Update while interrupts are disabled, so its atomic with | 765 | /* Update while interrupts are disabled, so its atomic with |
766 | respect to ipis */ | 766 | respect to ipis */ |
767 | x86_write_percpu(xen_cr3, cr3); | 767 | percpu_write(xen_cr3, cr3); |
768 | 768 | ||
769 | __xen_write_cr3(true, cr3); | 769 | __xen_write_cr3(true, cr3); |
770 | 770 | ||
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index bb042608c602..2e8271431e1a 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -39,7 +39,7 @@ static unsigned long xen_save_fl(void) | |||
39 | struct vcpu_info *vcpu; | 39 | struct vcpu_info *vcpu; |
40 | unsigned long flags; | 40 | unsigned long flags; |
41 | 41 | ||
42 | vcpu = x86_read_percpu(xen_vcpu); | 42 | vcpu = percpu_read(xen_vcpu); |
43 | 43 | ||
44 | /* flag has opposite sense of mask */ | 44 | /* flag has opposite sense of mask */ |
45 | flags = !vcpu->evtchn_upcall_mask; | 45 | flags = !vcpu->evtchn_upcall_mask; |
@@ -62,7 +62,7 @@ static void xen_restore_fl(unsigned long flags) | |||
62 | make sure we're don't switch CPUs between getting the vcpu | 62 | make sure we're don't switch CPUs between getting the vcpu |
63 | pointer and updating the mask. */ | 63 | pointer and updating the mask. */ |
64 | preempt_disable(); | 64 | preempt_disable(); |
65 | vcpu = x86_read_percpu(xen_vcpu); | 65 | vcpu = percpu_read(xen_vcpu); |
66 | vcpu->evtchn_upcall_mask = flags; | 66 | vcpu->evtchn_upcall_mask = flags; |
67 | preempt_enable_no_resched(); | 67 | preempt_enable_no_resched(); |
68 | 68 | ||
@@ -83,7 +83,7 @@ static void xen_irq_disable(void) | |||
83 | make sure we're don't switch CPUs between getting the vcpu | 83 | make sure we're don't switch CPUs between getting the vcpu |
84 | pointer and updating the mask. */ | 84 | pointer and updating the mask. */ |
85 | preempt_disable(); | 85 | preempt_disable(); |
86 | x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1; | 86 | percpu_read(xen_vcpu)->evtchn_upcall_mask = 1; |
87 | preempt_enable_no_resched(); | 87 | preempt_enable_no_resched(); |
88 | } | 88 | } |
89 | 89 | ||
@@ -96,7 +96,7 @@ static void xen_irq_enable(void) | |||
96 | the caller is confused and is trying to re-enable interrupts | 96 | the caller is confused and is trying to re-enable interrupts |
97 | on an indeterminate processor. */ | 97 | on an indeterminate processor. */ |
98 | 98 | ||
99 | vcpu = x86_read_percpu(xen_vcpu); | 99 | vcpu = percpu_read(xen_vcpu); |
100 | vcpu->evtchn_upcall_mask = 0; | 100 | vcpu->evtchn_upcall_mask = 0; |
101 | 101 | ||
102 | /* Doesn't matter if we get preempted here, because any | 102 | /* Doesn't matter if we get preempted here, because any |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 503c240e26c7..7bc7852cc5c4 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1074,7 +1074,7 @@ static void drop_other_mm_ref(void *info) | |||
1074 | 1074 | ||
1075 | /* If this cpu still has a stale cr3 reference, then make sure | 1075 | /* If this cpu still has a stale cr3 reference, then make sure |
1076 | it has been flushed. */ | 1076 | it has been flushed. */ |
1077 | if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) { | 1077 | if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) { |
1078 | load_cr3(swapper_pg_dir); | 1078 | load_cr3(swapper_pg_dir); |
1079 | arch_flush_lazy_cpu_mode(); | 1079 | arch_flush_lazy_cpu_mode(); |
1080 | } | 1080 | } |
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h index 858938241616..e786fa7f2615 100644 --- a/arch/x86/xen/multicalls.h +++ b/arch/x86/xen/multicalls.h | |||
@@ -39,7 +39,7 @@ static inline void xen_mc_issue(unsigned mode) | |||
39 | xen_mc_flush(); | 39 | xen_mc_flush(); |
40 | 40 | ||
41 | /* restore flags saved in xen_mc_batch */ | 41 | /* restore flags saved in xen_mc_batch */ |
42 | local_irq_restore(x86_read_percpu(xen_mc_irq_flags)); | 42 | local_irq_restore(percpu_read(xen_mc_irq_flags)); |
43 | } | 43 | } |
44 | 44 | ||
45 | /* Set up a callback to be called when the current batch is flushed */ | 45 | /* Set up a callback to be called when the current batch is flushed */ |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 83fa4236477d..3bfd6dd0b47c 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -78,7 +78,7 @@ static __cpuinit void cpu_bringup(void) | |||
78 | xen_setup_cpu_clockevents(); | 78 | xen_setup_cpu_clockevents(); |
79 | 79 | ||
80 | cpu_set(cpu, cpu_online_map); | 80 | cpu_set(cpu, cpu_online_map); |
81 | x86_write_percpu(cpu_state, CPU_ONLINE); | 81 | percpu_write(cpu_state, CPU_ONLINE); |
82 | wmb(); | 82 | wmb(); |
83 | 83 | ||
84 | /* We can take interrupts now: we're officially "up". */ | 84 | /* We can take interrupts now: we're officially "up". */ |