215 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright 2022 Advanced Micro Devices, Inc.4 */5 6#define pr_fmt(fmt) "drm_exec: " fmt7 8#include <kunit/test.h>9 10#include <linux/module.h>11#include <linux/prime_numbers.h>12 13#include <drm/drm_exec.h>14#include <drm/drm_device.h>15#include <drm/drm_drv.h>16#include <drm/drm_gem.h>17#include <drm/drm_kunit_helpers.h>18 19#include "../lib/drm_random.h"20 21struct drm_exec_priv {22 struct device *dev;23 struct drm_device *drm;24};25 26static int drm_exec_test_init(struct kunit *test)27{28 struct drm_exec_priv *priv;29 30 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);31 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);32 33 test->priv = priv;34 35 priv->dev = drm_kunit_helper_alloc_device(test);36 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);37 38 priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev, sizeof(*priv->drm), 0,39 DRIVER_MODESET);40 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);41 42 return 0;43}44 45static void sanitycheck(struct kunit *test)46{47 struct drm_exec exec;48 49 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);50 drm_exec_fini(&exec);51 KUNIT_SUCCEED(test);52}53 54static void test_lock(struct kunit *test)55{56 struct drm_exec_priv *priv = test->priv;57 struct drm_gem_object gobj = { };58 struct drm_exec exec;59 int ret;60 61 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);62 63 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);64 drm_exec_until_all_locked(&exec) {65 ret = drm_exec_lock_obj(&exec, &gobj);66 drm_exec_retry_on_contention(&exec);67 KUNIT_EXPECT_EQ(test, ret, 0);68 if (ret)69 break;70 }71 drm_exec_fini(&exec);72}73 74static void test_lock_unlock(struct kunit *test)75{76 struct drm_exec_priv *priv = test->priv;77 struct drm_gem_object gobj = { };78 struct drm_exec exec;79 int ret;80 81 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);82 83 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);84 drm_exec_until_all_locked(&exec) {85 ret = drm_exec_lock_obj(&exec, &gobj);86 drm_exec_retry_on_contention(&exec);87 KUNIT_EXPECT_EQ(test, ret, 0);88 if (ret)89 break;90 91 drm_exec_unlock_obj(&exec, &gobj);92 ret = drm_exec_lock_obj(&exec, &gobj);93 drm_exec_retry_on_contention(&exec);94 KUNIT_EXPECT_EQ(test, ret, 0);95 if (ret)96 break;97 }98 drm_exec_fini(&exec);99}100 101static void test_duplicates(struct kunit *test)102{103 struct drm_exec_priv *priv = test->priv;104 struct drm_gem_object gobj = { };105 struct drm_exec exec;106 int ret;107 108 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);109 110 drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);111 drm_exec_until_all_locked(&exec) {112 ret = drm_exec_lock_obj(&exec, &gobj);113 drm_exec_retry_on_contention(&exec);114 KUNIT_EXPECT_EQ(test, ret, 0);115 if (ret)116 break;117 118 ret = drm_exec_lock_obj(&exec, &gobj);119 drm_exec_retry_on_contention(&exec);120 KUNIT_EXPECT_EQ(test, ret, 0);121 if (ret)122 break;123 }124 drm_exec_unlock_obj(&exec, &gobj);125 drm_exec_fini(&exec);126}127 128static void test_prepare(struct kunit *test)129{130 struct drm_exec_priv *priv = test->priv;131 struct drm_gem_object gobj = { };132 struct drm_exec exec;133 int ret;134 135 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);136 137 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);138 drm_exec_until_all_locked(&exec) {139 ret = drm_exec_prepare_obj(&exec, &gobj, 1);140 drm_exec_retry_on_contention(&exec);141 KUNIT_EXPECT_EQ(test, ret, 0);142 if (ret)143 break;144 }145 drm_exec_fini(&exec);146 147 drm_gem_private_object_fini(&gobj);148}149 150static void test_prepare_array(struct kunit *test)151{152 struct drm_exec_priv *priv = test->priv;153 struct drm_gem_object gobj1 = { };154 struct drm_gem_object gobj2 = { };155 struct drm_gem_object *array[] = { &gobj1, &gobj2 };156 struct drm_exec exec;157 int ret;158 159 drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE);160 drm_gem_private_object_init(priv->drm, &gobj2, PAGE_SIZE);161 162 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);163 drm_exec_until_all_locked(&exec)164 ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array),165 1);166 KUNIT_EXPECT_EQ(test, ret, 0);167 drm_exec_fini(&exec);168 169 drm_gem_private_object_fini(&gobj1);170 drm_gem_private_object_fini(&gobj2);171}172 173static void test_multiple_loops(struct kunit *test)174{175 struct drm_exec exec;176 177 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);178 drm_exec_until_all_locked(&exec)179 {180 break;181 }182 drm_exec_fini(&exec);183 184 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);185 drm_exec_until_all_locked(&exec)186 {187 break;188 }189 drm_exec_fini(&exec);190 KUNIT_SUCCEED(test);191}192 193static struct kunit_case drm_exec_tests[] = {194 KUNIT_CASE(sanitycheck),195 KUNIT_CASE(test_lock),196 KUNIT_CASE(test_lock_unlock),197 KUNIT_CASE(test_duplicates),198 KUNIT_CASE(test_prepare),199 KUNIT_CASE(test_prepare_array),200 KUNIT_CASE(test_multiple_loops),201 {}202};203 204static struct kunit_suite drm_exec_test_suite = {205 .name = "drm_exec",206 .init = drm_exec_test_init,207 .test_cases = drm_exec_tests,208};209 210kunit_test_suite(drm_exec_test_suite);211 212MODULE_AUTHOR("AMD");213MODULE_DESCRIPTION("Kunit test for drm_exec functions");214MODULE_LICENSE("GPL and additional rights");215