Skip to content

Commit 4f97c9b

Browse files
committed
Merge branch 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
Pull Tile bugfixes from Chris Metcalf: "This fixes some serious issues with PREEMPT support, and a couple of smaller corner-case issues fixed in the last couple of weeks" * 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: arch: tile: re-use kbasename() helper tile: use a more conservative __my_cpu_offset in CONFIG_PREEMPT tile: ensure interrupts disabled for preempt_schedule_irq() tile: change lock initalization in hardwall tile: include: asm: use 'long long' instead of 'u64' for atomic64_t and its related functions
2 parents 162bdaf + 0cc96a7 commit 4f97c9b

File tree

9 files changed

+84
-42
lines changed

9 files changed

+84
-42
lines changed

arch/tile/include/asm/atomic.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
166166
*
167167
* Atomically sets @v to @i and returns old @v
168168
*/
169-
static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
169+
static inline long long atomic64_xchg(atomic64_t *v, long long n)
170170
{
171171
return xchg64(&v->counter, n);
172172
}
@@ -180,7 +180,8 @@ static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
180180
* Atomically checks if @v holds @o and replaces it with @n if so.
181181
* Returns the old value at @v.
182182
*/
183-
static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
183+
static inline long long atomic64_cmpxchg(atomic64_t *v, long long o,
184+
long long n)
184185
{
185186
return cmpxchg64(&v->counter, o, n);
186187
}

arch/tile/include/asm/atomic_32.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static inline void atomic_set(atomic_t *v, int n)
8080
/* A 64bit atomic type */
8181

8282
typedef struct {
83-
u64 __aligned(8) counter;
83+
long long counter;
8484
} atomic64_t;
8585

8686
#define ATOMIC64_INIT(val) { (val) }
@@ -91,14 +91,14 @@ typedef struct {
9191
*
9292
* Atomically reads the value of @v.
9393
*/
94-
static inline u64 atomic64_read(const atomic64_t *v)
94+
static inline long long atomic64_read(const atomic64_t *v)
9595
{
9696
/*
9797
* Requires an atomic op to read both 32-bit parts consistently.
9898
* Casting away const is safe since the atomic support routines
9999
* do not write to memory if the value has not been modified.
100100
*/
101-
return _atomic64_xchg_add((u64 *)&v->counter, 0);
101+
return _atomic64_xchg_add((long long *)&v->counter, 0);
102102
}
103103

104104
/**
@@ -108,7 +108,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
108108
*
109109
* Atomically adds @i to @v.
110110
*/
111-
static inline void atomic64_add(u64 i, atomic64_t *v)
111+
static inline void atomic64_add(long long i, atomic64_t *v)
112112
{
113113
_atomic64_xchg_add(&v->counter, i);
114114
}
@@ -120,7 +120,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
120120
*
121121
* Atomically adds @i to @v and returns @i + @v
122122
*/
123-
static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
123+
static inline long long atomic64_add_return(long long i, atomic64_t *v)
124124
{
125125
smp_mb(); /* barrier for proper semantics */
126126
return _atomic64_xchg_add(&v->counter, i) + i;
@@ -135,7 +135,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
135135
* Atomically adds @a to @v, so long as @v was not already @u.
136136
* Returns non-zero if @v was not @u, and zero otherwise.
137137
*/
138-
static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
138+
static inline long long atomic64_add_unless(atomic64_t *v, long long a,
139+
long long u)
139140
{
140141
smp_mb(); /* barrier for proper semantics */
141142
return _atomic64_xchg_add_unless(&v->counter, a, u) != u;
@@ -151,7 +152,7 @@ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
151152
* atomic64_set() can't be just a raw store, since it would be lost if it
152153
* fell between the load and store of one of the other atomic ops.
153154
*/
154-
static inline void atomic64_set(atomic64_t *v, u64 n)
155+
static inline void atomic64_set(atomic64_t *v, long long n)
155156
{
156157
_atomic64_xchg(&v->counter, n);
157158
}
@@ -236,11 +237,13 @@ extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
236237
extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
237238
extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
238239
extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
239-
extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
240-
extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
241-
extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
242-
extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
243-
int *lock, u64 o, u64 n);
240+
extern long long __atomic64_cmpxchg(volatile long long *p, int *lock,
241+
long long o, long long n);
242+
extern long long __atomic64_xchg(volatile long long *p, int *lock, long long n);
243+
extern long long __atomic64_xchg_add(volatile long long *p, int *lock,
244+
long long n);
245+
extern long long __atomic64_xchg_add_unless(volatile long long *p,
246+
int *lock, long long o, long long n);
244247

245248
/* Return failure from the atomic wrappers. */
246249
struct __get_user __atomic_bad_address(int __user *addr);

arch/tile/include/asm/cmpxchg.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ int _atomic_xchg(int *ptr, int n);
3535
int _atomic_xchg_add(int *v, int i);
3636
int _atomic_xchg_add_unless(int *v, int a, int u);
3737
int _atomic_cmpxchg(int *ptr, int o, int n);
38-
u64 _atomic64_xchg(u64 *v, u64 n);
39-
u64 _atomic64_xchg_add(u64 *v, u64 i);
40-
u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u);
41-
u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
38+
long long _atomic64_xchg(long long *v, long long n);
39+
long long _atomic64_xchg_add(long long *v, long long i);
40+
long long _atomic64_xchg_add_unless(long long *v, long long a, long long u);
41+
long long _atomic64_cmpxchg(long long *v, long long o, long long n);
4242

4343
#define xchg(ptr, n) \
4444
({ \
@@ -53,23 +53,26 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
5353
if (sizeof(*(ptr)) != 4) \
5454
__cmpxchg_called_with_bad_pointer(); \
5555
smp_mb(); \
56-
(typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, (int)n); \
56+
(typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, \
57+
(int)n); \
5758
})
5859

5960
#define xchg64(ptr, n) \
6061
({ \
6162
if (sizeof(*(ptr)) != 8) \
6263
__xchg_called_with_bad_pointer(); \
6364
smp_mb(); \
64-
(typeof(*(ptr)))_atomic64_xchg((u64 *)(ptr), (u64)(n)); \
65+
(typeof(*(ptr)))_atomic64_xchg((long long *)(ptr), \
66+
(long long)(n)); \
6567
})
6668

6769
#define cmpxchg64(ptr, o, n) \
6870
({ \
6971
if (sizeof(*(ptr)) != 8) \
7072
__cmpxchg_called_with_bad_pointer(); \
7173
smp_mb(); \
72-
(typeof(*(ptr)))_atomic64_cmpxchg((u64 *)ptr, (u64)o, (u64)n); \
74+
(typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr, \
75+
(long long)o, (long long)n); \
7376
})
7477

7578
#else
@@ -81,10 +84,11 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
8184
switch (sizeof(*(ptr))) { \
8285
case 4: \
8386
__x = (typeof(__x))(unsigned long) \
84-
__insn_exch4((ptr), (u32)(unsigned long)(n)); \
87+
__insn_exch4((ptr), \
88+
(u32)(unsigned long)(n)); \
8589
break; \
8690
case 8: \
87-
__x = (typeof(__x)) \
91+
__x = (typeof(__x)) \
8892
__insn_exch((ptr), (unsigned long)(n)); \
8993
break; \
9094
default: \
@@ -103,10 +107,12 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
103107
switch (sizeof(*(ptr))) { \
104108
case 4: \
105109
__x = (typeof(__x))(unsigned long) \
106-
__insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \
110+
__insn_cmpexch4((ptr), \
111+
(u32)(unsigned long)(n)); \
107112
break; \
108113
case 8: \
109-
__x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \
114+
__x = (typeof(__x))__insn_cmpexch((ptr), \
115+
(long long)(n)); \
110116
break; \
111117
default: \
112118
__cmpxchg_called_with_bad_pointer(); \

arch/tile/include/asm/percpu.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,37 @@
1515
#ifndef _ASM_TILE_PERCPU_H
1616
#define _ASM_TILE_PERCPU_H
1717

18-
register unsigned long __my_cpu_offset __asm__("tp");
19-
#define __my_cpu_offset __my_cpu_offset
20-
#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp))
18+
register unsigned long my_cpu_offset_reg asm("tp");
19+
20+
#ifdef CONFIG_PREEMPT
21+
/*
22+
* For full preemption, we can't just use the register variable
23+
* directly, since we need barrier() to hazard against it, causing the
24+
* compiler to reload anything computed from a previous "tp" value.
25+
* But we also don't want to use volatile asm, since we'd like the
26+
* compiler to be able to cache the value across multiple percpu reads.
27+
* So we use a fake stack read as a hazard against barrier().
28+
* The 'U' constraint is like 'm' but disallows postincrement.
29+
*/
30+
static inline unsigned long __my_cpu_offset(void)
31+
{
32+
unsigned long tp;
33+
register unsigned long *sp asm("sp");
34+
asm("move %0, tp" : "=r" (tp) : "U" (*sp));
35+
return tp;
36+
}
37+
#define __my_cpu_offset __my_cpu_offset()
38+
#else
39+
/*
40+
* We don't need to hazard against barrier() since "tp" doesn't ever
41+
* change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only
42+
* changes at function call points, at which we are already re-reading
43+
* the value of "tp" due to "my_cpu_offset_reg" being a global variable.
44+
*/
45+
#define __my_cpu_offset my_cpu_offset_reg
46+
#endif
47+
48+
#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp))
2149

2250
#include <asm-generic/percpu.h>
2351

arch/tile/kernel/hardwall.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static struct hardwall_type hardwall_types[] = {
6666
0,
6767
"udn",
6868
LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
69-
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock),
69+
__SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_UDN].lock),
7070
NULL
7171
},
7272
#ifndef __tilepro__
@@ -77,7 +77,7 @@ static struct hardwall_type hardwall_types[] = {
7777
1, /* disabled pending hypervisor support */
7878
"idn",
7979
LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
80-
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock),
80+
__SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IDN].lock),
8181
NULL
8282
},
8383
{ /* access to user-space IPI */
@@ -87,7 +87,7 @@ static struct hardwall_type hardwall_types[] = {
8787
0,
8888
"ipi",
8989
LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
90-
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock),
90+
__SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IPI].lock),
9191
NULL
9292
},
9393
#endif

arch/tile/kernel/intvec_32.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,9 @@ STD_ENTRY(interrupt_return)
815815
}
816816
bzt r28, 1f
817817
bnz r29, 1f
818+
/* Disable interrupts explicitly for preemption. */
819+
IRQ_DISABLE(r20,r21)
820+
TRACE_IRQS_OFF
818821
jal preempt_schedule_irq
819822
FEEDBACK_REENTER(interrupt_return)
820823
1:

arch/tile/kernel/intvec_64.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,9 @@ STD_ENTRY(interrupt_return)
841841
}
842842
beqzt r28, 1f
843843
bnez r29, 1f
844+
/* Disable interrupts explicitly for preemption. */
845+
IRQ_DISABLE(r20,r21)
846+
TRACE_IRQS_OFF
844847
jal preempt_schedule_irq
845848
FEEDBACK_REENTER(interrupt_return)
846849
1:

arch/tile/kernel/stack.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/mmzone.h>
2424
#include <linux/dcache.h>
2525
#include <linux/fs.h>
26+
#include <linux/string.h>
2627
#include <asm/backtrace.h>
2728
#include <asm/page.h>
2829
#include <asm/ucontext.h>
@@ -332,21 +333,18 @@ static void describe_addr(struct KBacktraceIterator *kbt,
332333
}
333334

334335
if (vma->vm_file) {
335-
char *s;
336336
p = d_path(&vma->vm_file->f_path, buf, bufsize);
337337
if (IS_ERR(p))
338338
p = "?";
339-
s = strrchr(p, '/');
340-
if (s)
341-
p = s+1;
339+
name = kbasename(p);
342340
} else {
343-
p = "anon";
341+
name = "anon";
344342
}
345343

346344
/* Generate a string description of the vma info. */
347-
namelen = strlen(p);
345+
namelen = strlen(name);
348346
remaining = (bufsize - 1) - namelen;
349-
memmove(buf, p, namelen);
347+
memmove(buf, name, namelen);
350348
snprintf(buf + namelen, remaining, "[%lx+%lx] ",
351349
vma->vm_start, vma->vm_end - vma->vm_start);
352350
}

arch/tile/lib/atomic_32.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,19 @@ unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
107107
EXPORT_SYMBOL(_atomic_xor);
108108

109109

110-
u64 _atomic64_xchg(u64 *v, u64 n)
110+
long long _atomic64_xchg(long long *v, long long n)
111111
{
112112
return __atomic64_xchg(v, __atomic_setup(v), n);
113113
}
114114
EXPORT_SYMBOL(_atomic64_xchg);
115115

116-
u64 _atomic64_xchg_add(u64 *v, u64 i)
116+
long long _atomic64_xchg_add(long long *v, long long i)
117117
{
118118
return __atomic64_xchg_add(v, __atomic_setup(v), i);
119119
}
120120
EXPORT_SYMBOL(_atomic64_xchg_add);
121121

122-
u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
122+
long long _atomic64_xchg_add_unless(long long *v, long long a, long long u)
123123
{
124124
/*
125125
* Note: argument order is switched here since it is easier
@@ -130,7 +130,7 @@ u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
130130
}
131131
EXPORT_SYMBOL(_atomic64_xchg_add_unless);
132132

133-
u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n)
133+
long long _atomic64_cmpxchg(long long *v, long long o, long long n)
134134
{
135135
return __atomic64_cmpxchg(v, __atomic_setup(v), o, n);
136136
}

0 commit comments

Comments
 (0)