aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorGreg KH <gregkh@suse.de>2005-09-12 15:45:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-12 15:45:04 -0400
commitd58dde0f552a5c5c4485b962d8b6e9dd54fefb30 (patch)
treed9a7e35eb88fea6265d5aadcc3d4ed39122b052a /lib
parent877599fdef5ea4a7dd1956e22fa9d6923add97f8 (diff)
parent2ade81473636b33aaac64495f89a7dc572c529f0 (diff)
Merge ../torvalds-2.6/
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug8
-rw-r--r--lib/Makefile1
-rw-r--r--lib/dec_and_lock.c3
-rw-r--r--lib/kernel_lock.c3
-rw-r--r--lib/radix-tree.c2
-rw-r--r--lib/sort.c5
-rw-r--r--lib/spinlock_debug.c257
7 files changed, 267 insertions, 12 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3754c9a8f5c8..016e89a44ac8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -170,11 +170,11 @@ config DEBUG_FS
170 170
171config FRAME_POINTER 171config FRAME_POINTER
172 bool "Compile the kernel with frame pointers" 172 bool "Compile the kernel with frame pointers"
173 depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV || UML) 173 depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
174 default y if DEBUG_INFO && UML 174 default y if DEBUG_INFO && UML
175 help 175 help
176 If you say Y here the resulting kernel image will be slightly larger 176 If you say Y here the resulting kernel image will be slightly larger
177 and slower, but it will give very useful debugging information. 177 and slower, but it might give very useful debugging information
178 If you don't debug the kernel, you can say N, but we may not be able 178 on some architectures or you use external debuggers.
179 to solve problems without frame pointers. 179 If you don't debug the kernel, you can say N.
180 180
diff --git a/lib/Makefile b/lib/Makefile
index d9c38ba05e7b..44a46750690a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -16,6 +16,7 @@ CFLAGS_kobject.o += -DDEBUG
16CFLAGS_kobject_uevent.o += -DDEBUG 16CFLAGS_kobject_uevent.o += -DDEBUG
17endif 17endif
18 18
19obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
19lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o 20lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
20lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o 21lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
21lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o 22lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c
index 6658d81e1836..2377af057d09 100644
--- a/lib/dec_and_lock.c
+++ b/lib/dec_and_lock.c
@@ -25,8 +25,6 @@
25 * this is trivially done efficiently using a load-locked 25 * this is trivially done efficiently using a load-locked
26 * store-conditional approach, for example. 26 * store-conditional approach, for example.
27 */ 27 */
28
29#ifndef ATOMIC_DEC_AND_LOCK
30int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) 28int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
31{ 29{
32 spin_lock(lock); 30 spin_lock(lock);
@@ -37,4 +35,3 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
37} 35}
38 36
39EXPORT_SYMBOL(_atomic_dec_and_lock); 37EXPORT_SYMBOL(_atomic_dec_and_lock);
40#endif
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index bd2bc5d887b8..cb5490ec00f2 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -177,8 +177,7 @@ static inline void __lock_kernel(void)
177 177
178static inline void __unlock_kernel(void) 178static inline void __unlock_kernel(void)
179{ 179{
180 _raw_spin_unlock(&kernel_flag); 180 spin_unlock(&kernel_flag);
181 preempt_enable();
182} 181}
183 182
184/* 183/*
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index b972dd29289d..6a8bc6e06431 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -110,7 +110,7 @@ radix_tree_node_free(struct radix_tree_node *node)
110 * success, return zero, with preemption disabled. On error, return -ENOMEM 110 * success, return zero, with preemption disabled. On error, return -ENOMEM
111 * with preemption not disabled. 111 * with preemption not disabled.
112 */ 112 */
113int radix_tree_preload(int gfp_mask) 113int radix_tree_preload(unsigned int __nocast gfp_mask)
114{ 114{
115 struct radix_tree_preload *rtp; 115 struct radix_tree_preload *rtp;
116 struct radix_tree_node *node; 116 struct radix_tree_node *node;
diff --git a/lib/sort.c b/lib/sort.c
index b73dbb0e7c83..ddc4d35df289 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -6,15 +6,16 @@
6 6
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/sort.h>
9 10
10void u32_swap(void *a, void *b, int size) 11static void u32_swap(void *a, void *b, int size)
11{ 12{
12 u32 t = *(u32 *)a; 13 u32 t = *(u32 *)a;
13 *(u32 *)a = *(u32 *)b; 14 *(u32 *)a = *(u32 *)b;
14 *(u32 *)b = t; 15 *(u32 *)b = t;
15} 16}
16 17
17void generic_swap(void *a, void *b, int size) 18static void generic_swap(void *a, void *b, int size)
18{ 19{
19 char t; 20 char t;
20 21
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
new file mode 100644
index 000000000000..906ad101eab3
--- /dev/null
+++ b/lib/spinlock_debug.c
@@ -0,0 +1,257 @@
1/*
2 * Copyright 2005, Red Hat, Inc., Ingo Molnar
3 * Released under the General Public License (GPL).
4 *
5 * This file contains the spinlock/rwlock implementations for
6 * DEBUG_SPINLOCK.
7 */
8
9#include <linux/config.h>
10#include <linux/spinlock.h>
11#include <linux/interrupt.h>
12#include <linux/delay.h>
13
14static void spin_bug(spinlock_t *lock, const char *msg)
15{
16 static long print_once = 1;
17 struct task_struct *owner = NULL;
18
19 if (xchg(&print_once, 0)) {
20 if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
21 owner = lock->owner;
22 printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
23 msg, smp_processor_id(), current->comm, current->pid);
24 printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
25 lock, lock->magic,
26 owner ? owner->comm : "<none>",
27 owner ? owner->pid : -1,
28 lock->owner_cpu);
29 dump_stack();
30#ifdef CONFIG_SMP
31 /*
32 * We cannot continue on SMP:
33 */
34// panic("bad locking");
35#endif
36 }
37}
38
39#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
40
41static inline void debug_spin_lock_before(spinlock_t *lock)
42{
43 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_cpu == raw_smp_processor_id(),
46 lock, "cpu recursion");
47}
48
49static inline void debug_spin_lock_after(spinlock_t *lock)
50{
51 lock->owner_cpu = raw_smp_processor_id();
52 lock->owner = current;
53}
54
55static inline void debug_spin_unlock(spinlock_t *lock)
56{
57 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(lock->owner != current, lock, "wrong owner");
60 SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
61 lock, "wrong CPU");
62 lock->owner = SPINLOCK_OWNER_INIT;
63 lock->owner_cpu = -1;
64}
65
66static void __spin_lock_debug(spinlock_t *lock)
67{
68 int print_once = 1;
69 u64 i;
70
71 for (;;) {
72 for (i = 0; i < loops_per_jiffy * HZ; i++) {
73 cpu_relax();
74 if (__raw_spin_trylock(&lock->raw_lock))
75 return;
76 }
77 /* lockup suspected: */
78 if (print_once) {
79 print_once = 0;
80 printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
81 smp_processor_id(), current->comm, current->pid,
82 lock);
83 dump_stack();
84 }
85 }
86}
87
88void _raw_spin_lock(spinlock_t *lock)
89{
90 debug_spin_lock_before(lock);
91 if (unlikely(!__raw_spin_trylock(&lock->raw_lock)))
92 __spin_lock_debug(lock);
93 debug_spin_lock_after(lock);
94}
95
96int _raw_spin_trylock(spinlock_t *lock)
97{
98 int ret = __raw_spin_trylock(&lock->raw_lock);
99
100 if (ret)
101 debug_spin_lock_after(lock);
102#ifndef CONFIG_SMP
103 /*
104 * Must not happen on UP:
105 */
106 SPIN_BUG_ON(!ret, lock, "trylock failure on UP");
107#endif
108 return ret;
109}
110
111void _raw_spin_unlock(spinlock_t *lock)
112{
113 debug_spin_unlock(lock);
114 __raw_spin_unlock(&lock->raw_lock);
115}
116
117static void rwlock_bug(rwlock_t *lock, const char *msg)
118{
119 static long print_once = 1;
120
121 if (xchg(&print_once, 0)) {
122 printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
123 smp_processor_id(), current->comm, current->pid, lock);
124 dump_stack();
125#ifdef CONFIG_SMP
126 /*
127 * We cannot continue on SMP:
128 */
129 panic("bad locking");
130#endif
131 }
132}
133
134#define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg)
135
136static void __read_lock_debug(rwlock_t *lock)
137{
138 int print_once = 1;
139 u64 i;
140
141 for (;;) {
142 for (i = 0; i < loops_per_jiffy * HZ; i++) {
143 cpu_relax();
144 if (__raw_read_trylock(&lock->raw_lock))
145 return;
146 }
147 /* lockup suspected: */
148 if (print_once) {
149 print_once = 0;
150 printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
151 smp_processor_id(), current->comm, current->pid,
152 lock);
153 dump_stack();
154 }
155 }
156}
157
158void _raw_read_lock(rwlock_t *lock)
159{
160 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
161 if (unlikely(!__raw_read_trylock(&lock->raw_lock)))
162 __read_lock_debug(lock);
163}
164
165int _raw_read_trylock(rwlock_t *lock)
166{
167 int ret = __raw_read_trylock(&lock->raw_lock);
168
169#ifndef CONFIG_SMP
170 /*
171 * Must not happen on UP:
172 */
173 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
174#endif
175 return ret;
176}
177
178void _raw_read_unlock(rwlock_t *lock)
179{
180 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
181 __raw_read_unlock(&lock->raw_lock);
182}
183
184static inline void debug_write_lock_before(rwlock_t *lock)
185{
186 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
187 RWLOCK_BUG_ON(lock->owner == current, lock, "recursion");
188 RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
189 lock, "cpu recursion");
190}
191
192static inline void debug_write_lock_after(rwlock_t *lock)
193{
194 lock->owner_cpu = raw_smp_processor_id();
195 lock->owner = current;
196}
197
198static inline void debug_write_unlock(rwlock_t *lock)
199{
200 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
201 RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner");
202 RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
203 lock, "wrong CPU");
204 lock->owner = SPINLOCK_OWNER_INIT;
205 lock->owner_cpu = -1;
206}
207
208static void __write_lock_debug(rwlock_t *lock)
209{
210 int print_once = 1;
211 u64 i;
212
213 for (;;) {
214 for (i = 0; i < loops_per_jiffy * HZ; i++) {
215 cpu_relax();
216 if (__raw_write_trylock(&lock->raw_lock))
217 return;
218 }
219 /* lockup suspected: */
220 if (print_once) {
221 print_once = 0;
222 printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
223 smp_processor_id(), current->comm, current->pid,
224 lock);
225 dump_stack();
226 }
227 }
228}
229
230void _raw_write_lock(rwlock_t *lock)
231{
232 debug_write_lock_before(lock);
233 if (unlikely(!__raw_write_trylock(&lock->raw_lock)))
234 __write_lock_debug(lock);
235 debug_write_lock_after(lock);
236}
237
238int _raw_write_trylock(rwlock_t *lock)
239{
240 int ret = __raw_write_trylock(&lock->raw_lock);
241
242 if (ret)
243 debug_write_lock_after(lock);
244#ifndef CONFIG_SMP
245 /*
246 * Must not happen on UP:
247 */
248 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP");
249#endif
250 return ret;
251}
252
253void _raw_write_unlock(rwlock_t *lock)
254{
255 debug_write_unlock(lock);
256 __raw_write_unlock(&lock->raw_lock);
257}