1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2022 Advanced Micro Devices, Inc. 4 */ 5 6 #define pr_fmt(fmt) "drm_exec: " fmt 7 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_gem.h> 16 17 #include "../lib/drm_random.h" 18 19 static struct drm_device dev; 20 21 static void sanitycheck(struct kunit *test) 22 { 23 struct drm_exec exec; 24 25 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); 26 drm_exec_fini(&exec); 27 KUNIT_SUCCEED(test); 28 } 29 30 static void test_lock(struct kunit *test) 31 { 32 struct drm_gem_object gobj = { }; 33 struct drm_exec exec; 34 int ret; 35 36 drm_gem_private_object_init(&dev, &gobj, PAGE_SIZE); 37 38 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); 39 drm_exec_until_all_locked(&exec) { 40 ret = drm_exec_lock_obj(&exec, &gobj); 41 drm_exec_retry_on_contention(&exec); 42 KUNIT_EXPECT_EQ(test, ret, 0); 43 if (ret) 44 break; 45 } 46 drm_exec_fini(&exec); 47 } 48 49 static void test_lock_unlock(struct kunit *test) 50 { 51 struct drm_gem_object gobj = { }; 52 struct drm_exec exec; 53 int ret; 54 55 drm_gem_private_object_init(&dev, &gobj, PAGE_SIZE); 56 57 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); 58 drm_exec_until_all_locked(&exec) { 59 ret = drm_exec_lock_obj(&exec, &gobj); 60 drm_exec_retry_on_contention(&exec); 61 KUNIT_EXPECT_EQ(test, ret, 0); 62 if (ret) 63 break; 64 65 drm_exec_unlock_obj(&exec, &gobj); 66 ret = drm_exec_lock_obj(&exec, &gobj); 67 drm_exec_retry_on_contention(&exec); 68 KUNIT_EXPECT_EQ(test, ret, 0); 69 if (ret) 70 break; 71 } 72 drm_exec_fini(&exec); 73 } 74 75 static void test_duplicates(struct kunit *test) 76 { 77 struct drm_gem_object gobj = { }; 78 struct drm_exec exec; 79 int ret; 80 81 drm_gem_private_object_init(&dev, &gobj, PAGE_SIZE); 82 83 drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES); 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 ret = drm_exec_lock_obj(&exec, &gobj); 92 drm_exec_retry_on_contention(&exec); 93 KUNIT_EXPECT_EQ(test, ret, 0); 94 if (ret) 95 break; 96 } 97 drm_exec_unlock_obj(&exec, &gobj); 98 drm_exec_fini(&exec); 99 } 100 101 102 103 static void test_prepare(struct kunit *test) 104 { 105 struct drm_gem_object gobj = { }; 106 struct drm_exec exec; 107 int ret; 108 109 drm_gem_private_object_init(&dev, &gobj, PAGE_SIZE); 110 111 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); 112 drm_exec_until_all_locked(&exec) { 113 ret = drm_exec_prepare_obj(&exec, &gobj, 1); 114 drm_exec_retry_on_contention(&exec); 115 KUNIT_EXPECT_EQ(test, ret, 0); 116 if (ret) 117 break; 118 } 119 drm_exec_fini(&exec); 120 } 121 122 static void test_prepare_array(struct kunit *test) 123 { 124 struct drm_gem_object gobj1 = { }; 125 struct drm_gem_object gobj2 = { }; 126 struct drm_gem_object *array[] = { &gobj1, &gobj2 }; 127 struct drm_exec exec; 128 int ret; 129 130 drm_gem_private_object_init(&dev, &gobj1, PAGE_SIZE); 131 drm_gem_private_object_init(&dev, &gobj2, PAGE_SIZE); 132 133 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); 134 drm_exec_until_all_locked(&exec) 135 ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array), 136 1); 137 KUNIT_EXPECT_EQ(test, ret, 0); 138 drm_exec_fini(&exec); 139 } 140 141 static struct kunit_case drm_exec_tests[] = { 142 KUNIT_CASE(sanitycheck), 143 KUNIT_CASE(test_lock), 144 KUNIT_CASE(test_lock_unlock), 145 KUNIT_CASE(test_duplicates), 146 KUNIT_CASE(test_prepare), 147 KUNIT_CASE(test_prepare_array), 148 {} 149 }; 150 151 static struct kunit_suite drm_exec_test_suite = { 152 .name = "drm_exec", 153 .test_cases = drm_exec_tests, 154 }; 155 156 kunit_test_suite(drm_exec_test_suite); 157 158 MODULE_AUTHOR("AMD"); 159 MODULE_LICENSE("GPL and additional rights"); 160