aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug9
-rw-r--r--lib/Makefile1
-rw-r--r--lib/list_debug.c77
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
323config 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
323config FRAME_POINTER 332config 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
28obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o 28obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
29obj-$(CONFIG_PLIST) += plist.o 29obj-$(CONFIG_PLIST) += plist.o
30obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o 30obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
31obj-$(CONFIG_DEBUG_LIST) += list_debug.o
31 32
32ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 33ifneq ($(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
19void __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}
38EXPORT_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 */
48void list_add(struct list_head *new, struct list_head *head)
49{
50 __list_add(new, head, head->next);
51}
52EXPORT_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 */
60void 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}
76EXPORT_SYMBOL(list_del);
77