]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
sparc64: Fix cpu strand yielding.
authorDavid S. Miller <davem@davemloft.net>
Sun, 28 Oct 2012 01:05:20 +0000 (18:05 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 28 Oct 2012 01:35:27 +0000 (18:35 -0700)
For atomic backoff, we just loop over an exponentially backed off
counter.  This is extremely ineffective as it doesn't actually yield
the cpu strand so that other competing strands can use the cpu core.

In cpus previous to SPARC-T4 we have to do this in a slightly hackish
way, by doing an operation with no side effects that also happens to
mark the strand as unavailable.

The mechanism we choose for this is three reads of the %ccr
(condition-code) register into %g0 (the zero register).

SPARC-T4 has an explicit "pause" instruction, and we'll make use of
that in a subsequent commit.

Yield strands also in cpu_relax().  We really should have done this a
very long time ago.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/include/asm/backoff.h
arch/sparc/include/asm/processor_64.h

index db3af0d30fb10129124c594d1f1195bb59f2a6f2..64b077b3b13b31e2a36c65c714e29ae72c08acad 100644 (file)
 
 #define BACKOFF_SPIN(reg, tmp, label)  \
        mov     reg, tmp; \
-88:    brnz,pt tmp, 88b; \
+88:    rd      %ccr, %g0; \
+       rd      %ccr, %g0; \
+       rd      %ccr, %g0; \
+       brnz,pt tmp, 88b; \
         sub    tmp, 1, tmp; \
        set     BACKOFF_LIMIT, tmp; \
        cmp     reg, tmp; \
index 4e5a483122a043a7eeba9e42001d32cdf56c0015..986563409469bcabd532942808466c84c39e6ddd 100644 (file)
@@ -196,7 +196,10 @@ extern unsigned long get_wchan(struct task_struct *task);
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->u_regs[UREG_FP])
 
-#define cpu_relax()    barrier()
+#define cpu_relax()    asm volatile("rd        %%ccr, %%g0\n\t" \
+                                    "rd        %%ccr, %%g0\n\t" \
+                                    "rd        %%ccr, %%g0" \
+                                    ::: "memory")
 
 /* Prefetch support.  This is tuned for UltraSPARC-III and later.
  * UltraSPARC-I will treat these as nops, and UltraSPARC-II has