|
@@ -28,6 +28,8 @@
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_PI_LIST
|
|
#ifdef CONFIG_DEBUG_PI_LIST
|
|
|
|
|
|
|
|
+static struct plist_head test_head;
|
|
|
|
+
|
|
static void plist_check_prev_next(struct list_head *t, struct list_head *p,
|
|
static void plist_check_prev_next(struct list_head *t, struct list_head *p,
|
|
struct list_head *n)
|
|
struct list_head *n)
|
|
{
|
|
{
|
|
@@ -54,7 +56,7 @@ static void plist_check_list(struct list_head *top)
|
|
|
|
|
|
static void plist_check_head(struct plist_head *head)
|
|
static void plist_check_head(struct plist_head *head)
|
|
{
|
|
{
|
|
- WARN_ON(!head->rawlock && !head->spinlock);
|
|
|
|
|
|
+ WARN_ON(head != &test_head && !head->rawlock && !head->spinlock);
|
|
if (head->rawlock)
|
|
if (head->rawlock)
|
|
WARN_ON_SMP(!raw_spin_is_locked(head->rawlock));
|
|
WARN_ON_SMP(!raw_spin_is_locked(head->rawlock));
|
|
if (head->spinlock)
|
|
if (head->spinlock)
|
|
@@ -135,3 +137,80 @@ void plist_del(struct plist_node *node, struct plist_head *head)
|
|
|
|
|
|
plist_check_head(head);
|
|
plist_check_head(head);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DEBUG_PI_LIST
|
|
|
|
+#include <linux/sched.h>
|
|
|
|
+#include <linux/module.h>
|
|
|
|
+#include <linux/init.h>
|
|
|
|
+
|
|
|
|
+static struct plist_node __initdata test_node[241];
|
|
|
|
+
|
|
|
|
+static void __init plist_test_check(int nr_expect)
|
|
|
|
+{
|
|
|
|
+ struct plist_node *first, *prio_pos, *node_pos;
|
|
|
|
+
|
|
|
|
+ if (plist_head_empty(&test_head)) {
|
|
|
|
+ BUG_ON(nr_expect != 0);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ prio_pos = first = plist_first(&test_head);
|
|
|
|
+ plist_for_each(node_pos, &test_head) {
|
|
|
|
+ if (nr_expect-- < 0)
|
|
|
|
+ break;
|
|
|
|
+ if (node_pos == first)
|
|
|
|
+ continue;
|
|
|
|
+ if (node_pos->prio == prio_pos->prio) {
|
|
|
|
+ BUG_ON(!list_empty(&node_pos->prio_list));
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ BUG_ON(prio_pos->prio > node_pos->prio);
|
|
|
|
+ BUG_ON(prio_pos->prio_list.next != &node_pos->prio_list);
|
|
|
|
+ prio_pos = node_pos;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ BUG_ON(nr_expect != 0);
|
|
|
|
+ BUG_ON(prio_pos->prio_list.next != &first->prio_list);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int __init plist_test(void)
|
|
|
|
+{
|
|
|
|
+ int nr_expect = 0, i, loop;
|
|
|
|
+ unsigned int r = local_clock();
|
|
|
|
+
|
|
|
|
+ printk(KERN_INFO "start plist test\n");
|
|
|
|
+ plist_head_init(&test_head, NULL);
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(test_node); i++)
|
|
|
|
+ plist_node_init(test_node + i, 0);
|
|
|
|
+
|
|
|
|
+ for (loop = 0; loop < 1000; loop++) {
|
|
|
|
+ r = r * 193939 % 47629;
|
|
|
|
+ i = r % ARRAY_SIZE(test_node);
|
|
|
|
+ if (plist_node_empty(test_node + i)) {
|
|
|
|
+ r = r * 193939 % 47629;
|
|
|
|
+ test_node[i].prio = r % 99;
|
|
|
|
+ plist_add(test_node + i, &test_head);
|
|
|
|
+ nr_expect++;
|
|
|
|
+ } else {
|
|
|
|
+ plist_del(test_node + i, &test_head);
|
|
|
|
+ nr_expect--;
|
|
|
|
+ }
|
|
|
|
+ plist_test_check(nr_expect);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(test_node); i++) {
|
|
|
|
+ if (plist_node_empty(test_node + i))
|
|
|
|
+ continue;
|
|
|
|
+ plist_del(test_node + i, &test_head);
|
|
|
|
+ nr_expect--;
|
|
|
|
+ plist_test_check(nr_expect);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printk(KERN_INFO "end plist test\n");
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+module_init(plist_test);
|
|
|
|
+
|
|
|
|
+#endif
|