xref: /linux/lib/tests/list-private-test.c (revision 23b0f90ba871f096474e1c27c3d14f455189d2d9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * KUnit compilation/smoke test for Private list primitives.
4  *
5  * Copyright (c) 2025, Google LLC.
6  * Pasha Tatashin <pasha.tatashin@soleen.com>
7  */
8 #include <linux/list_private.h>
9 #include <kunit/test.h>
10 
11 /*
12  * This forces compiler to warn if you access it directly, because list
13  * primitives expect (struct list_head *), not (volatile struct list_head *).
14  */
15 #undef __private
16 #define __private volatile
17 
18 /* Redefine ACCESS_PRIVATE for this test. */
19 #undef ACCESS_PRIVATE
20 #define ACCESS_PRIVATE(p, member) \
21 	(*((struct list_head *)((unsigned long)&((p)->member))))
22 
23 struct list_test_struct {
24 	int data;
25 	struct list_head __private list;
26 };
27 
28 static void list_private_compile_test(struct kunit *test)
29 {
30 	struct list_test_struct entry;
31 	struct list_test_struct *pos, *n;
32 	LIST_HEAD(head);
33 
34 	INIT_LIST_HEAD(&ACCESS_PRIVATE(&entry, list));
35 	list_add(&ACCESS_PRIVATE(&entry, list), &head);
36 	pos = &entry;
37 
38 	pos = list_private_entry(&ACCESS_PRIVATE(&entry, list), struct list_test_struct, list);
39 	pos = list_private_first_entry(&head, struct list_test_struct, list);
40 	pos = list_private_last_entry(&head, struct list_test_struct, list);
41 	pos = list_private_next_entry(pos, list);
42 	pos = list_private_prev_entry(pos, list);
43 	pos = list_private_next_entry_circular(pos, &head, list);
44 	pos = list_private_prev_entry_circular(pos, &head, list);
45 
46 	if (list_private_entry_is_head(pos, &head, list))
47 		return;
48 
49 	list_private_for_each_entry(pos, &head, list) { }
50 	list_private_for_each_entry_reverse(pos, &head, list) { }
51 	list_private_for_each_entry_continue(pos, &head, list) { }
52 	list_private_for_each_entry_continue_reverse(pos, &head, list) { }
53 	list_private_for_each_entry_from(pos, &head, list) { }
54 	list_private_for_each_entry_from_reverse(pos, &head, list) { }
55 
56 	list_private_for_each_entry_safe(pos, n, &head, list)
57 		list_private_safe_reset_next(pos, n, list);
58 	list_private_for_each_entry_safe_continue(pos, n, &head, list) { }
59 	list_private_for_each_entry_safe_from(pos, n, &head, list) { }
60 	list_private_for_each_entry_safe_reverse(pos, n, &head, list) { }
61 }
62 
63 static struct kunit_case list_private_test_cases[] = {
64 	KUNIT_CASE(list_private_compile_test),
65 	{},
66 };
67 
68 static struct kunit_suite list_private_test_module = {
69 	.name = "list-private-kunit-test",
70 	.test_cases = list_private_test_cases,
71 };
72 
73 kunit_test_suite(list_private_test_module);
74 
75 MODULE_DESCRIPTION("KUnit compilation test for private list primitives");
76 MODULE_LICENSE("GPL");
77