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 | |||
