From eb314613cd7c5fa5a26a2293d6ea935cf6cfaac0 Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 12 Jul 2024 09:43:24 +0200 Subject: drm/ttm: revert "Export ttm_bo_get_unless_zero()" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 24dc64c1ba5c3ef0463d59fef6df09336754188d. Shouldn't be needed by drivers any more. Signed-off-by: Christian König Reviewed-by: Matthew Brost Reviewed-by: Danilo Krummrich Reviewed-by: Simona Vetter Link: https://lore.kernel.org/r/20240723121750.2086-6-christian.koenig@amd.com --- drivers/gpu/drm/ttm/ttm_bo.c | 1 + drivers/gpu/drm/ttm/ttm_bo_internal.h | 48 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/ttm/ttm_bo_util.c | 2 ++ drivers/gpu/drm/ttm/ttm_device.c | 1 + 4 files changed, 52 insertions(+) create mode 100644 drivers/gpu/drm/ttm/ttm_bo_internal.h (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 08a23ab037cb..0f874f1e2526 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -46,6 +46,7 @@ #include #include "ttm_module.h" +#include "ttm_bo_internal.h" static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, struct ttm_placement *placement) diff --git a/drivers/gpu/drm/ttm/ttm_bo_internal.h b/drivers/gpu/drm/ttm/ttm_bo_internal.h new file mode 100644 index 000000000000..6a7305efd778 --- /dev/null +++ b/drivers/gpu/drm/ttm/ttm_bo_internal.h @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * + */ + +#ifndef _TTM_BO_INTERNAL_H_ +#define _TTM_BO_INTERNAL_H_ + +#include + +/** + * ttm_bo_get_unless_zero - reference a struct ttm_buffer_object unless + * its refcount has already reached zero. + * @bo: The buffer object. + * + * Used to reference a TTM buffer object in lookups where the object is removed + * from the lookup structure during the destructor and for RCU lookups. + * + * Returns: @bo if the referencing was successful, NULL otherwise. + */ +static inline __must_check struct ttm_buffer_object * +ttm_bo_get_unless_zero(struct ttm_buffer_object *bo) +{ + if (!kref_get_unless_zero(&bo->kref)) + return NULL; + return bo; +} + +#endif diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 15cab9bda17f..b78365dc1fed 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -37,6 +37,8 @@ #include +#include "ttm_bo_internal.h" + struct ttm_transfer_obj { struct ttm_buffer_object base; struct ttm_buffer_object *bo; diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index 02e797fd1891..36075772555a 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -36,6 +36,7 @@ #include #include "ttm_module.h" +#include "ttm_bo_internal.h" /* * ttm_global_mutex - protecting the global state -- cgit v1.2.3 From 9ec1ac835e489b9ab2776c0cbbb1b1ca813923a2 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 16 Jul 2024 14:28:40 +0200 Subject: drm/ttm: make ttm_bo_get internal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent drivers from using this directly. Signed-off-by: Christian König Reviewed-by: Matthew Brost Reviewed-by: Simona Vetter Link: https://lore.kernel.org/r/20240723121750.2086-8-christian.koenig@amd.com --- drivers/gpu/drm/ttm/ttm_bo_internal.h | 10 ++++++++++ include/drm/ttm/ttm_bo.h | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo_internal.h b/drivers/gpu/drm/ttm/ttm_bo_internal.h index 6a7305efd778..9d8b747a34db 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_internal.h +++ b/drivers/gpu/drm/ttm/ttm_bo_internal.h @@ -27,6 +27,16 @@ #include +/** + * ttm_bo_get - reference a struct ttm_buffer_object + * + * @bo: The buffer object. + */ +static inline void ttm_bo_get(struct ttm_buffer_object *bo) +{ + kref_get(&bo->kref); +} + /** * ttm_bo_get_unless_zero - reference a struct ttm_buffer_object unless * its refcount has already reached zero. diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index bf241698a527..8ad6e2713625 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -244,16 +244,6 @@ bool ttm_bo_shrink_suitable(struct ttm_buffer_object *bo, struct ttm_operation_c bool ttm_bo_shrink_avoid_wait(void); -/** - * ttm_bo_get - reference a struct ttm_buffer_object - * - * @bo: The buffer object. - */ -static inline void ttm_bo_get(struct ttm_buffer_object *bo) -{ - kref_get(&bo->kref); -} - /** * ttm_bo_reserve: * -- cgit v1.2.3 From eac21f8ebeb4f84d703cf41dc3f81d16fa9dc00a Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 3 Jun 2025 12:27:49 +0100 Subject: drm/ttm: Respect the shrinker core free target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the TTM shrinker aborts shrinking as soon as it frees pages from any of the page order pools and by doing so it can fail to respect the freeing target which was configured by the shrinker core. We use the wording "can fail" because the number of freed pages will depend on the presence of pages in the pools and the order of the pools on the LRU list. For example if there are no free pages in the high order pools the shrinker core may require multiple passes over the TTM shrinker before it will free the default target of 128 pages (assuming there are free pages in the low order pools). This inefficiency can be compounded by the pool LRU where multiple further calls into the TTM shrinker are required to end up looking at the pool with pages. Improve this by never freeing less than the shrinker core has requested. At the same time we start reporting the number of scanned pages (freed in this case), which prevents the core shrinker from giving up on the TTM shrinker too soon and moving on. v2: * Simplify loop logic. (Christian) * Improve commit message. Signed-off-by: Tvrtko Ursulin Cc: Christian König Cc: Thomas Hellström Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20250603112750.34997-2-tvrtko.ursulin@igalia.com --- drivers/gpu/drm/ttm/ttm_pool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 83b10706ba89..cb44745106bc 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1132,7 +1132,6 @@ void ttm_pool_fini(struct ttm_pool *pool) } EXPORT_SYMBOL(ttm_pool_fini); -/* As long as pages are available make sure to release at least one */ static unsigned long ttm_pool_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc) { @@ -1140,9 +1139,12 @@ static unsigned long ttm_pool_shrinker_scan(struct shrinker *shrink, do num_freed += ttm_pool_shrink(); - while (!num_freed && atomic_long_read(&allocated_pages)); + while (num_freed < sc->nr_to_scan && + atomic_long_read(&allocated_pages)); - return num_freed; + sc->nr_scanned = num_freed; + + return num_freed ?: SHRINK_STOP; } /* Return the number of pages available or SHRINK_EMPTY if we have none */ -- cgit v1.2.3 From 22b929b25293208d9d34ff6fa783c6788e0b791c Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 3 Jun 2025 12:27:50 +0100 Subject: drm/ttm: Increase pool shrinker batch target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default core shrink target of 128 pages (SHRINK_BATCH) is quite low relative to how cheap TTM pool shrinking is, and how the free pages are distributed in page order pools. We can make the target a bit more aggressive by making it roughly the average number of pages across all pools, freeing more of the cached pages every time shrinker core invokes our callback. Signed-off-by: Tvrtko Ursulin Cc: Christian König Cc: Thomas Hellström Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20250603112750.34997-3-tvrtko.ursulin@igalia.com --- drivers/gpu/drm/ttm/ttm_pool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index cb44745106bc..90b1bb903b93 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1265,10 +1265,16 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) } EXPORT_SYMBOL(ttm_pool_debugfs); +/* Free average pool number of pages. */ +#define TTM_SHRINKER_BATCH ((1 << (MAX_PAGE_ORDER / 2)) * NR_PAGE_ORDERS) + /* Test the shrinker functions and dump the result */ static int ttm_pool_debugfs_shrink_show(struct seq_file *m, void *data) { - struct shrink_control sc = { .gfp_mask = GFP_NOFS }; + struct shrink_control sc = { + .gfp_mask = GFP_NOFS, + .nr_to_scan = TTM_SHRINKER_BATCH, + }; fs_reclaim_acquire(GFP_KERNEL); seq_printf(m, "%lu/%lu\n", ttm_pool_shrinker_count(mm_shrinker, &sc), @@ -1326,6 +1332,7 @@ int ttm_pool_mgr_init(unsigned long num_pages) mm_shrinker->count_objects = ttm_pool_shrinker_count; mm_shrinker->scan_objects = ttm_pool_shrinker_scan; + mm_shrinker->batch = TTM_SHRINKER_BATCH; mm_shrinker->seeks = 1; shrinker_register(mm_shrinker); -- cgit v1.2.3 From 0f6afbb2ae6c9bd2acd5acf75762fec68bc6fab0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 Jun 2025 06:40:10 +1000 Subject: ttm/pool: allow debugfs dumps for numa pools. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently you can't see per-device numa aware pools properly. Cc: Christian König Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://lore.kernel.org/r/20250602204013.1104258-1-airlied@gmail.com --- drivers/gpu/drm/ttm/ttm_pool.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 90b1bb903b93..4b16946d3248 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1235,7 +1235,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) { unsigned int i; - if (!pool->use_dma_alloc) { + if (!pool->use_dma_alloc && pool->nid == NUMA_NO_NODE) { seq_puts(m, "unused\n"); return 0; } @@ -1244,7 +1244,12 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) spin_lock(&shrinker_lock); for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) { - seq_puts(m, "DMA "); + if (!ttm_pool_select_type(pool, i, 0)) + continue; + if (pool->use_dma_alloc) + seq_puts(m, "DMA "); + else + seq_printf(m, "N%d ", pool->nid); switch (i) { case ttm_cached: seq_puts(m, "\t:"); -- cgit v1.2.3 From 685c407f168cb49a12cc703230d1e2d62767bfd2 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Tue, 3 Jun 2025 11:47:51 -0700 Subject: drm/ttm: Fix build with CONFIG_DEBUG_FS=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the define outside the ifdef for CONFIG_DEBUG_FS to fix the build. This currently breaks drm kunit tests: $ ./tools/testing/kunit/kunit.py run --kunitconfig drivers/gpu/drm/ttm/tests/.kunitconfig ERROR:root:../drivers/gpu/drm/ttm/ttm_pool.c: In function ‘ttm_pool_mgr_init’: ../drivers/gpu/drm/ttm/ttm_pool.c:1335:30: error: ‘TTM_SHRINKER_BATCH’ undeclared (first use in this function) 1335 | mm_shrinker->batch = TTM_SHRINKER_BATCH; Fixes: 22b929b25293 ("drm/ttm: Increase pool shrinker batch target") Cc: Tvrtko Ursulin Cc: Christian König Reviewed-by: Tvrtko Ursulin Signed-off-by: Lucas De Marchi Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20250603184750.3304647-2-lucas.demarchi@intel.com --- drivers/gpu/drm/ttm/ttm_pool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 4b16946d3248..cd31a30df3b0 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1132,6 +1132,9 @@ void ttm_pool_fini(struct ttm_pool *pool) } EXPORT_SYMBOL(ttm_pool_fini); +/* Free average pool number of pages. */ +#define TTM_SHRINKER_BATCH ((1 << (MAX_PAGE_ORDER / 2)) * NR_PAGE_ORDERS) + static unsigned long ttm_pool_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc) { @@ -1270,9 +1273,6 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) } EXPORT_SYMBOL(ttm_pool_debugfs); -/* Free average pool number of pages. */ -#define TTM_SHRINKER_BATCH ((1 << (MAX_PAGE_ORDER / 2)) * NR_PAGE_ORDERS) - /* Test the shrinker functions and dump the result */ static int ttm_pool_debugfs_shrink_show(struct seq_file *m, void *data) { -- cgit v1.2.3 From c87a3f4fac5b6fee3b3e6a82a12147da5b5df507 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Jun 2025 08:09:01 +1000 Subject: drm/ttm: handle undefined printf arg evaluation order in debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When you read this debugfs file it's isn't guaranteed the count will happen before the scan, but I think the intent is that it does. printf argument evaluation order is undefined. Cc: Christian Koenig Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://lore.kernel.org/r/20250603220901.1217161-1-airlied@gmail.com --- drivers/gpu/drm/ttm/ttm_pool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index cd31a30df3b0..99197aac09a1 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1280,9 +1280,11 @@ static int ttm_pool_debugfs_shrink_show(struct seq_file *m, void *data) .gfp_mask = GFP_NOFS, .nr_to_scan = TTM_SHRINKER_BATCH, }; + unsigned long count; fs_reclaim_acquire(GFP_KERNEL); - seq_printf(m, "%lu/%lu\n", ttm_pool_shrinker_count(mm_shrinker, &sc), + count = ttm_pool_shrinker_count(mm_shrinker, &sc); + seq_printf(m, "%lu/%lu\n", count, ttm_pool_shrinker_scan(mm_shrinker, &sc)); fs_reclaim_release(GFP_KERNEL); -- cgit v1.2.3 From 4e16a9a00239db5d819197b9a00f70665951bf50 Mon Sep 17 00:00:00 2001 From: Emily Deng Date: Tue, 3 Jun 2025 17:11:54 +0800 Subject: drm/ttm: Should to return the evict error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the evict fail case, the evict error should be returned. v2: Consider ENOENT case. v3: Abort directly when the eviction failed for some reason (except for -ENOENT) and not wait for the move to finish Signed-off-by: Emily Deng Reviewed-by: Christian König Signed-off-by: Christian König Link: https://lore.kernel.org/r/20250603091154.3472646-1-Emily.Deng@amd.com --- drivers/gpu/drm/ttm/ttm_resource.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 769b0ca9be47..006202fcd3c2 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -557,6 +557,9 @@ int ttm_resource_manager_evict_all(struct ttm_device *bdev, cond_resched(); } while (!ret); + if (ret && ret != -ENOENT) + return ret; + spin_lock(&man->move_lock); fence = dma_fence_get(man->move); spin_unlock(&man->move_lock); -- cgit v1.2.3 From af5ea7d8a30512de2836175bd7aa9ae0bba94bad Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Jun 2025 14:10:03 +0200 Subject: drm/ttm: Include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the compile-time warnings drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/tests/ttm_mock_manager.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_agp_backend.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_backup.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_bo.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_bo_util.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_bo_vm.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_device.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_execbuf_util.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_pool.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_range_manager.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_resource.c: warning: EXPORT_SYMBOL() is used, but #include is missing drivers/gpu/drm/ttm/ttm_tt.c: warning: EXPORT_SYMBOL() is used, but #include is missing Signed-off-by: Thomas Zimmermann Fixes: a934a57a42f6 ("scripts/misc-check: check missing #include when W=1") Reviewed-by: André Almeida Cc: Masahiro Yamada Cc: Nathan Chancellor Link: https://lore.kernel.org/r/20250612121633.229222-10-tzimmermann@suse.de --- drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c | 3 +++ drivers/gpu/drm/ttm/tests/ttm_mock_manager.c | 3 +++ drivers/gpu/drm/ttm/ttm_agp_backend.c | 1 + drivers/gpu/drm/ttm/ttm_backup.c | 2 ++ drivers/gpu/drm/ttm/ttm_bo.c | 1 + drivers/gpu/drm/ttm/ttm_bo_util.c | 2 ++ drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 ++ drivers/gpu/drm/ttm/ttm_device.c | 1 + drivers/gpu/drm/ttm/ttm_execbuf_util.c | 2 ++ drivers/gpu/drm/ttm/ttm_pool.c | 1 + drivers/gpu/drm/ttm/ttm_range_manager.c | 2 ++ drivers/gpu/drm/ttm/ttm_resource.c | 1 + drivers/gpu/drm/ttm/ttm_tt.c | 1 + 13 files changed, 22 insertions(+) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c index b91c13f46225..7aaf0d1395ff 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c +++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c @@ -2,6 +2,9 @@ /* * Copyright © 2023 Intel Corporation */ + +#include + #include #include "ttm_kunit_helpers.h" diff --git a/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c b/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c index f6d1c8a2845d..d7eb6471f2ed 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c +++ b/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c @@ -2,6 +2,9 @@ /* * Copyright © 2023 Intel Corporation */ + +#include + #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index d27691f2e451..fca0a1a3c6fd 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_backup.c b/drivers/gpu/drm/ttm/ttm_backup.c index ffaab68bd5dd..cb1b8e5dadf5 100644 --- a/drivers/gpu/drm/ttm/ttm_backup.c +++ b/drivers/gpu/drm/ttm/ttm_backup.c @@ -4,6 +4,8 @@ */ #include + +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 0f874f1e2526..bb9c5c8e16b5 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index b78365dc1fed..b9a772b26fa1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -28,6 +28,8 @@ /* * Authors: Thomas Hellstrom */ + +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index bdfa6ecfef05..b47020fca199 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -31,6 +31,8 @@ #define pr_fmt(fmt) "[TTM] " fmt +#include + #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index 36075772555a..816e2cba6016 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -28,6 +28,7 @@ #define pr_fmt(fmt) "[TTM DEVICE] " fmt #include +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index f1c60fa80c2d..bc7a83a9fe44 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -26,6 +26,8 @@ * **************************************************************************/ +#include + #include #include diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index a0436971b6a6..baf27c70a419 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -31,6 +31,7 @@ * cause they are rather slow compared to alloc_pages+map. */ +#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index ae11d07eb63a..db854b581d83 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -34,6 +34,8 @@ #include #include #include + +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 006202fcd3c2..e2c82ad07eb4 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 698cd4bf5e46..506e257dfba8 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From c8e3d6d77507c42cc1a02783f70e1e4e85e3c80f Mon Sep 17 00:00:00 2001 From: Thomas Hellström Date: Mon, 23 Jun 2025 17:53:11 +0200 Subject: drm/ttm: Use a struct for the common part of struct ttm_lru_walk and struct ttm_bo_lru_cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let the locking functions take the new struct ttm_lru_walk_arg as argument in order for them to be easily used from both types of walk. v2: - Whitespace fix Signed-off-by: Thomas Hellström Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250623155313.4901-2-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/ttm/ttm_bo.c | 24 ++++++++++++++---------- drivers/gpu/drm/ttm/ttm_bo_util.c | 26 ++++++++++++++------------ include/drm/ttm/ttm_bo.h | 23 ++++++++++++++--------- 3 files changed, 42 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index bb9c5c8e16b5..f4d9e68b21e7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -526,11 +526,11 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object * return 0; if (bo->deleted) { - lret = ttm_bo_wait_ctx(bo, walk->ctx); + lret = ttm_bo_wait_ctx(bo, walk->arg.ctx); if (!lret) ttm_bo_cleanup_memtype_use(bo); } else { - lret = ttm_bo_evict(bo, walk->ctx); + lret = ttm_bo_evict(bo, walk->arg.ctx); } if (lret) @@ -566,8 +566,10 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev, struct ttm_bo_evict_walk evict_walk = { .walk = { .ops = &ttm_evict_walk_ops, - .ctx = ctx, - .ticket = ticket, + .arg = { + .ctx = ctx, + .ticket = ticket, + } }, .place = place, .evictor = evictor, @@ -576,7 +578,7 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev, }; s64 lret; - evict_walk.walk.trylock_only = true; + evict_walk.walk.arg.trylock_only = true; lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1); /* One more attempt if we hit low limit? */ @@ -590,12 +592,12 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev, /* Reset low limit */ evict_walk.try_low = evict_walk.hit_low = false; /* If ticket-locking, repeat while making progress. */ - evict_walk.walk.trylock_only = false; + evict_walk.walk.arg.trylock_only = false; retry: do { /* The walk may clear the evict_walk.walk.ticket field */ - evict_walk.walk.ticket = ticket; + evict_walk.walk.arg.ticket = ticket; evict_walk.evicted = 0; lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1); } while (!lret && evict_walk.evicted); @@ -1106,7 +1108,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) struct ttm_place place = {.mem_type = bo->resource->mem_type}; struct ttm_bo_swapout_walk *swapout_walk = container_of(walk, typeof(*swapout_walk), walk); - struct ttm_operation_ctx *ctx = walk->ctx; + struct ttm_operation_ctx *ctx = walk->arg.ctx; s64 ret; /* @@ -1217,8 +1219,10 @@ s64 ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx, struct ttm_bo_swapout_walk swapout_walk = { .walk = { .ops = &ttm_swap_ops, - .ctx = ctx, - .trylock_only = true, + .arg = { + .ctx = ctx, + .trylock_only = true, + }, }, .gfp_flags = gfp_flags, }; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index b9a772b26fa1..5433eb87593d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -773,10 +773,12 @@ error_destroy_tt: return ret; } -static bool ttm_lru_walk_trylock(struct ttm_operation_ctx *ctx, +static bool ttm_lru_walk_trylock(struct ttm_lru_walk_arg *arg, struct ttm_buffer_object *bo, bool *needs_unlock) { + struct ttm_operation_ctx *ctx = arg->ctx; + *needs_unlock = false; if (dma_resv_trylock(bo->base.resv)) { @@ -792,17 +794,17 @@ static bool ttm_lru_walk_trylock(struct ttm_operation_ctx *ctx, return false; } -static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk, +static int ttm_lru_walk_ticketlock(struct ttm_lru_walk_arg *arg, struct ttm_buffer_object *bo, bool *needs_unlock) { struct dma_resv *resv = bo->base.resv; int ret; - if (walk->ctx->interruptible) - ret = dma_resv_lock_interruptible(resv, walk->ticket); + if (arg->ctx->interruptible) + ret = dma_resv_lock_interruptible(resv, arg->ticket); else - ret = dma_resv_lock(resv, walk->ticket); + ret = dma_resv_lock(resv, arg->ticket); if (!ret) { *needs_unlock = true; @@ -812,7 +814,7 @@ static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk, * after waiting for the ticketlock, revert back to * trylocking for this walk. */ - walk->ticket = NULL; + arg->ticket = NULL; } else if (ret == -EDEADLK) { /* Caller needs to exit the ww transaction. */ ret = -ENOSPC; @@ -879,10 +881,10 @@ s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev, * since if we do it the other way around, and the trylock fails, * we need to drop the lru lock to put the bo. */ - if (ttm_lru_walk_trylock(walk->ctx, bo, &bo_needs_unlock)) + if (ttm_lru_walk_trylock(&walk->arg, bo, &bo_needs_unlock)) bo_locked = true; - else if (!walk->ticket || walk->ctx->no_wait_gpu || - walk->trylock_only) + else if (!walk->arg.ticket || walk->arg.ctx->no_wait_gpu || + walk->arg.trylock_only) continue; if (!ttm_bo_get_unless_zero(bo)) { @@ -895,7 +897,7 @@ s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev, lret = 0; if (!bo_locked) - lret = ttm_lru_walk_ticketlock(walk, bo, &bo_needs_unlock); + lret = ttm_lru_walk_ticketlock(&walk->arg, bo, &bo_needs_unlock); /* * Note that in between the release of the lru lock and the @@ -972,7 +974,7 @@ ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs, { memset(curs, 0, sizeof(*curs)); ttm_resource_cursor_init(&curs->res_curs, man); - curs->ctx = ctx; + curs->arg.ctx = ctx; return curs; } @@ -983,7 +985,7 @@ ttm_bo_from_res_reserved(struct ttm_resource *res, struct ttm_bo_lru_cursor *cur { struct ttm_buffer_object *bo = res->bo; - if (!ttm_lru_walk_trylock(curs->ctx, bo, &curs->needs_unlock)) + if (!ttm_lru_walk_trylock(&curs->arg, bo, &curs->needs_unlock)) return NULL; if (!ttm_bo_get_unless_zero(bo)) { diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index 8ad6e2713625..c19ac92c33a9 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -207,11 +207,9 @@ struct ttm_lru_walk_ops { }; /** - * struct ttm_lru_walk - Structure describing a LRU walk. + * struct ttm_lru_walk_arg - Common part for the variants of BO LRU walk. */ -struct ttm_lru_walk { - /** @ops: Pointer to the ops structure. */ - const struct ttm_lru_walk_ops *ops; +struct ttm_lru_walk_arg { /** @ctx: Pointer to the struct ttm_operation_ctx. */ struct ttm_operation_ctx *ctx; /** @ticket: The struct ww_acquire_ctx if any. */ @@ -220,6 +218,16 @@ struct ttm_lru_walk { bool trylock_only; }; +/** + * struct ttm_lru_walk - Structure describing a LRU walk. + */ +struct ttm_lru_walk { + /** @ops: Pointer to the ops structure. */ + const struct ttm_lru_walk_ops *ops; + /** @arg: Common bo LRU walk arguments. */ + struct ttm_lru_walk_arg arg; +}; + s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev, struct ttm_resource_manager *man, s64 target); @@ -466,11 +474,6 @@ int ttm_bo_populate(struct ttm_buffer_object *bo, struct ttm_bo_lru_cursor { /** @res_curs: Embedded struct ttm_resource_cursor. */ struct ttm_resource_cursor res_curs; - /** - * @ctx: The struct ttm_operation_ctx used while looping. - * governs the locking mode. - */ - struct ttm_operation_ctx *ctx; /** * @bo: Buffer object pointer if a buffer object is refcounted, * NULL otherwise. @@ -481,6 +484,8 @@ struct ttm_bo_lru_cursor { * unlock before the next iteration or after loop exit. */ bool needs_unlock; + /** @arg: Common BO LRU walk arguments. */ + struct ttm_lru_walk_arg arg; }; void ttm_bo_lru_cursor_fini(struct ttm_bo_lru_cursor *curs); -- cgit v1.2.3 From e1e85eb0a977f1eb1d17d4627aceaa8eeac37159 Mon Sep 17 00:00:00 2001 From: Thomas Hellström Date: Mon, 23 Jun 2025 17:53:12 +0200 Subject: drm/ttm, drm/xe: Modify the struct ttm_bo_lru_walk_cursor initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of the struct ttm_operation_ctx, Pass a struct ttm_lru_walk_arg to enable us to easily extend the walk functionality, and to implement ttm_lru_walk_for_evict() using the guarded LRU iteration. Signed-off-by: Thomas Hellström Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250623155313.4901-3-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/ttm/ttm_bo_util.c | 10 +++++----- drivers/gpu/drm/xe/xe_shrinker.c | 3 ++- include/drm/ttm/ttm_bo.h | 16 ++++++++-------- 3 files changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 5433eb87593d..6de1f0c432c2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -958,11 +958,11 @@ EXPORT_SYMBOL(ttm_bo_lru_cursor_fini); * ttm_bo_lru_cursor_init() - Initialize a struct ttm_bo_lru_cursor * @curs: The ttm_bo_lru_cursor to initialize. * @man: The ttm resource_manager whose LRU lists to iterate over. - * @ctx: The ttm_operation_ctx to govern the locking. + * @arg: The ttm_lru_walk_arg to govern the walk. * * Initialize a struct ttm_bo_lru_cursor. Currently only trylocking * or prelocked buffer objects are available as detailed by - * @ctx::resv and @ctx::allow_res_evict. Ticketlocking is not + * @arg->ctx.resv and @arg->ctx.allow_res_evict. Ticketlocking is not * supported. * * Return: Pointer to @curs. The function does not fail. @@ -970,11 +970,11 @@ EXPORT_SYMBOL(ttm_bo_lru_cursor_fini); struct ttm_bo_lru_cursor * ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs, struct ttm_resource_manager *man, - struct ttm_operation_ctx *ctx) + struct ttm_lru_walk_arg *arg) { memset(curs, 0, sizeof(*curs)); ttm_resource_cursor_init(&curs->res_curs, man); - curs->arg.ctx = ctx; + curs->arg = arg; return curs; } @@ -985,7 +985,7 @@ ttm_bo_from_res_reserved(struct ttm_resource *res, struct ttm_bo_lru_cursor *cur { struct ttm_buffer_object *bo = res->bo; - if (!ttm_lru_walk_trylock(&curs->arg, bo, &curs->needs_unlock)) + if (!ttm_lru_walk_trylock(curs->arg, bo, &curs->needs_unlock)) return NULL; if (!ttm_bo_get_unless_zero(bo)) { diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c index 86d47aaf0358..c9df97ccadc3 100644 --- a/drivers/gpu/drm/xe/xe_shrinker.c +++ b/drivers/gpu/drm/xe/xe_shrinker.c @@ -65,11 +65,12 @@ static s64 xe_shrinker_walk(struct xe_device *xe, struct ttm_resource_manager *man = ttm_manager_type(&xe->ttm, mem_type); struct ttm_bo_lru_cursor curs; struct ttm_buffer_object *ttm_bo; + struct ttm_lru_walk_arg arg = {.ctx = ctx}; if (!man || !man->use_tt) continue; - ttm_bo_lru_for_each_reserved_guarded(&curs, man, ctx, ttm_bo) { + ttm_bo_lru_for_each_reserved_guarded(&curs, man, &arg, ttm_bo) { if (!ttm_bo_shrink_suitable(ttm_bo, ctx)) continue; diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index c19ac92c33a9..ab9a6b343a53 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -484,8 +484,8 @@ struct ttm_bo_lru_cursor { * unlock before the next iteration or after loop exit. */ bool needs_unlock; - /** @arg: Common BO LRU walk arguments. */ - struct ttm_lru_walk_arg arg; + /** @arg: Pointer to common BO LRU walk arguments. */ + struct ttm_lru_walk_arg *arg; }; void ttm_bo_lru_cursor_fini(struct ttm_bo_lru_cursor *curs); @@ -493,7 +493,7 @@ void ttm_bo_lru_cursor_fini(struct ttm_bo_lru_cursor *curs); struct ttm_bo_lru_cursor * ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs, struct ttm_resource_manager *man, - struct ttm_operation_ctx *ctx); + struct ttm_lru_walk_arg *arg); struct ttm_buffer_object *ttm_bo_lru_cursor_first(struct ttm_bo_lru_cursor *curs); @@ -504,9 +504,9 @@ struct ttm_buffer_object *ttm_bo_lru_cursor_next(struct ttm_bo_lru_cursor *curs) */ DEFINE_CLASS(ttm_bo_lru_cursor, struct ttm_bo_lru_cursor *, if (_T) {ttm_bo_lru_cursor_fini(_T); }, - ttm_bo_lru_cursor_init(curs, man, ctx), + ttm_bo_lru_cursor_init(curs, man, arg), struct ttm_bo_lru_cursor *curs, struct ttm_resource_manager *man, - struct ttm_operation_ctx *ctx); + struct ttm_lru_walk_arg *arg); static inline void * class_ttm_bo_lru_cursor_lock_ptr(class_ttm_bo_lru_cursor_t *_T) { return *_T; } @@ -517,7 +517,7 @@ class_ttm_bo_lru_cursor_lock_ptr(class_ttm_bo_lru_cursor_t *_T) * resources on LRU lists. * @_cursor: struct ttm_bo_lru_cursor to use for the iteration. * @_man: The resource manager whose LRU lists to iterate over. - * @_ctx: The struct ttm_operation_context to govern the @_bo locking. + * @_arg: The struct ttm_lru_walk_arg to govern the LRU walk. * @_bo: The struct ttm_buffer_object pointer pointing to the buffer object * for the current iteration. * @@ -530,8 +530,8 @@ class_ttm_bo_lru_cursor_lock_ptr(class_ttm_bo_lru_cursor_t *_T) * example a return or break statement. Exiting the loop will also unlock * (if needed) and unreference @_bo. */ -#define ttm_bo_lru_for_each_reserved_guarded(_cursor, _man, _ctx, _bo) \ - scoped_guard(ttm_bo_lru_cursor, _cursor, _man, _ctx) \ +#define ttm_bo_lru_for_each_reserved_guarded(_cursor, _man, _arg, _bo) \ + scoped_guard(ttm_bo_lru_cursor, _cursor, _man, _arg) \ for ((_bo) = ttm_bo_lru_cursor_first(_cursor); (_bo); \ (_bo) = ttm_bo_lru_cursor_next(_cursor)) -- cgit v1.2.3 From bb8aa27eff6f3376242da37c2d02b9dcc66934b1 Mon Sep 17 00:00:00 2001 From: Thomas Hellström Date: Mon, 23 Jun 2025 17:53:13 +0200 Subject: drm/ttm, drm_xe, Implement ttm_lru_walk_for_evict() using the guarded LRU iteration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid duplicating the tricky bo locking implementation, Implement ttm_lru_walk_for_evict() using the guarded bo LRU iteration. To facilitate this, support ticketlocking from the guarded bo LRU iteration. v2: - Clean up some static function interfaces (Christian König) - Fix Handling -EALREADY from ticketlocking in the loop by skipping to the next item. (Intel CI) Signed-off-by: Thomas Hellström Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250623155313.4901-4-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/ttm/ttm_bo_util.c | 188 +++++++++++++++----------------------- drivers/gpu/drm/xe/xe_shrinker.c | 7 +- include/drm/ttm/ttm_bo.h | 9 +- 3 files changed, 88 insertions(+), 116 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 6de1f0c432c2..250675d56b1c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -773,16 +773,15 @@ error_destroy_tt: return ret; } -static bool ttm_lru_walk_trylock(struct ttm_lru_walk_arg *arg, - struct ttm_buffer_object *bo, - bool *needs_unlock) +static bool ttm_lru_walk_trylock(struct ttm_bo_lru_cursor *curs, + struct ttm_buffer_object *bo) { - struct ttm_operation_ctx *ctx = arg->ctx; + struct ttm_operation_ctx *ctx = curs->arg->ctx; - *needs_unlock = false; + curs->needs_unlock = false; if (dma_resv_trylock(bo->base.resv)) { - *needs_unlock = true; + curs->needs_unlock = true; return true; } @@ -794,10 +793,10 @@ static bool ttm_lru_walk_trylock(struct ttm_lru_walk_arg *arg, return false; } -static int ttm_lru_walk_ticketlock(struct ttm_lru_walk_arg *arg, - struct ttm_buffer_object *bo, - bool *needs_unlock) +static int ttm_lru_walk_ticketlock(struct ttm_bo_lru_cursor *curs, + struct ttm_buffer_object *bo) { + struct ttm_lru_walk_arg *arg = curs->arg; struct dma_resv *resv = bo->base.resv; int ret; @@ -807,7 +806,7 @@ static int ttm_lru_walk_ticketlock(struct ttm_lru_walk_arg *arg, ret = dma_resv_lock(resv, arg->ticket); if (!ret) { - *needs_unlock = true; + curs->needs_unlock = true; /* * Only a single ticketlock per loop. Ticketlocks are prone * to return -EDEADLK causing the eviction to fail, so @@ -823,12 +822,6 @@ static int ttm_lru_walk_ticketlock(struct ttm_lru_walk_arg *arg, return ret; } -static void ttm_lru_walk_unlock(struct ttm_buffer_object *bo, bool locked) -{ - if (locked) - dma_resv_unlock(bo->base.resv); -} - /** * ttm_lru_walk_for_evict() - Perform a LRU list walk, with actions taken on * valid items. @@ -863,64 +856,21 @@ static void ttm_lru_walk_unlock(struct ttm_buffer_object *bo, bool locked) s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev, struct ttm_resource_manager *man, s64 target) { - struct ttm_resource_cursor cursor; - struct ttm_resource *res; + struct ttm_bo_lru_cursor cursor; + struct ttm_buffer_object *bo; s64 progress = 0; s64 lret; - spin_lock(&bdev->lru_lock); - ttm_resource_cursor_init(&cursor, man); - ttm_resource_manager_for_each_res(&cursor, res) { - struct ttm_buffer_object *bo = res->bo; - bool bo_needs_unlock = false; - bool bo_locked = false; - int mem_type; - - /* - * Attempt a trylock before taking a reference on the bo, - * since if we do it the other way around, and the trylock fails, - * we need to drop the lru lock to put the bo. - */ - if (ttm_lru_walk_trylock(&walk->arg, bo, &bo_needs_unlock)) - bo_locked = true; - else if (!walk->arg.ticket || walk->arg.ctx->no_wait_gpu || - walk->arg.trylock_only) - continue; - - if (!ttm_bo_get_unless_zero(bo)) { - ttm_lru_walk_unlock(bo, bo_needs_unlock); - continue; - } - - mem_type = res->mem_type; - spin_unlock(&bdev->lru_lock); - - lret = 0; - if (!bo_locked) - lret = ttm_lru_walk_ticketlock(&walk->arg, bo, &bo_needs_unlock); - - /* - * Note that in between the release of the lru lock and the - * ticketlock, the bo may have switched resource, - * and also memory type, since the resource may have been - * freed and allocated again with a different memory type. - * In that case, just skip it. - */ - if (!lret && bo->resource && bo->resource->mem_type == mem_type) - lret = walk->ops->process_bo(walk, bo); - - ttm_lru_walk_unlock(bo, bo_needs_unlock); - ttm_bo_put(bo); + ttm_bo_lru_for_each_reserved_guarded(&cursor, man, &walk->arg, bo) { + lret = walk->ops->process_bo(walk, bo); if (lret == -EBUSY || lret == -EALREADY) lret = 0; progress = (lret < 0) ? lret : progress + lret; - - spin_lock(&bdev->lru_lock); if (progress < 0 || progress >= target) break; } - ttm_resource_cursor_fini(&cursor); - spin_unlock(&bdev->lru_lock); + if (IS_ERR(bo)) + return PTR_ERR(bo); return progress; } @@ -960,10 +910,7 @@ EXPORT_SYMBOL(ttm_bo_lru_cursor_fini); * @man: The ttm resource_manager whose LRU lists to iterate over. * @arg: The ttm_lru_walk_arg to govern the walk. * - * Initialize a struct ttm_bo_lru_cursor. Currently only trylocking - * or prelocked buffer objects are available as detailed by - * @arg->ctx.resv and @arg->ctx.allow_res_evict. Ticketlocking is not - * supported. + * Initialize a struct ttm_bo_lru_cursor. * * Return: Pointer to @curs. The function does not fail. */ @@ -981,21 +928,67 @@ ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs, EXPORT_SYMBOL(ttm_bo_lru_cursor_init); static struct ttm_buffer_object * -ttm_bo_from_res_reserved(struct ttm_resource *res, struct ttm_bo_lru_cursor *curs) +__ttm_bo_lru_cursor_next(struct ttm_bo_lru_cursor *curs) { - struct ttm_buffer_object *bo = res->bo; + spinlock_t *lru_lock = &curs->res_curs.man->bdev->lru_lock; + struct ttm_resource *res = NULL; + struct ttm_buffer_object *bo; + struct ttm_lru_walk_arg *arg = curs->arg; + bool first = !curs->bo; - if (!ttm_lru_walk_trylock(curs->arg, bo, &curs->needs_unlock)) - return NULL; + ttm_bo_lru_cursor_cleanup_bo(curs); - if (!ttm_bo_get_unless_zero(bo)) { - if (curs->needs_unlock) - dma_resv_unlock(bo->base.resv); - return NULL; + spin_lock(lru_lock); + for (;;) { + int mem_type, ret = 0; + bool bo_locked = false; + + if (first) { + res = ttm_resource_manager_first(&curs->res_curs); + first = false; + } else { + res = ttm_resource_manager_next(&curs->res_curs); + } + if (!res) + break; + + bo = res->bo; + if (ttm_lru_walk_trylock(curs, bo)) + bo_locked = true; + else if (!arg->ticket || arg->ctx->no_wait_gpu || arg->trylock_only) + continue; + + if (!ttm_bo_get_unless_zero(bo)) { + if (curs->needs_unlock) + dma_resv_unlock(bo->base.resv); + continue; + } + + mem_type = res->mem_type; + spin_unlock(lru_lock); + if (!bo_locked) + ret = ttm_lru_walk_ticketlock(curs, bo); + + /* + * Note that in between the release of the lru lock and the + * ticketlock, the bo may have switched resource, + * and also memory type, since the resource may have been + * freed and allocated again with a different memory type. + * In that case, just skip it. + */ + curs->bo = bo; + if (!ret && bo->resource && bo->resource->mem_type == mem_type) + return bo; + + ttm_bo_lru_cursor_cleanup_bo(curs); + if (ret && ret != -EALREADY) + return ERR_PTR(ret); + + spin_lock(lru_lock); } - curs->bo = bo; - return bo; + spin_unlock(lru_lock); + return res ? bo : NULL; } /** @@ -1009,25 +1002,7 @@ ttm_bo_from_res_reserved(struct ttm_resource *res, struct ttm_bo_lru_cursor *cur */ struct ttm_buffer_object *ttm_bo_lru_cursor_next(struct ttm_bo_lru_cursor *curs) { - spinlock_t *lru_lock = &curs->res_curs.man->bdev->lru_lock; - struct ttm_resource *res = NULL; - struct ttm_buffer_object *bo; - - ttm_bo_lru_cursor_cleanup_bo(curs); - - spin_lock(lru_lock); - for (;;) { - res = ttm_resource_manager_next(&curs->res_curs); - if (!res) - break; - - bo = ttm_bo_from_res_reserved(res, curs); - if (bo) - break; - } - - spin_unlock(lru_lock); - return res ? bo : NULL; + return __ttm_bo_lru_cursor_next(curs); } EXPORT_SYMBOL(ttm_bo_lru_cursor_next); @@ -1041,21 +1016,8 @@ EXPORT_SYMBOL(ttm_bo_lru_cursor_next); */ struct ttm_buffer_object *ttm_bo_lru_cursor_first(struct ttm_bo_lru_cursor *curs) { - spinlock_t *lru_lock = &curs->res_curs.man->bdev->lru_lock; - struct ttm_buffer_object *bo; - struct ttm_resource *res; - - spin_lock(lru_lock); - res = ttm_resource_manager_first(&curs->res_curs); - if (!res) { - spin_unlock(lru_lock); - return NULL; - } - - bo = ttm_bo_from_res_reserved(res, curs); - spin_unlock(lru_lock); - - return bo ? bo : ttm_bo_lru_cursor_next(curs); + ttm_bo_lru_cursor_cleanup_bo(curs); + return __ttm_bo_lru_cursor_next(curs); } EXPORT_SYMBOL(ttm_bo_lru_cursor_first); diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c index c9df97ccadc3..532f6dd7eb6d 100644 --- a/drivers/gpu/drm/xe/xe_shrinker.c +++ b/drivers/gpu/drm/xe/xe_shrinker.c @@ -65,7 +65,10 @@ static s64 xe_shrinker_walk(struct xe_device *xe, struct ttm_resource_manager *man = ttm_manager_type(&xe->ttm, mem_type); struct ttm_bo_lru_cursor curs; struct ttm_buffer_object *ttm_bo; - struct ttm_lru_walk_arg arg = {.ctx = ctx}; + struct ttm_lru_walk_arg arg = { + .ctx = ctx, + .trylock_only = true, + }; if (!man || !man->use_tt) continue; @@ -82,6 +85,8 @@ static s64 xe_shrinker_walk(struct xe_device *xe, if (*scanned >= to_scan) break; } + /* Trylocks should never error, just fail. */ + xe_assert(xe, !IS_ERR(ttm_bo)); } return freed; diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index ab9a6b343a53..894ff7ccd68e 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -529,10 +529,15 @@ class_ttm_bo_lru_cursor_lock_ptr(class_ttm_bo_lru_cursor_t *_T) * up at looping termination, even if terminated prematurely by, for * example a return or break statement. Exiting the loop will also unlock * (if needed) and unreference @_bo. + * + * Return: If locking of a bo returns an error, then iteration is terminated + * and @_bo is set to a corresponding error pointer. It's illegal to + * dereference @_bo after loop exit. */ #define ttm_bo_lru_for_each_reserved_guarded(_cursor, _man, _arg, _bo) \ scoped_guard(ttm_bo_lru_cursor, _cursor, _man, _arg) \ - for ((_bo) = ttm_bo_lru_cursor_first(_cursor); (_bo); \ - (_bo) = ttm_bo_lru_cursor_next(_cursor)) + for ((_bo) = ttm_bo_lru_cursor_first(_cursor); \ + !IS_ERR_OR_NULL(_bo); \ + (_bo) = ttm_bo_lru_cursor_next(_cursor)) #endif -- cgit v1.2.3 From 718370ff283284f191155a5eb9d4f376aaf93bb8 Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Tue, 24 Jun 2025 11:01:14 +0200 Subject: drm/ttm: Add ttm_bo_kmap_try_from_panic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the ttm bo is backed by pages, then it's possible to safely kmap one page at a time, using kmap_try_from_panic(). Unfortunately there is no way to do the same with ioremap, so it only supports the kmap case. This is needed for proper drm_panic support with xe driver. Signed-off-by: Jocelyn Falempe Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250624091501.257661-6-jfalempe@redhat.com Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/ttm/ttm_bo_util.c | 27 +++++++++++++++++++++++++++ include/drm/ttm/ttm_bo.h | 1 + 2 files changed, 28 insertions(+) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index b9a772b26fa1..ad95e8b9852b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -381,6 +381,33 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, return (!map->virtual) ? -ENOMEM : 0; } +/** + * + * ttm_bo_kmap_try_from_panic + * + * @bo: The buffer object + * @page: The page to map + * + * Sets up a kernel virtual mapping using kmap_local_page_try_from_panic(). + * This should only be called from the panic handler, if you make sure the bo + * is the one being displayed, so is properly allocated, and protected. + * + * Returns the vaddr, that you can use to write to the bo, and that you should + * pass to kunmap_local() when you're done with this page, or NULL if the bo + * is in iomem. + */ +void *ttm_bo_kmap_try_from_panic(struct ttm_buffer_object *bo, unsigned long page) +{ + if (page + 1 > PFN_UP(bo->resource->size)) + return NULL; + + if (!bo->resource->bus.is_iomem && bo->ttm->pages && bo->ttm->pages[page]) + return kmap_local_page_try_from_panic(bo->ttm->pages[page]); + + return NULL; +} +EXPORT_SYMBOL(ttm_bo_kmap_try_from_panic); + /** * ttm_bo_kmap * diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index 8ad6e2713625..5332ee74d95b 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -401,6 +401,7 @@ int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo, int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map); void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); +void *ttm_bo_kmap_try_from_panic(struct ttm_buffer_object *bo, unsigned long page); int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map); void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map); int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo); -- cgit v1.2.3 From d6a59ee852758bc69c4cc821954db277a2bd5b93 Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Mon, 30 Jun 2025 16:41:08 +0200 Subject: drm/ttm: Remove unneeded blank line in comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an unneeded blank line in the documentation of the function ttm_bo_kmap_try_from_panic(). Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506290453.NeTXAb7S-lkp@intel.com/ Fixes: 718370ff28328 ("drm/ttm: Add ttm_bo_kmap_try_from_panic()") Signed-off-by: Jocelyn Falempe Reviewed-by: Christian König Acked-by: Thomas Zimmermann Link: https://lore.kernel.org/r/20250630144154.44661-1-jfalempe@redhat.com Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/ttm/ttm_bo_util.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ad95e8b9852b..16cb4065214d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -382,7 +382,6 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, } /** - * * ttm_bo_kmap_try_from_panic * * @bo: The buffer object -- cgit v1.2.3 From 40b6a946d21ee7b2b6d394bb2f1cdd3973aa9da5 Mon Sep 17 00:00:00 2001 From: Samuel Zhang Date: Thu, 10 Jul 2025 14:23:09 +0800 Subject: drm/ttm: add new api ttm_device_prepare_hibernation() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new api is used for hibernation to move GTT BOs to shmem after VRAM eviction. shmem will be flushed to swap disk later to reduce the system memory usage for hibernation. Signed-off-by: Samuel Zhang Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250710062313.3226149-2-guoqing.zhang@amd.com Signed-off-by: Mario Limonciello --- drivers/gpu/drm/ttm/ttm_device.c | 22 ++++++++++++++++++++++ include/drm/ttm/ttm_device.h | 1 + 2 files changed, 23 insertions(+) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index 816e2cba6016..c3e2fcbdd2cc 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -125,6 +125,28 @@ out: return ret; } +/** + * ttm_device_prepare_hibernation - move GTT BOs to shmem for hibernation. + * + * @bdev: A pointer to a struct ttm_device to prepare hibernation for. + * + * Return: 0 on success, negative number on failure. + */ +int ttm_device_prepare_hibernation(struct ttm_device *bdev) +{ + struct ttm_operation_ctx ctx = { + .interruptible = false, + .no_wait_gpu = false, + }; + int ret; + + do { + ret = ttm_device_swapout(bdev, &ctx, GFP_KERNEL); + } while (ret > 0); + return ret; +} +EXPORT_SYMBOL(ttm_device_prepare_hibernation); + /* * A buffer object shrink method that tries to swap out the first * buffer object on the global::swap_lru list. diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 39b8636b1845..592b5f802859 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -272,6 +272,7 @@ struct ttm_device { int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags); int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx, gfp_t gfp_flags); +int ttm_device_prepare_hibernation(struct ttm_device *bdev); static inline struct ttm_resource_manager * ttm_manager_type(struct ttm_device *bdev, int mem_type) -- cgit v1.2.3 From 8b824e9d2d0acf9f8c7f33fa8afd6016e8bb9ab4 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 10 Jul 2025 15:45:20 +0200 Subject: drm/ttm: fix locking in test ttm_bo_validate_no_placement_signaled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test works even without it, but lockdep starts screaming when it is activated. Trivially fix it by acquiring the lock before we try to allocate something. Signed-off-by: Christian König Reviewed-by: Matthew Brost Link: https://lore.kernel.org/r/20250710144129.1803-1-christian.koenig@amd.com --- drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c index 3148f5d3dbd6..38f476787302 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c @@ -542,14 +542,15 @@ static void ttm_bo_validate_no_placement_signaled(struct kunit *test) bo->ttm = old_tt; } - err = ttm_resource_alloc(bo, place, &bo->resource, NULL); - KUNIT_EXPECT_EQ(test, err, 0); - KUNIT_ASSERT_EQ(test, man->usage, size); - placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL); KUNIT_ASSERT_NOT_NULL(test, placement); ttm_bo_reserve(bo, false, false, NULL); + + err = ttm_resource_alloc(bo, place, &bo->resource, NULL); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_ASSERT_EQ(test, man->usage, size); + err = ttm_bo_validate(bo, placement, &ctx); ttm_bo_unreserve(bo); -- cgit v1.2.3 From 76689eb526673d2dfab82d49c41e03caaff838fe Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 10 Jul 2025 16:25:21 +0200 Subject: drm/ttm: remove ttm_bo_validate_swapout test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test is quite fragile since it tries to allocate halve available system memory + 1 page. If the system has either not enough memory to make the allocation work with other things running in parallel or to much memory so the allocation fails as to large/invalid the test will fail. Completely remove the test. We already validate swapout on the device level and that test seems to be stable. Signed-off-by: Christian König Reviewed-by: Matthew Brost Link: https://lore.kernel.org/r/20250710144129.1803-2-christian.koenig@amd.com --- drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c | 51 ------------------------ 1 file changed, 51 deletions(-) (limited to 'drivers/gpu/drm/ttm') diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c index 38f476787302..1bcc67977f48 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c @@ -758,56 +758,6 @@ static void ttm_bo_validate_move_fence_not_signaled(struct kunit *test) ttm_mock_manager_fini(priv->ttm_dev, snd_mem); } -static void ttm_bo_validate_swapout(struct kunit *test) -{ - unsigned long size_big, size = ALIGN(BO_SIZE, PAGE_SIZE); - enum ttm_bo_type bo_type = ttm_bo_type_device; - struct ttm_buffer_object *bo_small, *bo_big; - struct ttm_test_devices *priv = test->priv; - struct ttm_operation_ctx ctx = { }; - struct ttm_placement *placement; - u32 mem_type = TTM_PL_TT; - struct ttm_place *place; - struct sysinfo si; - int err; - - si_meminfo(&si); - size_big = ALIGN(((u64)si.totalram * si.mem_unit / 2), PAGE_SIZE); - - ttm_mock_manager_init(priv->ttm_dev, mem_type, size_big + size); - - place = ttm_place_kunit_init(test, mem_type, 0); - placement = ttm_placement_kunit_init(test, place, 1); - - bo_small = kunit_kzalloc(test, sizeof(*bo_small), GFP_KERNEL); - KUNIT_ASSERT_NOT_NULL(test, bo_small); - - drm_gem_private_object_init(priv->drm, &bo_small->base, size); - - err = ttm_bo_init_reserved(priv->ttm_dev, bo_small, bo_type, placement, - PAGE_SIZE, &ctx, NULL, NULL, - &dummy_ttm_bo_destroy); - KUNIT_EXPECT_EQ(test, err, 0); - dma_resv_unlock(bo_small->base.resv); - - bo_big = ttm_bo_kunit_init(test, priv, size_big, NULL); - - dma_resv_lock(bo_big->base.resv, NULL); - err = ttm_bo_validate(bo_big, placement, &ctx); - dma_resv_unlock(bo_big->base.resv); - - KUNIT_EXPECT_EQ(test, err, 0); - KUNIT_EXPECT_NOT_NULL(test, bo_big->resource); - KUNIT_EXPECT_EQ(test, bo_big->resource->mem_type, mem_type); - KUNIT_EXPECT_EQ(test, bo_small->resource->mem_type, TTM_PL_SYSTEM); - KUNIT_EXPECT_TRUE(test, bo_small->ttm->page_flags & TTM_TT_FLAG_SWAPPED); - - ttm_bo_put(bo_big); - ttm_bo_put(bo_small); - - ttm_mock_manager_fini(priv->ttm_dev, mem_type); -} - static void ttm_bo_validate_happy_evict(struct kunit *test) { u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT, @@ -1202,7 +1152,6 @@ static struct kunit_case ttm_bo_validate_test_cases[] = { KUNIT_CASE(ttm_bo_validate_move_fence_signaled), KUNIT_CASE_PARAM(ttm_bo_validate_move_fence_not_signaled, ttm_bo_validate_wait_gen_params), - KUNIT_CASE(ttm_bo_validate_swapout), KUNIT_CASE(ttm_bo_validate_happy_evict), KUNIT_CASE(ttm_bo_validate_all_pinned_evict), KUNIT_CASE(ttm_bo_validate_allowed_only_evict), -- cgit v1.2.3