forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/selftests/test-drm_mm.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Test cases for the drm_mm range manager
34 */
....@@ -9,6 +10,7 @@
910 #include <linux/slab.h>
1011 #include <linux/random.h>
1112 #include <linux/vmalloc.h>
13
+#include <linux/ktime.h>
1214
1315 #include <drm/drm_mm.h>
1416
....@@ -853,7 +855,7 @@
853855
854856 if (start > 0) {
855857 node = __drm_mm_interval_first(mm, 0, start - 1);
856
- if (node->allocated) {
858
+ if (drm_mm_node_allocated(node)) {
857859 pr_err("node before start: node=%llx+%llu, start=%llx\n",
858860 node->start, node->size, start);
859861 return false;
....@@ -862,7 +864,7 @@
862864
863865 if (end < U64_MAX) {
864866 node = __drm_mm_interval_first(mm, end, U64_MAX);
865
- if (node->allocated) {
867
+ if (drm_mm_node_allocated(node)) {
866868 pr_err("node after end: node=%llx+%llu, end=%llx\n",
867869 node->start, node->size, end);
868870 return false;
....@@ -1032,6 +1034,122 @@
10321034 return 0;
10331035 }
10341036
1037
+static int prepare_igt_frag(struct drm_mm *mm,
1038
+ struct drm_mm_node *nodes,
1039
+ unsigned int num_insert,
1040
+ const struct insert_mode *mode)
1041
+{
1042
+ unsigned int size = 4096;
1043
+ unsigned int i;
1044
+
1045
+ for (i = 0; i < num_insert; i++) {
1046
+ if (!expect_insert(mm, &nodes[i], size, 0, i,
1047
+ mode) != 0) {
1048
+ pr_err("%s insert failed\n", mode->name);
1049
+ return -EINVAL;
1050
+ }
1051
+ }
1052
+
1053
+ /* introduce fragmentation by freeing every other node */
1054
+ for (i = 0; i < num_insert; i++) {
1055
+ if (i % 2 == 0)
1056
+ drm_mm_remove_node(&nodes[i]);
1057
+ }
1058
+
1059
+ return 0;
1060
+
1061
+}
1062
+
1063
+static u64 get_insert_time(struct drm_mm *mm,
1064
+ unsigned int num_insert,
1065
+ struct drm_mm_node *nodes,
1066
+ const struct insert_mode *mode)
1067
+{
1068
+ unsigned int size = 8192;
1069
+ ktime_t start;
1070
+ unsigned int i;
1071
+
1072
+ start = ktime_get();
1073
+ for (i = 0; i < num_insert; i++) {
1074
+ if (!expect_insert(mm, &nodes[i], size, 0, i, mode) != 0) {
1075
+ pr_err("%s insert failed\n", mode->name);
1076
+ return 0;
1077
+ }
1078
+ }
1079
+
1080
+ return ktime_to_ns(ktime_sub(ktime_get(), start));
1081
+}
1082
+
1083
+static int igt_frag(void *ignored)
1084
+{
1085
+ struct drm_mm mm;
1086
+ const struct insert_mode *mode;
1087
+ struct drm_mm_node *nodes, *node, *next;
1088
+ unsigned int insert_size = 10000;
1089
+ unsigned int scale_factor = 4;
1090
+ int ret = -EINVAL;
1091
+
1092
+ /* We need 4 * insert_size nodes to hold intermediate allocated
1093
+ * drm_mm nodes.
1094
+ * 1 times for prepare_igt_frag()
1095
+ * 1 times for get_insert_time()
1096
+ * 2 times for get_insert_time()
1097
+ */
1098
+ nodes = vzalloc(array_size(insert_size * 4, sizeof(*nodes)));
1099
+ if (!nodes)
1100
+ return -ENOMEM;
1101
+
1102
+ /* For BOTTOMUP and TOPDOWN, we first fragment the
1103
+ * address space using prepare_igt_frag() and then try to verify
1104
+ * that that insertions scale quadratically from 10k to 20k insertions
1105
+ */
1106
+ drm_mm_init(&mm, 1, U64_MAX - 2);
1107
+ for (mode = insert_modes; mode->name; mode++) {
1108
+ u64 insert_time1, insert_time2;
1109
+
1110
+ if (mode->mode != DRM_MM_INSERT_LOW &&
1111
+ mode->mode != DRM_MM_INSERT_HIGH)
1112
+ continue;
1113
+
1114
+ ret = prepare_igt_frag(&mm, nodes, insert_size, mode);
1115
+ if (ret)
1116
+ goto err;
1117
+
1118
+ insert_time1 = get_insert_time(&mm, insert_size,
1119
+ nodes + insert_size, mode);
1120
+ if (insert_time1 == 0)
1121
+ goto err;
1122
+
1123
+ insert_time2 = get_insert_time(&mm, (insert_size * 2),
1124
+ nodes + insert_size * 2, mode);
1125
+ if (insert_time2 == 0)
1126
+ goto err;
1127
+
1128
+ pr_info("%s fragmented insert of %u and %u insertions took %llu and %llu nsecs\n",
1129
+ mode->name, insert_size, insert_size * 2,
1130
+ insert_time1, insert_time2);
1131
+
1132
+ if (insert_time2 > (scale_factor * insert_time1)) {
1133
+ pr_err("%s fragmented insert took %llu nsecs more\n",
1134
+ mode->name,
1135
+ insert_time2 - (scale_factor * insert_time1));
1136
+ goto err;
1137
+ }
1138
+
1139
+ drm_mm_for_each_node_safe(node, next, &mm)
1140
+ drm_mm_remove_node(node);
1141
+ }
1142
+
1143
+ ret = 0;
1144
+err:
1145
+ drm_mm_for_each_node_safe(node, next, &mm)
1146
+ drm_mm_remove_node(node);
1147
+ drm_mm_takedown(&mm);
1148
+ vfree(nodes);
1149
+
1150
+ return ret;
1151
+}
1152
+
10351153 static int igt_align(void *ignored)
10361154 {
10371155 const struct insert_mode *mode;
....@@ -1155,12 +1273,12 @@
11551273 struct drm_mm_node *next = list_next_entry(hole, node_list);
11561274 const char *node1 = NULL, *node2 = NULL;
11571275
1158
- if (hole->allocated)
1276
+ if (drm_mm_node_allocated(hole))
11591277 node1 = kasprintf(GFP_KERNEL,
11601278 "[%llx + %lld, color=%ld], ",
11611279 hole->start, hole->size, hole->color);
11621280
1163
- if (next->allocated)
1281
+ if (drm_mm_node_allocated(next))
11641282 node2 = kasprintf(GFP_KERNEL,
11651283 ", [%llx + %lld, color=%ld]",
11661284 next->start, next->size, next->color);
....@@ -1615,7 +1733,7 @@
16151733 DRM_RND_STATE(prng, random_seed);
16161734 const unsigned int count = 8192;
16171735 unsigned int size;
1618
- unsigned long *bitmap = NULL;
1736
+ unsigned long *bitmap;
16191737 struct drm_mm mm;
16201738 struct drm_mm_node *nodes, *node, *next;
16211739 unsigned int *order, n, m, o = 0;
....@@ -1631,8 +1749,7 @@
16311749 if (!nodes)
16321750 goto err;
16331751
1634
- bitmap = kcalloc(count / BITS_PER_LONG, sizeof(unsigned long),
1635
- GFP_KERNEL);
1752
+ bitmap = bitmap_zalloc(count, GFP_KERNEL);
16361753 if (!bitmap)
16371754 goto err_nodes;
16381755
....@@ -1717,7 +1834,7 @@
17171834 drm_mm_takedown(&mm);
17181835 kfree(order);
17191836 err_bitmap:
1720
- kfree(bitmap);
1837
+ bitmap_free(bitmap);
17211838 err_nodes:
17221839 vfree(nodes);
17231840 err:
....@@ -1745,8 +1862,7 @@
17451862 if (!nodes)
17461863 goto err;
17471864
1748
- bitmap = kcalloc(count / BITS_PER_LONG, sizeof(unsigned long),
1749
- GFP_KERNEL);
1865
+ bitmap = bitmap_zalloc(count, GFP_KERNEL);
17501866 if (!bitmap)
17511867 goto err_nodes;
17521868
....@@ -1818,7 +1934,7 @@
18181934 drm_mm_takedown(&mm);
18191935 kfree(order);
18201936 err_bitmap:
1821
- kfree(bitmap);
1937
+ bitmap_free(bitmap);
18221938 err_nodes:
18231939 vfree(nodes);
18241940 err:
....@@ -1858,16 +1974,6 @@
18581974 }
18591975
18601976 memset(&node, 0, sizeof(node));
1861
- err = drm_mm_insert_node_generic(&mm, &node,
1862
- 2, 0, 0,
1863
- mode | DRM_MM_INSERT_ONCE);
1864
- if (!err) {
1865
- pr_err("Unexpectedly inserted the node into the wrong hole: node.start=%llx\n",
1866
- node.start);
1867
- err = -EINVAL;
1868
- goto err_node;
1869
- }
1870
-
18711977 err = drm_mm_insert_node_generic(&mm, &node, 2, 0, 0, mode);
18721978 if (err) {
18731979 pr_err("Could not insert the node into the available hole!\n");
....@@ -1875,7 +1981,6 @@
18751981 goto err_hi;
18761982 }
18771983
1878
-err_node:
18791984 drm_mm_remove_node(&node);
18801985 err_hi:
18811986 drm_mm_remove_node(&rsvd_hi);
....@@ -1901,18 +2006,18 @@
19012006 u64 *start,
19022007 u64 *end)
19032008 {
1904
- if (node->allocated && node->color != color)
2009
+ if (drm_mm_node_allocated(node) && node->color != color)
19052010 ++*start;
19062011
19072012 node = list_next_entry(node, node_list);
1908
- if (node->allocated && node->color != color)
2013
+ if (drm_mm_node_allocated(node) && node->color != color)
19092014 --*end;
19102015 }
19112016
19122017 static bool colors_abutt(const struct drm_mm_node *node)
19132018 {
19142019 if (!drm_mm_hole_follows(node) &&
1915
- list_next_entry(node, node_list)->allocated) {
2020
+ drm_mm_node_allocated(list_next_entry(node, node_list))) {
19162021 pr_err("colors abutt; %ld [%llx + %llx] is next to %ld [%llx + %llx]!\n",
19172022 node->color, node->start, node->size,
19182023 list_next_entry(node, node_list)->color,
....@@ -2360,7 +2465,7 @@
23602465 while (!random_seed)
23612466 random_seed = get_random_int();
23622467
2363
- pr_info("Testing DRM range manger (struct drm_mm), with random_seed=0x%x max_iterations=%u max_prime=%u\n",
2468
+ pr_info("Testing DRM range manager (struct drm_mm), with random_seed=0x%x max_iterations=%u max_prime=%u\n",
23642469 random_seed, max_iterations, max_prime);
23652470 err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
23662471