blob: 87ad147670da71f92ae2807648d9ad2529e8146a [file] [log] [blame]
Chris Wilson50f00332016-12-22 08:36:09 +00001/*
2 * Test cases for the drm_mm range manager
3 */
4
5#define pr_fmt(fmt) "drm_mm: " fmt
6
7#include <linux/module.h>
8#include <linux/prime_numbers.h>
9#include <linux/slab.h>
10#include <linux/random.h>
11#include <linux/vmalloc.h>
12
13#include <drm/drm_mm.h>
14
15#include "../lib/drm_random.h"
16
17#define TESTS "drm_mm_selftests.h"
18#include "drm_selftest.h"
19
20static unsigned int random_seed;
21static unsigned int max_iterations = 8192;
22static unsigned int max_prime = 128;
23
24static int igt_sanitycheck(void *ignored)
25{
26 pr_info("%s - ok!\n", __func__);
27 return 0;
28}
29
Chris Wilson393b50f2016-12-22 08:36:10 +000030static bool assert_no_holes(const struct drm_mm *mm)
31{
32 struct drm_mm_node *hole;
33 u64 hole_start, hole_end;
34 unsigned long count;
35
36 count = 0;
37 drm_mm_for_each_hole(hole, mm, hole_start, hole_end)
38 count++;
39 if (count) {
40 pr_err("Expected to find no holes (after reserve), found %lu instead\n", count);
41 return false;
42 }
43
44 drm_mm_for_each_node(hole, mm) {
45 if (hole->hole_follows) {
46 pr_err("Hole follows node, expected none!\n");
47 return false;
48 }
49 }
50
51 return true;
52}
53
54static bool assert_one_hole(const struct drm_mm *mm, u64 start, u64 end)
55{
56 struct drm_mm_node *hole;
57 u64 hole_start, hole_end;
58 unsigned long count;
59 bool ok = true;
60
61 if (end <= start)
62 return true;
63
64 count = 0;
65 drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
66 if (start != hole_start || end != hole_end) {
67 if (ok)
68 pr_err("empty mm has incorrect hole, found (%llx, %llx), expect (%llx, %llx)\n",
69 hole_start, hole_end,
70 start, end);
71 ok = false;
72 }
73 count++;
74 }
75 if (count != 1) {
76 pr_err("Expected to find one hole, found %lu instead\n", count);
77 ok = false;
78 }
79
80 return ok;
81}
82
83static int igt_init(void *ignored)
84{
85 const unsigned int size = 4096;
86 struct drm_mm mm;
87 struct drm_mm_node tmp;
88 int ret = -EINVAL;
89
90 /* Start with some simple checks on initialising the struct drm_mm */
91 memset(&mm, 0, sizeof(mm));
92 if (drm_mm_initialized(&mm)) {
93 pr_err("zeroed mm claims to be initialized\n");
94 return ret;
95 }
96
97 memset(&mm, 0xff, sizeof(mm));
98 drm_mm_init(&mm, 0, size);
99 if (!drm_mm_initialized(&mm)) {
100 pr_err("mm claims not to be initialized\n");
101 goto out;
102 }
103
104 if (!drm_mm_clean(&mm)) {
105 pr_err("mm not empty on creation\n");
106 goto out;
107 }
108
109 /* After creation, it should all be one massive hole */
110 if (!assert_one_hole(&mm, 0, size)) {
111 ret = -EINVAL;
112 goto out;
113 }
114
115 memset(&tmp, 0, sizeof(tmp));
116 tmp.start = 0;
117 tmp.size = size;
118 ret = drm_mm_reserve_node(&mm, &tmp);
119 if (ret) {
120 pr_err("failed to reserve whole drm_mm\n");
121 goto out;
122 }
123
124 /* After filling the range entirely, there should be no holes */
125 if (!assert_no_holes(&mm)) {
126 ret = -EINVAL;
127 goto out;
128 }
129
130 /* And then after emptying it again, the massive hole should be back */
131 drm_mm_remove_node(&tmp);
132 if (!assert_one_hole(&mm, 0, size)) {
133 ret = -EINVAL;
134 goto out;
135 }
136
137out:
138 if (ret)
139 drm_mm_debug_table(&mm, __func__);
140 drm_mm_takedown(&mm);
141 return ret;
142}
143
Chris Wilson50f00332016-12-22 08:36:09 +0000144#include "drm_selftest.c"
145
146static int __init test_drm_mm_init(void)
147{
148 int err;
149
150 while (!random_seed)
151 random_seed = get_random_int();
152
153 pr_info("Testing DRM range manger (struct drm_mm), with random_seed=0x%x max_iterations=%u max_prime=%u\n",
154 random_seed, max_iterations, max_prime);
155 err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
156
157 return err > 0 ? 0 : err;
158}
159
160static void __exit test_drm_mm_exit(void)
161{
162}
163
164module_init(test_drm_mm_init);
165module_exit(test_drm_mm_exit);
166
167module_param(random_seed, uint, 0400);
168module_param(max_iterations, uint, 0400);
169module_param(max_prime, uint, 0400);
170
171MODULE_AUTHOR("Intel Corporation");
172MODULE_LICENSE("GPL");