mips: Replace __get_cpu_var uses
authorChristoph Lameter <cl@linux.com>
Sun, 17 Aug 2014 17:30:44 +0000 (12:30 -0500)
committerTejun Heo <tj@kernel.org>
Tue, 26 Aug 2014 17:45:51 +0000 (13:45 -0400)
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x).  This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.

Other use cases are for storing and retrieving data from the current
processors percpu area.  __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.

__get_cpu_var() is defined as :

#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))

__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.

this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.

This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset.  Thereby address calculations are avoided and less registers
are used when code is generated.

At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.

The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e.  using a global
register that may be set to the per cpu base.

Transformations done to __get_cpu_var()

1. Determine the address of the percpu instance of the current processor.

DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);

    Converts to

int *x = this_cpu_ptr(&y);

2. Same as #1 but this time an array structure is involved.

DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);

    Converts to

int *x = this_cpu_ptr(y);

3. Retrieve the content of the current processors instance of a per cpu
variable.

DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)

   Converts to

int x = __this_cpu_read(y);

4. Retrieve the content of a percpu struct

DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);

   Converts to

memcpy(&x, this_cpu_ptr(&y), sizeof(x));

5. Assignment to a per cpu variable

DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;

   Converts to

__this_cpu_write(y, x);

6. Increment/Decrement etc of a per cpu variable

DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++

   Converts to

__this_cpu_inc(y)

Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
arch/mips/cavium-octeon/octeon-irq.c
arch/mips/kernel/kprobes.c
arch/mips/kernel/perf_event_mipsxx.c
arch/mips/kernel/smp-bmips.c
arch/mips/loongson/loongson-3/smp.c

index 1b82ac6921e031644687979d69b4287064751891..7417340496756d30d159aae9b48e4af0f8edf531 100644 (file)
@@ -264,13 +264,13 @@ static void octeon_irq_ciu_enable_local(struct irq_data *data)
        unsigned long *pen;
        unsigned long flags;
        union octeon_ciu_chip_data cd;
-       raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
+       raw_spinlock_t *lock = this_cpu_ptr(&octeon_irq_ciu_spinlock);
 
        cd.p = irq_data_get_irq_chip_data(data);
 
        raw_spin_lock_irqsave(lock, flags);
        if (cd.s.line == 0) {
-               pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+               pen = this_cpu_ptr(&octeon_irq_ciu0_en_mirror);
                __set_bit(cd.s.bit, pen);
                /*
                 * Must be visible to octeon_irq_ip{2,3}_ciu() before
@@ -279,7 +279,7 @@ static void octeon_irq_ciu_enable_local(struct irq_data *data)
                wmb();
                cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
        } else {
-               pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+               pen = this_cpu_ptr(&octeon_irq_ciu1_en_mirror);
                __set_bit(cd.s.bit, pen);
                /*
                 * Must be visible to octeon_irq_ip{2,3}_ciu() before
@@ -296,13 +296,13 @@ static void octeon_irq_ciu_disable_local(struct irq_data *data)
        unsigned long *pen;
        unsigned long flags;
        union octeon_ciu_chip_data cd;
-       raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
+       raw_spinlock_t *lock = this_cpu_ptr(&octeon_irq_ciu_spinlock);
 
        cd.p = irq_data_get_irq_chip_data(data);
 
        raw_spin_lock_irqsave(lock, flags);
        if (cd.s.line == 0) {
-               pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+               pen = this_cpu_ptr(&octeon_irq_ciu0_en_mirror);
                __clear_bit(cd.s.bit, pen);
                /*
                 * Must be visible to octeon_irq_ip{2,3}_ciu() before
@@ -311,7 +311,7 @@ static void octeon_irq_ciu_disable_local(struct irq_data *data)
                wmb();
                cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
        } else {
-               pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+               pen = this_cpu_ptr(&octeon_irq_ciu1_en_mirror);
                __clear_bit(cd.s.bit, pen);
                /*
                 * Must be visible to octeon_irq_ip{2,3}_ciu() before
@@ -431,11 +431,11 @@ static void octeon_irq_ciu_enable_local_v2(struct irq_data *data)
 
        if (cd.s.line == 0) {
                int index = cvmx_get_core_num() * 2;
-               set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+               set_bit(cd.s.bit, this_cpu_ptr(&octeon_irq_ciu0_en_mirror));
                cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
        } else {
                int index = cvmx_get_core_num() * 2 + 1;
-               set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+               set_bit(cd.s.bit, this_cpu_ptr(&octeon_irq_ciu1_en_mirror));
                cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
        }
 }
@@ -450,11 +450,11 @@ static void octeon_irq_ciu_disable_local_v2(struct irq_data *data)
 
        if (cd.s.line == 0) {
                int index = cvmx_get_core_num() * 2;
-               clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+               clear_bit(cd.s.bit, this_cpu_ptr(&octeon_irq_ciu0_en_mirror));
                cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
        } else {
                int index = cvmx_get_core_num() * 2 + 1;
-               clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+               clear_bit(cd.s.bit, this_cpu_ptr(&octeon_irq_ciu1_en_mirror));
                cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
        }
 }
@@ -1063,7 +1063,7 @@ static void octeon_irq_ip2_ciu(void)
        const unsigned long core_id = cvmx_get_core_num();
        u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
 
-       ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
+       ciu_sum &= __this_cpu_read(octeon_irq_ciu0_en_mirror);
        if (likely(ciu_sum)) {
                int bit = fls64(ciu_sum) - 1;
                int irq = octeon_irq_ciu_to_irq[0][bit];
@@ -1080,7 +1080,7 @@ static void octeon_irq_ip3_ciu(void)
 {
        u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
 
-       ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
+       ciu_sum &= __this_cpu_read(octeon_irq_ciu1_en_mirror);
        if (likely(ciu_sum)) {
                int bit = fls64(ciu_sum) - 1;
                int irq = octeon_irq_ciu_to_irq[1][bit];
@@ -1129,10 +1129,10 @@ static void octeon_irq_init_ciu_percpu(void)
        int coreid = cvmx_get_core_num();
 
 
-       __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
-       __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
+       __this_cpu_write(octeon_irq_ciu0_en_mirror, 0);
+       __this_cpu_write(octeon_irq_ciu1_en_mirror, 0);
        wmb();
-       raw_spin_lock_init(&__get_cpu_var(octeon_irq_ciu_spinlock));
+       raw_spin_lock_init(this_cpu_ptr(&octeon_irq_ciu_spinlock));
        /*
         * Disable All CIU Interrupts. The ones we need will be
         * enabled later.  Read the SUM register so we know the write
index 1f8187ab0997be478f69b66eadb8ac4a6bf7e489..212f46f2014e06b36aed708b26215457be72ece7 100644 (file)
@@ -224,7 +224,7 @@ static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 
 static void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
        kcb->kprobe_status = kcb->prev_kprobe.status;
        kcb->kprobe_old_SR = kcb->prev_kprobe.old_SR;
        kcb->kprobe_saved_SR = kcb->prev_kprobe.saved_SR;
@@ -234,7 +234,7 @@ static void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 static void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                               struct kprobe_ctlblk *kcb)
 {
-       __get_cpu_var(current_kprobe) = p;
+       __this_cpu_write(current_kprobe, p);
        kcb->kprobe_saved_SR = kcb->kprobe_old_SR = (regs->cp0_status & ST0_IE);
        kcb->kprobe_saved_epc = regs->cp0_epc;
 }
@@ -385,7 +385,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                                ret = 1;
                                goto no_kprobe;
                        }
-                       p = __get_cpu_var(current_kprobe);
+                       p = __this_cpu_read(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs))
                                goto ss_probe;
                }
index 14bf74b0f51c066f488caba872ebdaddd8caefe8..abb209fa28c67c27c45a2d0499420c8f8cd91902 100644 (file)
@@ -340,7 +340,7 @@ static int mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
 
 static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 
        WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
 
@@ -360,7 +360,7 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
 
 static void mipsxx_pmu_disable_event(int idx)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        unsigned long flags;
 
        WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
@@ -460,7 +460,7 @@ static void mipspmu_stop(struct perf_event *event, int flags)
 
 static int mipspmu_add(struct perf_event *event, int flags)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        struct hw_perf_event *hwc = &event->hw;
        int idx;
        int err = 0;
@@ -496,7 +496,7 @@ out:
 
 static void mipspmu_del(struct perf_event *event, int flags)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        struct hw_perf_event *hwc = &event->hw;
        int idx = hwc->idx;
 
@@ -1275,7 +1275,7 @@ static int __hw_perf_event_init(struct perf_event *event)
 
 static void pause_local_counters(void)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        int ctr = mipspmu.num_counters;
        unsigned long flags;
 
@@ -1291,7 +1291,7 @@ static void pause_local_counters(void)
 
 static void resume_local_counters(void)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        int ctr = mipspmu.num_counters;
 
        do {
@@ -1302,7 +1302,7 @@ static void resume_local_counters(void)
 
 static int mipsxx_pmu_handle_shared_irq(void)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        struct perf_sample_data data;
        unsigned int counters = mipspmu.num_counters;
        u64 counter;
index df9e2bd9b2c292e0497cdd0daba5217589575c2c..06bb5ed6d80a68728b56329db41a6531d377eca8 100644 (file)
@@ -346,7 +346,7 @@ static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
        int action, cpu = irq - IPI0_IRQ;
 
        spin_lock_irqsave(&ipi_lock, flags);
-       action = __get_cpu_var(ipi_action_mask);
+       action = __this_cpu_read(ipi_action_mask);
        per_cpu(ipi_action_mask, cpu) = 0;
        clear_c0_cause(cpu ? C_SW1 : C_SW0);
        spin_unlock_irqrestore(&ipi_lock, flags);
index 74e827b4ec8f11aa208844d738d2b74afa1a1e7c..d8c63af6c7ccea9c69a4985ae14d2f0c263e7281 100644 (file)
@@ -299,16 +299,16 @@ static void loongson3_init_secondary(void)
        per_cpu(cpu_state, cpu) = CPU_ONLINE;
 
        i = 0;
-       __get_cpu_var(core0_c0count) = 0;
+       __this_cpu_write(core0_c0count, 0);
        loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
-       while (!__get_cpu_var(core0_c0count)) {
+       while (!__this_cpu_read(core0_c0count)) {
                i++;
                cpu_relax();
        }
 
        if (i > MAX_LOOPS)
                i = MAX_LOOPS;
-       initcount = __get_cpu_var(core0_c0count) + i;
+       initcount = __this_cpu_read(core0_c0count) + i;
        write_c0_count(initcount);
 }