Commit bb44f116a14c4c932f15c79acfafd46bcb43ca9a

Authored by Ingo Molnar
Committed by Linus Torvalds
1 parent 391eadeec8

[PATCH] fix spinlock-debugging smp_processor_id() usage

When a spinlock debugging check hits, we print the CPU number as an
informational thing - but there is no guarantee that preemption is off
at that point - hence we should use raw_smp_processor_id().  Otherwise
DEBUG_PREEMPT will print a warning.

With this fix the warning goes away and only the spinlock-debugging info
is printed.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 10 additions and 8 deletions Inline Diff

lib/spinlock_debug.c
1 /* 1 /*
2 * Copyright 2005, Red Hat, Inc., Ingo Molnar 2 * Copyright 2005, Red Hat, Inc., Ingo Molnar
3 * Released under the General Public License (GPL). 3 * Released under the General Public License (GPL).
4 * 4 *
5 * This file contains the spinlock/rwlock implementations for 5 * This file contains the spinlock/rwlock implementations for
6 * DEBUG_SPINLOCK. 6 * DEBUG_SPINLOCK.
7 */ 7 */
8 8
9 #include <linux/config.h> 9 #include <linux/config.h>
10 #include <linux/spinlock.h> 10 #include <linux/spinlock.h>
11 #include <linux/interrupt.h> 11 #include <linux/interrupt.h>
12 #include <linux/delay.h> 12 #include <linux/delay.h>
13 13
14 static void spin_bug(spinlock_t *lock, const char *msg) 14 static void spin_bug(spinlock_t *lock, const char *msg)
15 { 15 {
16 static long print_once = 1; 16 static long print_once = 1;
17 struct task_struct *owner = NULL; 17 struct task_struct *owner = NULL;
18 18
19 if (xchg(&print_once, 0)) { 19 if (xchg(&print_once, 0)) {
20 if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT) 20 if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
21 owner = lock->owner; 21 owner = lock->owner;
22 printk("BUG: spinlock %s on CPU#%d, %s/%d\n", 22 printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
23 msg, smp_processor_id(), current->comm, current->pid); 23 msg, raw_smp_processor_id(),
24 current->comm, current->pid);
24 printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n", 25 printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
25 lock, lock->magic, 26 lock, lock->magic,
26 owner ? owner->comm : "<none>", 27 owner ? owner->comm : "<none>",
27 owner ? owner->pid : -1, 28 owner ? owner->pid : -1,
28 lock->owner_cpu); 29 lock->owner_cpu);
29 dump_stack(); 30 dump_stack();
30 #ifdef CONFIG_SMP 31 #ifdef CONFIG_SMP
31 /* 32 /*
32 * We cannot continue on SMP: 33 * We cannot continue on SMP:
33 */ 34 */
34 // panic("bad locking"); 35 // panic("bad locking");
35 #endif 36 #endif
36 } 37 }
37 } 38 }
38 39
39 #define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg) 40 #define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
40 41
41 static inline void debug_spin_lock_before(spinlock_t *lock) 42 static inline void debug_spin_lock_before(spinlock_t *lock)
42 { 43 {
43 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); 44 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
44 SPIN_BUG_ON(lock->owner == current, lock, "recursion"); 45 SPIN_BUG_ON(lock->owner == current, lock, "recursion");
45 SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(), 46 SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
46 lock, "cpu recursion"); 47 lock, "cpu recursion");
47 } 48 }
48 49
49 static inline void debug_spin_lock_after(spinlock_t *lock) 50 static inline void debug_spin_lock_after(spinlock_t *lock)
50 { 51 {
51 lock->owner_cpu = raw_smp_processor_id(); 52 lock->owner_cpu = raw_smp_processor_id();
52 lock->owner = current; 53 lock->owner = current;
53 } 54 }
54 55
55 static inline void debug_spin_unlock(spinlock_t *lock) 56 static inline void debug_spin_unlock(spinlock_t *lock)
56 { 57 {
57 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); 58 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
58 SPIN_BUG_ON(!spin_is_locked(lock), lock, "already unlocked"); 59 SPIN_BUG_ON(!spin_is_locked(lock), lock, "already unlocked");
59 SPIN_BUG_ON(lock->owner != current, lock, "wrong owner"); 60 SPIN_BUG_ON(lock->owner != current, lock, "wrong owner");
60 SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(), 61 SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
61 lock, "wrong CPU"); 62 lock, "wrong CPU");
62 lock->owner = SPINLOCK_OWNER_INIT; 63 lock->owner = SPINLOCK_OWNER_INIT;
63 lock->owner_cpu = -1; 64 lock->owner_cpu = -1;
64 } 65 }
65 66
66 static void __spin_lock_debug(spinlock_t *lock) 67 static void __spin_lock_debug(spinlock_t *lock)
67 { 68 {
68 int print_once = 1; 69 int print_once = 1;
69 u64 i; 70 u64 i;
70 71
71 for (;;) { 72 for (;;) {
72 for (i = 0; i < loops_per_jiffy * HZ; i++) { 73 for (i = 0; i < loops_per_jiffy * HZ; i++) {
73 cpu_relax(); 74 cpu_relax();
74 if (__raw_spin_trylock(&lock->raw_lock)) 75 if (__raw_spin_trylock(&lock->raw_lock))
75 return; 76 return;
76 } 77 }
77 /* lockup suspected: */ 78 /* lockup suspected: */
78 if (print_once) { 79 if (print_once) {
79 print_once = 0; 80 print_once = 0;
80 printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n", 81 printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
81 smp_processor_id(), current->comm, current->pid, 82 raw_smp_processor_id(), current->comm,
82 lock); 83 current->pid, lock);
83 dump_stack(); 84 dump_stack();
84 } 85 }
85 } 86 }
86 } 87 }
87 88
88 void _raw_spin_lock(spinlock_t *lock) 89 void _raw_spin_lock(spinlock_t *lock)
89 { 90 {
90 debug_spin_lock_before(lock); 91 debug_spin_lock_before(lock);
91 if (unlikely(!__raw_spin_trylock(&lock->raw_lock))) 92 if (unlikely(!__raw_spin_trylock(&lock->raw_lock)))
92 __spin_lock_debug(lock); 93 __spin_lock_debug(lock);
93 debug_spin_lock_after(lock); 94 debug_spin_lock_after(lock);
94 } 95 }
95 96
96 int _raw_spin_trylock(spinlock_t *lock) 97 int _raw_spin_trylock(spinlock_t *lock)
97 { 98 {
98 int ret = __raw_spin_trylock(&lock->raw_lock); 99 int ret = __raw_spin_trylock(&lock->raw_lock);
99 100
100 if (ret) 101 if (ret)
101 debug_spin_lock_after(lock); 102 debug_spin_lock_after(lock);
102 #ifndef CONFIG_SMP 103 #ifndef CONFIG_SMP
103 /* 104 /*
104 * Must not happen on UP: 105 * Must not happen on UP:
105 */ 106 */
106 SPIN_BUG_ON(!ret, lock, "trylock failure on UP"); 107 SPIN_BUG_ON(!ret, lock, "trylock failure on UP");
107 #endif 108 #endif
108 return ret; 109 return ret;
109 } 110 }
110 111
111 void _raw_spin_unlock(spinlock_t *lock) 112 void _raw_spin_unlock(spinlock_t *lock)
112 { 113 {
113 debug_spin_unlock(lock); 114 debug_spin_unlock(lock);
114 __raw_spin_unlock(&lock->raw_lock); 115 __raw_spin_unlock(&lock->raw_lock);
115 } 116 }
116 117
117 static void rwlock_bug(rwlock_t *lock, const char *msg) 118 static void rwlock_bug(rwlock_t *lock, const char *msg)
118 { 119 {
119 static long print_once = 1; 120 static long print_once = 1;
120 121
121 if (xchg(&print_once, 0)) { 122 if (xchg(&print_once, 0)) {
122 printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg, 123 printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
123 smp_processor_id(), current->comm, current->pid, lock); 124 raw_smp_processor_id(), current->comm,
125 current->pid, lock);
124 dump_stack(); 126 dump_stack();
125 #ifdef CONFIG_SMP 127 #ifdef CONFIG_SMP
126 /* 128 /*
127 * We cannot continue on SMP: 129 * We cannot continue on SMP:
128 */ 130 */
129 panic("bad locking"); 131 panic("bad locking");
130 #endif 132 #endif
131 } 133 }
132 } 134 }
133 135
134 #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) 136 #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg)
135 137
136 static void __read_lock_debug(rwlock_t *lock) 138 static void __read_lock_debug(rwlock_t *lock)
137 { 139 {
138 int print_once = 1; 140 int print_once = 1;
139 u64 i; 141 u64 i;
140 142
141 for (;;) { 143 for (;;) {
142 for (i = 0; i < loops_per_jiffy * HZ; i++) { 144 for (i = 0; i < loops_per_jiffy * HZ; i++) {
143 cpu_relax(); 145 cpu_relax();
144 if (__raw_read_trylock(&lock->raw_lock)) 146 if (__raw_read_trylock(&lock->raw_lock))
145 return; 147 return;
146 } 148 }
147 /* lockup suspected: */ 149 /* lockup suspected: */
148 if (print_once) { 150 if (print_once) {
149 print_once = 0; 151 print_once = 0;
150 printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n", 152 printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
151 smp_processor_id(), current->comm, current->pid, 153 raw_smp_processor_id(), current->comm,
152 lock); 154 current->pid, lock);
153 dump_stack(); 155 dump_stack();
154 } 156 }
155 } 157 }
156 } 158 }
157 159
158 void _raw_read_lock(rwlock_t *lock) 160 void _raw_read_lock(rwlock_t *lock)
159 { 161 {
160 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 162 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
161 if (unlikely(!__raw_read_trylock(&lock->raw_lock))) 163 if (unlikely(!__raw_read_trylock(&lock->raw_lock)))
162 __read_lock_debug(lock); 164 __read_lock_debug(lock);
163 } 165 }
164 166
165 int _raw_read_trylock(rwlock_t *lock) 167 int _raw_read_trylock(rwlock_t *lock)
166 { 168 {
167 int ret = __raw_read_trylock(&lock->raw_lock); 169 int ret = __raw_read_trylock(&lock->raw_lock);
168 170
169 #ifndef CONFIG_SMP 171 #ifndef CONFIG_SMP
170 /* 172 /*
171 * Must not happen on UP: 173 * Must not happen on UP:
172 */ 174 */
173 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP"); 175 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
174 #endif 176 #endif
175 return ret; 177 return ret;
176 } 178 }
177 179
178 void _raw_read_unlock(rwlock_t *lock) 180 void _raw_read_unlock(rwlock_t *lock)
179 { 181 {
180 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 182 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
181 __raw_read_unlock(&lock->raw_lock); 183 __raw_read_unlock(&lock->raw_lock);
182 } 184 }
183 185
184 static inline void debug_write_lock_before(rwlock_t *lock) 186 static inline void debug_write_lock_before(rwlock_t *lock)
185 { 187 {
186 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 188 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
187 RWLOCK_BUG_ON(lock->owner == current, lock, "recursion"); 189 RWLOCK_BUG_ON(lock->owner == current, lock, "recursion");
188 RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(), 190 RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
189 lock, "cpu recursion"); 191 lock, "cpu recursion");
190 } 192 }
191 193
192 static inline void debug_write_lock_after(rwlock_t *lock) 194 static inline void debug_write_lock_after(rwlock_t *lock)
193 { 195 {
194 lock->owner_cpu = raw_smp_processor_id(); 196 lock->owner_cpu = raw_smp_processor_id();
195 lock->owner = current; 197 lock->owner = current;
196 } 198 }
197 199
198 static inline void debug_write_unlock(rwlock_t *lock) 200 static inline void debug_write_unlock(rwlock_t *lock)
199 { 201 {
200 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 202 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
201 RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner"); 203 RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner");
202 RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(), 204 RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
203 lock, "wrong CPU"); 205 lock, "wrong CPU");
204 lock->owner = SPINLOCK_OWNER_INIT; 206 lock->owner = SPINLOCK_OWNER_INIT;
205 lock->owner_cpu = -1; 207 lock->owner_cpu = -1;
206 } 208 }
207 209
208 static void __write_lock_debug(rwlock_t *lock) 210 static void __write_lock_debug(rwlock_t *lock)
209 { 211 {
210 int print_once = 1; 212 int print_once = 1;
211 u64 i; 213 u64 i;
212 214
213 for (;;) { 215 for (;;) {
214 for (i = 0; i < loops_per_jiffy * HZ; i++) { 216 for (i = 0; i < loops_per_jiffy * HZ; i++) {
215 cpu_relax(); 217 cpu_relax();
216 if (__raw_write_trylock(&lock->raw_lock)) 218 if (__raw_write_trylock(&lock->raw_lock))
217 return; 219 return;
218 } 220 }
219 /* lockup suspected: */ 221 /* lockup suspected: */
220 if (print_once) { 222 if (print_once) {
221 print_once = 0; 223 print_once = 0;
222 printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n", 224 printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
223 smp_processor_id(), current->comm, current->pid, 225 raw_smp_processor_id(), current->comm,
224 lock); 226 current->pid, lock);
225 dump_stack(); 227 dump_stack();
226 } 228 }
227 } 229 }
228 } 230 }
229 231
230 void _raw_write_lock(rwlock_t *lock) 232 void _raw_write_lock(rwlock_t *lock)
231 { 233 {
232 debug_write_lock_before(lock); 234 debug_write_lock_before(lock);
233 if (unlikely(!__raw_write_trylock(&lock->raw_lock))) 235 if (unlikely(!__raw_write_trylock(&lock->raw_lock)))
234 __write_lock_debug(lock); 236 __write_lock_debug(lock);
235 debug_write_lock_after(lock); 237 debug_write_lock_after(lock);
236 } 238 }
237 239
238 int _raw_write_trylock(rwlock_t *lock) 240 int _raw_write_trylock(rwlock_t *lock)
239 { 241 {
240 int ret = __raw_write_trylock(&lock->raw_lock); 242 int ret = __raw_write_trylock(&lock->raw_lock);
241 243
242 if (ret) 244 if (ret)
243 debug_write_lock_after(lock); 245 debug_write_lock_after(lock);
244 #ifndef CONFIG_SMP 246 #ifndef CONFIG_SMP
245 /* 247 /*
246 * Must not happen on UP: 248 * Must not happen on UP:
247 */ 249 */
248 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP"); 250 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
249 #endif 251 #endif
250 return ret; 252 return ret;
251 } 253 }
252 254
253 void _raw_write_unlock(rwlock_t *lock) 255 void _raw_write_unlock(rwlock_t *lock)
254 { 256 {
255 debug_write_unlock(lock); 257 debug_write_unlock(lock);
256 __raw_write_unlock(&lock->raw_lock); 258 __raw_write_unlock(&lock->raw_lock);
257 } 259 }
258 260