diff options
author | Dave Jones <davej@redhat.com> | 2006-09-29 04:59:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-29 12:18:05 -0400 |
commit | 199a9afc3dbe98c35326f1d3907ab94dae953a6e (patch) | |
tree | f656df600bec86e8764af2e33bc4a0b98330e758 /lib | |
parent | df67b3daea602728b51325a4debaeeb912ee51d1 (diff) |
[PATCH] Debug variants of linked list macros
Signed-off-by: Dave Jones <davej@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig.debug | 9 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/list_debug.c | 77 |
3 files changed, 87 insertions, 0 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index b0f5ca72599f..f9ae75cc0145 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -320,6 +320,15 @@ config DEBUG_VM | |||
320 | 320 | ||
321 | If unsure, say N. | 321 | If unsure, say N. |
322 | 322 | ||
323 | config DEBUG_LIST | ||
324 | bool "Debug linked list manipulation" | ||
325 | depends on DEBUG_KERNEL | ||
326 | help | ||
327 | Enable this to turn on extended checks in the linked-list | ||
328 | walking routines. | ||
329 | |||
330 | If unsure, say N. | ||
331 | |||
323 | config FRAME_POINTER | 332 | config FRAME_POINTER |
324 | bool "Compile the kernel with frame pointers" | 333 | bool "Compile the kernel with frame pointers" |
325 | depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH) | 334 | depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH) |
diff --git a/lib/Makefile b/lib/Makefile index ef1d37afbbb6..402762fead70 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -28,6 +28,7 @@ lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | |||
28 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 28 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
29 | obj-$(CONFIG_PLIST) += plist.o | 29 | obj-$(CONFIG_PLIST) += plist.o |
30 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o | 30 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o |
31 | obj-$(CONFIG_DEBUG_LIST) += list_debug.o | ||
31 | 32 | ||
32 | ifneq ($(CONFIG_HAVE_DEC_LOCK),y) | 33 | ifneq ($(CONFIG_HAVE_DEC_LOCK),y) |
33 | lib-y += dec_and_lock.o | 34 | lib-y += dec_and_lock.o |
diff --git a/lib/list_debug.c b/lib/list_debug.c new file mode 100644 index 000000000000..1aae85cef92c --- /dev/null +++ b/lib/list_debug.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright 2006, Red Hat, Inc., Dave Jones | ||
3 | * Released under the General Public License (GPL). | ||
4 | * | ||
5 | * This file contains the linked list implementations for | ||
6 | * DEBUG_LIST. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/list.h> | ||
11 | |||
12 | /* | ||
13 | * Insert a new entry between two known consecutive entries. | ||
14 | * | ||
15 | * This is only for internal list manipulation where we know | ||
16 | * the prev/next entries already! | ||
17 | */ | ||
18 | |||
19 | void __list_add(struct list_head *new, | ||
20 | struct list_head *prev, | ||
21 | struct list_head *next) | ||
22 | { | ||
23 | if (unlikely(next->prev != prev)) { | ||
24 | printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n", | ||
25 | prev, next->prev); | ||
26 | BUG(); | ||
27 | } | ||
28 | if (unlikely(prev->next != next)) { | ||
29 | printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n", | ||
30 | next, prev->next); | ||
31 | BUG(); | ||
32 | } | ||
33 | next->prev = new; | ||
34 | new->next = next; | ||
35 | new->prev = prev; | ||
36 | prev->next = new; | ||
37 | } | ||
38 | EXPORT_SYMBOL(__list_add); | ||
39 | |||
40 | /** | ||
41 | * list_add - add a new entry | ||
42 | * @new: new entry to be added | ||
43 | * @head: list head to add it after | ||
44 | * | ||
45 | * Insert a new entry after the specified head. | ||
46 | * This is good for implementing stacks. | ||
47 | */ | ||
48 | void list_add(struct list_head *new, struct list_head *head) | ||
49 | { | ||
50 | __list_add(new, head, head->next); | ||
51 | } | ||
52 | EXPORT_SYMBOL(list_add); | ||
53 | |||
54 | /** | ||
55 | * list_del - deletes entry from list. | ||
56 | * @entry: the element to delete from the list. | ||
57 | * Note: list_empty on entry does not return true after this, the entry is | ||
58 | * in an undefined state. | ||
59 | */ | ||
60 | void list_del(struct list_head *entry) | ||
61 | { | ||
62 | if (unlikely(entry->prev->next != entry)) { | ||
63 | printk(KERN_ERR "list_del corruption. prev->next should be %p, but was %p\n", | ||
64 | entry, entry->prev->next); | ||
65 | BUG(); | ||
66 | } | ||
67 | if (unlikely(entry->next->prev != entry)) { | ||
68 | printk(KERN_ERR "list_del corruption. next->prev should be %p, but was %p\n", | ||
69 | entry, entry->next->prev); | ||
70 | BUG(); | ||
71 | } | ||
72 | __list_del(entry->prev, entry->next); | ||
73 | entry->next = LIST_POISON1; | ||
74 | entry->prev = LIST_POISON2; | ||
75 | } | ||
76 | EXPORT_SYMBOL(list_del); | ||
77 | |||