1 // SPDX-License-Identifier: GPL-2.0-only
2 #define pr_fmt(fmt) "list_sort_test: " fmt
4 #include <linux/kernel.h>
5 #include <linux/list_sort.h>
6 #include <linux/list.h>
7 #include <linux/module.h>
8 #include <linux/printk.h>
9 #include <linux/slab.h>
10 #include <linux/random.h>
13 * The pattern of set bits in the list length determines which cases
14 * are hit in list_sort().
16 #define TEST_LIST_LEN (512+128+2) /* not including head */
18 #define TEST_POISON1 0xDEADBEEF
19 #define TEST_POISON2 0xA324354C
23 struct list_head list
;
29 /* Array, containing pointers to all elements in the test list */
30 static struct debug_el
**elts __initdata
;
32 static int __init
check(struct debug_el
*ela
, struct debug_el
*elb
)
34 if (ela
->serial
>= TEST_LIST_LEN
) {
35 pr_err("error: incorrect serial %d\n", ela
->serial
);
38 if (elb
->serial
>= TEST_LIST_LEN
) {
39 pr_err("error: incorrect serial %d\n", elb
->serial
);
42 if (elts
[ela
->serial
] != ela
|| elts
[elb
->serial
] != elb
) {
43 pr_err("error: phantom element\n");
46 if (ela
->poison1
!= TEST_POISON1
|| ela
->poison2
!= TEST_POISON2
) {
47 pr_err("error: bad poison: %#x/%#x\n",
48 ela
->poison1
, ela
->poison2
);
51 if (elb
->poison1
!= TEST_POISON1
|| elb
->poison2
!= TEST_POISON2
) {
52 pr_err("error: bad poison: %#x/%#x\n",
53 elb
->poison1
, elb
->poison2
);
59 static int __init
cmp(void *priv
, struct list_head
*a
, struct list_head
*b
)
61 struct debug_el
*ela
, *elb
;
63 ela
= container_of(a
, struct debug_el
, list
);
64 elb
= container_of(b
, struct debug_el
, list
);
67 return ela
->value
- elb
->value
;
70 static int __init
list_sort_test(void)
72 int i
, count
= 1, err
= -ENOMEM
;
74 struct list_head
*cur
;
77 pr_debug("start testing list_sort()\n");
79 elts
= kcalloc(TEST_LIST_LEN
, sizeof(*elts
), GFP_KERNEL
);
83 for (i
= 0; i
< TEST_LIST_LEN
; i
++) {
84 el
= kmalloc(sizeof(*el
), GFP_KERNEL
);
88 /* force some equivalencies */
89 el
->value
= prandom_u32() % (TEST_LIST_LEN
/ 3);
91 el
->poison1
= TEST_POISON1
;
92 el
->poison2
= TEST_POISON2
;
94 list_add_tail(&el
->list
, &head
);
97 list_sort(NULL
, &head
, cmp
);
100 for (cur
= head
.next
; cur
->next
!= &head
; cur
= cur
->next
) {
101 struct debug_el
*el1
;
104 if (cur
->next
->prev
!= cur
) {
105 pr_err("error: list is corrupted\n");
109 cmp_result
= cmp(NULL
, cur
, cur
->next
);
110 if (cmp_result
> 0) {
111 pr_err("error: list is not sorted\n");
115 el
= container_of(cur
, struct debug_el
, list
);
116 el1
= container_of(cur
->next
, struct debug_el
, list
);
117 if (cmp_result
== 0 && el
->serial
>= el1
->serial
) {
118 pr_err("error: order of equivalent elements not "
123 if (check(el
, el1
)) {
124 pr_err("error: element check failed\n");
129 if (head
.prev
!= cur
) {
130 pr_err("error: list is corrupted\n");
135 if (count
!= TEST_LIST_LEN
) {
136 pr_err("error: bad list length %d", count
);
142 for (i
= 0; i
< TEST_LIST_LEN
; i
++)
147 module_init(list_sort_test
);
148 MODULE_LICENSE("GPL");