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