diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-16 22:28:43 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-16 22:28:43 -0500 |
commit | 2bf81c8af92dd53890557c5d87875842d573a3e9 (patch) | |
tree | 83e7e3539599b091ac69557658c06c0a39cfa60e /arch/sparc/include | |
parent | 9526d9bc23f362035cfabf044aa90f4ed1787955 (diff) | |
parent | 5f6c4ab6ee781c9aace7c8548ad9bd87f5678df7 (diff) |
Merge branch 'arch-microblaze' into no-rebases
Diffstat (limited to 'arch/sparc/include')
-rw-r--r-- | arch/sparc/include/asm/atomic_64.h | 4 | ||||
-rw-r--r-- | arch/sparc/include/asm/backoff.h | 69 | ||||
-rw-r--r-- | arch/sparc/include/asm/processor_64.h | 17 | ||||
-rw-r--r-- | arch/sparc/include/asm/prom.h | 5 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/unistd.h | 3 |
5 files changed, 85 insertions, 13 deletions
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index ce35a1cf1a20..be56a244c9cf 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* atomic.h: Thankfully the V9 is at least reasonable for this | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
2 | * stuff. | 2 | * stuff. |
3 | * | 3 | * |
4 | * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __ARCH_SPARC64_ATOMIC__ | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
@@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) | |||
106 | 106 | ||
107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
108 | 108 | ||
109 | extern long atomic64_dec_if_positive(atomic64_t *v); | ||
110 | |||
109 | /* Atomic operations are already serializing */ | 111 | /* Atomic operations are already serializing */ |
110 | #define smp_mb__before_atomic_dec() barrier() | 112 | #define smp_mb__before_atomic_dec() barrier() |
111 | #define smp_mb__after_atomic_dec() barrier() | 113 | #define smp_mb__after_atomic_dec() barrier() |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index db3af0d30fb1..4e02086b839c 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -1,6 +1,46 @@ | |||
1 | #ifndef _SPARC64_BACKOFF_H | 1 | #ifndef _SPARC64_BACKOFF_H |
2 | #define _SPARC64_BACKOFF_H | 2 | #define _SPARC64_BACKOFF_H |
3 | 3 | ||
4 | /* The macros in this file implement an exponential backoff facility | ||
5 | * for atomic operations. | ||
6 | * | ||
7 | * When multiple threads compete on an atomic operation, it is | ||
8 | * possible for one thread to be continually denied a successful | ||
9 | * completion of the compare-and-swap instruction. Heavily | ||
10 | * threaded cpu implementations like Niagara can compound this | ||
11 | * problem even further. | ||
12 | * | ||
13 | * When an atomic operation fails and needs to be retried, we spin a | ||
14 | * certain number of times. At each subsequent failure of the same | ||
15 | * operation we double the spin count, realizing an exponential | ||
16 | * backoff. | ||
17 | * | ||
18 | * When we spin, we try to use an operation that will cause the | ||
19 | * current cpu strand to block, and therefore make the core fully | ||
20 | * available to any other other runnable strands. There are two | ||
21 | * options, based upon cpu capabilities. | ||
22 | * | ||
23 | * On all cpus prior to SPARC-T4 we do three dummy reads of the | ||
24 | * condition code register. Each read blocks the strand for something | ||
25 | * between 40 and 50 cpu cycles. | ||
26 | * | ||
27 | * For SPARC-T4 and later we have a special "pause" instruction | ||
28 | * available. This is implemented using writes to register %asr27. | ||
29 | * The cpu will block the number of cycles written into the register, | ||
30 | * unless a disrupting trap happens first. SPARC-T4 specifically | ||
31 | * implements pause with a granularity of 8 cycles. Each strand has | ||
32 | * an internal pause counter which decrements every 8 cycles. So the | ||
33 | * chip shifts the %asr27 value down by 3 bits, and writes the result | ||
34 | * into the pause counter. If a value smaller than 8 is written, the | ||
35 | * chip blocks for 1 cycle. | ||
36 | * | ||
37 | * To achieve the same amount of backoff as the three %ccr reads give | ||
38 | * on earlier chips, we shift the backoff value up by 7 bits. (Three | ||
39 | * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | ||
40 | * whole amount we want to block into the pause register, rather than | ||
41 | * loop writing 128 each time. | ||
42 | */ | ||
43 | |||
4 | #define BACKOFF_LIMIT (4 * 1024) | 44 | #define BACKOFF_LIMIT (4 * 1024) |
5 | 45 | ||
6 | #ifdef CONFIG_SMP | 46 | #ifdef CONFIG_SMP |
@@ -11,16 +51,25 @@ | |||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
12 | spin_label | 52 | spin_label |
13 | 53 | ||
14 | #define BACKOFF_SPIN(reg, tmp, label) \ | 54 | #define BACKOFF_SPIN(reg, tmp, label) \ |
15 | mov reg, tmp; \ | 55 | mov reg, tmp; \ |
16 | 88: brnz,pt tmp, 88b; \ | 56 | 88: rd %ccr, %g0; \ |
17 | sub tmp, 1, tmp; \ | 57 | rd %ccr, %g0; \ |
18 | set BACKOFF_LIMIT, tmp; \ | 58 | rd %ccr, %g0; \ |
19 | cmp reg, tmp; \ | 59 | .section .pause_3insn_patch,"ax";\ |
20 | bg,pn %xcc, label; \ | 60 | .word 88b; \ |
21 | nop; \ | 61 | sllx tmp, 7, tmp; \ |
22 | ba,pt %xcc, label; \ | 62 | wr tmp, 0, %asr27; \ |
23 | sllx reg, 1, reg; | 63 | clr tmp; \ |
64 | .previous; \ | ||
65 | brnz,pt tmp, 88b; \ | ||
66 | sub tmp, 1, tmp; \ | ||
67 | set BACKOFF_LIMIT, tmp; \ | ||
68 | cmp reg, tmp; \ | ||
69 | bg,pn %xcc, label; \ | ||
70 | nop; \ | ||
71 | ba,pt %xcc, label; \ | ||
72 | sllx reg, 1, reg; | ||
24 | 73 | ||
25 | #else | 74 | #else |
26 | 75 | ||
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 0305d56d9b1a..cce72ce4c334 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h | |||
@@ -203,7 +203,22 @@ extern unsigned long get_wchan(struct task_struct *task); | |||
203 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) | 203 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
204 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) | 204 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
205 | 205 | ||
206 | #define cpu_relax() barrier() | 206 | /* Please see the commentary in asm/backoff.h for a description of |
207 | * what these instructions are doing and how they have been choosen. | ||
208 | * To make a long story short, we are trying to yield the current cpu | ||
209 | * strand during busy loops. | ||
210 | */ | ||
211 | #define cpu_relax() asm volatile("\n99:\n\t" \ | ||
212 | "rd %%ccr, %%g0\n\t" \ | ||
213 | "rd %%ccr, %%g0\n\t" \ | ||
214 | "rd %%ccr, %%g0\n\t" \ | ||
215 | ".section .pause_3insn_patch,\"ax\"\n\t"\ | ||
216 | ".word 99b\n\t" \ | ||
217 | "wr %%g0, 128, %%asr27\n\t" \ | ||
218 | "nop\n\t" \ | ||
219 | "nop\n\t" \ | ||
220 | ".previous" \ | ||
221 | ::: "memory") | ||
207 | 222 | ||
208 | /* Prefetch support. This is tuned for UltraSPARC-III and later. | 223 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
209 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has | 224 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c28765110706..f93003123bce 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
@@ -63,5 +63,10 @@ extern char *of_console_options; | |||
63 | extern void irq_trans_init(struct device_node *dp); | 63 | extern void irq_trans_init(struct device_node *dp); |
64 | extern char *build_path_component(struct device_node *dp); | 64 | extern char *build_path_component(struct device_node *dp); |
65 | 65 | ||
66 | /* SPARC has a local implementation */ | ||
67 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
68 | struct resource *r); | ||
69 | #define of_address_to_resource of_address_to_resource | ||
70 | |||
66 | #endif /* __KERNEL__ */ | 71 | #endif /* __KERNEL__ */ |
67 | #endif /* _SPARC_PROM_H */ | 72 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index bed86a820d09..cac719d1bc5c 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h | |||
@@ -406,8 +406,9 @@ | |||
406 | #define __NR_process_vm_readv 338 | 406 | #define __NR_process_vm_readv 338 |
407 | #define __NR_process_vm_writev 339 | 407 | #define __NR_process_vm_writev 339 |
408 | #define __NR_kern_features 340 | 408 | #define __NR_kern_features 340 |
409 | #define __NR_kcmp 341 | ||
409 | 410 | ||
410 | #define NR_syscalls 341 | 411 | #define NR_syscalls 342 |
411 | 412 | ||
412 | /* Bitmask values returned from kern_features system call. */ | 413 | /* Bitmask values returned from kern_features system call. */ |
413 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | 414 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 |