xref: /openbmc/linux/lib/list-test.c (revision 57b4f760)
1ea2dd7c0SDavid Gow // SPDX-License-Identifier: GPL-2.0
2ea2dd7c0SDavid Gow /*
3ea2dd7c0SDavid Gow  * KUnit test for the Kernel Linked-list structures.
4ea2dd7c0SDavid Gow  *
5ea2dd7c0SDavid Gow  * Copyright (C) 2019, Google LLC.
6ea2dd7c0SDavid Gow  * Author: David Gow <davidgow@google.com>
7ea2dd7c0SDavid Gow  */
8ea2dd7c0SDavid Gow #include <kunit/test.h>
9ea2dd7c0SDavid Gow 
10ea2dd7c0SDavid Gow #include <linux/list.h>
11*57b4f760SSadiya Kazi #include <linux/klist.h>
12ea2dd7c0SDavid Gow 
13ea2dd7c0SDavid Gow struct list_test_struct {
14ea2dd7c0SDavid Gow 	int data;
15ea2dd7c0SDavid Gow 	struct list_head list;
16ea2dd7c0SDavid Gow };
17ea2dd7c0SDavid Gow 
list_test_list_init(struct kunit * test)18ea2dd7c0SDavid Gow static void list_test_list_init(struct kunit *test)
19ea2dd7c0SDavid Gow {
20ea2dd7c0SDavid Gow 	/* Test the different ways of initialising a list. */
21ea2dd7c0SDavid Gow 	struct list_head list1 = LIST_HEAD_INIT(list1);
22ea2dd7c0SDavid Gow 	struct list_head list2;
23ea2dd7c0SDavid Gow 	LIST_HEAD(list3);
24ea2dd7c0SDavid Gow 	struct list_head *list4;
25ea2dd7c0SDavid Gow 	struct list_head *list5;
26ea2dd7c0SDavid Gow 
27ea2dd7c0SDavid Gow 	INIT_LIST_HEAD(&list2);
28ea2dd7c0SDavid Gow 
29ea2dd7c0SDavid Gow 	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
30ea2dd7c0SDavid Gow 	INIT_LIST_HEAD(list4);
31ea2dd7c0SDavid Gow 
32ea2dd7c0SDavid Gow 	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
33ea2dd7c0SDavid Gow 	memset(list5, 0xFF, sizeof(*list5));
34ea2dd7c0SDavid Gow 	INIT_LIST_HEAD(list5);
35ea2dd7c0SDavid Gow 
36ea2dd7c0SDavid Gow 	/* list_empty_careful() checks both next and prev. */
37ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list1));
38ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
39ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list3));
40ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(list4));
41ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(list5));
42ea2dd7c0SDavid Gow 
43ea2dd7c0SDavid Gow 	kfree(list4);
44ea2dd7c0SDavid Gow 	kfree(list5);
45ea2dd7c0SDavid Gow }
46ea2dd7c0SDavid Gow 
list_test_list_add(struct kunit * test)47ea2dd7c0SDavid Gow static void list_test_list_add(struct kunit *test)
48ea2dd7c0SDavid Gow {
49ea2dd7c0SDavid Gow 	struct list_head a, b;
50ea2dd7c0SDavid Gow 	LIST_HEAD(list);
51ea2dd7c0SDavid Gow 
52ea2dd7c0SDavid Gow 	list_add(&a, &list);
53ea2dd7c0SDavid Gow 	list_add(&b, &list);
54ea2dd7c0SDavid Gow 
55ea2dd7c0SDavid Gow 	/* should be [list] -> b -> a */
56ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
57ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
58ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
59ea2dd7c0SDavid Gow }
60ea2dd7c0SDavid Gow 
list_test_list_add_tail(struct kunit * test)61ea2dd7c0SDavid Gow static void list_test_list_add_tail(struct kunit *test)
62ea2dd7c0SDavid Gow {
63ea2dd7c0SDavid Gow 	struct list_head a, b;
64ea2dd7c0SDavid Gow 	LIST_HEAD(list);
65ea2dd7c0SDavid Gow 
66ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
67ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
68ea2dd7c0SDavid Gow 
69ea2dd7c0SDavid Gow 	/* should be [list] -> a -> b */
70ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &a);
71ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.prev, &list);
72ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.next, &b);
73ea2dd7c0SDavid Gow }
74ea2dd7c0SDavid Gow 
list_test_list_del(struct kunit * test)75ea2dd7c0SDavid Gow static void list_test_list_del(struct kunit *test)
76ea2dd7c0SDavid Gow {
77ea2dd7c0SDavid Gow 	struct list_head a, b;
78ea2dd7c0SDavid Gow 	LIST_HEAD(list);
79ea2dd7c0SDavid Gow 
80ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
81ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
82ea2dd7c0SDavid Gow 
83ea2dd7c0SDavid Gow 	/* before: [list] -> a -> b */
84ea2dd7c0SDavid Gow 	list_del(&a);
85ea2dd7c0SDavid Gow 
86ea2dd7c0SDavid Gow 	/* now: [list] -> b */
87ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
88ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
89ea2dd7c0SDavid Gow }
90ea2dd7c0SDavid Gow 
list_test_list_replace(struct kunit * test)91ea2dd7c0SDavid Gow static void list_test_list_replace(struct kunit *test)
92ea2dd7c0SDavid Gow {
93ea2dd7c0SDavid Gow 	struct list_head a_old, a_new, b;
94ea2dd7c0SDavid Gow 	LIST_HEAD(list);
95ea2dd7c0SDavid Gow 
96ea2dd7c0SDavid Gow 	list_add_tail(&a_old, &list);
97ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
98ea2dd7c0SDavid Gow 
99ea2dd7c0SDavid Gow 	/* before: [list] -> a_old -> b */
100ea2dd7c0SDavid Gow 	list_replace(&a_old, &a_new);
101ea2dd7c0SDavid Gow 
102ea2dd7c0SDavid Gow 	/* now: [list] -> a_new -> b */
103ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
104ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
105ea2dd7c0SDavid Gow }
106ea2dd7c0SDavid Gow 
list_test_list_replace_init(struct kunit * test)107ea2dd7c0SDavid Gow static void list_test_list_replace_init(struct kunit *test)
108ea2dd7c0SDavid Gow {
109ea2dd7c0SDavid Gow 	struct list_head a_old, a_new, b;
110ea2dd7c0SDavid Gow 	LIST_HEAD(list);
111ea2dd7c0SDavid Gow 
112ea2dd7c0SDavid Gow 	list_add_tail(&a_old, &list);
113ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
114ea2dd7c0SDavid Gow 
115ea2dd7c0SDavid Gow 	/* before: [list] -> a_old -> b */
116ea2dd7c0SDavid Gow 	list_replace_init(&a_old, &a_new);
117ea2dd7c0SDavid Gow 
118ea2dd7c0SDavid Gow 	/* now: [list] -> a_new -> b */
119ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
120ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
121ea2dd7c0SDavid Gow 
122ea2dd7c0SDavid Gow 	/* check a_old is empty (initialized) */
123ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a_old));
124ea2dd7c0SDavid Gow }
125ea2dd7c0SDavid Gow 
list_test_list_swap(struct kunit * test)126ea2dd7c0SDavid Gow static void list_test_list_swap(struct kunit *test)
127ea2dd7c0SDavid Gow {
128ea2dd7c0SDavid Gow 	struct list_head a, b;
129ea2dd7c0SDavid Gow 	LIST_HEAD(list);
130ea2dd7c0SDavid Gow 
131ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
132ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
133ea2dd7c0SDavid Gow 
134ea2dd7c0SDavid Gow 	/* before: [list] -> a -> b */
135ea2dd7c0SDavid Gow 	list_swap(&a, &b);
136ea2dd7c0SDavid Gow 
137ea2dd7c0SDavid Gow 	/* after: [list] -> b -> a */
138ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &b, list.next);
139ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &a, list.prev);
140ea2dd7c0SDavid Gow 
141ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
142ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &list, b.prev);
143ea2dd7c0SDavid Gow 
144ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &list, a.next);
145ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &b, a.prev);
146ea2dd7c0SDavid Gow }
147ea2dd7c0SDavid Gow 
list_test_list_del_init(struct kunit * test)148ea2dd7c0SDavid Gow static void list_test_list_del_init(struct kunit *test)
149ea2dd7c0SDavid Gow {
150ea2dd7c0SDavid Gow 	struct list_head a, b;
151ea2dd7c0SDavid Gow 	LIST_HEAD(list);
152ea2dd7c0SDavid Gow 
153ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
154ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
155ea2dd7c0SDavid Gow 
156ea2dd7c0SDavid Gow 	/* before: [list] -> a -> b */
157ea2dd7c0SDavid Gow 	list_del_init(&a);
158ea2dd7c0SDavid Gow 	/* after: [list] -> b, a initialised */
159ea2dd7c0SDavid Gow 
160ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
161ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
162ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
163ea2dd7c0SDavid Gow }
164ea2dd7c0SDavid Gow 
list_test_list_del_init_careful(struct kunit * test)165d7fd696cSDavid Gow static void list_test_list_del_init_careful(struct kunit *test)
166d7fd696cSDavid Gow {
167d7fd696cSDavid Gow 	/* NOTE: This test only checks the behaviour of this function in
168d7fd696cSDavid Gow 	 * isolation. It does not verify memory model guarantees.
169d7fd696cSDavid Gow 	 */
170d7fd696cSDavid Gow 	struct list_head a, b;
171d7fd696cSDavid Gow 	LIST_HEAD(list);
172d7fd696cSDavid Gow 
173d7fd696cSDavid Gow 	list_add_tail(&a, &list);
174d7fd696cSDavid Gow 	list_add_tail(&b, &list);
175d7fd696cSDavid Gow 
176d7fd696cSDavid Gow 	/* before: [list] -> a -> b */
177d7fd696cSDavid Gow 	list_del_init_careful(&a);
178d7fd696cSDavid Gow 	/* after: [list] -> b, a initialised */
179d7fd696cSDavid Gow 
180d7fd696cSDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
181d7fd696cSDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
182d7fd696cSDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
183d7fd696cSDavid Gow }
184d7fd696cSDavid Gow 
list_test_list_move(struct kunit * test)185ea2dd7c0SDavid Gow static void list_test_list_move(struct kunit *test)
186ea2dd7c0SDavid Gow {
187ea2dd7c0SDavid Gow 	struct list_head a, b;
188ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
189ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
190ea2dd7c0SDavid Gow 
191ea2dd7c0SDavid Gow 	list_add_tail(&a, &list1);
192ea2dd7c0SDavid Gow 	list_add_tail(&b, &list2);
193ea2dd7c0SDavid Gow 
194ea2dd7c0SDavid Gow 	/* before: [list1] -> a, [list2] -> b */
195ea2dd7c0SDavid Gow 	list_move(&a, &list2);
196ea2dd7c0SDavid Gow 	/* after: [list1] empty, [list2] -> a -> b */
197ea2dd7c0SDavid Gow 
198ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
199ea2dd7c0SDavid Gow 
200ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &a, list2.next);
201ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &b, a.next);
202ea2dd7c0SDavid Gow }
203ea2dd7c0SDavid Gow 
list_test_list_move_tail(struct kunit * test)204ea2dd7c0SDavid Gow static void list_test_list_move_tail(struct kunit *test)
205ea2dd7c0SDavid Gow {
206ea2dd7c0SDavid Gow 	struct list_head a, b;
207ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
208ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
209ea2dd7c0SDavid Gow 
210ea2dd7c0SDavid Gow 	list_add_tail(&a, &list1);
211ea2dd7c0SDavid Gow 	list_add_tail(&b, &list2);
212ea2dd7c0SDavid Gow 
213ea2dd7c0SDavid Gow 	/* before: [list1] -> a, [list2] -> b */
214ea2dd7c0SDavid Gow 	list_move_tail(&a, &list2);
215ea2dd7c0SDavid Gow 	/* after: [list1] empty, [list2] -> b -> a */
216ea2dd7c0SDavid Gow 
217ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
218ea2dd7c0SDavid Gow 
219ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &b, list2.next);
220ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
221ea2dd7c0SDavid Gow }
222ea2dd7c0SDavid Gow 
list_test_list_bulk_move_tail(struct kunit * test)223ea2dd7c0SDavid Gow static void list_test_list_bulk_move_tail(struct kunit *test)
224ea2dd7c0SDavid Gow {
225ea2dd7c0SDavid Gow 	struct list_head a, b, c, d, x, y;
226ea2dd7c0SDavid Gow 	struct list_head *list1_values[] = { &x, &b, &c, &y };
227ea2dd7c0SDavid Gow 	struct list_head *list2_values[] = { &a, &d };
228ea2dd7c0SDavid Gow 	struct list_head *ptr;
229ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
230ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
231ea2dd7c0SDavid Gow 	int i = 0;
232ea2dd7c0SDavid Gow 
233ea2dd7c0SDavid Gow 	list_add_tail(&x, &list1);
234ea2dd7c0SDavid Gow 	list_add_tail(&y, &list1);
235ea2dd7c0SDavid Gow 
236ea2dd7c0SDavid Gow 	list_add_tail(&a, &list2);
237ea2dd7c0SDavid Gow 	list_add_tail(&b, &list2);
238ea2dd7c0SDavid Gow 	list_add_tail(&c, &list2);
239ea2dd7c0SDavid Gow 	list_add_tail(&d, &list2);
240ea2dd7c0SDavid Gow 
241ea2dd7c0SDavid Gow 	/* before: [list1] -> x -> y, [list2] -> a -> b -> c -> d */
242ea2dd7c0SDavid Gow 	list_bulk_move_tail(&y, &b, &c);
243ea2dd7c0SDavid Gow 	/* after: [list1] -> x -> b -> c -> y, [list2] -> a -> d */
244ea2dd7c0SDavid Gow 
245ea2dd7c0SDavid Gow 	list_for_each(ptr, &list1) {
246ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, ptr, list1_values[i]);
247ea2dd7c0SDavid Gow 		i++;
248ea2dd7c0SDavid Gow 	}
249ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 4);
250ea2dd7c0SDavid Gow 	i = 0;
251ea2dd7c0SDavid Gow 	list_for_each(ptr, &list2) {
252ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, ptr, list2_values[i]);
253ea2dd7c0SDavid Gow 		i++;
254ea2dd7c0SDavid Gow 	}
255ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 2);
256ea2dd7c0SDavid Gow }
257ea2dd7c0SDavid Gow 
list_test_list_is_head(struct kunit * test)25837dc573cSDavid Gow static void list_test_list_is_head(struct kunit *test)
25937dc573cSDavid Gow {
26037dc573cSDavid Gow 	struct list_head a, b, c;
26137dc573cSDavid Gow 
26237dc573cSDavid Gow 	/* Two lists: [a] -> b, [c] */
26337dc573cSDavid Gow 	INIT_LIST_HEAD(&a);
26437dc573cSDavid Gow 	INIT_LIST_HEAD(&c);
26537dc573cSDavid Gow 	list_add_tail(&b, &a);
26637dc573cSDavid Gow 
26737dc573cSDavid Gow 	KUNIT_EXPECT_TRUE_MSG(test, list_is_head(&a, &a),
26837dc573cSDavid Gow 		"Head element of same list");
26937dc573cSDavid Gow 	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &b),
27037dc573cSDavid Gow 		"Non-head element of same list");
27137dc573cSDavid Gow 	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &c),
27237dc573cSDavid Gow 		"Head element of different list");
27337dc573cSDavid Gow }
27437dc573cSDavid Gow 
27537dc573cSDavid Gow 
list_test_list_is_first(struct kunit * test)276ea2dd7c0SDavid Gow static void list_test_list_is_first(struct kunit *test)
277ea2dd7c0SDavid Gow {
278ea2dd7c0SDavid Gow 	struct list_head a, b;
279ea2dd7c0SDavid Gow 	LIST_HEAD(list);
280ea2dd7c0SDavid Gow 
281ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
282ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
283ea2dd7c0SDavid Gow 
284ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_is_first(&a, &list));
285ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_is_first(&b, &list));
286ea2dd7c0SDavid Gow }
287ea2dd7c0SDavid Gow 
list_test_list_is_last(struct kunit * test)288ea2dd7c0SDavid Gow static void list_test_list_is_last(struct kunit *test)
289ea2dd7c0SDavid Gow {
290ea2dd7c0SDavid Gow 	struct list_head a, b;
291ea2dd7c0SDavid Gow 	LIST_HEAD(list);
292ea2dd7c0SDavid Gow 
293ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
294ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
295ea2dd7c0SDavid Gow 
296ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_is_last(&a, &list));
297ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_is_last(&b, &list));
298ea2dd7c0SDavid Gow }
299ea2dd7c0SDavid Gow 
list_test_list_empty(struct kunit * test)300ea2dd7c0SDavid Gow static void list_test_list_empty(struct kunit *test)
301ea2dd7c0SDavid Gow {
302ea2dd7c0SDavid Gow 	struct list_head a;
303ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
304ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
305ea2dd7c0SDavid Gow 
306ea2dd7c0SDavid Gow 	list_add_tail(&a, &list1);
307ea2dd7c0SDavid Gow 
308ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_empty(&list1));
309ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty(&list2));
310ea2dd7c0SDavid Gow }
311ea2dd7c0SDavid Gow 
list_test_list_empty_careful(struct kunit * test)312ea2dd7c0SDavid Gow static void list_test_list_empty_careful(struct kunit *test)
313ea2dd7c0SDavid Gow {
314ea2dd7c0SDavid Gow 	/* This test doesn't check correctness under concurrent access */
315ea2dd7c0SDavid Gow 	struct list_head a;
316ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
317ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
318ea2dd7c0SDavid Gow 
319ea2dd7c0SDavid Gow 	list_add_tail(&a, &list1);
320ea2dd7c0SDavid Gow 
321ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_empty_careful(&list1));
322ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
323ea2dd7c0SDavid Gow }
324ea2dd7c0SDavid Gow 
list_test_list_rotate_left(struct kunit * test)325ea2dd7c0SDavid Gow static void list_test_list_rotate_left(struct kunit *test)
326ea2dd7c0SDavid Gow {
327ea2dd7c0SDavid Gow 	struct list_head a, b;
328ea2dd7c0SDavid Gow 	LIST_HEAD(list);
329ea2dd7c0SDavid Gow 
330ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
331ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
332ea2dd7c0SDavid Gow 
333ea2dd7c0SDavid Gow 	/* before: [list] -> a -> b */
334ea2dd7c0SDavid Gow 	list_rotate_left(&list);
335ea2dd7c0SDavid Gow 	/* after: [list] -> b -> a */
336ea2dd7c0SDavid Gow 
337ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
338ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
339ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
340ea2dd7c0SDavid Gow }
341ea2dd7c0SDavid Gow 
list_test_list_rotate_to_front(struct kunit * test)342ea2dd7c0SDavid Gow static void list_test_list_rotate_to_front(struct kunit *test)
343ea2dd7c0SDavid Gow {
344ea2dd7c0SDavid Gow 	struct list_head a, b, c, d;
345ea2dd7c0SDavid Gow 	struct list_head *list_values[] = { &c, &d, &a, &b };
346ea2dd7c0SDavid Gow 	struct list_head *ptr;
347ea2dd7c0SDavid Gow 	LIST_HEAD(list);
348ea2dd7c0SDavid Gow 	int i = 0;
349ea2dd7c0SDavid Gow 
350ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
351ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
352ea2dd7c0SDavid Gow 	list_add_tail(&c, &list);
353ea2dd7c0SDavid Gow 	list_add_tail(&d, &list);
354ea2dd7c0SDavid Gow 
355ea2dd7c0SDavid Gow 	/* before: [list] -> a -> b -> c -> d */
356ea2dd7c0SDavid Gow 	list_rotate_to_front(&c, &list);
357ea2dd7c0SDavid Gow 	/* after: [list] -> c -> d -> a -> b */
358ea2dd7c0SDavid Gow 
359ea2dd7c0SDavid Gow 	list_for_each(ptr, &list) {
360ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, ptr, list_values[i]);
361ea2dd7c0SDavid Gow 		i++;
362ea2dd7c0SDavid Gow 	}
363ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 4);
364ea2dd7c0SDavid Gow }
365ea2dd7c0SDavid Gow 
list_test_list_is_singular(struct kunit * test)366ea2dd7c0SDavid Gow static void list_test_list_is_singular(struct kunit *test)
367ea2dd7c0SDavid Gow {
368ea2dd7c0SDavid Gow 	struct list_head a, b;
369ea2dd7c0SDavid Gow 	LIST_HEAD(list);
370ea2dd7c0SDavid Gow 
371ea2dd7c0SDavid Gow 	/* [list] empty */
372ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
373ea2dd7c0SDavid Gow 
374ea2dd7c0SDavid Gow 	list_add_tail(&a, &list);
375ea2dd7c0SDavid Gow 
376ea2dd7c0SDavid Gow 	/* [list] -> a */
377ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_is_singular(&list));
378ea2dd7c0SDavid Gow 
379ea2dd7c0SDavid Gow 	list_add_tail(&b, &list);
380ea2dd7c0SDavid Gow 
381ea2dd7c0SDavid Gow 	/* [list] -> a -> b */
382ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
383ea2dd7c0SDavid Gow }
384ea2dd7c0SDavid Gow 
list_test_list_cut_position(struct kunit * test)385ea2dd7c0SDavid Gow static void list_test_list_cut_position(struct kunit *test)
386ea2dd7c0SDavid Gow {
387ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur;
388ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
389ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
390ea2dd7c0SDavid Gow 	int i = 0;
391ea2dd7c0SDavid Gow 
392ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
393ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
394ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list1);
395ea2dd7c0SDavid Gow 
396ea2dd7c0SDavid Gow 	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
397ea2dd7c0SDavid Gow 	list_cut_position(&list2, &list1, &entries[1]);
398ea2dd7c0SDavid Gow 	/* after: [list2] -> entries[0] -> entries[1], [list1] -> entries[2] */
399ea2dd7c0SDavid Gow 
400ea2dd7c0SDavid Gow 	list_for_each(cur, &list2) {
401ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
402ea2dd7c0SDavid Gow 		i++;
403ea2dd7c0SDavid Gow 	}
404ea2dd7c0SDavid Gow 
405ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 2);
406ea2dd7c0SDavid Gow 
407ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
408ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
409ea2dd7c0SDavid Gow 		i++;
410ea2dd7c0SDavid Gow 	}
411ea2dd7c0SDavid Gow }
412ea2dd7c0SDavid Gow 
list_test_list_cut_before(struct kunit * test)413ea2dd7c0SDavid Gow static void list_test_list_cut_before(struct kunit *test)
414ea2dd7c0SDavid Gow {
415ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur;
416ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
417ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
418ea2dd7c0SDavid Gow 	int i = 0;
419ea2dd7c0SDavid Gow 
420ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
421ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
422ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list1);
423ea2dd7c0SDavid Gow 
424ea2dd7c0SDavid Gow 	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
425ea2dd7c0SDavid Gow 	list_cut_before(&list2, &list1, &entries[1]);
426ea2dd7c0SDavid Gow 	/* after: [list2] -> entries[0], [list1] -> entries[1] -> entries[2] */
427ea2dd7c0SDavid Gow 
428ea2dd7c0SDavid Gow 	list_for_each(cur, &list2) {
429ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
430ea2dd7c0SDavid Gow 		i++;
431ea2dd7c0SDavid Gow 	}
432ea2dd7c0SDavid Gow 
433ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 1);
434ea2dd7c0SDavid Gow 
435ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
436ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
437ea2dd7c0SDavid Gow 		i++;
438ea2dd7c0SDavid Gow 	}
439ea2dd7c0SDavid Gow }
440ea2dd7c0SDavid Gow 
list_test_list_splice(struct kunit * test)441ea2dd7c0SDavid Gow static void list_test_list_splice(struct kunit *test)
442ea2dd7c0SDavid Gow {
443ea2dd7c0SDavid Gow 	struct list_head entries[5], *cur;
444ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
445ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
446ea2dd7c0SDavid Gow 	int i = 0;
447ea2dd7c0SDavid Gow 
448ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
449ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
450ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list2);
451ea2dd7c0SDavid Gow 	list_add_tail(&entries[3], &list2);
452ea2dd7c0SDavid Gow 	list_add_tail(&entries[4], &list1);
453ea2dd7c0SDavid Gow 
454ea2dd7c0SDavid Gow 	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
455ea2dd7c0SDavid Gow 	list_splice(&list2, &entries[1]);
456ea2dd7c0SDavid Gow 	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
457ea2dd7c0SDavid Gow 
458ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
459ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
460ea2dd7c0SDavid Gow 		i++;
461ea2dd7c0SDavid Gow 	}
462ea2dd7c0SDavid Gow 
463ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
464ea2dd7c0SDavid Gow }
465ea2dd7c0SDavid Gow 
list_test_list_splice_tail(struct kunit * test)466ea2dd7c0SDavid Gow static void list_test_list_splice_tail(struct kunit *test)
467ea2dd7c0SDavid Gow {
468ea2dd7c0SDavid Gow 	struct list_head entries[5], *cur;
469ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
470ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
471ea2dd7c0SDavid Gow 	int i = 0;
472ea2dd7c0SDavid Gow 
473ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
474ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
475ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list2);
476ea2dd7c0SDavid Gow 	list_add_tail(&entries[3], &list2);
477ea2dd7c0SDavid Gow 	list_add_tail(&entries[4], &list1);
478ea2dd7c0SDavid Gow 
479ea2dd7c0SDavid Gow 	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
480ea2dd7c0SDavid Gow 	list_splice_tail(&list2, &entries[4]);
481ea2dd7c0SDavid Gow 	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
482ea2dd7c0SDavid Gow 
483ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
484ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
485ea2dd7c0SDavid Gow 		i++;
486ea2dd7c0SDavid Gow 	}
487ea2dd7c0SDavid Gow 
488ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
489ea2dd7c0SDavid Gow }
490ea2dd7c0SDavid Gow 
list_test_list_splice_init(struct kunit * test)491ea2dd7c0SDavid Gow static void list_test_list_splice_init(struct kunit *test)
492ea2dd7c0SDavid Gow {
493ea2dd7c0SDavid Gow 	struct list_head entries[5], *cur;
494ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
495ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
496ea2dd7c0SDavid Gow 	int i = 0;
497ea2dd7c0SDavid Gow 
498ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
499ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
500ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list2);
501ea2dd7c0SDavid Gow 	list_add_tail(&entries[3], &list2);
502ea2dd7c0SDavid Gow 	list_add_tail(&entries[4], &list1);
503ea2dd7c0SDavid Gow 
504ea2dd7c0SDavid Gow 	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
505ea2dd7c0SDavid Gow 	list_splice_init(&list2, &entries[1]);
506ea2dd7c0SDavid Gow 	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
507ea2dd7c0SDavid Gow 
508ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
509ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
510ea2dd7c0SDavid Gow 		i++;
511ea2dd7c0SDavid Gow 	}
512ea2dd7c0SDavid Gow 
513ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
514ea2dd7c0SDavid Gow 
515ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
516ea2dd7c0SDavid Gow }
517ea2dd7c0SDavid Gow 
list_test_list_splice_tail_init(struct kunit * test)518ea2dd7c0SDavid Gow static void list_test_list_splice_tail_init(struct kunit *test)
519ea2dd7c0SDavid Gow {
520ea2dd7c0SDavid Gow 	struct list_head entries[5], *cur;
521ea2dd7c0SDavid Gow 	LIST_HEAD(list1);
522ea2dd7c0SDavid Gow 	LIST_HEAD(list2);
523ea2dd7c0SDavid Gow 	int i = 0;
524ea2dd7c0SDavid Gow 
525ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list1);
526ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list1);
527ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list2);
528ea2dd7c0SDavid Gow 	list_add_tail(&entries[3], &list2);
529ea2dd7c0SDavid Gow 	list_add_tail(&entries[4], &list1);
530ea2dd7c0SDavid Gow 
531ea2dd7c0SDavid Gow 	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
532ea2dd7c0SDavid Gow 	list_splice_tail_init(&list2, &entries[4]);
533ea2dd7c0SDavid Gow 	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
534ea2dd7c0SDavid Gow 
535ea2dd7c0SDavid Gow 	list_for_each(cur, &list1) {
536ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
537ea2dd7c0SDavid Gow 		i++;
538ea2dd7c0SDavid Gow 	}
539ea2dd7c0SDavid Gow 
540ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
541ea2dd7c0SDavid Gow 
542ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
543ea2dd7c0SDavid Gow }
544ea2dd7c0SDavid Gow 
list_test_list_entry(struct kunit * test)545ea2dd7c0SDavid Gow static void list_test_list_entry(struct kunit *test)
546ea2dd7c0SDavid Gow {
547ea2dd7c0SDavid Gow 	struct list_test_struct test_struct;
548ea2dd7c0SDavid Gow 
549ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct, list_entry(&(test_struct.list),
550ea2dd7c0SDavid Gow 				struct list_test_struct, list));
551ea2dd7c0SDavid Gow }
552ea2dd7c0SDavid Gow 
list_test_list_entry_is_head(struct kunit * test)5535debe5bfSDavid Gow static void list_test_list_entry_is_head(struct kunit *test)
5545debe5bfSDavid Gow {
5555debe5bfSDavid Gow 	struct list_test_struct test_struct1, test_struct2, test_struct3;
5565debe5bfSDavid Gow 
5575debe5bfSDavid Gow 	INIT_LIST_HEAD(&test_struct1.list);
5585debe5bfSDavid Gow 	INIT_LIST_HEAD(&test_struct3.list);
5595debe5bfSDavid Gow 
5605debe5bfSDavid Gow 	list_add_tail(&test_struct2.list, &test_struct1.list);
5615debe5bfSDavid Gow 
5625debe5bfSDavid Gow 	KUNIT_EXPECT_TRUE_MSG(test,
5635debe5bfSDavid Gow 		list_entry_is_head((&test_struct1), &test_struct1.list, list),
5645debe5bfSDavid Gow 		"Head element of same list");
5655debe5bfSDavid Gow 	KUNIT_EXPECT_FALSE_MSG(test,
5665debe5bfSDavid Gow 		list_entry_is_head((&test_struct2), &test_struct1.list, list),
5675debe5bfSDavid Gow 		"Non-head element of same list");
5685debe5bfSDavid Gow 	KUNIT_EXPECT_FALSE_MSG(test,
5695debe5bfSDavid Gow 		list_entry_is_head((&test_struct3), &test_struct1.list, list),
5705debe5bfSDavid Gow 		"Head element of different list");
5715debe5bfSDavid Gow }
5725debe5bfSDavid Gow 
list_test_list_first_entry(struct kunit * test)573ea2dd7c0SDavid Gow static void list_test_list_first_entry(struct kunit *test)
574ea2dd7c0SDavid Gow {
575ea2dd7c0SDavid Gow 	struct list_test_struct test_struct1, test_struct2;
576ea2dd7c0SDavid Gow 	LIST_HEAD(list);
577ea2dd7c0SDavid Gow 
578ea2dd7c0SDavid Gow 	list_add_tail(&test_struct1.list, &list);
579ea2dd7c0SDavid Gow 	list_add_tail(&test_struct2.list, &list);
580ea2dd7c0SDavid Gow 
581ea2dd7c0SDavid Gow 
582ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_first_entry(&list,
583ea2dd7c0SDavid Gow 				struct list_test_struct, list));
584ea2dd7c0SDavid Gow }
585ea2dd7c0SDavid Gow 
list_test_list_last_entry(struct kunit * test)586ea2dd7c0SDavid Gow static void list_test_list_last_entry(struct kunit *test)
587ea2dd7c0SDavid Gow {
588ea2dd7c0SDavid Gow 	struct list_test_struct test_struct1, test_struct2;
589ea2dd7c0SDavid Gow 	LIST_HEAD(list);
590ea2dd7c0SDavid Gow 
591ea2dd7c0SDavid Gow 	list_add_tail(&test_struct1.list, &list);
592ea2dd7c0SDavid Gow 	list_add_tail(&test_struct2.list, &list);
593ea2dd7c0SDavid Gow 
594ea2dd7c0SDavid Gow 
595ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_last_entry(&list,
596ea2dd7c0SDavid Gow 				struct list_test_struct, list));
597ea2dd7c0SDavid Gow }
598ea2dd7c0SDavid Gow 
list_test_list_first_entry_or_null(struct kunit * test)599ea2dd7c0SDavid Gow static void list_test_list_first_entry_or_null(struct kunit *test)
600ea2dd7c0SDavid Gow {
601ea2dd7c0SDavid Gow 	struct list_test_struct test_struct1, test_struct2;
602ea2dd7c0SDavid Gow 	LIST_HEAD(list);
603ea2dd7c0SDavid Gow 
604ea2dd7c0SDavid Gow 	KUNIT_EXPECT_FALSE(test, list_first_entry_or_null(&list,
605ea2dd7c0SDavid Gow 				struct list_test_struct, list));
606ea2dd7c0SDavid Gow 
607ea2dd7c0SDavid Gow 	list_add_tail(&test_struct1.list, &list);
608ea2dd7c0SDavid Gow 	list_add_tail(&test_struct2.list, &list);
609ea2dd7c0SDavid Gow 
610ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct1,
611ea2dd7c0SDavid Gow 			list_first_entry_or_null(&list,
612ea2dd7c0SDavid Gow 				struct list_test_struct, list));
613ea2dd7c0SDavid Gow }
614ea2dd7c0SDavid Gow 
list_test_list_next_entry(struct kunit * test)615ea2dd7c0SDavid Gow static void list_test_list_next_entry(struct kunit *test)
616ea2dd7c0SDavid Gow {
617ea2dd7c0SDavid Gow 	struct list_test_struct test_struct1, test_struct2;
618ea2dd7c0SDavid Gow 	LIST_HEAD(list);
619ea2dd7c0SDavid Gow 
620ea2dd7c0SDavid Gow 	list_add_tail(&test_struct1.list, &list);
621ea2dd7c0SDavid Gow 	list_add_tail(&test_struct2.list, &list);
622ea2dd7c0SDavid Gow 
623ea2dd7c0SDavid Gow 
624ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_next_entry(&test_struct1,
625ea2dd7c0SDavid Gow 				list));
626ea2dd7c0SDavid Gow }
627ea2dd7c0SDavid Gow 
list_test_list_prev_entry(struct kunit * test)628ea2dd7c0SDavid Gow static void list_test_list_prev_entry(struct kunit *test)
629ea2dd7c0SDavid Gow {
630ea2dd7c0SDavid Gow 	struct list_test_struct test_struct1, test_struct2;
631ea2dd7c0SDavid Gow 	LIST_HEAD(list);
632ea2dd7c0SDavid Gow 
633ea2dd7c0SDavid Gow 	list_add_tail(&test_struct1.list, &list);
634ea2dd7c0SDavid Gow 	list_add_tail(&test_struct2.list, &list);
635ea2dd7c0SDavid Gow 
636ea2dd7c0SDavid Gow 
637ea2dd7c0SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_prev_entry(&test_struct2,
638ea2dd7c0SDavid Gow 				list));
639ea2dd7c0SDavid Gow }
640ea2dd7c0SDavid Gow 
list_test_list_for_each(struct kunit * test)641ea2dd7c0SDavid Gow static void list_test_list_for_each(struct kunit *test)
642ea2dd7c0SDavid Gow {
643ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur;
644ea2dd7c0SDavid Gow 	LIST_HEAD(list);
645ea2dd7c0SDavid Gow 	int i = 0;
646ea2dd7c0SDavid Gow 
647ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list);
648ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list);
649ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list);
650ea2dd7c0SDavid Gow 
651ea2dd7c0SDavid Gow 	list_for_each(cur, &list) {
652ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
653ea2dd7c0SDavid Gow 		i++;
654ea2dd7c0SDavid Gow 	}
655ea2dd7c0SDavid Gow 
656ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 3);
657ea2dd7c0SDavid Gow }
658ea2dd7c0SDavid Gow 
list_test_list_for_each_prev(struct kunit * test)659ea2dd7c0SDavid Gow static void list_test_list_for_each_prev(struct kunit *test)
660ea2dd7c0SDavid Gow {
661ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur;
662ea2dd7c0SDavid Gow 	LIST_HEAD(list);
663ea2dd7c0SDavid Gow 	int i = 2;
664ea2dd7c0SDavid Gow 
665ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list);
666ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list);
667ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list);
668ea2dd7c0SDavid Gow 
669ea2dd7c0SDavid Gow 	list_for_each_prev(cur, &list) {
670ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
671ea2dd7c0SDavid Gow 		i--;
672ea2dd7c0SDavid Gow 	}
673ea2dd7c0SDavid Gow 
674ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, -1);
675ea2dd7c0SDavid Gow }
676ea2dd7c0SDavid Gow 
list_test_list_for_each_safe(struct kunit * test)677ea2dd7c0SDavid Gow static void list_test_list_for_each_safe(struct kunit *test)
678ea2dd7c0SDavid Gow {
679ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur, *n;
680ea2dd7c0SDavid Gow 	LIST_HEAD(list);
681ea2dd7c0SDavid Gow 	int i = 0;
682ea2dd7c0SDavid Gow 
683ea2dd7c0SDavid Gow 
684ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list);
685ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list);
686ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list);
687ea2dd7c0SDavid Gow 
688ea2dd7c0SDavid Gow 	list_for_each_safe(cur, n, &list) {
689ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
690ea2dd7c0SDavid Gow 		list_del(&entries[i]);
691ea2dd7c0SDavid Gow 		i++;
692ea2dd7c0SDavid Gow 	}
693ea2dd7c0SDavid Gow 
694ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 3);
695ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty(&list));
696ea2dd7c0SDavid Gow }
697ea2dd7c0SDavid Gow 
list_test_list_for_each_prev_safe(struct kunit * test)698ea2dd7c0SDavid Gow static void list_test_list_for_each_prev_safe(struct kunit *test)
699ea2dd7c0SDavid Gow {
700ea2dd7c0SDavid Gow 	struct list_head entries[3], *cur, *n;
701ea2dd7c0SDavid Gow 	LIST_HEAD(list);
702ea2dd7c0SDavid Gow 	int i = 2;
703ea2dd7c0SDavid Gow 
704ea2dd7c0SDavid Gow 	list_add_tail(&entries[0], &list);
705ea2dd7c0SDavid Gow 	list_add_tail(&entries[1], &list);
706ea2dd7c0SDavid Gow 	list_add_tail(&entries[2], &list);
707ea2dd7c0SDavid Gow 
708ea2dd7c0SDavid Gow 	list_for_each_prev_safe(cur, n, &list) {
709ea2dd7c0SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
710ea2dd7c0SDavid Gow 		list_del(&entries[i]);
711ea2dd7c0SDavid Gow 		i--;
712ea2dd7c0SDavid Gow 	}
713ea2dd7c0SDavid Gow 
714ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, -1);
715ea2dd7c0SDavid Gow 	KUNIT_EXPECT_TRUE(test, list_empty(&list));
716ea2dd7c0SDavid Gow }
717ea2dd7c0SDavid Gow 
list_test_list_for_each_entry(struct kunit * test)718ea2dd7c0SDavid Gow static void list_test_list_for_each_entry(struct kunit *test)
719ea2dd7c0SDavid Gow {
720ea2dd7c0SDavid Gow 	struct list_test_struct entries[5], *cur;
721cb88577bSDavid Gow 	LIST_HEAD(list);
722ea2dd7c0SDavid Gow 	int i = 0;
723ea2dd7c0SDavid Gow 
724ea2dd7c0SDavid Gow 	for (i = 0; i < 5; ++i) {
725ea2dd7c0SDavid Gow 		entries[i].data = i;
726ea2dd7c0SDavid Gow 		list_add_tail(&entries[i].list, &list);
727ea2dd7c0SDavid Gow 	}
728ea2dd7c0SDavid Gow 
729ea2dd7c0SDavid Gow 	i = 0;
730ea2dd7c0SDavid Gow 
731ea2dd7c0SDavid Gow 	list_for_each_entry(cur, &list, list) {
732ea2dd7c0SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
733ea2dd7c0SDavid Gow 		i++;
734ea2dd7c0SDavid Gow 	}
735ea2dd7c0SDavid Gow 
736ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
737ea2dd7c0SDavid Gow }
738ea2dd7c0SDavid Gow 
list_test_list_for_each_entry_reverse(struct kunit * test)739ea2dd7c0SDavid Gow static void list_test_list_for_each_entry_reverse(struct kunit *test)
740ea2dd7c0SDavid Gow {
741ea2dd7c0SDavid Gow 	struct list_test_struct entries[5], *cur;
742cb88577bSDavid Gow 	LIST_HEAD(list);
743ea2dd7c0SDavid Gow 	int i = 0;
744ea2dd7c0SDavid Gow 
745ea2dd7c0SDavid Gow 	for (i = 0; i < 5; ++i) {
746ea2dd7c0SDavid Gow 		entries[i].data = i;
747ea2dd7c0SDavid Gow 		list_add_tail(&entries[i].list, &list);
748ea2dd7c0SDavid Gow 	}
749ea2dd7c0SDavid Gow 
750ea2dd7c0SDavid Gow 	i = 4;
751ea2dd7c0SDavid Gow 
752ea2dd7c0SDavid Gow 	list_for_each_entry_reverse(cur, &list, list) {
753ea2dd7c0SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
754ea2dd7c0SDavid Gow 		i--;
755ea2dd7c0SDavid Gow 	}
756ea2dd7c0SDavid Gow 
757ea2dd7c0SDavid Gow 	KUNIT_EXPECT_EQ(test, i, -1);
758ea2dd7c0SDavid Gow }
759ea2dd7c0SDavid Gow 
760ea2dd7c0SDavid Gow static struct kunit_case list_test_cases[] = {
761ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_init),
762ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_add),
763ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_add_tail),
764ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_del),
765ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_replace),
766ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_replace_init),
767ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_swap),
768ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_del_init),
769d7fd696cSDavid Gow 	KUNIT_CASE(list_test_list_del_init_careful),
770ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_move),
771ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_move_tail),
772ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_bulk_move_tail),
77337dc573cSDavid Gow 	KUNIT_CASE(list_test_list_is_head),
774ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_is_first),
775ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_is_last),
776ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_empty),
777ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_empty_careful),
778ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_rotate_left),
779ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_rotate_to_front),
780ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_is_singular),
781ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_cut_position),
782ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_cut_before),
783ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_splice),
784ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_splice_tail),
785ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_splice_init),
786ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_splice_tail_init),
787ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_entry),
7885debe5bfSDavid Gow 	KUNIT_CASE(list_test_list_entry_is_head),
789ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_first_entry),
790ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_last_entry),
791ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_first_entry_or_null),
792ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_next_entry),
793ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_prev_entry),
794ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each),
795ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each_prev),
796ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each_safe),
797ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each_prev_safe),
798ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each_entry),
799ea2dd7c0SDavid Gow 	KUNIT_CASE(list_test_list_for_each_entry_reverse),
800ea2dd7c0SDavid Gow 	{},
801ea2dd7c0SDavid Gow };
802ea2dd7c0SDavid Gow 
803ea2dd7c0SDavid Gow static struct kunit_suite list_test_module = {
804ea2dd7c0SDavid Gow 	.name = "list-kunit-test",
805ea2dd7c0SDavid Gow 	.test_cases = list_test_cases,
806ea2dd7c0SDavid Gow };
807ea2dd7c0SDavid Gow 
8081ff522b6SDavid Gow struct hlist_test_struct {
8091ff522b6SDavid Gow 	int data;
8101ff522b6SDavid Gow 	struct hlist_node list;
8111ff522b6SDavid Gow };
8121ff522b6SDavid Gow 
hlist_test_init(struct kunit * test)8131ff522b6SDavid Gow static void hlist_test_init(struct kunit *test)
8141ff522b6SDavid Gow {
8151ff522b6SDavid Gow 	/* Test the different ways of initialising a list. */
8161ff522b6SDavid Gow 	struct hlist_head list1 = HLIST_HEAD_INIT;
8171ff522b6SDavid Gow 	struct hlist_head list2;
8181ff522b6SDavid Gow 	HLIST_HEAD(list3);
8191ff522b6SDavid Gow 	struct hlist_head *list4;
8201ff522b6SDavid Gow 	struct hlist_head *list5;
8211ff522b6SDavid Gow 
8221ff522b6SDavid Gow 	INIT_HLIST_HEAD(&list2);
8231ff522b6SDavid Gow 
8241ff522b6SDavid Gow 	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
8251ff522b6SDavid Gow 	INIT_HLIST_HEAD(list4);
8261ff522b6SDavid Gow 
8271ff522b6SDavid Gow 	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
8281ff522b6SDavid Gow 	memset(list5, 0xFF, sizeof(*list5));
8291ff522b6SDavid Gow 	INIT_HLIST_HEAD(list5);
8301ff522b6SDavid Gow 
8311ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
8321ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
8331ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list3));
8341ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(list4));
8351ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(list5));
8361ff522b6SDavid Gow 
8371ff522b6SDavid Gow 	kfree(list4);
8381ff522b6SDavid Gow 	kfree(list5);
8391ff522b6SDavid Gow }
8401ff522b6SDavid Gow 
hlist_test_unhashed(struct kunit * test)8411ff522b6SDavid Gow static void hlist_test_unhashed(struct kunit *test)
8421ff522b6SDavid Gow {
8431ff522b6SDavid Gow 	struct hlist_node a;
8441ff522b6SDavid Gow 	HLIST_HEAD(list);
8451ff522b6SDavid Gow 
8461ff522b6SDavid Gow 	INIT_HLIST_NODE(&a);
8471ff522b6SDavid Gow 
8481ff522b6SDavid Gow 	/* is unhashed by default */
8491ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
8501ff522b6SDavid Gow 
8511ff522b6SDavid Gow 	hlist_add_head(&a, &list);
8521ff522b6SDavid Gow 
8531ff522b6SDavid Gow 	/* is hashed once added to list */
8541ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_unhashed(&a));
8551ff522b6SDavid Gow 
8561ff522b6SDavid Gow 	hlist_del_init(&a);
8571ff522b6SDavid Gow 
8581ff522b6SDavid Gow 	/* is again unhashed after del_init */
8591ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
8601ff522b6SDavid Gow }
8611ff522b6SDavid Gow 
8621ff522b6SDavid Gow /* Doesn't test concurrency guarantees */
hlist_test_unhashed_lockless(struct kunit * test)8631ff522b6SDavid Gow static void hlist_test_unhashed_lockless(struct kunit *test)
8641ff522b6SDavid Gow {
8651ff522b6SDavid Gow 	struct hlist_node a;
8661ff522b6SDavid Gow 	HLIST_HEAD(list);
8671ff522b6SDavid Gow 
8681ff522b6SDavid Gow 	INIT_HLIST_NODE(&a);
8691ff522b6SDavid Gow 
8701ff522b6SDavid Gow 	/* is unhashed by default */
8711ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
8721ff522b6SDavid Gow 
8731ff522b6SDavid Gow 	hlist_add_head(&a, &list);
8741ff522b6SDavid Gow 
8751ff522b6SDavid Gow 	/* is hashed once added to list */
8761ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_unhashed_lockless(&a));
8771ff522b6SDavid Gow 
8781ff522b6SDavid Gow 	hlist_del_init(&a);
8791ff522b6SDavid Gow 
8801ff522b6SDavid Gow 	/* is again unhashed after del_init */
8811ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
8821ff522b6SDavid Gow }
8831ff522b6SDavid Gow 
hlist_test_del(struct kunit * test)8841ff522b6SDavid Gow static void hlist_test_del(struct kunit *test)
8851ff522b6SDavid Gow {
8861ff522b6SDavid Gow 	struct hlist_node a, b;
8871ff522b6SDavid Gow 	HLIST_HEAD(list);
8881ff522b6SDavid Gow 
8891ff522b6SDavid Gow 	hlist_add_head(&a, &list);
8901ff522b6SDavid Gow 	hlist_add_behind(&b, &a);
8911ff522b6SDavid Gow 
8921ff522b6SDavid Gow 	/* before: [list] -> a -> b */
8931ff522b6SDavid Gow 	hlist_del(&a);
8941ff522b6SDavid Gow 
8951ff522b6SDavid Gow 	/* now: [list] -> b */
8961ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
8971ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
8981ff522b6SDavid Gow }
8991ff522b6SDavid Gow 
hlist_test_del_init(struct kunit * test)9001ff522b6SDavid Gow static void hlist_test_del_init(struct kunit *test)
9011ff522b6SDavid Gow {
9021ff522b6SDavid Gow 	struct hlist_node a, b;
9031ff522b6SDavid Gow 	HLIST_HEAD(list);
9041ff522b6SDavid Gow 
9051ff522b6SDavid Gow 	hlist_add_head(&a, &list);
9061ff522b6SDavid Gow 	hlist_add_behind(&b, &a);
9071ff522b6SDavid Gow 
9081ff522b6SDavid Gow 	/* before: [list] -> a -> b */
9091ff522b6SDavid Gow 	hlist_del_init(&a);
9101ff522b6SDavid Gow 
9111ff522b6SDavid Gow 	/* now: [list] -> b */
9121ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
9131ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
9141ff522b6SDavid Gow 
9151ff522b6SDavid Gow 	/* a is now initialised */
9161ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.next, NULL);
9171ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.pprev, NULL);
9181ff522b6SDavid Gow }
9191ff522b6SDavid Gow 
9201ff522b6SDavid Gow /* Tests all three hlist_add_* functions */
hlist_test_add(struct kunit * test)9211ff522b6SDavid Gow static void hlist_test_add(struct kunit *test)
9221ff522b6SDavid Gow {
9231ff522b6SDavid Gow 	struct hlist_node a, b, c, d;
9241ff522b6SDavid Gow 	HLIST_HEAD(list);
9251ff522b6SDavid Gow 
9261ff522b6SDavid Gow 	hlist_add_head(&a, &list);
9271ff522b6SDavid Gow 	hlist_add_head(&b, &list);
9281ff522b6SDavid Gow 	hlist_add_before(&c, &a);
9291ff522b6SDavid Gow 	hlist_add_behind(&d, &a);
9301ff522b6SDavid Gow 
9311ff522b6SDavid Gow 	/* should be [list] -> b -> c -> a -> d */
9321ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
9331ff522b6SDavid Gow 
9341ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, c.pprev, &(b.next));
9351ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, b.next, &c);
9361ff522b6SDavid Gow 
9371ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.pprev, &(c.next));
9381ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, c.next, &a);
9391ff522b6SDavid Gow 
9401ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, d.pprev, &(a.next));
9411ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, a.next, &d);
9421ff522b6SDavid Gow }
9431ff522b6SDavid Gow 
9441ff522b6SDavid Gow /* Tests both hlist_fake() and hlist_add_fake() */
hlist_test_fake(struct kunit * test)9451ff522b6SDavid Gow static void hlist_test_fake(struct kunit *test)
9461ff522b6SDavid Gow {
9471ff522b6SDavid Gow 	struct hlist_node a;
9481ff522b6SDavid Gow 
9491ff522b6SDavid Gow 	INIT_HLIST_NODE(&a);
9501ff522b6SDavid Gow 
9511ff522b6SDavid Gow 	/* not fake after init */
9521ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_fake(&a));
9531ff522b6SDavid Gow 
9541ff522b6SDavid Gow 	hlist_add_fake(&a);
9551ff522b6SDavid Gow 
9561ff522b6SDavid Gow 	/* is now fake */
9571ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_fake(&a));
9581ff522b6SDavid Gow }
9591ff522b6SDavid Gow 
hlist_test_is_singular_node(struct kunit * test)9601ff522b6SDavid Gow static void hlist_test_is_singular_node(struct kunit *test)
9611ff522b6SDavid Gow {
9621ff522b6SDavid Gow 	struct hlist_node a, b;
9631ff522b6SDavid Gow 	HLIST_HEAD(list);
9641ff522b6SDavid Gow 
9651ff522b6SDavid Gow 	INIT_HLIST_NODE(&a);
9661ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
9671ff522b6SDavid Gow 
9681ff522b6SDavid Gow 	hlist_add_head(&a, &list);
9691ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_is_singular_node(&a, &list));
9701ff522b6SDavid Gow 
9711ff522b6SDavid Gow 	hlist_add_head(&b, &list);
9721ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
9731ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&b, &list));
9741ff522b6SDavid Gow }
9751ff522b6SDavid Gow 
hlist_test_empty(struct kunit * test)9761ff522b6SDavid Gow static void hlist_test_empty(struct kunit *test)
9771ff522b6SDavid Gow {
9781ff522b6SDavid Gow 	struct hlist_node a;
9791ff522b6SDavid Gow 	HLIST_HEAD(list);
9801ff522b6SDavid Gow 
9811ff522b6SDavid Gow 	/* list starts off empty */
9821ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
9831ff522b6SDavid Gow 
9841ff522b6SDavid Gow 	hlist_add_head(&a, &list);
9851ff522b6SDavid Gow 
9861ff522b6SDavid Gow 	/* list is no longer empty */
9871ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_empty(&list));
9881ff522b6SDavid Gow }
9891ff522b6SDavid Gow 
hlist_test_move_list(struct kunit * test)9901ff522b6SDavid Gow static void hlist_test_move_list(struct kunit *test)
9911ff522b6SDavid Gow {
9921ff522b6SDavid Gow 	struct hlist_node a;
9931ff522b6SDavid Gow 	HLIST_HEAD(list1);
9941ff522b6SDavid Gow 	HLIST_HEAD(list2);
9951ff522b6SDavid Gow 
9961ff522b6SDavid Gow 	hlist_add_head(&a, &list1);
9971ff522b6SDavid Gow 
9981ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_empty(&list1));
9991ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
10001ff522b6SDavid Gow 	hlist_move_list(&list1, &list2);
10011ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
10021ff522b6SDavid Gow 	KUNIT_EXPECT_FALSE(test, hlist_empty(&list2));
10031ff522b6SDavid Gow 
10041ff522b6SDavid Gow }
10051ff522b6SDavid Gow 
hlist_test_entry(struct kunit * test)10061ff522b6SDavid Gow static void hlist_test_entry(struct kunit *test)
10071ff522b6SDavid Gow {
10081ff522b6SDavid Gow 	struct hlist_test_struct test_struct;
10091ff522b6SDavid Gow 
10101ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
10111ff522b6SDavid Gow 			    hlist_entry(&(test_struct.list),
10121ff522b6SDavid Gow 				struct hlist_test_struct, list));
10131ff522b6SDavid Gow }
10141ff522b6SDavid Gow 
hlist_test_entry_safe(struct kunit * test)10151ff522b6SDavid Gow static void hlist_test_entry_safe(struct kunit *test)
10161ff522b6SDavid Gow {
10171ff522b6SDavid Gow 	struct hlist_test_struct test_struct;
10181ff522b6SDavid Gow 
10191ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
10201ff522b6SDavid Gow 			    hlist_entry_safe(&(test_struct.list),
10211ff522b6SDavid Gow 				struct hlist_test_struct, list));
10221ff522b6SDavid Gow 
10231ff522b6SDavid Gow 	KUNIT_EXPECT_PTR_EQ(test, NULL,
10241ff522b6SDavid Gow 			    hlist_entry_safe((struct hlist_node *)NULL,
10251ff522b6SDavid Gow 				struct hlist_test_struct, list));
10261ff522b6SDavid Gow }
10271ff522b6SDavid Gow 
hlist_test_for_each(struct kunit * test)10281ff522b6SDavid Gow static void hlist_test_for_each(struct kunit *test)
10291ff522b6SDavid Gow {
10301ff522b6SDavid Gow 	struct hlist_node entries[3], *cur;
10311ff522b6SDavid Gow 	HLIST_HEAD(list);
10321ff522b6SDavid Gow 	int i = 0;
10331ff522b6SDavid Gow 
10341ff522b6SDavid Gow 	hlist_add_head(&entries[0], &list);
10351ff522b6SDavid Gow 	hlist_add_behind(&entries[1], &entries[0]);
10361ff522b6SDavid Gow 	hlist_add_behind(&entries[2], &entries[1]);
10371ff522b6SDavid Gow 
10381ff522b6SDavid Gow 	hlist_for_each(cur, &list) {
10391ff522b6SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
10401ff522b6SDavid Gow 		i++;
10411ff522b6SDavid Gow 	}
10421ff522b6SDavid Gow 
10431ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 3);
10441ff522b6SDavid Gow }
10451ff522b6SDavid Gow 
10461ff522b6SDavid Gow 
hlist_test_for_each_safe(struct kunit * test)10471ff522b6SDavid Gow static void hlist_test_for_each_safe(struct kunit *test)
10481ff522b6SDavid Gow {
10491ff522b6SDavid Gow 	struct hlist_node entries[3], *cur, *n;
10501ff522b6SDavid Gow 	HLIST_HEAD(list);
10511ff522b6SDavid Gow 	int i = 0;
10521ff522b6SDavid Gow 
10531ff522b6SDavid Gow 	hlist_add_head(&entries[0], &list);
10541ff522b6SDavid Gow 	hlist_add_behind(&entries[1], &entries[0]);
10551ff522b6SDavid Gow 	hlist_add_behind(&entries[2], &entries[1]);
10561ff522b6SDavid Gow 
10571ff522b6SDavid Gow 	hlist_for_each_safe(cur, n, &list) {
10581ff522b6SDavid Gow 		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
10591ff522b6SDavid Gow 		hlist_del(&entries[i]);
10601ff522b6SDavid Gow 		i++;
10611ff522b6SDavid Gow 	}
10621ff522b6SDavid Gow 
10631ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 3);
10641ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
10651ff522b6SDavid Gow }
10661ff522b6SDavid Gow 
hlist_test_for_each_entry(struct kunit * test)10671ff522b6SDavid Gow static void hlist_test_for_each_entry(struct kunit *test)
10681ff522b6SDavid Gow {
10691ff522b6SDavid Gow 	struct hlist_test_struct entries[5], *cur;
10701ff522b6SDavid Gow 	HLIST_HEAD(list);
10711ff522b6SDavid Gow 	int i = 0;
10721ff522b6SDavid Gow 
10731ff522b6SDavid Gow 	entries[0].data = 0;
10741ff522b6SDavid Gow 	hlist_add_head(&entries[0].list, &list);
10751ff522b6SDavid Gow 	for (i = 1; i < 5; ++i) {
10761ff522b6SDavid Gow 		entries[i].data = i;
10771ff522b6SDavid Gow 		hlist_add_behind(&entries[i].list, &entries[i-1].list);
10781ff522b6SDavid Gow 	}
10791ff522b6SDavid Gow 
10801ff522b6SDavid Gow 	i = 0;
10811ff522b6SDavid Gow 
10821ff522b6SDavid Gow 	hlist_for_each_entry(cur, &list, list) {
10831ff522b6SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
10841ff522b6SDavid Gow 		i++;
10851ff522b6SDavid Gow 	}
10861ff522b6SDavid Gow 
10871ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
10881ff522b6SDavid Gow }
10891ff522b6SDavid Gow 
hlist_test_for_each_entry_continue(struct kunit * test)10901ff522b6SDavid Gow static void hlist_test_for_each_entry_continue(struct kunit *test)
10911ff522b6SDavid Gow {
10921ff522b6SDavid Gow 	struct hlist_test_struct entries[5], *cur;
10931ff522b6SDavid Gow 	HLIST_HEAD(list);
10941ff522b6SDavid Gow 	int i = 0;
10951ff522b6SDavid Gow 
10961ff522b6SDavid Gow 	entries[0].data = 0;
10971ff522b6SDavid Gow 	hlist_add_head(&entries[0].list, &list);
10981ff522b6SDavid Gow 	for (i = 1; i < 5; ++i) {
10991ff522b6SDavid Gow 		entries[i].data = i;
11001ff522b6SDavid Gow 		hlist_add_behind(&entries[i].list, &entries[i-1].list);
11011ff522b6SDavid Gow 	}
11021ff522b6SDavid Gow 
11031ff522b6SDavid Gow 	/* We skip the first (zero-th) entry. */
11041ff522b6SDavid Gow 	i = 1;
11051ff522b6SDavid Gow 
11061ff522b6SDavid Gow 	cur = &entries[0];
11071ff522b6SDavid Gow 	hlist_for_each_entry_continue(cur, list) {
11081ff522b6SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
11091ff522b6SDavid Gow 		/* Stamp over the entry. */
11101ff522b6SDavid Gow 		cur->data = 42;
11111ff522b6SDavid Gow 		i++;
11121ff522b6SDavid Gow 	}
11131ff522b6SDavid Gow 
11141ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
11151ff522b6SDavid Gow 	/* The first entry was not visited. */
11161ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, entries[0].data, 0);
11171ff522b6SDavid Gow 	/* The second (and presumably others), were. */
11181ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, entries[1].data, 42);
11191ff522b6SDavid Gow }
11201ff522b6SDavid Gow 
hlist_test_for_each_entry_from(struct kunit * test)11211ff522b6SDavid Gow static void hlist_test_for_each_entry_from(struct kunit *test)
11221ff522b6SDavid Gow {
11231ff522b6SDavid Gow 	struct hlist_test_struct entries[5], *cur;
11241ff522b6SDavid Gow 	HLIST_HEAD(list);
11251ff522b6SDavid Gow 	int i = 0;
11261ff522b6SDavid Gow 
11271ff522b6SDavid Gow 	entries[0].data = 0;
11281ff522b6SDavid Gow 	hlist_add_head(&entries[0].list, &list);
11291ff522b6SDavid Gow 	for (i = 1; i < 5; ++i) {
11301ff522b6SDavid Gow 		entries[i].data = i;
11311ff522b6SDavid Gow 		hlist_add_behind(&entries[i].list, &entries[i-1].list);
11321ff522b6SDavid Gow 	}
11331ff522b6SDavid Gow 
11341ff522b6SDavid Gow 	i = 0;
11351ff522b6SDavid Gow 
11361ff522b6SDavid Gow 	cur = &entries[0];
11371ff522b6SDavid Gow 	hlist_for_each_entry_from(cur, list) {
11381ff522b6SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
11391ff522b6SDavid Gow 		/* Stamp over the entry. */
11401ff522b6SDavid Gow 		cur->data = 42;
11411ff522b6SDavid Gow 		i++;
11421ff522b6SDavid Gow 	}
11431ff522b6SDavid Gow 
11441ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
11451ff522b6SDavid Gow 	/* The first entry was visited. */
11461ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, entries[0].data, 42);
11471ff522b6SDavid Gow }
11481ff522b6SDavid Gow 
hlist_test_for_each_entry_safe(struct kunit * test)11491ff522b6SDavid Gow static void hlist_test_for_each_entry_safe(struct kunit *test)
11501ff522b6SDavid Gow {
11511ff522b6SDavid Gow 	struct hlist_test_struct entries[5], *cur;
11521ff522b6SDavid Gow 	struct hlist_node *tmp_node;
11531ff522b6SDavid Gow 	HLIST_HEAD(list);
11541ff522b6SDavid Gow 	int i = 0;
11551ff522b6SDavid Gow 
11561ff522b6SDavid Gow 	entries[0].data = 0;
11571ff522b6SDavid Gow 	hlist_add_head(&entries[0].list, &list);
11581ff522b6SDavid Gow 	for (i = 1; i < 5; ++i) {
11591ff522b6SDavid Gow 		entries[i].data = i;
11601ff522b6SDavid Gow 		hlist_add_behind(&entries[i].list, &entries[i-1].list);
11611ff522b6SDavid Gow 	}
11621ff522b6SDavid Gow 
11631ff522b6SDavid Gow 	i = 0;
11641ff522b6SDavid Gow 
11651ff522b6SDavid Gow 	hlist_for_each_entry_safe(cur, tmp_node, &list, list) {
11661ff522b6SDavid Gow 		KUNIT_EXPECT_EQ(test, cur->data, i);
11671ff522b6SDavid Gow 		hlist_del(&cur->list);
11681ff522b6SDavid Gow 		i++;
11691ff522b6SDavid Gow 	}
11701ff522b6SDavid Gow 
11711ff522b6SDavid Gow 	KUNIT_EXPECT_EQ(test, i, 5);
11721ff522b6SDavid Gow 	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
11731ff522b6SDavid Gow }
11741ff522b6SDavid Gow 
11751ff522b6SDavid Gow 
11761ff522b6SDavid Gow static struct kunit_case hlist_test_cases[] = {
11771ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_init),
11781ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_unhashed),
11791ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_unhashed_lockless),
11801ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_del),
11811ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_del_init),
11821ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_add),
11831ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_fake),
11841ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_is_singular_node),
11851ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_empty),
11861ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_move_list),
11871ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_entry),
11881ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_entry_safe),
11891ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each),
11901ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each_safe),
11911ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each_entry),
11921ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each_entry_continue),
11931ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each_entry_from),
11941ff522b6SDavid Gow 	KUNIT_CASE(hlist_test_for_each_entry_safe),
11951ff522b6SDavid Gow 	{},
11961ff522b6SDavid Gow };
11971ff522b6SDavid Gow 
11981ff522b6SDavid Gow static struct kunit_suite hlist_test_module = {
11991ff522b6SDavid Gow 	.name = "hlist",
12001ff522b6SDavid Gow 	.test_cases = hlist_test_cases,
12011ff522b6SDavid Gow };
12021ff522b6SDavid Gow 
1203*57b4f760SSadiya Kazi 
1204*57b4f760SSadiya Kazi struct klist_test_struct {
1205*57b4f760SSadiya Kazi 	int data;
1206*57b4f760SSadiya Kazi 	struct klist klist;
1207*57b4f760SSadiya Kazi 	struct klist_node klist_node;
1208*57b4f760SSadiya Kazi };
1209*57b4f760SSadiya Kazi 
1210*57b4f760SSadiya Kazi static int node_count;
1211*57b4f760SSadiya Kazi static struct klist_node *last_node;
1212*57b4f760SSadiya Kazi 
check_node(struct klist_node * node_ptr)1213*57b4f760SSadiya Kazi static void check_node(struct klist_node *node_ptr)
1214*57b4f760SSadiya Kazi {
1215*57b4f760SSadiya Kazi 	node_count++;
1216*57b4f760SSadiya Kazi 	last_node = node_ptr;
1217*57b4f760SSadiya Kazi }
1218*57b4f760SSadiya Kazi 
check_delete_node(struct klist_node * node_ptr)1219*57b4f760SSadiya Kazi static void check_delete_node(struct klist_node *node_ptr)
1220*57b4f760SSadiya Kazi {
1221*57b4f760SSadiya Kazi 	node_count--;
1222*57b4f760SSadiya Kazi 	last_node = node_ptr;
1223*57b4f760SSadiya Kazi }
1224*57b4f760SSadiya Kazi 
klist_test_add_tail(struct kunit * test)1225*57b4f760SSadiya Kazi static void klist_test_add_tail(struct kunit *test)
1226*57b4f760SSadiya Kazi {
1227*57b4f760SSadiya Kazi 	struct klist_node a, b;
1228*57b4f760SSadiya Kazi 	struct klist mylist;
1229*57b4f760SSadiya Kazi 	struct klist_iter i;
1230*57b4f760SSadiya Kazi 
1231*57b4f760SSadiya Kazi 	node_count = 0;
1232*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, NULL);
1233*57b4f760SSadiya Kazi 
1234*57b4f760SSadiya Kazi 	klist_add_tail(&a, &mylist);
1235*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 1);
1236*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
1237*57b4f760SSadiya Kazi 
1238*57b4f760SSadiya Kazi 	klist_add_tail(&b, &mylist);
1239*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 2);
1240*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
1241*57b4f760SSadiya Kazi 
1242*57b4f760SSadiya Kazi 	/* should be [list] -> a -> b */
1243*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1244*57b4f760SSadiya Kazi 
1245*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1246*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1247*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1248*57b4f760SSadiya Kazi 
1249*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1250*57b4f760SSadiya Kazi 
1251*57b4f760SSadiya Kazi }
1252*57b4f760SSadiya Kazi 
klist_test_add_head(struct kunit * test)1253*57b4f760SSadiya Kazi static void klist_test_add_head(struct kunit *test)
1254*57b4f760SSadiya Kazi {
1255*57b4f760SSadiya Kazi 	struct klist_node a, b;
1256*57b4f760SSadiya Kazi 	struct klist mylist;
1257*57b4f760SSadiya Kazi 	struct klist_iter i;
1258*57b4f760SSadiya Kazi 
1259*57b4f760SSadiya Kazi 	node_count = 0;
1260*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, NULL);
1261*57b4f760SSadiya Kazi 
1262*57b4f760SSadiya Kazi 	klist_add_head(&a, &mylist);
1263*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 1);
1264*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
1265*57b4f760SSadiya Kazi 
1266*57b4f760SSadiya Kazi 	klist_add_head(&b, &mylist);
1267*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 2);
1268*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
1269*57b4f760SSadiya Kazi 
1270*57b4f760SSadiya Kazi 	/* should be [list] -> b -> a */
1271*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1272*57b4f760SSadiya Kazi 
1273*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1274*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1275*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1276*57b4f760SSadiya Kazi 
1277*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1278*57b4f760SSadiya Kazi 
1279*57b4f760SSadiya Kazi }
1280*57b4f760SSadiya Kazi 
klist_test_add_behind(struct kunit * test)1281*57b4f760SSadiya Kazi static void klist_test_add_behind(struct kunit *test)
1282*57b4f760SSadiya Kazi {
1283*57b4f760SSadiya Kazi 	struct klist_node a, b, c, d;
1284*57b4f760SSadiya Kazi 	struct klist mylist;
1285*57b4f760SSadiya Kazi 	struct klist_iter i;
1286*57b4f760SSadiya Kazi 
1287*57b4f760SSadiya Kazi 	node_count = 0;
1288*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, NULL);
1289*57b4f760SSadiya Kazi 
1290*57b4f760SSadiya Kazi 	klist_add_head(&a, &mylist);
1291*57b4f760SSadiya Kazi 	klist_add_head(&b, &mylist);
1292*57b4f760SSadiya Kazi 
1293*57b4f760SSadiya Kazi 	klist_add_behind(&c, &a);
1294*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 3);
1295*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
1296*57b4f760SSadiya Kazi 
1297*57b4f760SSadiya Kazi 	klist_add_behind(&d, &b);
1298*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 4);
1299*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
1300*57b4f760SSadiya Kazi 
1301*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1302*57b4f760SSadiya Kazi 
1303*57b4f760SSadiya Kazi 	/* should be [list] -> b -> d -> a -> c*/
1304*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1305*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
1306*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1307*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
1308*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1309*57b4f760SSadiya Kazi 
1310*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1311*57b4f760SSadiya Kazi 
1312*57b4f760SSadiya Kazi }
1313*57b4f760SSadiya Kazi 
klist_test_add_before(struct kunit * test)1314*57b4f760SSadiya Kazi static void klist_test_add_before(struct kunit *test)
1315*57b4f760SSadiya Kazi {
1316*57b4f760SSadiya Kazi 	struct klist_node a, b, c, d;
1317*57b4f760SSadiya Kazi 	struct klist mylist;
1318*57b4f760SSadiya Kazi 	struct klist_iter i;
1319*57b4f760SSadiya Kazi 
1320*57b4f760SSadiya Kazi 	node_count = 0;
1321*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, NULL);
1322*57b4f760SSadiya Kazi 
1323*57b4f760SSadiya Kazi 	klist_add_head(&a, &mylist);
1324*57b4f760SSadiya Kazi 	klist_add_head(&b, &mylist);
1325*57b4f760SSadiya Kazi 	klist_add_before(&c, &a);
1326*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 3);
1327*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
1328*57b4f760SSadiya Kazi 
1329*57b4f760SSadiya Kazi 	klist_add_before(&d, &b);
1330*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 4);
1331*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
1332*57b4f760SSadiya Kazi 
1333*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1334*57b4f760SSadiya Kazi 
1335*57b4f760SSadiya Kazi 	/* should be [list] -> b -> d -> a -> c*/
1336*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
1337*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1338*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
1339*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1340*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1341*57b4f760SSadiya Kazi 
1342*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1343*57b4f760SSadiya Kazi 
1344*57b4f760SSadiya Kazi }
1345*57b4f760SSadiya Kazi 
1346*57b4f760SSadiya Kazi /*
1347*57b4f760SSadiya Kazi  * Verify that klist_del() delays the deletion of a node until there
1348*57b4f760SSadiya Kazi  * are no other references to it
1349*57b4f760SSadiya Kazi  */
klist_test_del_refcount_greater_than_zero(struct kunit * test)1350*57b4f760SSadiya Kazi static void klist_test_del_refcount_greater_than_zero(struct kunit *test)
1351*57b4f760SSadiya Kazi {
1352*57b4f760SSadiya Kazi 	struct klist_node a, b, c, d;
1353*57b4f760SSadiya Kazi 	struct klist mylist;
1354*57b4f760SSadiya Kazi 	struct klist_iter i;
1355*57b4f760SSadiya Kazi 
1356*57b4f760SSadiya Kazi 	node_count = 0;
1357*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, &check_delete_node);
1358*57b4f760SSadiya Kazi 
1359*57b4f760SSadiya Kazi 	/* Add nodes a,b,c,d to the list*/
1360*57b4f760SSadiya Kazi 	klist_add_tail(&a, &mylist);
1361*57b4f760SSadiya Kazi 	klist_add_tail(&b, &mylist);
1362*57b4f760SSadiya Kazi 	klist_add_tail(&c, &mylist);
1363*57b4f760SSadiya Kazi 	klist_add_tail(&d, &mylist);
1364*57b4f760SSadiya Kazi 
1365*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1366*57b4f760SSadiya Kazi 
1367*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1368*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1369*57b4f760SSadiya Kazi 	/* Advance the iterator to point to node c*/
1370*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
1371*57b4f760SSadiya Kazi 
1372*57b4f760SSadiya Kazi 	/* Try to delete node c while there is a reference to it*/
1373*57b4f760SSadiya Kazi 	klist_del(&c);
1374*57b4f760SSadiya Kazi 
1375*57b4f760SSadiya Kazi 	/*
1376*57b4f760SSadiya Kazi 	 * Verify that node c is still attached to the list even after being
1377*57b4f760SSadiya Kazi 	 * deleted. Since the iterator still points to c, the reference count is not
1378*57b4f760SSadiya Kazi 	 * decreased to 0
1379*57b4f760SSadiya Kazi 	 */
1380*57b4f760SSadiya Kazi 	KUNIT_EXPECT_TRUE(test, klist_node_attached(&c));
1381*57b4f760SSadiya Kazi 
1382*57b4f760SSadiya Kazi 	/* Check that node c has not been removed yet*/
1383*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 4);
1384*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
1385*57b4f760SSadiya Kazi 
1386*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1387*57b4f760SSadiya Kazi 
1388*57b4f760SSadiya Kazi 	/*
1389*57b4f760SSadiya Kazi 	 * Since the iterator is no longer pointing to node c, node c is removed
1390*57b4f760SSadiya Kazi 	 * from the list
1391*57b4f760SSadiya Kazi 	 */
1392*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 3);
1393*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
1394*57b4f760SSadiya Kazi 
1395*57b4f760SSadiya Kazi }
1396*57b4f760SSadiya Kazi 
1397*57b4f760SSadiya Kazi /*
1398*57b4f760SSadiya Kazi  * Verify that klist_del() deletes a node immediately when there are no
1399*57b4f760SSadiya Kazi  * other references to it.
1400*57b4f760SSadiya Kazi  */
klist_test_del_refcount_zero(struct kunit * test)1401*57b4f760SSadiya Kazi static void klist_test_del_refcount_zero(struct kunit *test)
1402*57b4f760SSadiya Kazi {
1403*57b4f760SSadiya Kazi 	struct klist_node a, b, c, d;
1404*57b4f760SSadiya Kazi 	struct klist mylist;
1405*57b4f760SSadiya Kazi 	struct klist_iter i;
1406*57b4f760SSadiya Kazi 
1407*57b4f760SSadiya Kazi 	node_count = 0;
1408*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, &check_delete_node);
1409*57b4f760SSadiya Kazi 
1410*57b4f760SSadiya Kazi 	/* Add nodes a,b,c,d to the list*/
1411*57b4f760SSadiya Kazi 	klist_add_tail(&a, &mylist);
1412*57b4f760SSadiya Kazi 	klist_add_tail(&b, &mylist);
1413*57b4f760SSadiya Kazi 	klist_add_tail(&c, &mylist);
1414*57b4f760SSadiya Kazi 	klist_add_tail(&d, &mylist);
1415*57b4f760SSadiya Kazi 	/* Delete node c*/
1416*57b4f760SSadiya Kazi 	klist_del(&c);
1417*57b4f760SSadiya Kazi 
1418*57b4f760SSadiya Kazi 	/* Check that node c is deleted from the list*/
1419*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 3);
1420*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
1421*57b4f760SSadiya Kazi 
1422*57b4f760SSadiya Kazi 	/* Should be [list] -> a -> b -> d*/
1423*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1424*57b4f760SSadiya Kazi 
1425*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1426*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1427*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
1428*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1429*57b4f760SSadiya Kazi 
1430*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1431*57b4f760SSadiya Kazi 
1432*57b4f760SSadiya Kazi }
1433*57b4f760SSadiya Kazi 
klist_test_remove(struct kunit * test)1434*57b4f760SSadiya Kazi static void klist_test_remove(struct kunit *test)
1435*57b4f760SSadiya Kazi {
1436*57b4f760SSadiya Kazi 	/* This test doesn't check correctness under concurrent access */
1437*57b4f760SSadiya Kazi 	struct klist_node a, b, c, d;
1438*57b4f760SSadiya Kazi 	struct klist mylist;
1439*57b4f760SSadiya Kazi 	struct klist_iter i;
1440*57b4f760SSadiya Kazi 
1441*57b4f760SSadiya Kazi 	node_count = 0;
1442*57b4f760SSadiya Kazi 	klist_init(&mylist, &check_node, &check_delete_node);
1443*57b4f760SSadiya Kazi 
1444*57b4f760SSadiya Kazi 	/* Add nodes a,b,c,d to the list*/
1445*57b4f760SSadiya Kazi 	klist_add_tail(&a, &mylist);
1446*57b4f760SSadiya Kazi 	klist_add_tail(&b, &mylist);
1447*57b4f760SSadiya Kazi 	klist_add_tail(&c, &mylist);
1448*57b4f760SSadiya Kazi 	klist_add_tail(&d, &mylist);
1449*57b4f760SSadiya Kazi 	/* Delete node c*/
1450*57b4f760SSadiya Kazi 	klist_remove(&c);
1451*57b4f760SSadiya Kazi 
1452*57b4f760SSadiya Kazi 	/* Check the nodes in the list*/
1453*57b4f760SSadiya Kazi 	KUNIT_EXPECT_EQ(test, node_count, 3);
1454*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
1455*57b4f760SSadiya Kazi 
1456*57b4f760SSadiya Kazi 	/* should be [list] -> a -> b -> d*/
1457*57b4f760SSadiya Kazi 	klist_iter_init(&mylist, &i);
1458*57b4f760SSadiya Kazi 
1459*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
1460*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
1461*57b4f760SSadiya Kazi 	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
1462*57b4f760SSadiya Kazi 	KUNIT_EXPECT_NULL(test, klist_next(&i));
1463*57b4f760SSadiya Kazi 
1464*57b4f760SSadiya Kazi 	klist_iter_exit(&i);
1465*57b4f760SSadiya Kazi 
1466*57b4f760SSadiya Kazi }
1467*57b4f760SSadiya Kazi 
klist_test_node_attached(struct kunit * test)1468*57b4f760SSadiya Kazi static void klist_test_node_attached(struct kunit *test)
1469*57b4f760SSadiya Kazi {
1470*57b4f760SSadiya Kazi 	struct klist_node a = {};
1471*57b4f760SSadiya Kazi 	struct klist mylist;
1472*57b4f760SSadiya Kazi 
1473*57b4f760SSadiya Kazi 	klist_init(&mylist, NULL, NULL);
1474*57b4f760SSadiya Kazi 
1475*57b4f760SSadiya Kazi 	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
1476*57b4f760SSadiya Kazi 	klist_add_head(&a, &mylist);
1477*57b4f760SSadiya Kazi 	KUNIT_EXPECT_TRUE(test, klist_node_attached(&a));
1478*57b4f760SSadiya Kazi 	klist_del(&a);
1479*57b4f760SSadiya Kazi 	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
1480*57b4f760SSadiya Kazi 
1481*57b4f760SSadiya Kazi }
1482*57b4f760SSadiya Kazi 
1483*57b4f760SSadiya Kazi static struct kunit_case klist_test_cases[] = {
1484*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_add_tail),
1485*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_add_head),
1486*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_add_behind),
1487*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_add_before),
1488*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_del_refcount_greater_than_zero),
1489*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_del_refcount_zero),
1490*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_remove),
1491*57b4f760SSadiya Kazi 	KUNIT_CASE(klist_test_node_attached),
1492*57b4f760SSadiya Kazi 	{},
1493*57b4f760SSadiya Kazi };
1494*57b4f760SSadiya Kazi 
1495*57b4f760SSadiya Kazi static struct kunit_suite klist_test_module = {
1496*57b4f760SSadiya Kazi 	.name = "klist",
1497*57b4f760SSadiya Kazi 	.test_cases = klist_test_cases,
1498*57b4f760SSadiya Kazi };
1499*57b4f760SSadiya Kazi 
1500*57b4f760SSadiya Kazi kunit_test_suites(&list_test_module, &hlist_test_module, &klist_test_module);
1501c475c77dSAlan Maguire 
1502c475c77dSAlan Maguire MODULE_LICENSE("GPL v2");
1503