| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- // SPDX-License-Identifier: GPL-2.0 AND MIT
- /*
- * Copyright © 2023 Intel Corporation
- */
- #include <linux/dma-resv.h>
- #include <linux/kthread.h>
- #include <linux/delay.h>
- #include <linux/timer.h>
- #include <linux/jiffies.h>
- #include <linux/mutex.h>
- #include <linux/ww_mutex.h>
- #include <drm/ttm/ttm_resource.h>
- #include <drm/ttm/ttm_placement.h>
- #include <drm/ttm/ttm_tt.h>
- #include "ttm_kunit_helpers.h"
- #define BO_SIZE SZ_8K
- #ifdef CONFIG_PREEMPT_RT
- #define ww_mutex_base_lock(b) rt_mutex_lock(b)
- #else
- #define ww_mutex_base_lock(b) mutex_lock(b)
- #endif
- struct ttm_bo_test_case {
- const char *description;
- bool interruptible;
- bool no_wait;
- };
- static const struct ttm_bo_test_case ttm_bo_reserved_cases[] = {
- {
- .description = "Cannot be interrupted and sleeps",
- .interruptible = false,
- .no_wait = false,
- },
- {
- .description = "Cannot be interrupted, locks straight away",
- .interruptible = false,
- .no_wait = true,
- },
- {
- .description = "Can be interrupted, sleeps",
- .interruptible = true,
- .no_wait = false,
- },
- };
- static void ttm_bo_init_case_desc(const struct ttm_bo_test_case *t,
- char *desc)
- {
- strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
- }
- KUNIT_ARRAY_PARAM(ttm_bo_reserve, ttm_bo_reserved_cases, ttm_bo_init_case_desc);
- static void ttm_bo_reserve_optimistic_no_ticket(struct kunit *test)
- {
- const struct ttm_bo_test_case *params = test->param_value;
- struct ttm_buffer_object *bo;
- int err;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- err = ttm_bo_reserve(bo, params->interruptible, params->no_wait, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- dma_resv_unlock(bo->base.resv);
- }
- static void ttm_bo_reserve_locked_no_sleep(struct kunit *test)
- {
- struct ttm_buffer_object *bo;
- bool interruptible = false;
- bool no_wait = true;
- int err;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- /* Let's lock it beforehand */
- dma_resv_lock(bo->base.resv, NULL);
- err = ttm_bo_reserve(bo, interruptible, no_wait, NULL);
- dma_resv_unlock(bo->base.resv);
- KUNIT_ASSERT_EQ(test, err, -EBUSY);
- }
- static void ttm_bo_reserve_no_wait_ticket(struct kunit *test)
- {
- struct ttm_buffer_object *bo;
- struct ww_acquire_ctx ctx;
- bool interruptible = false;
- bool no_wait = true;
- int err;
- ww_acquire_init(&ctx, &reservation_ww_class);
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
- KUNIT_ASSERT_EQ(test, err, -EBUSY);
- ww_acquire_fini(&ctx);
- }
- static void ttm_bo_reserve_double_resv(struct kunit *test)
- {
- struct ttm_buffer_object *bo;
- struct ww_acquire_ctx ctx;
- bool interruptible = false;
- bool no_wait = false;
- int err;
- ww_acquire_init(&ctx, &reservation_ww_class);
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
- KUNIT_ASSERT_EQ(test, err, 0);
- err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
- dma_resv_unlock(bo->base.resv);
- ww_acquire_fini(&ctx);
- KUNIT_ASSERT_EQ(test, err, -EALREADY);
- }
- /*
- * A test case heavily inspired by ww_test_edeadlk_normal(). It injects
- * a deadlock by manipulating the sequence number of the context that holds
- * dma_resv lock of bo2 so the other context is "wounded" and has to back off
- * (indicated by -EDEADLK). The subtest checks if ttm_bo_reserve() properly
- * propagates that error.
- */
- static void ttm_bo_reserve_deadlock(struct kunit *test)
- {
- struct ttm_buffer_object *bo1, *bo2;
- struct ww_acquire_ctx ctx1, ctx2;
- bool interruptible = false;
- bool no_wait = false;
- int err;
- bo1 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- ww_acquire_init(&ctx1, &reservation_ww_class);
- ww_mutex_base_lock(&bo2->base.resv->lock.base);
- /* The deadlock will be caught by WW mutex, don't warn about it */
- lock_release(&bo2->base.resv->lock.base.dep_map, 1);
- bo2->base.resv->lock.ctx = &ctx2;
- ctx2 = ctx1;
- ctx2.stamp--; /* Make the context holding the lock younger */
- err = ttm_bo_reserve(bo1, interruptible, no_wait, &ctx1);
- KUNIT_ASSERT_EQ(test, err, 0);
- err = ttm_bo_reserve(bo2, interruptible, no_wait, &ctx1);
- KUNIT_ASSERT_EQ(test, err, -EDEADLK);
- dma_resv_unlock(bo1->base.resv);
- ww_acquire_fini(&ctx1);
- }
- #if IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST)
- struct signal_timer {
- struct timer_list timer;
- struct ww_acquire_ctx *ctx;
- };
- static void signal_for_ttm_bo_reserve(struct timer_list *t)
- {
- struct signal_timer *s_timer = timer_container_of(s_timer, t, timer);
- struct task_struct *task = s_timer->ctx->task;
- do_send_sig_info(SIGTERM, SEND_SIG_PRIV, task, PIDTYPE_PID);
- }
- static int threaded_ttm_bo_reserve(void *arg)
- {
- struct ttm_buffer_object *bo = arg;
- struct signal_timer s_timer;
- struct ww_acquire_ctx ctx;
- bool interruptible = true;
- bool no_wait = false;
- int err;
- ww_acquire_init(&ctx, &reservation_ww_class);
- /* Prepare a signal that will interrupt the reservation attempt */
- timer_setup_on_stack(&s_timer.timer, &signal_for_ttm_bo_reserve, 0);
- s_timer.ctx = &ctx;
- mod_timer(&s_timer.timer, msecs_to_jiffies(100));
- err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
- timer_delete_sync(&s_timer.timer);
- timer_destroy_on_stack(&s_timer.timer);
- ww_acquire_fini(&ctx);
- return err;
- }
- static void ttm_bo_reserve_interrupted(struct kunit *test)
- {
- struct ttm_buffer_object *bo;
- struct task_struct *task;
- int err;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- task = kthread_create(threaded_ttm_bo_reserve, bo, "ttm-bo-reserve");
- if (IS_ERR(task))
- KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n");
- /* Take a lock so the threaded reserve has to wait */
- dma_resv_lock(bo->base.resv, NULL);
- wake_up_process(task);
- msleep(20);
- err = kthread_stop(task);
- dma_resv_unlock(bo->base.resv);
- KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS);
- }
- #endif /* IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST) */
- static void ttm_bo_unreserve_basic(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_buffer_object *bo;
- struct ttm_device *ttm_dev;
- struct ttm_resource *res1, *res2;
- struct ttm_place *place;
- struct ttm_resource_manager *man;
- unsigned int bo_prio = TTM_MAX_BO_PRIORITY - 1;
- u32 mem_type = TTM_PL_SYSTEM;
- int err;
- place = ttm_place_kunit_init(test, mem_type, 0);
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- bo->priority = bo_prio;
- err = ttm_resource_alloc(bo, place, &res1, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo->resource = res1;
- /* Add a dummy resource to populate LRU */
- ttm_resource_alloc(bo, place, &res2, NULL);
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_unreserve(bo);
- man = ttm_manager_type(priv->ttm_dev, mem_type);
- KUNIT_ASSERT_EQ(test,
- list_is_last(&res1->lru.link, &man->lru[bo->priority]), 1);
- ttm_resource_free(bo, &res2);
- ttm_resource_free(bo, &res1);
- }
- static void ttm_bo_unreserve_pinned(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_buffer_object *bo;
- struct ttm_device *ttm_dev;
- struct ttm_resource *res1, *res2;
- struct ttm_place *place;
- u32 mem_type = TTM_PL_SYSTEM;
- int err;
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- place = ttm_place_kunit_init(test, mem_type, 0);
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_pin(bo);
- err = ttm_resource_alloc(bo, place, &res1, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo->resource = res1;
- /* Add a dummy resource to the pinned list */
- err = ttm_resource_alloc(bo, place, &res2, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- KUNIT_ASSERT_EQ(test,
- list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1);
- ttm_bo_unreserve(bo);
- KUNIT_ASSERT_EQ(test,
- list_is_last(&res1->lru.link, &priv->ttm_dev->unevictable), 1);
- ttm_resource_free(bo, &res1);
- ttm_resource_free(bo, &res2);
- }
- static void ttm_bo_unreserve_bulk(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_lru_bulk_move lru_bulk_move;
- struct ttm_lru_bulk_move_pos *pos;
- struct ttm_buffer_object *bo1, *bo2;
- struct ttm_resource *res1, *res2;
- struct ttm_device *ttm_dev;
- struct ttm_place *place;
- struct dma_resv *resv;
- u32 mem_type = TTM_PL_SYSTEM;
- unsigned int bo_priority = 0;
- int err;
- ttm_lru_bulk_move_init(&lru_bulk_move);
- place = ttm_place_kunit_init(test, mem_type, 0);
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- resv = kunit_kzalloc(test, sizeof(*resv), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, resv);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- dma_resv_init(resv);
- bo1 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, resv);
- bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, resv);
- dma_resv_lock(bo1->base.resv, NULL);
- ttm_bo_set_bulk_move(bo1, &lru_bulk_move);
- dma_resv_unlock(bo1->base.resv);
- err = ttm_resource_alloc(bo1, place, &res1, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo1->resource = res1;
- dma_resv_lock(bo2->base.resv, NULL);
- ttm_bo_set_bulk_move(bo2, &lru_bulk_move);
- dma_resv_unlock(bo2->base.resv);
- err = ttm_resource_alloc(bo2, place, &res2, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo2->resource = res2;
- ttm_bo_reserve(bo1, false, false, NULL);
- ttm_bo_unreserve(bo1);
- pos = &lru_bulk_move.pos[mem_type][bo_priority];
- KUNIT_ASSERT_PTR_EQ(test, res1, pos->last);
- ttm_resource_free(bo1, &res1);
- ttm_resource_free(bo2, &res2);
- dma_resv_fini(resv);
- }
- static void ttm_bo_fini_basic(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_buffer_object *bo;
- struct ttm_resource *res;
- struct ttm_device *ttm_dev;
- struct ttm_place *place;
- u32 mem_type = TTM_PL_SYSTEM;
- int err;
- place = ttm_place_kunit_init(test, mem_type, 0);
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- bo->type = ttm_bo_type_device;
- err = ttm_resource_alloc(bo, place, &res, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo->resource = res;
- dma_resv_lock(bo->base.resv, NULL);
- err = ttm_tt_create(bo, false);
- dma_resv_unlock(bo->base.resv);
- KUNIT_EXPECT_EQ(test, err, 0);
- ttm_bo_fini(bo);
- }
- static const char *mock_name(struct dma_fence *f)
- {
- return "kunit-ttm-bo-put";
- }
- static const struct dma_fence_ops mock_fence_ops = {
- .get_driver_name = mock_name,
- .get_timeline_name = mock_name,
- };
- static void ttm_bo_fini_shared_resv(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_buffer_object *bo;
- struct dma_resv *external_resv;
- struct dma_fence *fence;
- /* A dummy DMA fence lock */
- spinlock_t fence_lock;
- struct ttm_device *ttm_dev;
- int err;
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- external_resv = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, external_resv);
- dma_resv_init(external_resv);
- fence = kunit_kzalloc(test, sizeof(*fence), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, fence);
- spin_lock_init(&fence_lock);
- dma_fence_init(fence, &mock_fence_ops, &fence_lock, 0, 0);
- dma_resv_lock(external_resv, NULL);
- dma_resv_reserve_fences(external_resv, 1);
- dma_resv_add_fence(external_resv, fence, DMA_RESV_USAGE_BOOKKEEP);
- dma_resv_unlock(external_resv);
- dma_fence_signal(fence);
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- bo->type = ttm_bo_type_device;
- bo->base.resv = external_resv;
- ttm_bo_fini(bo);
- }
- static void ttm_bo_pin_basic(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_buffer_object *bo;
- struct ttm_device *ttm_dev;
- unsigned int no_pins = 3;
- int err;
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- for (int i = 0; i < no_pins; i++) {
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_pin(bo);
- dma_resv_unlock(bo->base.resv);
- }
- KUNIT_ASSERT_EQ(test, bo->pin_count, no_pins);
- }
- static void ttm_bo_pin_unpin_resource(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_lru_bulk_move lru_bulk_move;
- struct ttm_lru_bulk_move_pos *pos;
- struct ttm_buffer_object *bo;
- struct ttm_resource *res;
- struct ttm_device *ttm_dev;
- struct ttm_place *place;
- u32 mem_type = TTM_PL_SYSTEM;
- unsigned int bo_priority = 0;
- int err;
- ttm_lru_bulk_move_init(&lru_bulk_move);
- place = ttm_place_kunit_init(test, mem_type, 0);
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- err = ttm_resource_alloc(bo, place, &res, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo->resource = res;
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_set_bulk_move(bo, &lru_bulk_move);
- ttm_bo_pin(bo);
- dma_resv_unlock(bo->base.resv);
- pos = &lru_bulk_move.pos[mem_type][bo_priority];
- KUNIT_ASSERT_EQ(test, bo->pin_count, 1);
- KUNIT_ASSERT_NULL(test, pos->first);
- KUNIT_ASSERT_NULL(test, pos->last);
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_unpin(bo);
- dma_resv_unlock(bo->base.resv);
- KUNIT_ASSERT_PTR_EQ(test, res, pos->last);
- KUNIT_ASSERT_EQ(test, bo->pin_count, 0);
- ttm_resource_free(bo, &res);
- }
- static void ttm_bo_multiple_pin_one_unpin(struct kunit *test)
- {
- struct ttm_test_devices *priv = test->priv;
- struct ttm_lru_bulk_move lru_bulk_move;
- struct ttm_lru_bulk_move_pos *pos;
- struct ttm_buffer_object *bo;
- struct ttm_resource *res;
- struct ttm_device *ttm_dev;
- struct ttm_place *place;
- u32 mem_type = TTM_PL_SYSTEM;
- unsigned int bo_priority = 0;
- int err;
- ttm_lru_bulk_move_init(&lru_bulk_move);
- place = ttm_place_kunit_init(test, mem_type, 0);
- ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
- err = ttm_device_kunit_init(priv, ttm_dev, 0);
- KUNIT_ASSERT_EQ(test, err, 0);
- priv->ttm_dev = ttm_dev;
- bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
- err = ttm_resource_alloc(bo, place, &res, NULL);
- KUNIT_ASSERT_EQ(test, err, 0);
- bo->resource = res;
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_set_bulk_move(bo, &lru_bulk_move);
- /* Multiple pins */
- ttm_bo_pin(bo);
- ttm_bo_pin(bo);
- dma_resv_unlock(bo->base.resv);
- pos = &lru_bulk_move.pos[mem_type][bo_priority];
- KUNIT_ASSERT_EQ(test, bo->pin_count, 2);
- KUNIT_ASSERT_NULL(test, pos->first);
- KUNIT_ASSERT_NULL(test, pos->last);
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_unpin(bo);
- dma_resv_unlock(bo->base.resv);
- KUNIT_ASSERT_EQ(test, bo->pin_count, 1);
- KUNIT_ASSERT_NULL(test, pos->first);
- KUNIT_ASSERT_NULL(test, pos->last);
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_unpin(bo);
- dma_resv_unlock(bo->base.resv);
- ttm_resource_free(bo, &res);
- }
- static struct kunit_case ttm_bo_test_cases[] = {
- KUNIT_CASE_PARAM(ttm_bo_reserve_optimistic_no_ticket,
- ttm_bo_reserve_gen_params),
- KUNIT_CASE(ttm_bo_reserve_locked_no_sleep),
- KUNIT_CASE(ttm_bo_reserve_no_wait_ticket),
- KUNIT_CASE(ttm_bo_reserve_double_resv),
- #if IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST)
- KUNIT_CASE(ttm_bo_reserve_interrupted),
- #endif
- KUNIT_CASE(ttm_bo_reserve_deadlock),
- KUNIT_CASE(ttm_bo_unreserve_basic),
- KUNIT_CASE(ttm_bo_unreserve_pinned),
- KUNIT_CASE(ttm_bo_unreserve_bulk),
- KUNIT_CASE(ttm_bo_fini_basic),
- KUNIT_CASE(ttm_bo_fini_shared_resv),
- KUNIT_CASE(ttm_bo_pin_basic),
- KUNIT_CASE(ttm_bo_pin_unpin_resource),
- KUNIT_CASE(ttm_bo_multiple_pin_one_unpin),
- {}
- };
- static struct kunit_suite ttm_bo_test_suite = {
- .name = "ttm_bo",
- .init = ttm_test_devices_init,
- .exit = ttm_test_devices_fini,
- .test_cases = ttm_bo_test_cases,
- };
- kunit_test_suites(&ttm_bo_test_suite);
- MODULE_DESCRIPTION("KUnit tests for ttm_bo APIs");
- MODULE_LICENSE("GPL and additional rights");
|