* [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker
@ 2024-05-21 7:16 Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
` (29 more replies)
0 siblings, 30 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Somalapuram Amaranath,
Christian König, Matthew Brost, dri-devel
This series implements TTM shrinker / eviction helpers and an xe bo
shrinker. It builds on two previous series, *and obsoletes these*. First
https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg484425.html
Second the previous TTM shrinker series
https://lore.kernel.org/linux-mm/b7491378-defd-4f1c-31e2-29e4c77e2d67@amd.com/T/
Where the comment about layering
https://lore.kernel.org/linux-mm/b7491378-defd-4f1c-31e2-29e4c77e2d67@amd.com/T/#ma918844aa8a6efe8768fdcda0c6590d5c93850c9
now addressed, and this version also implements shmem objects for backup
rather than direct swap-cache insertions, which was used in the previuos
series. It turns out that with per-page backup / shrinking, shmem objects
appears to work just as well as direct swap-cache insertions with the
added benefit that was introduced in the previous TTM shrinker series to
avoid running out of swap entries isn't really needed.
Patch 1-4 implements restartable LRU list iteration.
Patch 5 implements a LRU walker + resv locking helper
Patch 6 moves TTM swapping over to the walker.
Patch 7 moves TTM eviction over to the walker.
Patch 8 could in theory be skipped but introduces a possibility to easily
add or test multiple backup backends, like the direct swap-cache
insertion or even files into fast dedicated nvme storage for for example.
Patch 9 introduces helpers in the ttm_pool code for page-by-page shrinking
and recovery. It avoids having to temporarily allocate a huge amount of
memory to be able to shrink a buffer object. It also introduces the
possibility to immediately write-back pages if needed, since that tends
to be a bit delayed when left to kswapd.
Patch 10 Adds a simple error injection to the above code to help increase
test coverage.
Patch 11 Implements an xe bo shrinker and a common helper in TTM for
shrinking.
Patch 12-21 are really a separate POC series, for introducing drm_exec locking
in TTM. The patch touches both drm_exec and dma-buf and is for now marked as
an RFC:
Patch 12 Introduces dma_resv_trylock_ctx.
Patches 13-14 deal with introducing drm_exec_trylock.
Patch 15 adds a snapshot capability to drm_exec.
Patch 16 adds an evict mode locking capability to drm_exec
Patch 17 converts the LRU + locking walker to drm_exec.
Patch 18 converts TTM vm to use drm_exec.
Patch 19 converts the xe fault handler to drm_exec.
Patch 20 converts bo initialization locking to drm_exec
Patch 21 introduces drm_exec locking around some of the
bo validation callsites in drm_exec.
v2:
- Squash obsolete revision history in the patch commit messages.
- Fix a couple of review comments by Christian
- Don't store the mem_type in the TTM managers but in the
resource cursor.
- Rename introduced TTM *back_up* function names to *backup*
- Add ttm pool recovery fault injection.
- Shrinker xe kunit test
- Various bugfixes
v3:
- Address some review comments from Matthew Brost and Christian König.
- Use the restartable LRU walk for TTM swapping and eviction.
- Provide a POC drm_exec locking implementation for exhaustive
eviction. (Christian König).
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Thomas Hellström (21):
drm/ttm: Allow TTM LRU list nodes of different types
drm/ttm: Slightly clean up LRU list iteration
drm/ttm: Use LRU hitches
drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist
moves
drm/ttm: Provide a generic LRU walker helper
drm/ttm: Use the LRU walker helper for swapping
drm/ttm: Use the LRU walker for eviction
drm/ttm: Add a virtual base class for graphics memory backup
drm/ttm/pool: Provide a helper to shrink pages
drm/ttm: Use fault-injection to test error paths
drm/ttm, drm/xe: Add a shrinker for xe bos
dma-buf/dma-resv: Introduce dma_resv_trylock_ctx()
drm/exec: Rework contended locking
drm/exec: Introduce a drm_exec_trylock_obj() function
drm/exec: Add a snapshot capability
drm/exec: Introduce an evict mode
drm/ttm: Support drm_exec locking for eviction and swapping
drm/ttm: Convert ttm vm to using drm_exec
drm/xe: Use drm_exec for fault locking
drm/ttm: Use drm_exec_trylock for bo initialization
drm/xe: Initial support for drm exec locking during validate
drivers/gpu/drm/Kconfig | 10 +
.../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 12 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
drivers/gpu/drm/drm_exec.c | 209 ++++++-
drivers/gpu/drm/drm_gpuvm.c | 8 +-
drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 4 +-
drivers/gpu/drm/imagination/pvr_job.c | 2 +-
drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-
drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
drivers/gpu/drm/radeon/radeon_gem.c | 4 +-
drivers/gpu/drm/tests/drm_exec_test.c | 12 +-
drivers/gpu/drm/ttm/Makefile | 2 +-
drivers/gpu/drm/ttm/ttm_backup_shmem.c | 137 +++++
drivers/gpu/drm/ttm/ttm_bo.c | 516 +++++++++---------
drivers/gpu/drm/ttm/ttm_bo_util.c | 241 ++++++++
drivers/gpu/drm/ttm/ttm_bo_vm.c | 101 ++--
drivers/gpu/drm/ttm/ttm_device.c | 29 +-
drivers/gpu/drm/ttm/ttm_pool.c | 412 +++++++++++++-
drivers/gpu/drm/ttm/ttm_resource.c | 264 +++++++--
drivers/gpu/drm/ttm/ttm_tt.c | 37 ++
drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 6 +-
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/display/xe_fb_pin.c | 2 +-
drivers/gpu/drm/xe/tests/xe_bo.c | 124 ++++-
drivers/gpu/drm/xe/tests/xe_bo_test.c | 1 +
drivers/gpu/drm/xe/tests/xe_bo_test.h | 1 +
drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 +-
drivers/gpu/drm/xe/tests/xe_migrate.c | 2 +-
drivers/gpu/drm/xe/xe_bo.c | 173 ++++--
drivers/gpu/drm/xe/xe_bo.h | 8 +-
drivers/gpu/drm/xe/xe_device.c | 8 +
drivers/gpu/drm/xe/xe_device_types.h | 2 +
drivers/gpu/drm/xe/xe_dma_buf.c | 2 +-
drivers/gpu/drm/xe/xe_ggtt.c | 2 +-
drivers/gpu/drm/xe/xe_gt_pagefault.c | 6 +-
drivers/gpu/drm/xe/xe_shrinker.c | 224 ++++++++
drivers/gpu/drm/xe/xe_shrinker.h | 18 +
drivers/gpu/drm/xe/xe_vm.c | 18 +-
include/drm/drm_exec.h | 62 ++-
include/drm/ttm/ttm_backup.h | 136 +++++
include/drm/ttm/ttm_bo.h | 59 +-
include/drm/ttm/ttm_pool.h | 5 +
include/drm/ttm/ttm_resource.h | 99 +++-
include/drm/ttm/ttm_tt.h | 20 +
include/linux/dma-resv.h | 23 +-
53 files changed, 2535 insertions(+), 531 deletions(-)
create mode 100644 drivers/gpu/drm/ttm/ttm_backup_shmem.c
create mode 100644 drivers/gpu/drm/xe/xe_shrinker.c
create mode 100644 drivers/gpu/drm/xe/xe_shrinker.h
create mode 100644 include/drm/ttm/ttm_backup.h
--
2.44.0
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 13:12 ` Matthew Brost
2024-05-28 9:16 ` Christian König
2024-05-21 7:16 ` [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration Thomas Hellström
` (28 subsequent siblings)
29 siblings, 2 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
To be able to handle list unlocking while traversing the LRU
list, we want the iterators not only to point to the next
position of the list traversal, but to insert themselves as
list nodes at that point to work around the fact that the
next node might otherwise disappear from the list while
the iterator is pointing to it.
These list nodes need to be easily distinguishable from other
list nodes so that others traversing the list can skip
over them.
So declare a struct ttm_lru_item, with a struct list_head member
and a type enum. This will slightly increase the size of a
struct ttm_resource.
Changes in previous series:
- Update enum ttm_lru_item_type documentation.
v3:
- Introduce ttm_lru_first_res_or_null()
(Christian König, Thomas Hellström)
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_device.c | 4 +-
drivers/gpu/drm/ttm/ttm_resource.c | 89 +++++++++++++++++++++++-------
include/drm/ttm/ttm_resource.h | 54 +++++++++++++++++-
3 files changed, 125 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 434cf0258000..09411978a13a 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -274,14 +274,14 @@ static void ttm_device_clear_lru_dma_mappings(struct ttm_device *bdev,
struct ttm_resource *res;
spin_lock(&bdev->lru_lock);
- while ((res = list_first_entry_or_null(list, typeof(*res), lru))) {
+ while ((res = ttm_lru_first_res_or_null(list))) {
struct ttm_buffer_object *bo = res->bo;
/* Take ref against racing releases once lru_lock is unlocked */
if (!ttm_bo_get_unless_zero(bo))
continue;
- list_del_init(&res->lru);
+ list_del_init(&bo->resource->lru.link);
spin_unlock(&bdev->lru_lock);
if (bo->ttm)
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 4a66b851b67d..db9a7a3717c4 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -70,8 +70,8 @@ void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk)
dma_resv_assert_held(pos->last->bo->base.resv);
man = ttm_manager_type(pos->first->bo->bdev, i);
- list_bulk_move_tail(&man->lru[j], &pos->first->lru,
- &pos->last->lru);
+ list_bulk_move_tail(&man->lru[j], &pos->first->lru.link,
+ &pos->last->lru.link);
}
}
}
@@ -84,14 +84,38 @@ ttm_lru_bulk_move_pos(struct ttm_lru_bulk_move *bulk, struct ttm_resource *res)
return &bulk->pos[res->mem_type][res->bo->priority];
}
+/* Return the previous resource on the list (skip over non-resource list items) */
+static struct ttm_resource *ttm_lru_prev_res(struct ttm_resource *cur)
+{
+ struct ttm_lru_item *lru = &cur->lru;
+
+ do {
+ lru = list_prev_entry(lru, link);
+ } while (!ttm_lru_item_is_res(lru));
+
+ return ttm_lru_item_to_res(lru);
+}
+
+/* Return the next resource on the list (skip over non-resource list items) */
+static struct ttm_resource *ttm_lru_next_res(struct ttm_resource *cur)
+{
+ struct ttm_lru_item *lru = &cur->lru;
+
+ do {
+ lru = list_next_entry(lru, link);
+ } while (!ttm_lru_item_is_res(lru));
+
+ return ttm_lru_item_to_res(lru);
+}
+
/* Move the resource to the tail of the bulk move range */
static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
struct ttm_resource *res)
{
if (pos->last != res) {
if (pos->first == res)
- pos->first = list_next_entry(res, lru);
- list_move(&res->lru, &pos->last->lru);
+ pos->first = ttm_lru_next_res(res);
+ list_move(&res->lru.link, &pos->last->lru.link);
pos->last = res;
}
}
@@ -122,11 +146,11 @@ static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
pos->first = NULL;
pos->last = NULL;
} else if (pos->first == res) {
- pos->first = list_next_entry(res, lru);
+ pos->first = ttm_lru_next_res(res);
} else if (pos->last == res) {
- pos->last = list_prev_entry(res, lru);
+ pos->last = ttm_lru_prev_res(res);
} else {
- list_move(&res->lru, &pos->last->lru);
+ list_move(&res->lru.link, &pos->last->lru.link);
}
}
@@ -155,7 +179,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
lockdep_assert_held(&bo->bdev->lru_lock);
if (bo->pin_count) {
- list_move_tail(&res->lru, &bdev->pinned);
+ list_move_tail(&res->lru.link, &bdev->pinned);
} else if (bo->bulk_move) {
struct ttm_lru_bulk_move_pos *pos =
@@ -166,7 +190,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
struct ttm_resource_manager *man;
man = ttm_manager_type(bdev, res->mem_type);
- list_move_tail(&res->lru, &man->lru[bo->priority]);
+ list_move_tail(&res->lru.link, &man->lru[bo->priority]);
}
}
@@ -197,9 +221,9 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
man = ttm_manager_type(bo->bdev, place->mem_type);
spin_lock(&bo->bdev->lru_lock);
if (bo->pin_count)
- list_add_tail(&res->lru, &bo->bdev->pinned);
+ list_add_tail(&res->lru.link, &bo->bdev->pinned);
else
- list_add_tail(&res->lru, &man->lru[bo->priority]);
+ list_add_tail(&res->lru.link, &man->lru[bo->priority]);
man->usage += res->size;
spin_unlock(&bo->bdev->lru_lock);
}
@@ -221,7 +245,7 @@ void ttm_resource_fini(struct ttm_resource_manager *man,
struct ttm_device *bdev = man->bdev;
spin_lock(&bdev->lru_lock);
- list_del_init(&res->lru);
+ list_del_init(&res->lru.link);
man->usage -= res->size;
spin_unlock(&bdev->lru_lock);
}
@@ -472,14 +496,16 @@ struct ttm_resource *
ttm_resource_manager_first(struct ttm_resource_manager *man,
struct ttm_resource_cursor *cursor)
{
- struct ttm_resource *res;
+ struct ttm_lru_item *lru;
lockdep_assert_held(&man->bdev->lru_lock);
for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
++cursor->priority)
- list_for_each_entry(res, &man->lru[cursor->priority], lru)
- return res;
+ list_for_each_entry(lru, &man->lru[cursor->priority], link) {
+ if (ttm_lru_item_is_res(lru))
+ return ttm_lru_item_to_res(lru);
+ }
return NULL;
}
@@ -498,15 +524,40 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
struct ttm_resource_cursor *cursor,
struct ttm_resource *res)
{
+ struct ttm_lru_item *lru = &res->lru;
+
lockdep_assert_held(&man->bdev->lru_lock);
- list_for_each_entry_continue(res, &man->lru[cursor->priority], lru)
- return res;
+ list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
+ if (ttm_lru_item_is_res(lru))
+ return ttm_lru_item_to_res(lru);
+ }
for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
++cursor->priority)
- list_for_each_entry(res, &man->lru[cursor->priority], lru)
- return res;
+ list_for_each_entry(lru, &man->lru[cursor->priority], link) {
+ if (ttm_lru_item_is_res(lru))
+ ttm_lru_item_to_res(lru);
+ }
+
+ return NULL;
+}
+
+/**
+ * ttm_lru_first_res_or_null() - Return the first resource on an lru list
+ * @head: The list head of the lru list.
+ *
+ * Return: Pointer to the first resource on the lru list or NULL if
+ * there is none.
+ */
+struct ttm_resource *ttm_lru_first_res_or_null(struct list_head *head)
+{
+ struct ttm_lru_item *lru;
+
+ list_for_each_entry(lru, head, link) {
+ if (ttm_lru_item_is_res(lru))
+ return ttm_lru_item_to_res(lru);
+ }
return NULL;
}
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index 69769355139f..1511d91e290d 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -49,6 +49,43 @@ struct io_mapping;
struct sg_table;
struct scatterlist;
+/**
+ * enum ttm_lru_item_type - enumerate ttm_lru_item subclasses
+ */
+enum ttm_lru_item_type {
+ /** @TTM_LRU_RESOURCE: The resource subclass */
+ TTM_LRU_RESOURCE,
+ /** @TTM_LRU_HITCH: The iterator hitch subclass */
+ TTM_LRU_HITCH
+};
+
+/**
+ * struct ttm_lru_item - The TTM lru list node base class
+ * @link: The list link
+ * @type: The subclass type
+ */
+struct ttm_lru_item {
+ struct list_head link;
+ enum ttm_lru_item_type type;
+};
+
+/**
+ * ttm_lru_item_init() - initialize a struct ttm_lru_item
+ * @item: The item to initialize
+ * @type: The subclass type
+ */
+static inline void ttm_lru_item_init(struct ttm_lru_item *item,
+ enum ttm_lru_item_type type)
+{
+ item->type = type;
+ INIT_LIST_HEAD(&item->link);
+}
+
+static inline bool ttm_lru_item_is_res(const struct ttm_lru_item *item)
+{
+ return item->type == TTM_LRU_RESOURCE;
+}
+
struct ttm_resource_manager_func {
/**
* struct ttm_resource_manager_func member alloc
@@ -217,9 +254,21 @@ struct ttm_resource {
/**
* @lru: Least recently used list, see &ttm_resource_manager.lru
*/
- struct list_head lru;
+ struct ttm_lru_item lru;
};
+/**
+ * ttm_lru_item_to_res() - Downcast a struct ttm_lru_item to a struct ttm_resource
+ * @item: The struct ttm_lru_item to downcast
+ *
+ * Return: Pointer to the embedding struct ttm_resource
+ */
+static inline struct ttm_resource *
+ttm_lru_item_to_res(struct ttm_lru_item *item)
+{
+ return container_of(item, struct ttm_resource, lru);
+}
+
/**
* struct ttm_resource_cursor
*
@@ -393,6 +442,9 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
struct ttm_resource_cursor *cursor,
struct ttm_resource *res);
+struct ttm_resource *
+ttm_lru_first_res_or_null(struct list_head *head);
+
/**
* ttm_resource_manager_for_each_res - iterate over all resources
* @man: the resource manager
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 15:39 ` Matthew Brost
2024-05-28 9:19 ` Christian König
2024-05-21 7:16 ` [PATCH v3 03/21] drm/ttm: Use LRU hitches Thomas Hellström
` (27 subsequent siblings)
29 siblings, 2 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
To make the transition to using lru hitches easier,
simplify the ttm_resource_manager_next() interface to only take
the cursor and reuse ttm_resource_manager_next() functionality
from ttm_resource_manager_first().
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_resource.c | 48 +++++++++++++-----------------
include/drm/ttm/ttm_resource.h | 10 ++++---
2 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index db9a7a3717c4..8bfbddddc0e8 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -496,50 +496,44 @@ struct ttm_resource *
ttm_resource_manager_first(struct ttm_resource_manager *man,
struct ttm_resource_cursor *cursor)
{
- struct ttm_lru_item *lru;
-
lockdep_assert_held(&man->bdev->lru_lock);
- for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
- ++cursor->priority)
- list_for_each_entry(lru, &man->lru[cursor->priority], link) {
- if (ttm_lru_item_is_res(lru))
- return ttm_lru_item_to_res(lru);
- }
-
- return NULL;
+ cursor->priority = 0;
+ cursor->man = man;
+ cursor->cur = &man->lru[cursor->priority];
+ return ttm_resource_manager_next(cursor);
}
/**
* ttm_resource_manager_next
*
- * @man: resource manager to iterate over
* @cursor: cursor to record the position
- * @res: the current resource pointer
*
- * Returns the next resource from the resource manager.
+ * Return: the next resource from the resource manager.
*/
struct ttm_resource *
-ttm_resource_manager_next(struct ttm_resource_manager *man,
- struct ttm_resource_cursor *cursor,
- struct ttm_resource *res)
+ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
{
- struct ttm_lru_item *lru = &res->lru;
+ struct ttm_resource_manager *man = cursor->man;
+ struct ttm_lru_item *lru;
lockdep_assert_held(&man->bdev->lru_lock);
- list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
- if (ttm_lru_item_is_res(lru))
- return ttm_lru_item_to_res(lru);
- }
-
- for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
- ++cursor->priority)
- list_for_each_entry(lru, &man->lru[cursor->priority], link) {
- if (ttm_lru_item_is_res(lru))
- ttm_lru_item_to_res(lru);
+ for (;;) {
+ lru = list_entry(cursor->cur, typeof(*lru), link);
+ list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
+ if (ttm_lru_item_is_res(lru)) {
+ cursor->cur = &lru->link;
+ return ttm_lru_item_to_res(lru);
+ }
}
+ if (++cursor->priority >= TTM_MAX_BO_PRIORITY)
+ break;
+
+ cursor->cur = &man->lru[cursor->priority];
+ }
+
return NULL;
}
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index 1511d91e290d..7d81fd5b5b83 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -272,11 +272,15 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
/**
* struct ttm_resource_cursor
*
+ * @man: The resource manager currently being iterated over.
+ * @cur: The list head the cursor currently points to.
* @priority: the current priority
*
* Cursor to iterate over the resources in a manager.
*/
struct ttm_resource_cursor {
+ struct ttm_resource_manager *man;
+ struct list_head *cur;
unsigned int priority;
};
@@ -438,9 +442,7 @@ struct ttm_resource *
ttm_resource_manager_first(struct ttm_resource_manager *man,
struct ttm_resource_cursor *cursor);
struct ttm_resource *
-ttm_resource_manager_next(struct ttm_resource_manager *man,
- struct ttm_resource_cursor *cursor,
- struct ttm_resource *res);
+ttm_resource_manager_next(struct ttm_resource_cursor *cursor);
struct ttm_resource *
ttm_lru_first_res_or_null(struct list_head *head);
@@ -455,7 +457,7 @@ ttm_lru_first_res_or_null(struct list_head *head);
*/
#define ttm_resource_manager_for_each_res(man, cursor, res) \
for (res = ttm_resource_manager_first(man, cursor); res; \
- res = ttm_resource_manager_next(man, cursor, res))
+ res = ttm_resource_manager_next(cursor))
struct ttm_kmap_iter *
ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 03/21] drm/ttm: Use LRU hitches
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 16:09 ` Matthew Brost
2024-05-21 7:16 ` [PATCH v3 04/21] drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves Thomas Hellström
` (26 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Have iterators insert themselves into the list they are iterating
over using hitch list nodes. Since only the iterator owner
can remove these list nodes from the list, it's safe to unlock
the list and when continuing, use them as a starting point. Due to
the way LRU bumping works in TTM, newly added items will not be
missed, and bumped items will be iterated over a second time before
reaching the end of the list.
The exception is list with bulk move sublists. When bumping a
sublist, a hitch that is part of that sublist will also be moved
and we might miss items if restarting from it. This will be
addressed in a later patch.
Changes in previous series:
- Updated ttm_resource_cursor_fini() documentation.
v2:
- Don't reorder ttm_resource_manager_first() and _next().
(Christian König).
- Use list_add instead of list_move
(Christian König)
v3:
- Split into two patches, one cleanup, one new functionality
(Christian König)
- use ttm_resource_cursor_fini_locked() instead of open-coding
(Matthew Brost)
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo.c | 1 +
drivers/gpu/drm/ttm/ttm_device.c | 9 +++--
drivers/gpu/drm/ttm/ttm_resource.c | 56 +++++++++++++++++++++++++-----
include/drm/ttm/ttm_resource.h | 9 +++--
4 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 6396dece0db1..43eda720657f 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -621,6 +621,7 @@ int ttm_mem_evict_first(struct ttm_device *bdev,
if (locked)
dma_resv_unlock(res->bo->base.resv);
}
+ ttm_resource_cursor_fini_locked(&cursor);
if (!bo) {
if (busy_bo && !ttm_bo_get_unless_zero(busy_bo))
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 09411978a13a..f9e9b1ec8c8a 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -170,12 +170,17 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
num_pages = PFN_UP(bo->base.size);
ret = ttm_bo_swapout(bo, ctx, gfp_flags);
/* ttm_bo_swapout has dropped the lru_lock */
- if (!ret)
+ if (!ret) {
+ ttm_resource_cursor_fini(&cursor);
return num_pages;
- if (ret != -EBUSY)
+ }
+ if (ret != -EBUSY) {
+ ttm_resource_cursor_fini(&cursor);
return ret;
+ }
}
}
+ ttm_resource_cursor_fini_locked(&cursor);
spin_unlock(&bdev->lru_lock);
return 0;
}
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 8bfbddddc0e8..9c8b6499edfb 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -33,6 +33,37 @@
#include <drm/drm_util.h>
+/**
+ * ttm_resource_cursor_fini_locked() - Finalize the LRU list cursor usage
+ * @cursor: The struct ttm_resource_cursor to finalize.
+ *
+ * The function pulls the LRU list cursor off any lists it was previusly
+ * attached to. Needs to be called with the LRU lock held. The function
+ * can be called multiple times after eachother.
+ */
+void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor)
+{
+ lockdep_assert_held(&cursor->man->bdev->lru_lock);
+ list_del_init(&cursor->hitch.link);
+}
+
+/**
+ * ttm_resource_cursor_fini() - Finalize the LRU list cursor usage
+ * @cursor: The struct ttm_resource_cursor to finalize.
+ *
+ * The function pulls the LRU list cursor off any lists it was previusly
+ * attached to. Needs to be called without the LRU list lock held. The
+ * function can be called multiple times after eachother.
+ */
+void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor)
+{
+ spinlock_t *lru_lock = &cursor->man->bdev->lru_lock;
+
+ spin_lock(lru_lock);
+ ttm_resource_cursor_fini_locked(cursor);
+ spin_unlock(lru_lock);
+}
+
/**
* ttm_lru_bulk_move_init - initialize a bulk move structure
* @bulk: the structure to init
@@ -485,12 +516,15 @@ void ttm_resource_manager_debug(struct ttm_resource_manager *man,
EXPORT_SYMBOL(ttm_resource_manager_debug);
/**
- * ttm_resource_manager_first
- *
+ * ttm_resource_manager_first() - Start iterating over the resources
+ * of a resource manager
* @man: resource manager to iterate over
* @cursor: cursor to record the position
*
- * Returns the first resource from the resource manager.
+ * Initializes the cursor and starts iterating. When done iterating,
+ * the caller must explicitly call ttm_resource_cursor_fini().
+ *
+ * Return: The first resource from the resource manager.
*/
struct ttm_resource *
ttm_resource_manager_first(struct ttm_resource_manager *man,
@@ -500,13 +534,15 @@ ttm_resource_manager_first(struct ttm_resource_manager *man,
cursor->priority = 0;
cursor->man = man;
- cursor->cur = &man->lru[cursor->priority];
+ ttm_lru_item_init(&cursor->hitch, TTM_LRU_HITCH);
+ list_add(&cursor->hitch.link, &man->lru[cursor->priority]);
+
return ttm_resource_manager_next(cursor);
}
/**
- * ttm_resource_manager_next
- *
+ * ttm_resource_manager_next() - Continue iterating over the resource manager
+ * resources
* @cursor: cursor to record the position
*
* Return: the next resource from the resource manager.
@@ -520,10 +556,10 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
lockdep_assert_held(&man->bdev->lru_lock);
for (;;) {
- lru = list_entry(cursor->cur, typeof(*lru), link);
+ lru = &cursor->hitch;
list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
if (ttm_lru_item_is_res(lru)) {
- cursor->cur = &lru->link;
+ list_move(&cursor->hitch.link, &lru->link);
return ttm_lru_item_to_res(lru);
}
}
@@ -531,9 +567,11 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
if (++cursor->priority >= TTM_MAX_BO_PRIORITY)
break;
- cursor->cur = &man->lru[cursor->priority];
+ list_move(&cursor->hitch.link, &man->lru[cursor->priority]);
}
+ ttm_resource_cursor_fini_locked(cursor);
+
return NULL;
}
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index 7d81fd5b5b83..8fac781f641e 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -273,17 +273,22 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
* struct ttm_resource_cursor
*
* @man: The resource manager currently being iterated over.
- * @cur: The list head the cursor currently points to.
+ * @hitch: A hitch list node inserted before the next resource
+ * to iterate over.
* @priority: the current priority
*
* Cursor to iterate over the resources in a manager.
*/
struct ttm_resource_cursor {
struct ttm_resource_manager *man;
- struct list_head *cur;
+ struct ttm_lru_item hitch;
unsigned int priority;
};
+void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor);
+
+void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor);
+
/**
* struct ttm_lru_bulk_move_pos
*
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 04/21] drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (2 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 03/21] drm/ttm: Use LRU hitches Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 05/21] drm/ttm: Provide a generic LRU walker helper Thomas Hellström
` (25 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
To address the problem with hitches moving when bulk move
sublists are lru-bumped, register the list cursors with the
ttm_lru_bulk_move structure when traversing its list, and
when lru-bumping the list, move the cursor hitch to the tail.
This also means it's mandatory for drivers to call
ttm_lru_bulk_move_init() and ttm_lru_bulk_move_fini() when
initializing and finalizing the bulk move structure, so add
those calls to the amdgpu- and xe driver.
Compared to v1 this is slightly more code but less fragile
and hopefully easier to understand.
Changes in previous series:
- Completely rework the functionality
- Avoid a NULL pointer dereference assigning manager->mem_type
- Remove some leftover code causing build problems
v2:
- For hitch bulk tail moves, store the mem_type in the cursor
instead of with the manager.
v3:
- Remove leftover mem_type member from change in v2.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 ++
drivers/gpu/drm/ttm/ttm_resource.c | 89 ++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm.c | 4 ++
include/drm/ttm/ttm_resource.h | 56 ++++++++++------
4 files changed, 132 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 4e2391c83d7c..6293f3b54b4a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2422,6 +2422,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r)
return r;
+ ttm_lru_bulk_move_init(&vm->lru_bulk_move);
+
vm->is_compute_context = false;
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
@@ -2486,6 +2488,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
error_free_delayed:
dma_fence_put(vm->last_tlb_flush);
dma_fence_put(vm->last_unlocked);
+ ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move);
amdgpu_vm_fini_entities(vm);
return r;
@@ -2642,6 +2645,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
}
}
+ ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move);
}
/**
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 9c8b6499edfb..a03090683e79 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -33,6 +33,49 @@
#include <drm/drm_util.h>
+/* Detach the cursor from the bulk move list*/
+static void
+ttm_resource_cursor_clear_bulk(struct ttm_resource_cursor *cursor)
+{
+ cursor->bulk = NULL;
+ list_del_init(&cursor->bulk_link);
+}
+
+/* Move the cursor to the end of the bulk move list it's in */
+static void ttm_resource_cursor_move_bulk_tail(struct ttm_lru_bulk_move *bulk,
+ struct ttm_resource_cursor *cursor)
+{
+ struct ttm_lru_bulk_move_pos *pos;
+
+ if (WARN_ON_ONCE(bulk != cursor->bulk)) {
+ list_del_init(&cursor->bulk_link);
+ return;
+ }
+
+ pos = &bulk->pos[cursor->mem_type][cursor->priority];
+ if (pos)
+ list_move(&cursor->hitch.link, &pos->last->lru.link);
+ ttm_resource_cursor_clear_bulk(cursor);
+}
+
+/* Move all cursors attached to a bulk move to its end */
+static void ttm_bulk_move_adjust_cursors(struct ttm_lru_bulk_move *bulk)
+{
+ struct ttm_resource_cursor *cursor, *next;
+
+ list_for_each_entry_safe(cursor, next, &bulk->cursor_list, bulk_link)
+ ttm_resource_cursor_move_bulk_tail(bulk, cursor);
+}
+
+/* Remove a cursor from an empty bulk move list */
+static void ttm_bulk_move_drop_cursors(struct ttm_lru_bulk_move *bulk)
+{
+ struct ttm_resource_cursor *cursor, *next;
+
+ list_for_each_entry_safe(cursor, next, &bulk->cursor_list, bulk_link)
+ ttm_resource_cursor_clear_bulk(cursor);
+}
+
/**
* ttm_resource_cursor_fini_locked() - Finalize the LRU list cursor usage
* @cursor: The struct ttm_resource_cursor to finalize.
@@ -45,6 +88,7 @@ void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor)
{
lockdep_assert_held(&cursor->man->bdev->lru_lock);
list_del_init(&cursor->hitch.link);
+ ttm_resource_cursor_clear_bulk(cursor);
}
/**
@@ -73,9 +117,27 @@ void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor)
void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk)
{
memset(bulk, 0, sizeof(*bulk));
+ INIT_LIST_HEAD(&bulk->cursor_list);
}
EXPORT_SYMBOL(ttm_lru_bulk_move_init);
+/**
+ * ttm_lru_bulk_move_fini - finalize a bulk move structure
+ * @bdev: The struct ttm_device
+ * @bulk: the structure to finalize
+ *
+ * Sanity checks that bulk moves don't have any
+ * resources left and hence no cursors attached.
+ */
+void ttm_lru_bulk_move_fini(struct ttm_device *bdev,
+ struct ttm_lru_bulk_move *bulk)
+{
+ spin_lock(&bdev->lru_lock);
+ ttm_bulk_move_drop_cursors(bulk);
+ spin_unlock(&bdev->lru_lock);
+}
+EXPORT_SYMBOL(ttm_lru_bulk_move_fini);
+
/**
* ttm_lru_bulk_move_tail - bulk move range of resources to the LRU tail.
*
@@ -88,6 +150,7 @@ void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk)
{
unsigned i, j;
+ ttm_bulk_move_adjust_cursors(bulk);
for (i = 0; i < TTM_NUM_MEM_TYPES; ++i) {
for (j = 0; j < TTM_MAX_BO_PRIORITY; ++j) {
struct ttm_lru_bulk_move_pos *pos = &bulk->pos[i][j];
@@ -515,6 +578,29 @@ void ttm_resource_manager_debug(struct ttm_resource_manager *man,
}
EXPORT_SYMBOL(ttm_resource_manager_debug);
+static void
+ttm_resource_cursor_check_bulk(struct ttm_resource_cursor *cursor,
+ struct ttm_lru_item *next_lru)
+{
+ struct ttm_resource *next = ttm_lru_item_to_res(next_lru);
+ struct ttm_lru_bulk_move *bulk = NULL;
+ struct ttm_buffer_object *bo = next->bo;
+
+ lockdep_assert_held(&cursor->man->bdev->lru_lock);
+ if (bo && bo->resource == next)
+ bulk = bo->bulk_move;
+
+ if (cursor->bulk != bulk) {
+ if (bulk) {
+ list_move_tail(&cursor->bulk_link, &bulk->cursor_list);
+ cursor->mem_type = next->mem_type;
+ } else {
+ list_del_init(&cursor->bulk_link);
+ }
+ cursor->bulk = bulk;
+ }
+}
+
/**
* ttm_resource_manager_first() - Start iterating over the resources
* of a resource manager
@@ -535,6 +621,7 @@ ttm_resource_manager_first(struct ttm_resource_manager *man,
cursor->priority = 0;
cursor->man = man;
ttm_lru_item_init(&cursor->hitch, TTM_LRU_HITCH);
+ INIT_LIST_HEAD(&cursor->bulk_link);
list_add(&cursor->hitch.link, &man->lru[cursor->priority]);
return ttm_resource_manager_next(cursor);
@@ -559,6 +646,7 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
lru = &cursor->hitch;
list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
if (ttm_lru_item_is_res(lru)) {
+ ttm_resource_cursor_check_bulk(cursor, lru);
list_move(&cursor->hitch.link, &lru->link);
return ttm_lru_item_to_res(lru);
}
@@ -568,6 +656,7 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
break;
list_move(&cursor->hitch.link, &man->lru[cursor->priority]);
+ ttm_resource_cursor_clear_bulk(cursor);
}
ttm_resource_cursor_fini_locked(cursor);
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index c5b1694b292f..e2ec148c9c33 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -1339,6 +1339,8 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
INIT_WORK(&vm->destroy_work, vm_destroy_work_func);
+ ttm_lru_bulk_move_init(&vm->lru_bulk_move);
+
INIT_LIST_HEAD(&vm->preempt.exec_queues);
vm->preempt.min_run_period_ms = 10; /* FIXME: Wire up to uAPI */
@@ -1456,6 +1458,7 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
mutex_destroy(&vm->snap_mutex);
for_each_tile(tile, xe, id)
xe_range_fence_tree_fini(&vm->rftree[id]);
+ ttm_lru_bulk_move_fini(&xe->ttm, &vm->lru_bulk_move);
kfree(vm);
if (!(flags & XE_VM_FLAG_MIGRATION))
xe_pm_runtime_put(xe);
@@ -1599,6 +1602,7 @@ static void vm_destroy_work_func(struct work_struct *w)
XE_WARN_ON(vm->pt_root[id]);
trace_xe_vm_free(vm);
+ ttm_lru_bulk_move_fini(&xe->ttm, &vm->lru_bulk_move);
kfree(vm);
}
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index 8fac781f641e..571abb4861a6 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -269,26 +269,6 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
return container_of(item, struct ttm_resource, lru);
}
-/**
- * struct ttm_resource_cursor
- *
- * @man: The resource manager currently being iterated over.
- * @hitch: A hitch list node inserted before the next resource
- * to iterate over.
- * @priority: the current priority
- *
- * Cursor to iterate over the resources in a manager.
- */
-struct ttm_resource_cursor {
- struct ttm_resource_manager *man;
- struct ttm_lru_item hitch;
- unsigned int priority;
-};
-
-void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor);
-
-void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor);
-
/**
* struct ttm_lru_bulk_move_pos
*
@@ -304,8 +284,9 @@ struct ttm_lru_bulk_move_pos {
/**
* struct ttm_lru_bulk_move
- *
* @pos: first/last lru entry for resources in the each domain/priority
+ * @cursor_list: The list of cursors currently traversing any of
+ * the sublists of @pos. Protected by the ttm device's lru_lock.
*
* Container for the current bulk move state. Should be used with
* ttm_lru_bulk_move_init() and ttm_bo_set_bulk_move().
@@ -315,8 +296,39 @@ struct ttm_lru_bulk_move_pos {
*/
struct ttm_lru_bulk_move {
struct ttm_lru_bulk_move_pos pos[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY];
+ struct list_head cursor_list;
};
+/**
+ * struct ttm_resource_cursor
+ * @man: The resource manager currently being iterated over
+ * @hitch: A hitch list node inserted before the next resource
+ * to iterate over.
+ * @bulk_link: A list link for the list of cursors traversing the
+ * bulk sublist of @bulk. Protected by the ttm device's lru_lock.
+ * @bulk: Pointer to struct ttm_lru_bulk_move whose subrange @hitch is
+ * inserted to. NULL if none. Never dereference this pointer since
+ * the struct ttm_lru_bulk_move object pointed to might have been
+ * freed. The pointer is only for comparison.
+ * @mem_type: The memory type of the LRU list being traversed.
+ * This field is valid iff @bulk != NULL.
+ * @priority: the current priority
+ *
+ * Cursor to iterate over the resources in a manager.
+ */
+struct ttm_resource_cursor {
+ struct ttm_resource_manager *man;
+ struct ttm_lru_item hitch;
+ struct list_head bulk_link;
+ struct ttm_lru_bulk_move *bulk;
+ unsigned int mem_type;
+ unsigned int priority;
+};
+
+void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor);
+
+void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor);
+
/**
* struct ttm_kmap_iter_iomap - Specialization for a struct io_mapping +
* struct sg_table backed struct ttm_resource.
@@ -405,6 +417,8 @@ ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk);
void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk);
+void ttm_lru_bulk_move_fini(struct ttm_device *bdev,
+ struct ttm_lru_bulk_move *bulk);
void ttm_resource_add_bulk_move(struct ttm_resource *res,
struct ttm_buffer_object *bo);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 05/21] drm/ttm: Provide a generic LRU walker helper
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (3 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 04/21] drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 06/21] drm/ttm: Use the LRU walker helper for swapping Thomas Hellström
` (24 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Provide a generic LRU walker in TTM, in the spirit of drm_gem_lru_scan()
but building on the restartable TTM LRU functionality.
The LRU walker optionally supports locking objects as part of
a ww mutex locking transaction, to mimic to some extent the
current functionality in ttm. However any -EDEADLK return
is converted to -ENOMEM, so that the driver will need to back
off and possibly retry without being able to keep the
ticket.
v3:
- Move the helper to core ttm.
- Remove the drm_exec usage from it for now, it will be
reintroduced later in the series.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo_util.c | 145 ++++++++++++++++++++++++++++++
include/drm/ttm/ttm_bo.h | 32 +++++++
2 files changed, 177 insertions(+)
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 0b3f4267130c..be200c06cc79 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -768,3 +768,148 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
ttm_tt_destroy(bo->bdev, ttm);
return ret;
}
+
+static bool ttm_lru_walk_trylock(struct ttm_lru_walk *walk,
+ struct ttm_buffer_object *bo,
+ bool *needs_unlock)
+{
+ struct ttm_operation_ctx *ctx = walk->ctx;
+
+ *needs_unlock = false;
+
+ if (dma_resv_trylock(bo->base.resv)) {
+ *needs_unlock = true;
+ return true;
+ }
+
+ if (bo->base.resv == ctx->resv && ctx->allow_res_evict) {
+ dma_resv_assert_held(bo->base.resv);
+ return true;
+ }
+
+ return false;
+}
+
+static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk,
+ 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);
+ else
+ ret = dma_resv_lock(resv, walk->ticket);
+
+ if (ret == -EDEADLK)
+ ret = -ENOSPC;
+
+ if (!ret) {
+ *needs_unlock = true;
+ /* Only a single ticketlock per loop */
+ walk->ticket = NULL;
+ }
+
+ 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.
+ * @walk: describe the walks and actions taken
+ * @bdev: The TTM device.
+ * @man: The struct ttm_resource manager whose LRU lists we're walking.
+ * @target: The end condition for the walk.
+ *
+ * The LRU lists of @man are walk, and for each struct ttm_resource encountered,
+ * the corresponding ttm_buffer_object is locked and taken a reference on, and
+ * the LRU lock is dropped. the LRU lock may be dropped before locking and, in
+ * that case, it's verified that the item actually remains on the LRU list after
+ * the lock, and that the buffer object didn't switch resource in between.
+ *
+ * With a locked object, the actions indicated by @walk->process_bo are
+ * performed, and after that, the bo is unlocked, the refcount dropped and the
+ * next struct ttm_resource is processed. Here, the walker relies on
+ * TTM's restartable LRU list implementation.
+ *
+ * Typically @walk->process_bo() would return the number of pages evicted,
+ * swapped or shrunken, so that when the total exceeds @target, or when the
+ * LRU list has been walked in full, iteration is terminated. It's also terminated
+ * on error. Note that the definition of @target is done by the caller, it
+ * could have a different meaning than the number of pages.
+ *
+ * Note that the way dma_resv individualization is done, locking needs to be done
+ * either with the LRU lock held (trylocking only) or with a reference on the
+ * object.
+ *
+ * Return: The progress made towards target or negative error code on error.
+ */
+long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
+ struct ttm_resource_manager *man, long target)
+{
+ struct ttm_resource_cursor cursor;
+ struct ttm_resource *res;
+ long sofar = 0;
+ long lret;
+
+ spin_lock(&bdev->lru_lock);
+ ttm_resource_manager_for_each_res(man, &cursor, res) {
+ struct ttm_buffer_object *bo = res->bo;
+ bool bo_needs_unlock = false;
+ bool bo_locked = false;
+ int mem_type;
+
+ if (!bo || bo->resource != res)
+ continue;
+
+ if (ttm_lru_walk_trylock(walk, bo, &bo_needs_unlock))
+ bo_locked = true;
+ else if ((!walk->ticket) || walk->ctx->no_wait_gpu ||
+ walk->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 && walk->ticket)
+ lret = ttm_lru_walk_ticketlock(walk, 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 == res && res->mem_type == mem_type)
+ lret = walk->ops->process_bo(walk, bo);
+
+ ttm_lru_walk_unlock(bo, bo_needs_unlock);
+ ttm_bo_put(bo);
+ if (lret == -EBUSY)
+ lret = 0;
+ sofar = (lret < 0) ? lret : sofar + lret;
+ if (sofar < 0 || sofar >= target)
+ goto out;
+
+ cond_resched();
+ spin_lock(&bdev->lru_lock);
+ }
+ spin_unlock(&bdev->lru_lock);
+out:
+ ttm_resource_cursor_fini(&cursor);
+ return sofar;
+}
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index 6ccf96c91f3a..8b032298d66e 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -190,6 +190,38 @@ struct ttm_operation_ctx {
uint64_t bytes_moved;
};
+struct ttm_lru_walk;
+
+/** struct ttm_lru_walk_ops - Operations for a LRU walk. */
+struct ttm_lru_walk_ops {
+ /**
+ * process_bo - Process this bo.
+ * @walk: struct ttm_lru_walk describing the walk.
+ * @bo: A locked and referenced buffer object.
+ *
+ * Return: Negative error code on error, Number of processed pages on
+ * success. 0 also indicates success.
+ */
+ long (*process_bo)(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo);
+};
+
+/**
+ * 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;
+ /** @ctx: Pointer to the struct ttm_operation_ctx. */
+ struct ttm_operation_ctx *ctx;
+ /** @ticket: The struct ww_acquire_ctx if any. */
+ struct ww_acquire_ctx *ticket;
+ /** @tryock_only: Only use trylock for locking. */
+ bool trylock_only;
+};
+
+long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
+ struct ttm_resource_manager *man, long target);
+
/**
* ttm_bo_get - reference a struct ttm_buffer_object
*
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 06/21] drm/ttm: Use the LRU walker helper for swapping
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (4 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 05/21] drm/ttm: Provide a generic LRU walker helper Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 07/21] drm/ttm: Use the LRU walker for eviction Thomas Hellström
` (23 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Rework the TTM swapping to use the LRU walker helper.
This helps fixing up the ttm_bo_swapout() interface
to be consistent about not requiring any locking.
For now mimic the current behaviour of using trylock
only. We could be using ticket-locks here but defer
that until it's deemed necessary. The TTM swapout
functionality is a bit weird anyway since it
alternates between memory types without exhausting
TTM_PL_SYSTEM first.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo.c | 112 +++++++++++++++++++++----------
drivers/gpu/drm/ttm/ttm_device.c | 30 ++-------
include/drm/ttm/ttm_bo.h | 5 +-
3 files changed, 83 insertions(+), 64 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 43eda720657f..63a91b77f7da 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1118,11 +1118,23 @@ int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx)
}
EXPORT_SYMBOL(ttm_bo_wait_ctx);
-int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
- gfp_t gfp_flags)
+/**
+ * struct ttm_bo_swapout_walk - Parameters for the swapout walk
+ */
+struct ttm_bo_swapout_walk {
+ /** @walk: The walk base parameters. */
+ struct ttm_lru_walk walk;
+ /** @gfp_flags: The gfp flags to use for ttm_tt_swapout() */
+ gfp_t gfp_flags;
+};
+
+static long
+ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
{
- struct ttm_place place;
- bool locked;
+ 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;
long ret;
/*
@@ -1131,28 +1143,29 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
* The driver may use the fact that we're moving from SYSTEM
* as an indication that we're about to swap out.
*/
- memset(&place, 0, sizeof(place));
- place.mem_type = bo->resource->mem_type;
- if (!ttm_bo_evict_swapout_allowable(bo, ctx, &place, &locked, NULL))
- return -EBUSY;
+ if (!bo->bdev->funcs->eviction_valuable(bo, &place)) {
+ ret = -EBUSY;
+ goto out;
+ }
if (!bo->ttm || !ttm_tt_is_populated(bo->ttm) ||
bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL ||
- bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED ||
- !ttm_bo_get_unless_zero(bo)) {
- if (locked)
- dma_resv_unlock(bo->base.resv);
- return -EBUSY;
+ bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED) {
+ ret = -EBUSY;
+ goto out;
}
if (bo->deleted) {
- ret = ttm_bo_cleanup_refs(bo, false, false, locked);
- ttm_bo_put(bo);
- return ret == -EBUSY ? -ENOSPC : ret;
- }
+ pgoff_t num_pages = bo->ttm->num_pages;
- /* TODO: Cleanup the locking */
- spin_unlock(&bo->bdev->lru_lock);
+ ret = ttm_bo_wait_ctx(bo, ctx);
+ if (ret)
+ goto out;
+
+ ttm_bo_cleanup_memtype_use(bo);
+ ret = num_pages;
+ goto out;
+ }
/*
* Move to system cached
@@ -1164,12 +1177,13 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
memset(&hop, 0, sizeof(hop));
place.mem_type = TTM_PL_SYSTEM;
ret = ttm_resource_alloc(bo, &place, &evict_mem);
- if (unlikely(ret))
+ if (ret)
goto out;
ret = ttm_bo_handle_move_mem(bo, evict_mem, true, ctx, &hop);
- if (unlikely(ret != 0)) {
- WARN(ret == -EMULTIHOP, "Unexpected multihop in swaput - likely driver bug.\n");
+ if (ret) {
+ WARN(ret == -EMULTIHOP,
+ "Unexpected multihop in swapout - likely driver bug.\n");
ttm_resource_free(bo, &evict_mem);
goto out;
}
@@ -1179,30 +1193,54 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
* Make sure BO is idle.
*/
ret = ttm_bo_wait_ctx(bo, ctx);
- if (unlikely(ret != 0))
+ if (ret)
goto out;
ttm_bo_unmap_virtual(bo);
-
- /*
- * Swap out. Buffer will be swapped in again as soon as
- * anyone tries to access a ttm page.
- */
if (bo->bdev->funcs->swap_notify)
bo->bdev->funcs->swap_notify(bo);
if (ttm_tt_is_populated(bo->ttm))
- ret = ttm_tt_swapout(bo->bdev, bo->ttm, gfp_flags);
+ ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags);
out:
+ /* Consider some error codes fatal. Others may continue the walk. */
+ if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS ||
+ ret == -EAGAIN || ret > 0)
+ return ret;
- /*
- * Unreserve without putting on LRU to avoid swapping out an
- * already swapped buffer.
- */
- if (locked)
- dma_resv_unlock(bo->base.resv);
- ttm_bo_put(bo);
- return ret == -EBUSY ? -ENOSPC : ret;
+ return 0;
+}
+
+const struct ttm_lru_walk_ops ttm_swap_ops = {
+ .process_bo = ttm_bo_swapout_cb,
+};
+
+/**
+ * ttm_bo_swapout() - Swap out buffer objects on the LRU list to shmem.
+ * @bdev: The ttm device.
+ * @ctx: The ttm_operation_ctx governing the swapout operation.
+ * @man: The resource manager whose resources / buffer objects are
+ * goint to be swapped out.
+ * @gfp_flags: The gfp flags used for shmem page allocations.
+ * @target: The desired number of pages to swap out.
+ *
+ * Return: The number of pages actually swapped out, or negative error code
+ * on error.
+ */
+long ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
+ struct ttm_resource_manager *man, gfp_t gfp_flags,
+ pgoff_t target)
+{
+ struct ttm_bo_swapout_walk swapout_walk = {
+ .walk = {
+ .ops = &ttm_swap_ops,
+ .ctx = ctx,
+ .trylock_only = true,
+ },
+ .gfp_flags = gfp_flags,
+ };
+
+ return ttm_lru_walk_for_evict(&swapout_walk.walk, bdev, man, target);
}
void ttm_bo_tt_destroy(struct ttm_buffer_object *bo)
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index f9e9b1ec8c8a..ee575d8a54c0 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -148,40 +148,20 @@ 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)
{
- struct ttm_resource_cursor cursor;
struct ttm_resource_manager *man;
- struct ttm_resource *res;
unsigned i;
- int ret;
+ long lret;
- spin_lock(&bdev->lru_lock);
for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) {
man = ttm_manager_type(bdev, i);
if (!man || !man->use_tt)
continue;
- ttm_resource_manager_for_each_res(man, &cursor, res) {
- struct ttm_buffer_object *bo = res->bo;
- uint32_t num_pages;
-
- if (!bo || bo->resource != res)
- continue;
-
- num_pages = PFN_UP(bo->base.size);
- ret = ttm_bo_swapout(bo, ctx, gfp_flags);
- /* ttm_bo_swapout has dropped the lru_lock */
- if (!ret) {
- ttm_resource_cursor_fini(&cursor);
- return num_pages;
- }
- if (ret != -EBUSY) {
- ttm_resource_cursor_fini(&cursor);
- return ret;
- }
- }
+ lret = ttm_bo_swapout(bdev, ctx, man, gfp_flags, 1);
+ /* Can be both positive (num_pages) and negative (error) */
+ if (lret)
+ return lret;
}
- ttm_resource_cursor_fini_locked(&cursor);
- spin_unlock(&bdev->lru_lock);
return 0;
}
EXPORT_SYMBOL(ttm_device_swapout);
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index 8b032298d66e..472a55b69afb 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -410,8 +410,9 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);
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);
-int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
- gfp_t gfp_flags);
+long ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
+ struct ttm_resource_manager *man, gfp_t gfp_flags,
+ pgoff_t target);
void ttm_bo_pin(struct ttm_buffer_object *bo);
void ttm_bo_unpin(struct ttm_buffer_object *bo);
int ttm_mem_evict_first(struct ttm_device *bdev,
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 07/21] drm/ttm: Use the LRU walker for eviction
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (5 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 06/21] drm/ttm: Use the LRU walker helper for swapping Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 08/21] drm/ttm: Add a virtual base class for graphics memory backup Thomas Hellström
` (22 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Use the LRU walker for eviction. This helps
removing a lot of code with weird locking
semantics.
The functionality is slightly changed so that
when trylocked buffer objects are exhausted, we
continue to interleave walks with ticket-locks while
there is still progress made. The list walks are
not restarted in-between evictions.
Also provide a separate ttm_bo_evict_first()
function for its single user. The context of that
user allows sleeping dma_resv locks.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo.c | 350 ++++++++++++-----------------
drivers/gpu/drm/ttm/ttm_resource.c | 20 +-
include/drm/ttm/ttm_bo.h | 8 +-
3 files changed, 145 insertions(+), 233 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 63a91b77f7da..316afe19a325 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -224,80 +224,6 @@ static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
dma_resv_iter_end(&cursor);
}
-/**
- * ttm_bo_cleanup_refs
- * If bo idle, remove from lru lists, and unref.
- * If not idle, block if possible.
- *
- * Must be called with lru_lock and reservation held, this function
- * will drop the lru lock and optionally the reservation lock before returning.
- *
- * @bo: The buffer object to clean-up
- * @interruptible: Any sleeps should occur interruptibly.
- * @no_wait_gpu: Never wait for gpu. Return -EBUSY instead.
- * @unlock_resv: Unlock the reservation lock as well.
- */
-
-static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
- bool interruptible, bool no_wait_gpu,
- bool unlock_resv)
-{
- struct dma_resv *resv = &bo->base._resv;
- int ret;
-
- if (dma_resv_test_signaled(resv, DMA_RESV_USAGE_BOOKKEEP))
- ret = 0;
- else
- ret = -EBUSY;
-
- if (ret && !no_wait_gpu) {
- long lret;
-
- if (unlock_resv)
- dma_resv_unlock(bo->base.resv);
- spin_unlock(&bo->bdev->lru_lock);
-
- lret = dma_resv_wait_timeout(resv, DMA_RESV_USAGE_BOOKKEEP,
- interruptible,
- 30 * HZ);
-
- if (lret < 0)
- return lret;
- else if (lret == 0)
- return -EBUSY;
-
- spin_lock(&bo->bdev->lru_lock);
- if (unlock_resv && !dma_resv_trylock(bo->base.resv)) {
- /*
- * We raced, and lost, someone else holds the reservation now,
- * and is probably busy in ttm_bo_cleanup_memtype_use.
- *
- * Even if it's not the case, because we finished waiting any
- * delayed destruction would succeed, so just return success
- * here.
- */
- spin_unlock(&bo->bdev->lru_lock);
- return 0;
- }
- ret = 0;
- }
-
- if (ret) {
- if (unlock_resv)
- dma_resv_unlock(bo->base.resv);
- spin_unlock(&bo->bdev->lru_lock);
- return ret;
- }
-
- spin_unlock(&bo->bdev->lru_lock);
- ttm_bo_cleanup_memtype_use(bo);
-
- if (unlock_resv)
- dma_resv_unlock(bo->base.resv);
-
- return 0;
-}
-
/*
* Block for the dma_resv object to become idle, lock the buffer and clean up
* the resource and tt object.
@@ -505,151 +431,154 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
}
EXPORT_SYMBOL(ttm_bo_eviction_valuable);
-/*
- * Check the target bo is allowable to be evicted or swapout, including cases:
- *
- * a. if share same reservation object with ctx->resv, have assumption
- * reservation objects should already be locked, so not lock again and
- * return true directly when either the opreation allow_reserved_eviction
- * or the target bo already is in delayed free list;
+/**
+ * ttm_bo_evict_first() - Evict the first bo on the manager's LRU list.
+ * @bdev: The ttm device.
+ * @man: The manager whose bo to evict.
+ * @ctx: The TTM operation ctx governing the eviction.
*
- * b. Otherwise, trylock it.
+ * Return: 0 if successful or the resource disappeared. Negative error code on error.
*/
-static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
- struct ttm_operation_ctx *ctx,
- const struct ttm_place *place,
- bool *locked, bool *busy)
+int ttm_bo_evict_first(struct ttm_device *bdev, struct ttm_resource_manager *man,
+ struct ttm_operation_ctx *ctx)
{
- bool ret = false;
+ struct ttm_resource_cursor cursor;
+ struct ttm_buffer_object *bo;
+ struct ttm_resource *res;
+ unsigned int mem_type;
+ int ret = 0;
- if (bo->pin_count) {
- *locked = false;
- if (busy)
- *busy = false;
- return false;
+ spin_lock(&bdev->lru_lock);
+ res = ttm_resource_manager_first(man, &cursor);
+ if (!res) {
+ ret = -ENOENT;
+ goto out_no_ref;
}
+ bo = res->bo;
+ if (!ttm_bo_get_unless_zero(bo))
+ goto out_no_ref;
+ mem_type = res->mem_type;
+ spin_unlock(&bdev->lru_lock);
+ ret = ttm_bo_reserve(bo, ctx->interruptible, ctx->no_wait_gpu, NULL);
+ if (ret)
+ goto out_no_lock;
+ if (bo->resource != res || res->mem_type != mem_type)
+ goto out_bad_res;
- if (bo->base.resv == ctx->resv) {
- dma_resv_assert_held(bo->base.resv);
- if (ctx->allow_res_evict)
- ret = true;
- *locked = false;
- if (busy)
- *busy = false;
+ if (bo->deleted) {
+ ret = ttm_bo_wait_ctx(bo, ctx);
+ if (ret)
+ ttm_bo_cleanup_memtype_use(bo);
} else {
- ret = dma_resv_trylock(bo->base.resv);
- *locked = ret;
- if (busy)
- *busy = !ret;
- }
-
- if (ret && place && (bo->resource->mem_type != place->mem_type ||
- !bo->bdev->funcs->eviction_valuable(bo, place))) {
- ret = false;
- if (*locked) {
- dma_resv_unlock(bo->base.resv);
- *locked = false;
- }
+ ret = ttm_bo_evict(bo, ctx);
}
-
+out_bad_res:
+ dma_resv_unlock(bo->base.resv);
+out_no_lock:
+ ttm_bo_put(bo);
+ ttm_resource_cursor_fini(&cursor);
return ret;
+
+out_no_ref:
+ ttm_resource_cursor_fini_locked(&cursor);
+ spin_unlock(&bdev->lru_lock);
+ return -ENOENT;
}
/**
- * ttm_mem_evict_wait_busy - wait for a busy BO to become available
- *
- * @busy_bo: BO which couldn't be locked with trylock
- * @ctx: operation context
- * @ticket: acquire ticket
- *
- * Try to lock a busy buffer object to avoid failing eviction.
+ * struct ttm_bo_evict_walk - Parameters for the evict walk.
*/
-static int ttm_mem_evict_wait_busy(struct ttm_buffer_object *busy_bo,
- struct ttm_operation_ctx *ctx,
- struct ww_acquire_ctx *ticket)
-{
- int r;
-
- if (!busy_bo || !ticket)
- return -EBUSY;
-
- if (ctx->interruptible)
- r = dma_resv_lock_interruptible(busy_bo->base.resv,
- ticket);
- else
- r = dma_resv_lock(busy_bo->base.resv, ticket);
-
- /*
- * TODO: It would be better to keep the BO locked until allocation is at
- * least tried one more time, but that would mean a much larger rework
- * of TTM.
- */
- if (!r)
- dma_resv_unlock(busy_bo->base.resv);
-
- return r == -EDEADLK ? -EBUSY : r;
-}
+struct ttm_bo_evict_walk {
+ /** @walk: The walk base parameters. */
+ struct ttm_lru_walk walk;
+ /** @place: The place passed to the resource allocation. */
+ const struct ttm_place *place;
+ /** @evictor: The buffer object we're trying to make room for. */
+ struct ttm_buffer_object *evictor;
+ /** @res: The allocated resource if any. */
+ struct ttm_resource **res;
+ /** @evicted: The number of evicted pages. */
+ unsigned long evicted;
+};
-int ttm_mem_evict_first(struct ttm_device *bdev,
- struct ttm_resource_manager *man,
- const struct ttm_place *place,
- struct ttm_operation_ctx *ctx,
- struct ww_acquire_ctx *ticket)
+static long ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
{
- struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;
- struct ttm_resource_cursor cursor;
- struct ttm_resource *res;
- bool locked = false;
- int ret;
+ struct ttm_bo_evict_walk *evict_walk =
+ container_of(walk, typeof(*evict_walk), walk);
+ long lret;
- spin_lock(&bdev->lru_lock);
- ttm_resource_manager_for_each_res(man, &cursor, res) {
- bool busy;
-
- if (!ttm_bo_evict_swapout_allowable(res->bo, ctx, place,
- &locked, &busy)) {
- if (busy && !busy_bo && ticket !=
- dma_resv_locking_ctx(res->bo->base.resv))
- busy_bo = res->bo;
- continue;
- }
+ if (!bo->bdev->funcs->eviction_valuable(bo, evict_walk->place))
+ return 0;
- if (ttm_bo_get_unless_zero(res->bo)) {
- bo = res->bo;
- break;
- }
- if (locked)
- dma_resv_unlock(res->bo->base.resv);
+ if (bo->deleted) {
+ lret = ttm_bo_wait_ctx(bo, walk->ctx);
+ if (!lret)
+ ttm_bo_cleanup_memtype_use(bo);
+ } else {
+ lret = ttm_bo_evict(bo, walk->ctx);
}
- ttm_resource_cursor_fini_locked(&cursor);
- if (!bo) {
- if (busy_bo && !ttm_bo_get_unless_zero(busy_bo))
- busy_bo = NULL;
- spin_unlock(&bdev->lru_lock);
- ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket);
- if (busy_bo)
- ttm_bo_put(busy_bo);
- return ret;
- }
+ if (lret)
+ goto out;
- if (bo->deleted) {
- ret = ttm_bo_cleanup_refs(bo, ctx->interruptible,
- ctx->no_wait_gpu, locked);
- ttm_bo_put(bo);
- return ret;
- }
+ evict_walk->evicted++;
+ if (evict_walk->res)
+ lret = ttm_resource_alloc(evict_walk->evictor, evict_walk->place,
+ evict_walk->res);
+ if (lret == 0)
+ return 1;
+out:
+ /* Errors that should terminate the walk. */
+ if (lret == -ENOMEM || lret == -EINTR || lret == -ERESTARTSYS ||
+ lret == -EAGAIN)
+ return lret;
- spin_unlock(&bdev->lru_lock);
+ return 0;
+}
- ret = ttm_bo_evict(bo, ctx);
- if (locked)
- ttm_bo_unreserve(bo);
- else
- ttm_bo_move_to_lru_tail_unlocked(bo);
+static const struct ttm_lru_walk_ops ttm_evict_walk_ops = {
+ .process_bo = ttm_bo_evict_cb,
+};
- ttm_bo_put(bo);
- return ret;
+static int ttm_bo_evict_alloc(struct ttm_device *bdev,
+ struct ttm_resource_manager *man,
+ const struct ttm_place *place,
+ struct ttm_buffer_object *evictor,
+ struct ttm_operation_ctx *ctx,
+ struct ww_acquire_ctx *ticket,
+ struct ttm_resource **res)
+{
+ struct ttm_bo_evict_walk evict_walk = {
+ .walk = {
+ .ops = &ttm_evict_walk_ops,
+ .ctx = ctx,
+ .ticket = ticket,
+ },
+ .place = place,
+ .evictor = evictor,
+ .res = res,
+ };
+ long lret;
+
+ evict_walk.walk.trylock_only = true;
+ lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
+ if (lret || !ticket)
+ goto out;
+
+ /* If ticket-locking, repeat while making progress. */
+ evict_walk.walk.trylock_only = false;
+ do {
+ /* The walk may clear the evict_walk.walk.ticket field */
+ evict_walk.walk.ticket = ticket;
+ evict_walk.evicted = 0;
+ lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
+ } while (!lret && evict_walk.evicted);
+out:
+ if (lret < 0)
+ return lret;
+ if (lret == 0)
+ return -EBUSY;
+ return 0;
}
/**
@@ -760,6 +689,7 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
for (i = 0; i < placement->num_placement; ++i) {
const struct ttm_place *place = &placement->placement[i];
struct ttm_resource_manager *man;
+ bool may_evict;
man = ttm_manager_type(bdev, place->mem_type);
if (!man || !ttm_resource_manager_used(man))
@@ -769,22 +699,21 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
TTM_PL_FLAG_FALLBACK))
continue;
- do {
- ret = ttm_resource_alloc(bo, place, res);
- if (unlikely(ret && ret != -ENOSPC))
+ may_evict = (force_space && place->mem_type != TTM_PL_SYSTEM);
+ ret = ttm_resource_alloc(bo, place, res);
+ if (ret) {
+ if (ret != -ENOSPC)
return ret;
- if (likely(!ret) || !force_space)
- break;
-
- ret = ttm_mem_evict_first(bdev, man, place, ctx,
- ticket);
- if (unlikely(ret == -EBUSY))
- break;
- if (unlikely(ret))
+ if (!may_evict)
+ continue;
+
+ ret = ttm_bo_evict_alloc(bdev, man, place, bo, ctx,
+ ticket, res);
+ if (ret == -EBUSY)
+ continue;
+ if (ret)
return ret;
- } while (1);
- if (ret)
- continue;
+ }
ret = ttm_bo_add_move_fence(bo, man, ctx->no_wait_gpu);
if (unlikely(ret)) {
@@ -796,7 +725,6 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
}
return 0;
}
-
return -ENOSPC;
}
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index a03090683e79..6d0c66fc36e3 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -508,24 +508,10 @@ int ttm_resource_manager_evict_all(struct ttm_device *bdev,
};
struct dma_fence *fence;
int ret;
- unsigned i;
-
- /*
- * Can't use standard list traversal since we're unlocking.
- */
- spin_lock(&bdev->lru_lock);
- for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
- while (!list_empty(&man->lru[i])) {
- spin_unlock(&bdev->lru_lock);
- ret = ttm_mem_evict_first(bdev, man, NULL, &ctx,
- NULL);
- if (ret)
- return ret;
- spin_lock(&bdev->lru_lock);
- }
- }
- spin_unlock(&bdev->lru_lock);
+ do {
+ ret = ttm_bo_evict_first(bdev, man, &ctx);
+ } while (!ret);
spin_lock(&man->move_lock);
fence = dma_fence_get(man->move);
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index 472a55b69afb..148f49f625e4 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -415,11 +415,9 @@ long ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
pgoff_t target);
void ttm_bo_pin(struct ttm_buffer_object *bo);
void ttm_bo_unpin(struct ttm_buffer_object *bo);
-int ttm_mem_evict_first(struct ttm_device *bdev,
- struct ttm_resource_manager *man,
- const struct ttm_place *place,
- struct ttm_operation_ctx *ctx,
- struct ww_acquire_ctx *ticket);
+int ttm_bo_evict_first(struct ttm_device *bdev,
+ struct ttm_resource_manager *man,
+ struct ttm_operation_ctx *ctx);
vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
struct vm_fault *vmf);
vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 08/21] drm/ttm: Add a virtual base class for graphics memory backup
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (6 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 07/21] drm/ttm: Use the LRU walker for eviction Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 09/21] drm/ttm/pool: Provide a helper to shrink pages Thomas Hellström
` (21 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Initially intended for experimenting with different backup
solutions (shmem vs direct swap cache insertion), abstract
the backup destination using a virtual base class.
Also provide a sample implementation for shmem.
While when settling on a preferred backup solution, one could
perhaps skip the abstraction, this functionality may actually
come in handy for configurable dedicated graphics memory
backup to fast nvme files or similar, whithout affecting
swap-space. Could indeed be useful for VRAM backup on S4 and
other cases.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/Makefile | 2 +-
drivers/gpu/drm/ttm/ttm_backup_shmem.c | 137 +++++++++++++++++++++++++
include/drm/ttm/ttm_backup.h | 136 ++++++++++++++++++++++++
3 files changed, 274 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/ttm/ttm_backup_shmem.c
create mode 100644 include/drm/ttm/ttm_backup.h
diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile
index dad298127226..5e980dd90e41 100644
--- a/drivers/gpu/drm/ttm/Makefile
+++ b/drivers/gpu/drm/ttm/Makefile
@@ -4,7 +4,7 @@
ttm-y := ttm_tt.o ttm_bo.o ttm_bo_util.o ttm_bo_vm.o ttm_module.o \
ttm_execbuf_util.o ttm_range_manager.o ttm_resource.o ttm_pool.o \
- ttm_device.o ttm_sys_manager.o
+ ttm_device.o ttm_sys_manager.o ttm_backup_shmem.o
ttm-$(CONFIG_AGP) += ttm_agp_backend.o
obj-$(CONFIG_DRM_TTM) += ttm.o
diff --git a/drivers/gpu/drm/ttm/ttm_backup_shmem.c b/drivers/gpu/drm/ttm/ttm_backup_shmem.c
new file mode 100644
index 000000000000..79c2f552863a
--- /dev/null
+++ b/drivers/gpu/drm/ttm/ttm_backup_shmem.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <drm/ttm/ttm_backup.h>
+#include <linux/page-flags.h>
+
+/**
+ * struct ttm_backup_shmem - A shmem based ttm_backup subclass.
+ * @backup: The base struct ttm_backup
+ * @filp: The associated shmem object
+ */
+struct ttm_backup_shmem {
+ struct ttm_backup backup;
+ struct file *filp;
+};
+
+static struct ttm_backup_shmem *to_backup_shmem(struct ttm_backup *backup)
+{
+ return container_of(backup, struct ttm_backup_shmem, backup);
+}
+
+static void ttm_backup_shmem_drop(struct ttm_backup *backup, unsigned long handle)
+{
+ handle -= 1;
+ shmem_truncate_range(file_inode(to_backup_shmem(backup)->filp), handle,
+ handle + 1);
+}
+
+static int ttm_backup_shmem_copy_page(struct ttm_backup *backup, struct page *dst,
+ unsigned long handle, bool killable)
+{
+ struct file *filp = to_backup_shmem(backup)->filp;
+ struct address_space *mapping = filp->f_mapping;
+ struct folio *from_folio;
+
+ handle -= 1;
+ from_folio = shmem_read_folio(mapping, handle);
+ if (IS_ERR(from_folio))
+ return PTR_ERR(from_folio);
+
+ /* Note: Use drm_memcpy_from_wc? */
+ copy_highpage(dst, folio_file_page(from_folio, handle));
+ folio_put(from_folio);
+
+ return 0;
+}
+
+static unsigned long
+ttm_backup_shmem_backup_page(struct ttm_backup *backup, struct page *page,
+ bool writeback, pgoff_t i, gfp_t page_gfp,
+ gfp_t alloc_gfp)
+{
+ struct file *filp = to_backup_shmem(backup)->filp;
+ struct address_space *mapping = filp->f_mapping;
+ unsigned long handle = 0;
+ struct folio *to_folio;
+ int ret;
+
+ to_folio = shmem_read_folio_gfp(mapping, i, alloc_gfp);
+ if (IS_ERR(to_folio))
+ return handle;
+
+ folio_mark_accessed(to_folio);
+ folio_lock(to_folio);
+ folio_mark_dirty(to_folio);
+ copy_highpage(folio_file_page(to_folio, i), page);
+ handle = i + 1;
+
+ if (writeback && !folio_mapped(to_folio) && folio_clear_dirty_for_io(to_folio)) {
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_NONE,
+ .nr_to_write = SWAP_CLUSTER_MAX,
+ .range_start = 0,
+ .range_end = LLONG_MAX,
+ .for_reclaim = 1,
+ };
+ folio_set_reclaim(to_folio);
+ ret = mapping->a_ops->writepage(folio_page(to_folio, 0), &wbc);
+ if (!folio_test_writeback(to_folio))
+ folio_clear_reclaim(to_folio);
+ /* If writepage succeeds, it unlocks the folio */
+ if (ret)
+ folio_unlock(to_folio);
+ } else {
+ folio_unlock(to_folio);
+ }
+
+ folio_put(to_folio);
+
+ return handle;
+}
+
+static void ttm_backup_shmem_fini(struct ttm_backup *backup)
+{
+ struct ttm_backup_shmem *sbackup = to_backup_shmem(backup);
+
+ fput(sbackup->filp);
+ kfree(sbackup);
+}
+
+static const struct ttm_backup_ops ttm_backup_shmem_ops = {
+ .drop = ttm_backup_shmem_drop,
+ .copy_backed_up_page = ttm_backup_shmem_copy_page,
+ .backup_page = ttm_backup_shmem_backup_page,
+ .fini = ttm_backup_shmem_fini,
+};
+
+/**
+ * ttm_backup_shmem_create() - Create a shmem-based struct backup.
+ * @size: The maximum size (in bytes) to back up.
+ *
+ * Create a backup utilizing shmem objects.
+ *
+ * Return: A pointer to a struct ttm_backup on success,
+ * an error pointer on error.
+ */
+struct ttm_backup *ttm_backup_shmem_create(loff_t size)
+{
+ struct ttm_backup_shmem *sbackup =
+ kzalloc(sizeof(*sbackup), GFP_KERNEL | __GFP_ACCOUNT);
+
+ if (!sbackup)
+ return ERR_PTR(-ENOMEM);
+
+ sbackup->filp = shmem_file_setup("ttm shmem backup", size, 0);
+ if (IS_ERR(sbackup->filp)) {
+ kfree(sbackup);
+ return ERR_CAST(sbackup->filp);
+ }
+
+ sbackup->backup.ops = &ttm_backup_shmem_ops;
+
+ return &sbackup->backup;
+}
+EXPORT_SYMBOL_GPL(ttm_backup_shmem_create);
diff --git a/include/drm/ttm/ttm_backup.h b/include/drm/ttm/ttm_backup.h
new file mode 100644
index 000000000000..88e8b97a6fdc
--- /dev/null
+++ b/include/drm/ttm/ttm_backup.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _TTM_BACKUP_H_
+#define _TTM_BACKUP_H_
+
+#include <linux/mm_types.h>
+#include <linux/shmem_fs.h>
+
+struct ttm_backup;
+
+/**
+ * ttm_backup_handle_to_page_ptr() - Convert handle to struct page pointer
+ * @handle: The handle to convert.
+ *
+ * Converts an opaque handle received from the
+ * struct ttm_backoup_ops::backup_page() function to an (invalid)
+ * struct page pointer suitable for a struct page array.
+ *
+ * Return: An (invalid) struct page pointer.
+ */
+static inline struct page *
+ttm_backup_handle_to_page_ptr(unsigned long handle)
+{
+ return (struct page *)(handle << 1 | 1);
+}
+
+/**
+ * ttm_backup_page_ptr_is_handle() - Whether a struct page pointer is a handle
+ * @page: The struct page pointer to check.
+ *
+ * Return: true if the struct page pointer is a handld returned from
+ * ttm_backup_handle_to_page_ptr(). False otherwise.
+ */
+static inline bool ttm_backup_page_ptr_is_handle(const struct page *page)
+{
+ return (unsigned long)page & 1;
+}
+
+/**
+ * ttm_backup_page_ptr_to_handle() - Convert a struct page pointer to a handle
+ * @page: The struct page pointer to convert
+ *
+ * Return: The handle that was previously used in
+ * ttm_backup_handle_to_page_ptr() to obtain a struct page pointer, suitable
+ * for use as argument in the struct ttm_backup_ops drop() or
+ * copy_backed_up_page() functions.
+ */
+static inline unsigned long
+ttm_backup_page_ptr_to_handle(const struct page *page)
+{
+ WARN_ON(!ttm_backup_page_ptr_is_handle(page));
+ return (unsigned long)page >> 1;
+}
+
+/** struct ttm_backup_ops - A struct ttm_backup backend operations */
+struct ttm_backup_ops {
+ /**
+ * drop - release memory associated with a handle
+ * @backup: The struct backup pointer used to obtain the handle
+ * @handle: The handle obtained from the @backup_page function.
+ */
+ void (*drop)(struct ttm_backup *backup, unsigned long handle);
+
+ /**
+ * copy_backed_up_page - Copy the contents of a previously backed
+ * up page
+ * @backup: The struct backup pointer used to back up the page.
+ * @dst: The struct page to copy into.
+ * @handle: The handle returned when the page was backed up.
+ * @intr: Try to perform waits interruptable or at least killable.
+ *
+ * Return: 0 on success, Negative error code on failure, notably
+ * -EINTR if @intr was set to true and a signal is pending.
+ */
+ int (*copy_backed_up_page)(struct ttm_backup *backup, struct page *dst,
+ unsigned long handle, bool intr);
+
+ /**
+ * backup_page - Backup a page
+ * @backup: The struct backup pointer to use.
+ * @page: The page to back up.
+ * @writeback: Whether to perform immediate writeback of the page.
+ * This may have performance implications.
+ * @i: A unique integer for each page and each struct backup.
+ * This is a hint allowing the backup backend to avoid managing
+ * its address space separately.
+ * @page_gfp: The gfp value used when the page was allocated.
+ * This is used for accounting purposes.
+ * @alloc_gfp: The gpf to be used when the backend needs to allocaete
+ * memory.
+ *
+ * Return: A handle on success. 0 on failure.
+ * (This is following the swp_entry_t convention).
+ *
+ * Note: This function could be extended to back up a folio and
+ * backends would then split the folio internally if needed.
+ * Drawback is that the caller would then have to keep track of
+ */
+ unsigned long (*backup_page)(struct ttm_backup *backup, struct page *page,
+ bool writeback, pgoff_t i, gfp_t page_gfp,
+ gfp_t alloc_gfp);
+ /**
+ * fini - Free the struct backup resources after last use.
+ * @backup: Pointer to the struct backup whose resources to free.
+ *
+ * After a call to @fini, it's illegal to use the @backup pointer.
+ */
+ void (*fini)(struct ttm_backup *backup);
+};
+
+/**
+ * struct ttm_backup - Abstract a backup backend.
+ * @ops: The operations as described above.
+ *
+ * The struct ttm_backup is intended to be subclassed by the
+ * backend implementation.
+ */
+struct ttm_backup {
+ const struct ttm_backup_ops *ops;
+};
+
+/**
+ * ttm_backup_shmem_create() - Create a shmem-based struct backup.
+ * @size: The maximum size (in bytes) to back up.
+ *
+ * Create a backup utilizing shmem objects.
+ *
+ * Return: A pointer to a struct ttm_backup on success,
+ * an error pointer on error.
+ */
+struct ttm_backup *ttm_backup_shmem_create(loff_t size);
+
+#endif
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 09/21] drm/ttm/pool: Provide a helper to shrink pages
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (7 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 08/21] drm/ttm: Add a virtual base class for graphics memory backup Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 10/21] drm/ttm: Use fault-injection to test error paths Thomas Hellström
` (20 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Provide a helper to shrink ttm_tt page-vectors on a per-page
basis. A ttm_backup backend could then in theory get away with
allocating a single temporary page for each struct ttm_tt.
This is accomplished by splitting larger pages before trying to
back them up.
In the future we could allow ttm_backup to handle backing up
large pages as well, but currently there's no benefit in
doing that, since the shmem backup backend would have to
split those anyway to avoid allocating too much temporary
memory, and if the backend instead inserts pages into the
swap-cache, those are split on reclaim by the core.
Due to potential backup- and recover errors, allow partially swapped
out struct ttm_tt's, although mark them as swapped out stopping them
from being swapped out a second time. More details in the ttm_pool.c
DOC section.
v2:
- A couple of cleanups and error fixes in ttm_pool_back_up_tt.
- s/back_up/backup/
- Add a writeback parameter to the exported interface.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_pool.c | 397 +++++++++++++++++++++++++++++++--
drivers/gpu/drm/ttm/ttm_tt.c | 37 +++
include/drm/ttm/ttm_pool.h | 5 +
include/drm/ttm/ttm_tt.h | 20 ++
4 files changed, 446 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 6e1fd6985ffc..38e50cf81b0a 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -41,6 +41,7 @@
#include <asm/set_memory.h>
#endif
+#include <drm/ttm/ttm_backup.h>
#include <drm/ttm/ttm_pool.h>
#include <drm/ttm/ttm_tt.h>
#include <drm/ttm/ttm_bo.h>
@@ -58,6 +59,32 @@ struct ttm_pool_dma {
unsigned long vaddr;
};
+/**
+ * struct ttm_pool_tt_restore - State representing restore from backup
+ * @alloced_pages: Total number of already allocated pages for the ttm_tt.
+ * @restored_pages: Number of (sub) pages restored from swap for this
+ * chunk of 1 << @order pages.
+ * @first_page: The ttm page ptr representing for @old_pages[0].
+ * @caching_divide: Page pointer where subsequent pages are cached.
+ * @old_pages: Backup copy of page pointers that were replaced by the new
+ * page allocation.
+ * @pool: The pool used for page allocation while restoring.
+ * @order: The order of the last page allocated while restoring.
+ *
+ * Recovery from backup might fail when we've recovered less than the
+ * full ttm_tt. In order not to loose any data (yet), keep information
+ * around that allows us to restart a failed ttm backup recovery.
+ */
+struct ttm_pool_tt_restore {
+ pgoff_t alloced_pages;
+ pgoff_t restored_pages;
+ struct page **first_page;
+ struct page **caching_divide;
+ struct ttm_pool *pool;
+ unsigned int order;
+ struct page *old_pages[];
+};
+
static unsigned long page_pool_size;
MODULE_PARM_DESC(page_pool_size, "Number of pages in the WC/UC/DMA pool");
@@ -354,11 +381,102 @@ static unsigned int ttm_pool_page_order(struct ttm_pool *pool, struct page *p)
return p->private;
}
+/*
+ * To be able to insert single pages into backup directly,
+ * we need to split multi-order page allocations and make them look
+ * like single-page allocations.
+ */
+static void ttm_pool_split_for_swap(struct ttm_pool *pool, struct page *p)
+{
+ unsigned int order = ttm_pool_page_order(pool, p);
+ pgoff_t nr;
+
+ if (!order)
+ return;
+
+ split_page(p, order);
+ nr = 1UL << order;
+ while (nr--)
+ (p++)->private = 0;
+}
+
+/**
+ * DOC: Partial backup and restoration of a struct ttm_tt.
+ *
+ * Swapout using ttm_backup::ops::backup_page() and swapin using
+ * ttm_backup::ops::copy_backed_up_page() may fail.
+ * The former most likely due to lack of swap-space or memory, the latter due
+ * to lack of memory or because of signal interruption during waits.
+ *
+ * Backupfailure is easily handled by using a ttm_tt pages vector that holds
+ * both swap entries and page pointers. This has to be taken into account when
+ * restoring such a ttm_tt from backup, and when freeing it while backed up.
+ * When restoring, for simplicity, new pages are actually allocated from the
+ * pool and the contents of any old pages are copied in and then the old pages
+ * are released.
+ *
+ * For restoration failures, the struct ttm_pool_tt_restore holds sufficient state
+ * to be able to resume an interrupted restore, and that structure is freed once
+ * the restoration is complete. If the struct ttm_tt is destroyed while there
+ * is a valid struct ttm_pool_tt_restore attached, that is also properly taken
+ * care of.
+ */
+
+static bool ttm_pool_restore_valid(const struct ttm_pool_tt_restore *restore)
+{
+ return restore && restore->restored_pages < (1 << restore->order);
+}
+
+static int ttm_pool_restore_tt(struct ttm_pool_tt_restore *restore,
+ struct ttm_backup *backup,
+ struct ttm_operation_ctx *ctx)
+{
+ unsigned int i, nr = 1 << restore->order;
+ int ret = 0;
+
+ if (!ttm_pool_restore_valid(restore))
+ return 0;
+
+ for (i = restore->restored_pages; i < nr; ++i) {
+ struct page *p = restore->old_pages[i];
+
+ if (ttm_backup_page_ptr_is_handle(p)) {
+ unsigned long handle = ttm_backup_page_ptr_to_handle(p);
+
+ if (handle == 0)
+ continue;
+
+ ret = backup->ops->copy_backed_up_page
+ (backup, restore->first_page[i],
+ handle, ctx->interruptible);
+ if (ret)
+ break;
+
+ backup->ops->drop(backup, handle);
+ } else if (p) {
+ /*
+ * We could probably avoid splitting the old page
+ * using clever logic, but ATM we don't care.
+ */
+ ttm_pool_split_for_swap(restore->pool, p);
+ copy_highpage(restore->first_page[i], p);
+ __free_pages(p, 0);
+ }
+
+ restore->restored_pages++;
+ restore->old_pages[i] = NULL;
+ cond_resched();
+ }
+
+ return ret;
+}
+
/* Called when we got a page, either from a pool or newly allocated */
static int ttm_pool_page_allocated(struct ttm_pool *pool, unsigned int order,
struct page *p, dma_addr_t **dma_addr,
unsigned long *num_pages,
- struct page ***pages)
+ struct page ***pages,
+ struct ttm_pool_tt_restore *restore)
{
unsigned int i;
int r;
@@ -369,6 +487,16 @@ static int ttm_pool_page_allocated(struct ttm_pool *pool, unsigned int order,
return r;
}
+ if (restore) {
+ memcpy(restore->old_pages, *pages,
+ (1 << order) * sizeof(*restore->old_pages));
+ memset(*pages, 0, (1 << order) * sizeof(**pages));
+ restore->order = order;
+ restore->restored_pages = 0;
+ restore->first_page = *pages;
+ restore->alloced_pages += 1UL << order;
+ }
+
*num_pages -= 1 << order;
for (i = 1 << order; i; --i, ++(*pages), ++p)
**pages = p;
@@ -394,22 +522,39 @@ static void ttm_pool_free_range(struct ttm_pool *pool, struct ttm_tt *tt,
pgoff_t start_page, pgoff_t end_page)
{
struct page **pages = &tt->pages[start_page];
+ struct ttm_backup *backup = tt->backup;
unsigned int order;
pgoff_t i, nr;
for (i = start_page; i < end_page; i += nr, pages += nr) {
struct ttm_pool_type *pt = NULL;
+ struct page *p = *pages;
+
+ if (ttm_backup_page_ptr_is_handle(p)) {
+ unsigned long handle = ttm_backup_page_ptr_to_handle(p);
+
+ nr = 1;
+ if (handle != 0)
+ backup->ops->drop(backup, handle);
+ continue;
+ }
+
+ if (pool) {
+ order = ttm_pool_page_order(pool, p);
+ nr = (1UL << order);
+ if (tt->dma_address)
+ ttm_pool_unmap(pool, tt->dma_address[i], nr);
- order = ttm_pool_page_order(pool, *pages);
- nr = (1UL << order);
- if (tt->dma_address)
- ttm_pool_unmap(pool, tt->dma_address[i], nr);
+ pt = ttm_pool_select_type(pool, caching, order);
+ } else {
+ order = p->private;
+ nr = (1UL << order);
+ }
- pt = ttm_pool_select_type(pool, caching, order);
if (pt)
- ttm_pool_type_give(pt, *pages);
+ ttm_pool_type_give(pt, p);
else
- ttm_pool_free_page(pool, caching, order, *pages);
+ ttm_pool_free_page(pool, caching, order, p);
}
}
@@ -453,9 +598,37 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
else
gfp_flags |= GFP_HIGHUSER;
- for (order = min_t(unsigned int, MAX_PAGE_ORDER, __fls(num_pages));
- num_pages;
- order = min_t(unsigned int, order, __fls(num_pages))) {
+ order = min_t(unsigned int, MAX_PAGE_ORDER, __fls(num_pages));
+
+ if (tt->page_flags & TTM_TT_FLAG_PRIV_BACKED_UP) {
+ if (!tt->restore) {
+ gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
+
+ if (ctx->gfp_retry_mayfail)
+ gfp |= __GFP_RETRY_MAYFAIL;
+
+ tt->restore =
+ kvzalloc(struct_size(tt->restore, old_pages,
+ (size_t)1 << order), gfp);
+ /* RFC: Possibly loop on -ENOMEM and reduce order. */
+ if (!tt->restore)
+ return -ENOMEM;
+ } else if (ttm_pool_restore_valid(tt->restore)) {
+ struct ttm_pool_tt_restore *restore = tt->restore;
+
+ num_pages -= restore->alloced_pages;
+ order = min_t(unsigned int, order, __fls(num_pages));
+ pages += restore->alloced_pages;
+ r = ttm_pool_restore_tt(restore, tt->backup, ctx);
+ if (r)
+ return r;
+ caching = restore->caching_divide;
+ }
+
+ tt->restore->pool = pool;
+ }
+
+ for (; num_pages; order = min_t(unsigned int, order, __fls(num_pages))) {
struct ttm_pool_type *pt;
page_caching = tt->caching;
@@ -472,11 +645,19 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
r = ttm_pool_page_allocated(pool, order, p,
&dma_addr,
&num_pages,
- &pages);
+ &pages,
+ tt->restore);
if (r)
goto error_free_page;
caching = pages;
+ if (ttm_pool_restore_valid(tt->restore)) {
+ r = ttm_pool_restore_tt(tt->restore, tt->backup,
+ ctx);
+ if (r)
+ goto error_free_all;
+ }
+
if (num_pages < (1 << order))
break;
@@ -496,9 +677,17 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
caching = pages;
}
r = ttm_pool_page_allocated(pool, order, p, &dma_addr,
- &num_pages, &pages);
+ &num_pages, &pages,
+ tt->restore);
if (r)
goto error_free_page;
+
+ if (ttm_pool_restore_valid(tt->restore)) {
+ r = ttm_pool_restore_tt(tt->restore, tt->backup, ctx);
+ if (r)
+ goto error_free_all;
+ }
+
if (PageHighMem(p))
caching = pages;
}
@@ -517,12 +706,26 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
if (r)
goto error_free_all;
+ if (tt->restore) {
+ kvfree(tt->restore);
+ tt->restore = NULL;
+ }
+
+ if (tt->page_flags & TTM_TT_FLAG_PRIV_BACKED_UP)
+ tt->page_flags &= ~(TTM_TT_FLAG_PRIV_BACKED_UP |
+ TTM_TT_FLAG_SWAPPED);
+
return 0;
error_free_page:
ttm_pool_free_page(pool, page_caching, order, p);
error_free_all:
+ if (tt->page_flags & TTM_TT_FLAG_PRIV_BACKED_UP) {
+ tt->restore->caching_divide = caching;
+ return r;
+ }
+
num_pages = tt->num_pages - num_pages;
caching_divide = caching - tt->pages;
ttm_pool_free_range(pool, tt, tt->caching, 0, caching_divide);
@@ -549,6 +752,174 @@ void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt)
}
EXPORT_SYMBOL(ttm_pool_free);
+/**
+ * ttm_pool_release_backed_up() - Release content of a swapped-out struct ttm_tt
+ * @tt: The struct ttm_tt.
+ *
+ * Release handles with associated content or any remaining pages of
+ * a backed-up struct ttm_tt.
+ */
+void ttm_pool_release_backed_up(struct ttm_tt *tt)
+{
+ struct ttm_backup *backup = tt->backup;
+ struct ttm_pool_tt_restore *restore;
+ pgoff_t i, start_page = 0;
+ unsigned long handle;
+
+ if (!(tt->page_flags & TTM_TT_FLAG_PRIV_BACKED_UP))
+ return;
+
+ restore = tt->restore;
+
+ if (ttm_pool_restore_valid(restore)) {
+ pgoff_t nr = 1UL << restore->order;
+
+ for (i = restore->restored_pages; i < nr; ++i) {
+ struct page *p = restore->old_pages[i];
+
+ if (ttm_backup_page_ptr_is_handle(p)) {
+ handle = ttm_backup_page_ptr_to_handle(p);
+ if (handle == 0)
+ continue;
+
+ backup->ops->drop(backup, handle);
+ } else if (p) {
+ ttm_pool_split_for_swap(restore->pool, p);
+ __free_pages(p, 0);
+ }
+ }
+ }
+
+ if (restore) {
+ pgoff_t mid = restore->caching_divide - tt->pages;
+
+ start_page = restore->alloced_pages;
+ /* Pages that might be dma-mapped and non-cached */
+ ttm_pool_free_range(restore->pool, tt, tt->caching,
+ 0, mid);
+ /* Pages that might be dma-mapped but cached */
+ ttm_pool_free_range(restore->pool, tt, ttm_cached,
+ mid, restore->alloced_pages);
+ }
+
+ /* Shrunken pages. Cached and not dma-mapped. */
+ ttm_pool_free_range(NULL, tt, ttm_cached, start_page, tt->num_pages);
+
+ if (restore) {
+ kvfree(restore);
+ tt->restore = NULL;
+ }
+
+ tt->page_flags &= ~(TTM_TT_FLAG_PRIV_BACKED_UP | TTM_TT_FLAG_SWAPPED);
+}
+
+/**
+ * ttm_pool_backup_tt() - Back up or purge a struct ttm_tt
+ * @pool: The pool used when allocating the struct ttm_tt.
+ * @ttm: The struct ttm_tt.
+ * @purge: Don't back up but release pages directly to system.
+ * @writeback: If !@purge, Try to write out directly to the
+ * underlying persistent media.
+ *
+ * Back up or purge a struct ttm_tt. If @purge is true, then
+ * all pages will be freed directly to the system rather than to the pool
+ * they were allocated from, making the function behave similarly to
+ * ttm_pool_free(). If @purge is false the pages will be backed up instead,
+ * exchanged for handles.
+ * A subsequent call to ttm_pool_alloc() will then read back the content and
+ * a subsequent call to ttm_pool_release_shrunken() will drop it.
+ * If backup of a page fails for whatever reason, @ttm will still be
+ * partially backed up, retaining those pages for which backup fails.
+ *
+ * Return: Number of pages actually backed up or freed, or negative
+ * error code on error.
+ */
+long ttm_pool_backup_tt(struct ttm_pool *pool, struct ttm_tt *ttm, bool purge,
+ bool writeback)
+{
+ struct ttm_backup *backup = ttm->backup;
+ struct page *page;
+ unsigned long handle;
+ gfp_t alloc_gfp;
+ gfp_t gfp;
+ int ret = 0;
+ pgoff_t shrunken = 0;
+ pgoff_t i, num_pages;
+
+ if ((!get_nr_swap_pages() && !purge) ||
+ pool->use_dma_alloc ||
+ (ttm->page_flags & TTM_TT_FLAG_PRIV_BACKED_UP))
+ return -EBUSY;
+
+#ifdef CONFIG_X86
+ /* Anything returned to the system needs to be cached. */
+ if (ttm->caching != ttm_cached)
+ set_pages_array_wb(ttm->pages, ttm->num_pages);
+#endif
+
+ if (ttm->dma_address || purge) {
+ for (i = 0; i < ttm->num_pages; i += num_pages) {
+ unsigned int order;
+
+ page = ttm->pages[i];
+ if (unlikely(!page)) {
+ num_pages = 1;
+ continue;
+ }
+
+ order = ttm_pool_page_order(pool, page);
+ num_pages = 1UL << order;
+ if (ttm->dma_address)
+ ttm_pool_unmap(pool, ttm->dma_address[i],
+ num_pages);
+ if (purge) {
+ shrunken += num_pages;
+ page->private = 0;
+ __free_pages(page, order);
+ memset(ttm->pages + i, 0,
+ num_pages * sizeof(*ttm->pages));
+ }
+ }
+ }
+
+ if (purge)
+ return shrunken;
+
+ if (pool->use_dma32)
+ gfp = GFP_DMA32;
+ else
+ gfp = GFP_HIGHUSER;
+
+ alloc_gfp = GFP_KERNEL | __GFP_HIGH | __GFP_NOWARN | __GFP_RETRY_MAYFAIL;
+
+ for (i = 0; i < ttm->num_pages; ++i) {
+ page = ttm->pages[i];
+ if (unlikely(!page))
+ continue;
+
+ ttm_pool_split_for_swap(pool, page);
+
+ handle = backup->ops->backup_page(backup, page, writeback, i,
+ gfp, alloc_gfp);
+ if (handle) {
+ ttm->pages[i] = ttm_backup_handle_to_page_ptr(handle);
+ put_page(page);
+ shrunken++;
+ } else {
+ /* We allow partially shrunken tts */
+ ret = -ENOMEM;
+ break;
+ }
+ cond_resched();
+ }
+
+ if (shrunken)
+ ttm->page_flags |= (TTM_TT_FLAG_PRIV_BACKED_UP |
+ TTM_TT_FLAG_SWAPPED);
+
+ return shrunken ? shrunken : ret;
+}
+
/**
* ttm_pool_init - Initialize a pool
*
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 7b00ddf0ce49..bc994b8e7e73 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -40,6 +40,7 @@
#include <drm/drm_cache.h>
#include <drm/drm_device.h>
#include <drm/drm_util.h>
+#include <drm/ttm/ttm_backup.h>
#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_tt.h>
@@ -158,6 +159,7 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm,
ttm->swap_storage = NULL;
ttm->sg = bo->sg;
ttm->caching = caching;
+ ttm->restore = NULL;
}
int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
@@ -182,6 +184,12 @@ void ttm_tt_fini(struct ttm_tt *ttm)
fput(ttm->swap_storage);
ttm->swap_storage = NULL;
+ ttm_pool_release_backed_up(ttm);
+ if (ttm->backup) {
+ ttm->backup->ops->fini(ttm->backup);
+ ttm->backup = NULL;
+ }
+
if (ttm->pages)
kvfree(ttm->pages);
else
@@ -252,6 +260,35 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
return ret;
}
+/**
+ * ttm_tt_backup() - Helper to back up a struct ttm_tt.
+ * @bdev: The TTM device.
+ * @tt: The struct ttm_tt.
+ * @purge: Don't back up but release pages directly to system,
+ * bypassing any pooling.
+ * @writeback: If !@purge, try to write out directly to the
+ * underlying persistent media.
+ *
+ * Helper for a TTM driver to use from the bo_shrink() method to shrink
+ * a struct ttm_tt, after it has done the necessary unbinding. This function
+ * will update the page accounting and call ttm_pool_shrink_tt to free pages
+ * or move them to the swap cache.
+ *
+ * Return: Number of pages freed or swapped out, or negative error code on
+ * error.
+ */
+long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt, bool purge,
+ bool writeback)
+{
+ long ret = ttm_pool_backup_tt(&bdev->pool, tt, purge, writeback);
+
+ if (ret > 0)
+ tt->page_flags &= ~TTM_TT_FLAG_PRIV_POPULATED;
+
+ return ret;
+}
+EXPORT_SYMBOL(ttm_tt_backup);
+
/**
* ttm_tt_swapout - swap out tt object
*
diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h
index 160d954a261e..4e4db369952b 100644
--- a/include/drm/ttm/ttm_pool.h
+++ b/include/drm/ttm/ttm_pool.h
@@ -89,6 +89,11 @@ void ttm_pool_fini(struct ttm_pool *pool);
int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m);
+void ttm_pool_release_backed_up(struct ttm_tt *tt);
+
+long ttm_pool_backup_tt(struct ttm_pool *pool, struct ttm_tt *ttm,
+ bool purge, bool writeback);
+
int ttm_pool_mgr_init(unsigned long num_pages);
void ttm_pool_mgr_fini(void);
diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
index 2b9d856ff388..6b990f1e7dd0 100644
--- a/include/drm/ttm/ttm_tt.h
+++ b/include/drm/ttm/ttm_tt.h
@@ -32,11 +32,13 @@
#include <drm/ttm/ttm_caching.h>
#include <drm/ttm/ttm_kmap_iter.h>
+struct ttm_backup;
struct ttm_device;
struct ttm_tt;
struct ttm_resource;
struct ttm_buffer_object;
struct ttm_operation_ctx;
+struct ttm_pool_tt_restore;
/**
* struct ttm_tt - This is a structure holding the pages, caching- and aperture
@@ -85,6 +87,9 @@ struct ttm_tt {
* fault handling abuses the DMA api a bit and dma_map_attrs can't be
* used to assure pgprot always matches.
*
+ * TTM_TT_FLAG_PRIV_BACKED_UP: TTM internal only. This is set if the
+ * struct ttm_tt has been (possibly partially) backed up.
+ *
* TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. This is
* set by TTM after ttm_tt_populate() has successfully returned, and is
* then unset when TTM calls ttm_tt_unpopulate().
@@ -96,6 +101,7 @@ struct ttm_tt {
#define TTM_TT_FLAG_DECRYPTED BIT(4)
#define TTM_TT_FLAG_PRIV_POPULATED BIT(5)
+#define TTM_TT_FLAG_PRIV_BACKED_UP BIT(6)
uint32_t page_flags;
/** @num_pages: Number of pages in the page array. */
uint32_t num_pages;
@@ -105,11 +111,21 @@ struct ttm_tt {
dma_addr_t *dma_address;
/** @swap_storage: Pointer to shmem struct file for swap storage. */
struct file *swap_storage;
+ /**
+ * @backup: Pointer to backup struct for backed up tts.
+ * RFC: Could possibly be unified with @swap_storage.
+ */
+ struct ttm_backup *backup;
/**
* @caching: The current caching state of the pages, see enum
* ttm_caching.
*/
enum ttm_caching caching;
+ /**
+ * @restore: Partial restoration from backup state.
+ * RFC: Incorporate in struct ttm_backup?
+ */
+ struct ttm_pool_tt_restore *restore;
};
/**
@@ -230,6 +246,10 @@ void ttm_tt_mgr_init(unsigned long num_pages, unsigned long num_dma32_pages);
struct ttm_kmap_iter *ttm_kmap_iter_tt_init(struct ttm_kmap_iter_tt *iter_tt,
struct ttm_tt *tt);
unsigned long ttm_tt_pages_limit(void);
+
+long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt, bool purge,
+ bool writeback);
+
#if IS_ENABLED(CONFIG_AGP)
#include <linux/agp_backend.h>
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 10/21] drm/ttm: Use fault-injection to test error paths
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (8 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 09/21] drm/ttm/pool: Provide a helper to shrink pages Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 11/21] drm/ttm, drm/xe: Add a shrinker for xe bos Thomas Hellström
` (19 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Use fault-injection to test partial TTM swapout and interrupted swapin.
Return -EINTR for swapin to test the callers ability to handle and
restart the swapin, and on swapout perform a partial swapout to test that
the swapin and release_shrunken functionality.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/Kconfig | 10 ++++++++++
drivers/gpu/drm/ttm/ttm_pool.c | 17 ++++++++++++++++-
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 026444eeb5c6..f041ef44228d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -258,6 +258,16 @@ config DRM_GPUVM
GPU-VM representation providing helpers to manage a GPUs virtual
address space
+config DRM_TTM_BACKUP_FAULT_INJECT
+ bool "Enable fault injection during TTM backup"
+ depends on DRM_TTM
+ default n
+ help
+ Inject recoverable failures during TTM backup and recovery of
+ backed-up objects. For DRM driver developers only.
+
+ If in doubt, choose N.
+
config DRM_BUDDY
tristate
depends on DRM
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 38e50cf81b0a..d32a1f2e5e50 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -431,6 +431,7 @@ static int ttm_pool_restore_tt(struct ttm_pool_tt_restore *restore,
struct ttm_backup *backup,
struct ttm_operation_ctx *ctx)
{
+ static unsigned long __maybe_unused swappedin;
unsigned int i, nr = 1 << restore->order;
int ret = 0;
@@ -446,6 +447,13 @@ static int ttm_pool_restore_tt(struct ttm_pool_tt_restore *restore,
if (handle == 0)
continue;
+ if (IS_ENABLED(CONFIG_DRM_TTM_BACKUP_FAULT_INJECT) &&
+ ctx->interruptible &&
+ ++swappedin % 100 == 0) {
+ ret = -EINTR;
+ break;
+ }
+
ret = backup->ops->copy_backed_up_page
(backup, restore->first_page[i],
handle, ctx->interruptible);
@@ -892,7 +900,14 @@ long ttm_pool_backup_tt(struct ttm_pool *pool, struct ttm_tt *ttm, bool purge,
alloc_gfp = GFP_KERNEL | __GFP_HIGH | __GFP_NOWARN | __GFP_RETRY_MAYFAIL;
- for (i = 0; i < ttm->num_pages; ++i) {
+ num_pages = ttm->num_pages;
+
+ /* Pretend doing fault injection by shrinking only half of the pages. */
+
+ if (IS_ENABLED(CONFIG_DRM_TTM_BACKUP_FAULT_INJECT))
+ num_pages = DIV_ROUND_UP(num_pages, 2);
+
+ for (i = 0; i < num_pages; ++i) {
page = ttm->pages[i];
if (unlikely(!page))
continue;
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v3 11/21] drm/ttm, drm/xe: Add a shrinker for xe bos
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (9 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 10/21] drm/ttm: Use fault-injection to test error paths Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 12/21] dma-buf/dma-resv: Introduce dma_resv_trylock_ctx() Thomas Hellström
` (18 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Rather than relying on the TTM watermark accounting add a shrinker
for xe_bos in TT or system memory.
Leverage the newly added TTM per-page shrinking and shmem backup
support.
Although xe doesn't fully support WONTNEED (purgeable) bos yet,
introduce and add shrinker support for purgeable ttm_tts.
v2:
- Cleanups bugfixes and a KUNIT shrinker test.
- Add writeback support, and activate if kswapd.
v3:
- Move the try_shrink() helper to core TTM.
- Minor cleanups.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo_util.c | 67 ++++++++
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/tests/xe_bo.c | 118 ++++++++++++++
drivers/gpu/drm/xe/tests/xe_bo_test.c | 1 +
drivers/gpu/drm/xe/tests/xe_bo_test.h | 1 +
drivers/gpu/drm/xe/xe_bo.c | 128 +++++++++++++--
drivers/gpu/drm/xe/xe_bo.h | 4 +
drivers/gpu/drm/xe/xe_device.c | 8 +
drivers/gpu/drm/xe/xe_device_types.h | 2 +
drivers/gpu/drm/xe/xe_shrinker.c | 224 ++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_shrinker.h | 18 +++
include/drm/ttm/ttm_bo.h | 3 +
12 files changed, 559 insertions(+), 16 deletions(-)
create mode 100644 drivers/gpu/drm/xe/xe_shrinker.c
create mode 100644 drivers/gpu/drm/xe/xe_shrinker.h
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index be200c06cc79..f6460024077d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -913,3 +913,70 @@ long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
ttm_resource_cursor_fini(&cursor);
return sofar;
}
+EXPORT_SYMBOL(ttm_lru_walk_for_evict);
+
+/**
+ * ttm_bo_try_shrink - LRU walk helper to shrink a ttm buffer object.
+ * @walk: The struct xe_ttm_lru_walk that describes the walk.
+ * @bo: The buffer object.
+ * @purge: Whether to attempt to purge the bo content since it's no
+ * longer needed.
+ * @writeback: If !@purge, attempt to write out to persistent storage.
+ *
+ * The function uses the ttm_tt_back_up functionality to back up or
+ * purge a struct ttm_tt. If the bo is not in system, it's first
+ * moved there.
+ *
+ * Return: The number of pages shrunken or purged, or
+ * negative error code on failure.
+ */
+long ttm_bo_try_shrink(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo,
+ bool purge, bool writeback)
+{
+ static const struct ttm_place sys_placement_flags = {
+ .fpfn = 0,
+ .lpfn = 0,
+ .mem_type = TTM_PL_SYSTEM,
+ .flags = 0,
+ };
+ static struct ttm_placement sys_placement = {
+ .num_placement = 1,
+ .placement = &sys_placement_flags,
+ };
+ struct ttm_operation_ctx *ctx = walk->ctx;
+ struct ttm_tt *tt = bo->ttm;
+ long lret;
+
+ dma_resv_assert_held(bo->base.resv);
+
+ if (!tt || !ttm_tt_is_populated(tt))
+ return 0;
+
+ if (bo->resource->mem_type != TTM_PL_SYSTEM) {
+ int ret = ttm_bo_validate(bo, &sys_placement, ctx);
+
+ if (ret) {
+ if (ret == -EINTR || ret == -EDEADLK ||
+ ret == -ERESTARTSYS)
+ return ret;
+ return 0;
+ }
+ }
+
+ lret = ttm_bo_wait_ctx(bo, ctx);
+ if (lret < 0) {
+ if (lret == -ERESTARTSYS)
+ return lret;
+ return 0;
+ }
+
+ if (bo->deleted)
+ lret = ttm_tt_backup(bo->bdev, tt, true, writeback);
+ else
+ lret = ttm_tt_backup(bo->bdev, tt, purge, writeback);
+ if (lret < 0 && lret != -EINTR)
+ return 0;
+
+ return lret;
+}
+EXPORT_SYMBOL(ttm_bo_try_shrink);
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index c9f067b8f54d..83d57d530a35 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -130,6 +130,7 @@ xe-y += xe_bb.o \
xe_ring_ops.o \
xe_sa.o \
xe_sched_job.o \
+ xe_shrinker.o \
xe_step.o \
xe_sync.o \
xe_tile.o \
diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
index 9f3c02826464..7576d362020f 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo.c
@@ -6,6 +6,8 @@
#include <kunit/test.h>
#include <kunit/visibility.h>
+#include <uapi/linux/sysinfo.h>
+
#include "tests/xe_bo_test.h"
#include "tests/xe_pci_test.h"
#include "tests/xe_test.h"
@@ -350,3 +352,119 @@ void xe_bo_evict_kunit(struct kunit *test)
xe_call_for_each_device(evict_test_run_device);
}
EXPORT_SYMBOL_IF_KUNIT(xe_bo_evict_kunit);
+
+struct xe_bo_link {
+ struct list_head link;
+ struct xe_bo *bo;
+};
+
+#define XE_BO_SHRINK_SIZE ((unsigned long)SZ_64M)
+
+/*
+ * Try to create system bos corresponding to twice the amount
+ * of available system memory to test shrinker functionality.
+ * If no swap space is available to accommodate the
+ * memory overcommit, mark bos purgeable.
+ */
+static int shrink_test_run_device(struct xe_device *xe)
+{
+ struct kunit *test = xe_cur_kunit();
+ LIST_HEAD(bos);
+ struct xe_bo_link *link, *next;
+ struct sysinfo si;
+ size_t total, alloced;
+ unsigned int interrupted = 0, successful = 0;
+
+ si_meminfo(&si);
+ total = si.freeram * si.mem_unit;
+
+ kunit_info(test, "Free ram is %lu bytes. Will allocate twice of that.\n",
+ total);
+
+ total <<= 1;
+ for (alloced = 0; alloced < total ; alloced += XE_BO_SHRINK_SIZE) {
+ struct xe_bo *bo;
+ unsigned int mem_type;
+
+ link = kzalloc(sizeof(*link), GFP_KERNEL);
+ if (!link) {
+ KUNIT_FAIL(test, "Unexpeced link allocation failure\n");
+ break;
+ }
+
+ INIT_LIST_HEAD(&link->link);
+
+ /* We can create bos using WC caching here. But it is slower. */
+ bo = xe_bo_create_user(xe, NULL, NULL, XE_BO_SHRINK_SIZE,
+ DRM_XE_GEM_CPU_CACHING_WB,
+ ttm_bo_type_device,
+ XE_BO_FLAG_SYSTEM);
+ if (IS_ERR(bo)) {
+ if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) &&
+ bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS))
+ KUNIT_FAIL(test, "Error creating bo: %pe\n", bo);
+ kfree(link);
+ break;
+ }
+ link->bo = bo;
+ list_add_tail(&link->link, &bos);
+ xe_bo_lock(bo, false);
+
+ /*
+ * If we're low on swap entries, we can't shrink unless the bo
+ * is marked purgeable.
+ */
+ if (get_nr_swap_pages() < (XE_BO_SHRINK_SIZE >> PAGE_SHIFT) * 128) {
+ struct xe_ttm_tt *xe_tt =
+ container_of(bo->ttm.ttm, typeof(*xe_tt), ttm);
+ long num_pages = xe_tt->ttm.num_pages;
+
+ xe_tt->purgeable = true;
+ xe_shrinker_mod_pages(xe->mem.shrinker, -num_pages,
+ num_pages);
+ }
+
+ mem_type = bo->ttm.resource->mem_type;
+ xe_bo_unlock(bo);
+ if (mem_type != XE_PL_TT)
+ KUNIT_FAIL(test, "Bo in incorrect memory type: %u\n",
+ bo->ttm.resource->mem_type);
+ cond_resched();
+ if (signal_pending(current))
+ break;
+ }
+
+ /* Read back and destroy bos */
+ list_for_each_entry_safe_reverse(link, next, &bos, link) {
+ static struct ttm_operation_ctx ctx = {.interruptible = true};
+ struct xe_bo *bo = link->bo;
+ int ret;
+
+ if (!signal_pending(current)) {
+ xe_bo_lock(bo, NULL);
+ ret = ttm_bo_validate(&bo->ttm, &tt_placement, &ctx);
+ xe_bo_unlock(bo);
+ if (ret && ret != -EINTR)
+ KUNIT_FAIL(test, "Validation failed: %pe\n",
+ ERR_PTR(ret));
+ else if (ret)
+ interrupted++;
+ else
+ successful++;
+ }
+ xe_bo_put(link->bo);
+ list_del(&link->link);
+ kfree(link);
+ cond_resched();
+ }
+ kunit_info(test, "Readbacks interrupted: %u successful: %u\n",
+ interrupted, successful);
+
+ return 0;
+}
+
+void xe_bo_shrink_kunit(struct kunit *test)
+{
+ xe_call_for_each_device(shrink_test_run_device);
+}
+EXPORT_SYMBOL_IF_KUNIT(xe_bo_shrink_kunit);
diff --git a/drivers/gpu/drm/xe/tests/xe_bo_test.c b/drivers/gpu/drm/xe/tests/xe_bo_test.c
index a324cde77db8..317fa923e287 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo_test.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo_test.c
@@ -10,6 +10,7 @@
static struct kunit_case xe_bo_tests[] = {
KUNIT_CASE(xe_ccs_migrate_kunit),
KUNIT_CASE(xe_bo_evict_kunit),
+ KUNIT_CASE_SLOW(xe_bo_shrink_kunit),
{}
};
diff --git a/drivers/gpu/drm/xe/tests/xe_bo_test.h b/drivers/gpu/drm/xe/tests/xe_bo_test.h
index 0113ab45066a..7f44d14a45c5 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo_test.h
+++ b/drivers/gpu/drm/xe/tests/xe_bo_test.h
@@ -10,5 +10,6 @@ struct kunit;
void xe_ccs_migrate_kunit(struct kunit *test);
void xe_bo_evict_kunit(struct kunit *test);
+void xe_bo_shrink_kunit(struct kunit *test);
#endif
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 03f7fe7acf8c..9a0ca2cab7b6 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -10,6 +10,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_managed.h>
+#include <drm/ttm/ttm_backup.h>
#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
@@ -25,6 +26,7 @@
#include "xe_pm.h"
#include "xe_preempt_fence.h"
#include "xe_res_cursor.h"
+#include "xe_shrinker.h"
#include "xe_trace.h"
#include "xe_ttm_stolen_mgr.h"
#include "xe_vm.h"
@@ -278,11 +280,15 @@ static void xe_evict_flags(struct ttm_buffer_object *tbo,
}
}
+/* struct xe_ttm_tt - Subclassed ttm_tt for xe */
struct xe_ttm_tt {
struct ttm_tt ttm;
- struct device *dev;
+ /** @xe - The xe device */
+ struct xe_device *xe;
struct sg_table sgt;
struct sg_table *sg;
+ /** @purgeable - Whether the bo is purgeable (WONTNEED) */
+ bool purgeable;
};
static int xe_tt_map_sg(struct ttm_tt *tt)
@@ -291,7 +297,8 @@ static int xe_tt_map_sg(struct ttm_tt *tt)
unsigned long num_pages = tt->num_pages;
int ret;
- XE_WARN_ON(tt->page_flags & TTM_TT_FLAG_EXTERNAL);
+ XE_WARN_ON((tt->page_flags & TTM_TT_FLAG_EXTERNAL) &&
+ !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE));
if (xe_tt->sg)
return 0;
@@ -299,13 +306,13 @@ static int xe_tt_map_sg(struct ttm_tt *tt)
ret = sg_alloc_table_from_pages_segment(&xe_tt->sgt, tt->pages,
num_pages, 0,
(u64)num_pages << PAGE_SHIFT,
- xe_sg_segment_size(xe_tt->dev),
+ xe_sg_segment_size(xe_tt->xe->drm.dev),
GFP_KERNEL);
if (ret)
return ret;
xe_tt->sg = &xe_tt->sgt;
- ret = dma_map_sgtable(xe_tt->dev, xe_tt->sg, DMA_BIDIRECTIONAL,
+ ret = dma_map_sgtable(xe_tt->xe->drm.dev, xe_tt->sg, DMA_BIDIRECTIONAL,
DMA_ATTR_SKIP_CPU_SYNC);
if (ret) {
sg_free_table(xe_tt->sg);
@@ -321,7 +328,7 @@ static void xe_tt_unmap_sg(struct ttm_tt *tt)
struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
if (xe_tt->sg) {
- dma_unmap_sgtable(xe_tt->dev, xe_tt->sg,
+ dma_unmap_sgtable(xe_tt->xe->drm.dev, xe_tt->sg,
DMA_BIDIRECTIONAL, 0);
sg_free_table(xe_tt->sg);
xe_tt->sg = NULL;
@@ -336,21 +343,41 @@ struct sg_table *xe_bo_sg(struct xe_bo *bo)
return xe_tt->sg;
}
+/*
+ * Account ttm pages against the device shrinker's shrinkable and
+ * purgeable counts.
+ */
+static void xe_ttm_tt_account(struct ttm_tt *tt, bool add)
+{
+ struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+ long num_pages = tt->num_pages;
+
+ if (!add)
+ num_pages = -num_pages;
+
+ if (xe_tt->purgeable)
+ xe_shrinker_mod_pages(xe_tt->xe->mem.shrinker, 0, num_pages);
+ else
+ xe_shrinker_mod_pages(xe_tt->xe->mem.shrinker, num_pages, 0);
+}
+
static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo,
u32 page_flags)
{
struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
struct xe_device *xe = xe_bo_device(bo);
- struct xe_ttm_tt *tt;
+ struct xe_ttm_tt *xe_tt;
+ struct ttm_tt *tt;
unsigned long extra_pages;
enum ttm_caching caching;
int err;
- tt = kzalloc(sizeof(*tt), GFP_KERNEL);
- if (!tt)
+ xe_tt = kzalloc(sizeof(*xe_tt), GFP_KERNEL);
+ if (!xe_tt)
return NULL;
- tt->dev = xe->drm.dev;
+ tt = &xe_tt->ttm;
+ xe_tt->xe = xe;
extra_pages = 0;
if (xe_bo_needs_ccs_pages(bo))
@@ -378,42 +405,101 @@ static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo,
(xe->info.graphics_verx100 >= 1270 && bo->flags & XE_BO_FLAG_PAGETABLE))
caching = ttm_write_combined;
- err = ttm_tt_init(&tt->ttm, &bo->ttm, page_flags, caching, extra_pages);
+ if (ttm_bo->type != ttm_bo_type_sg)
+ page_flags |= TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE;
+
+ err = ttm_tt_init(tt, &bo->ttm, page_flags, caching, extra_pages);
if (err) {
- kfree(tt);
+ kfree(xe_tt);
+ return NULL;
+ }
+
+ tt->backup = ttm_backup_shmem_create(tt->num_pages << PAGE_SHIFT);
+ if (IS_ERR(tt->backup)) {
+ ttm_tt_fini(tt);
+ kfree(xe_tt);
return NULL;
}
- return &tt->ttm;
+ return tt;
}
static int xe_ttm_tt_populate(struct ttm_device *ttm_dev, struct ttm_tt *tt,
struct ttm_operation_ctx *ctx)
{
+ struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
int err;
/*
* dma-bufs are not populated with pages, and the dma-
* addresses are set up when moved to XE_PL_TT.
*/
- if (tt->page_flags & TTM_TT_FLAG_EXTERNAL)
+ if ((tt->page_flags & TTM_TT_FLAG_EXTERNAL) &&
+ !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE))
return 0;
err = ttm_pool_alloc(&ttm_dev->pool, tt, ctx);
if (err)
return err;
- return err;
+ xe_tt->purgeable = false;
+ xe_ttm_tt_account(tt, true);
+
+ return 0;
}
static void xe_ttm_tt_unpopulate(struct ttm_device *ttm_dev, struct ttm_tt *tt)
{
- if (tt->page_flags & TTM_TT_FLAG_EXTERNAL)
+ if ((tt->page_flags & TTM_TT_FLAG_EXTERNAL) &&
+ !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE))
return;
xe_tt_unmap_sg(tt);
- return ttm_pool_free(&ttm_dev->pool, tt);
+ ttm_pool_free(&ttm_dev->pool, tt);
+ xe_ttm_tt_account(tt, false);
+}
+
+/**
+ * xe_bo_shrink() - Try to shrink an xe bo.
+ * @walk: - The walk parameters
+ * @bo: The TTM buffer object
+ * @purge: Only consider purgeable bos.
+ * @writeback: Try to write back to persistent storage.
+ *
+ * Try to shrink- or purge a bo, and if it succeeds, unmap dma.
+ * Note that we need to be able to handle also non xe bos
+ * (ghost bos), but only if the struct ttm_tt is embedded in
+ * a struct xe_ttm_tt.
+ *
+ * Return: The number of pages shrunken or purged, or negative error
+ * code on failure.
+ */
+long xe_bo_shrink(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo,
+ bool purge, bool writeback)
+{
+ struct ttm_tt *tt = bo->ttm;
+ struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+ struct ttm_place place = {.mem_type = bo->resource->mem_type};
+ struct xe_device *xe = xe_tt->xe;
+ long lret;
+
+ if (!tt || !ttm_tt_is_populated(tt) ||
+ !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE) ||
+ (purge && !xe_tt->purgeable))
+ return 0L;
+
+ if (!ttm_bo_eviction_valuable(bo, &place))
+ return 0L;
+
+ lret = ttm_bo_try_shrink(walk, bo, xe_tt->purgeable, writeback);
+ if (lret > 0) {
+ xe_assert(xe, !ttm_tt_is_populated(tt));
+
+ xe_ttm_tt_account(tt, false);
+ }
+
+ return lret;
}
static void xe_ttm_tt_destroy(struct ttm_device *ttm_dev, struct ttm_tt *tt)
@@ -1229,6 +1315,7 @@ struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
struct ttm_operation_ctx ctx = {
.interruptible = true,
.no_wait_gpu = false,
+ .gfp_retry_mayfail = true,
};
struct ttm_placement *placement;
uint32_t alignment;
@@ -1672,6 +1759,8 @@ int xe_bo_pin_external(struct xe_bo *bo)
}
ttm_bo_pin(&bo->ttm);
+ if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
+ xe_ttm_tt_account(bo->ttm.ttm, false);
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -1730,6 +1819,8 @@ int xe_bo_pin(struct xe_bo *bo)
}
ttm_bo_pin(&bo->ttm);
+ if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
+ xe_ttm_tt_account(bo->ttm.ttm, false);
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -1765,6 +1856,9 @@ void xe_bo_unpin_external(struct xe_bo *bo)
}
ttm_bo_unpin(&bo->ttm);
+ if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
+ xe_ttm_tt_account(bo->ttm.ttm, true);
+
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -1794,6 +1888,8 @@ void xe_bo_unpin(struct xe_bo *bo)
}
ttm_bo_unpin(&bo->ttm);
+ if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
+ xe_ttm_tt_account(bo->ttm.ttm, true);
}
/**
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 6de894c728f5..220e71086e65 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -63,6 +63,7 @@
#define XE_BO_PROPS_INVALID (-1)
struct sg_table;
+struct xe_ttm_lru_walk;
struct xe_bo *xe_bo_alloc(void);
void xe_bo_free(struct xe_bo *bo);
@@ -315,6 +316,9 @@ static inline unsigned int xe_sg_segment_size(struct device *dev)
#define i915_gem_object_flush_if_display(obj) ((void)(obj))
+long xe_bo_shrink(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo,
+ bool purge, bool writeback);
+
#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
/**
* xe_bo_is_mem_type - Whether the bo currently resides in the given
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 8da90934c900..7080558adb80 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -42,6 +42,7 @@
#include "xe_pcode.h"
#include "xe_pm.h"
#include "xe_query.h"
+#include "xe_shrinker.h"
#include "xe_sriov.h"
#include "xe_tile.h"
#include "xe_ttm_stolen_mgr.h"
@@ -239,6 +240,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
if (xe->unordered_wq)
destroy_workqueue(xe->unordered_wq);
+ if (!IS_ERR_OR_NULL(xe->mem.shrinker))
+ xe_shrinker_destroy(xe->mem.shrinker);
+
ttm_device_fini(&xe->ttm);
}
@@ -268,6 +272,10 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
if (err)
goto err;
+ xe->mem.shrinker = xe_shrinker_create(xe);
+ if (IS_ERR(xe->mem.shrinker))
+ return ERR_CAST(xe->mem.shrinker);
+
xe->info.devid = pdev->device;
xe->info.revid = pdev->revision;
xe->info.force_execlist = xe_modparam.force_execlist;
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 5c5e36de452a..fc4f4d17a89f 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -319,6 +319,8 @@ struct xe_device {
struct xe_mem_region vram;
/** @mem.sys_mgr: system TTM manager */
struct ttm_resource_manager sys_mgr;
+ /** @mem.sys_mgr: system memory shrinker. */
+ struct xe_shrinker *shrinker;
} mem;
/** @sriov: device level virtualization data */
diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c
new file mode 100644
index 000000000000..4913cba7700b
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_shrinker.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <linux/shrinker.h>
+#include <linux/swap.h>
+
+#include <drm/ttm/ttm_bo.h>
+#include <drm/ttm/ttm_tt.h>
+
+#include "xe_bo.h"
+#include "xe_shrinker.h"
+
+/**
+ * struct xe_shrinker - per-device shrinker
+ * @xe: Back pointer to the device.
+ * @lock: Lock protecting accounting.
+ * @shrinkable_pages: Number of pages that are currently shrinkable.
+ * @purgeable_pages: Number of pages that are currently purgeable.
+ * @shrink: Pointer to the mm shrinker.
+ */
+struct xe_shrinker {
+ struct xe_device *xe;
+ rwlock_t lock;
+ long shrinkable_pages;
+ long purgeable_pages;
+ struct shrinker *shrink;
+};
+
+/**
+ * struct xe_shrink_lru_walk - lru_walk subclass for shrinker
+ * @walk: The embedded base class.
+ * @xe: Pointer to the xe device.
+ * @purge: Purgeable only request from the srinker.
+ * @writeback: Try to write back to persistent storage.
+ */
+struct xe_shrink_lru_walk {
+ struct ttm_lru_walk walk;
+ struct xe_device *xe;
+ bool purge;
+ bool writeback;
+};
+
+static struct xe_shrinker *to_xe_shrinker(struct shrinker *shrink)
+{
+ return shrink->private_data;
+}
+
+static struct xe_shrink_lru_walk *
+to_xe_shrink_lru_walk(struct ttm_lru_walk *walk)
+{
+ return container_of(walk, struct xe_shrink_lru_walk, walk);
+}
+
+/**
+ * xe_shrinker_mod_pages() - Modify shrinker page accounting
+ * @shrinker: Pointer to the struct xe_shrinker.
+ * @shrinkable: Shrinkable pages delta. May be negative.
+ * @purgeable: Purgeable page delta. May be negative.
+ *
+ * Modifies the shrinkable and purgeable pages accounting.
+ */
+void
+xe_shrinker_mod_pages(struct xe_shrinker *shrinker, long shrinkable, long purgeable)
+{
+ write_lock(&shrinker->lock);
+ shrinker->shrinkable_pages += shrinkable;
+ shrinker->purgeable_pages += purgeable;
+ write_unlock(&shrinker->lock);
+}
+
+static long xe_shrinker_process_bo(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
+{
+ struct xe_shrink_lru_walk *shrink_walk = to_xe_shrink_lru_walk(walk);
+
+ return xe_bo_shrink(walk, bo, shrink_walk->purge, shrink_walk->writeback);
+}
+
+static long xe_shrinker_walk(struct xe_shrink_lru_walk *shrink_walk, long target)
+{
+ struct xe_device *xe = shrink_walk->xe;
+ struct ttm_resource_manager *man;
+ unsigned int mem_type;
+ long sofar = 0;
+ long lret;
+
+ for (mem_type = XE_PL_SYSTEM; mem_type <= XE_PL_TT; ++mem_type) {
+ man = ttm_manager_type(&xe->ttm, mem_type);
+ if (!man || !man->use_tt)
+ continue;
+
+ lret = ttm_lru_walk_for_evict(&shrink_walk->walk, &xe->ttm, man, target);
+ if (lret < 0)
+ return lret;
+
+ sofar += lret;
+ if (sofar >= target)
+ break;
+ }
+
+ return sofar;
+}
+
+static unsigned long
+xe_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
+{
+ struct xe_shrinker *shrinker = to_xe_shrinker(shrink);
+ unsigned long num_pages;
+
+ num_pages = get_nr_swap_pages();
+ read_lock(&shrinker->lock);
+ num_pages = min_t(unsigned long, num_pages, shrinker->shrinkable_pages);
+ num_pages += shrinker->purgeable_pages;
+ read_unlock(&shrinker->lock);
+
+ return num_pages ? num_pages : SHRINK_EMPTY;
+}
+
+static const struct ttm_lru_walk_ops xe_shrink_ops = {
+ .process_bo = xe_shrinker_process_bo,
+};
+
+static unsigned long xe_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc)
+{
+ struct xe_shrinker *shrinker = to_xe_shrinker(shrink);
+ bool is_kswapd = current_is_kswapd();
+ struct ttm_operation_ctx ctx = {
+ .interruptible = false,
+ .no_wait_gpu = !is_kswapd,
+ };
+ unsigned long nr_to_scan, freed = 0;
+ struct xe_shrink_lru_walk shrink_walk = {
+ .walk = {
+ .ops = &xe_shrink_ops,
+ .ctx = &ctx,
+ .trylock_only = true,
+ },
+ .xe = shrinker->xe,
+ .purge = true,
+ .writeback = is_kswapd,
+ };
+ bool purgeable;
+ long ret;
+
+ sc->nr_scanned = 0;
+ nr_to_scan = sc->nr_to_scan;
+
+ read_lock(&shrinker->lock);
+ purgeable = !!shrinker->purgeable_pages;
+ read_unlock(&shrinker->lock);
+
+ while (purgeable && freed < nr_to_scan) {
+ ret = xe_shrinker_walk(&shrink_walk, nr_to_scan);
+ if (ret <= 0)
+ break;
+
+ freed += ret;
+ }
+
+ sc->nr_scanned = freed;
+ if (freed < nr_to_scan)
+ nr_to_scan -= freed;
+ else
+ nr_to_scan = 0;
+ if (!nr_to_scan)
+ return freed ? freed : SHRINK_STOP;
+
+ shrink_walk.purge = false;
+ nr_to_scan = sc->nr_to_scan;
+ while (freed < nr_to_scan) {
+ ret = xe_shrinker_walk(&shrink_walk, nr_to_scan);
+ if (ret <= 0)
+ break;
+
+ freed += ret;
+ }
+
+ sc->nr_scanned = freed;
+
+ return freed ? freed : SHRINK_STOP;
+}
+
+/**
+ * xe_shrinker_create() - Create an xe per-device shrinker
+ * @xe: Pointer to the xe device.
+ *
+ * Returns: A pointer to the created shrinker on success,
+ * Negative error code on failure.
+ */
+struct xe_shrinker *xe_shrinker_create(struct xe_device *xe)
+{
+ struct xe_shrinker *shrinker = kzalloc(sizeof(*shrinker), GFP_KERNEL);
+
+ if (!shrinker)
+ return ERR_PTR(-ENOMEM);
+
+ shrinker->shrink = shrinker_alloc(0, "xe system shrinker");
+ if (!shrinker->shrink) {
+ kfree(shrinker);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ shrinker->xe = xe;
+ rwlock_init(&shrinker->lock);
+ shrinker->shrink->count_objects = xe_shrinker_count;
+ shrinker->shrink->scan_objects = xe_shrinker_scan;
+ shrinker->shrink->private_data = shrinker;
+ shrinker_register(shrinker->shrink);
+
+ return shrinker;
+}
+
+/**
+ * xe_shrinker_destroy() - Destroy an xe per-device shrinker
+ * @shrinker: Pointer to the shrinker to destroy.
+ */
+void xe_shrinker_destroy(struct xe_shrinker *shrinker)
+{
+ xe_assert(shrinker->xe, !shrinker->shrinkable_pages);
+ xe_assert(shrinker->xe, !shrinker->purgeable_pages);
+ shrinker_free(shrinker->shrink);
+ kfree(shrinker);
+}
diff --git a/drivers/gpu/drm/xe/xe_shrinker.h b/drivers/gpu/drm/xe/xe_shrinker.h
new file mode 100644
index 000000000000..28a038f4fcbf
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_shrinker.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _XE_SHRINKER_H_
+#define _XE_SHRINKER_H_
+
+struct xe_shrinker;
+struct xe_device;
+
+void xe_shrinker_mod_pages(struct xe_shrinker *shrinker, long shrinkable, long purgeable);
+
+struct xe_shrinker *xe_shrinker_create(struct xe_device *xe);
+
+void xe_shrinker_destroy(struct xe_shrinker *shrinker);
+
+#endif
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index 148f49f625e4..deaedfb060ed 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -222,6 +222,9 @@ struct ttm_lru_walk {
long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
struct ttm_resource_manager *man, long target);
+long ttm_bo_try_shrink(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo,
+ bool purge, bool writeback);
+
/**
* ttm_bo_get - reference a struct ttm_buffer_object
*
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 12/21] dma-buf/dma-resv: Introduce dma_resv_trylock_ctx()
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (10 preceding siblings ...)
2024-05-21 7:16 ` [PATCH v3 11/21] drm/ttm, drm/xe: Add a shrinker for xe bos Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 13/21] drm/exec: Rework contended locking Thomas Hellström
` (17 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel, linaro-mm-sig
For the drm_exec_trylock() functionality, there is a need to be able
to trylock a dma-resv object as part of a drm_exec transaction.
Therefore expose a variant of dma_resv_trylock that also takes
a struct ww_acquire_ctx parameter.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Cc: <linaro-mm-sig@lists.linaro.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
include/linux/dma-resv.h | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h
index 8d0e34dad446..68dae8f2a22c 100644
--- a/include/linux/dma-resv.h
+++ b/include/linux/dma-resv.h
@@ -405,6 +405,27 @@ static inline int dma_resv_lock_slow_interruptible(struct dma_resv *obj,
return ww_mutex_lock_slow_interruptible(&obj->lock, ctx);
}
+/**
+ * dma_resv_trylock_ctx - trylock the reservation object
+ * @obj: the reservation object
+ * @ctx: The ww acquire context or NULL.
+ *
+ * Tries to lock the reservation object for exclusive access and modification.
+ * Note, that the lock is only against other writers, readers will run
+ * concurrently with a writer under RCU. The seqlock is used to notify readers
+ * if they overlap with a writer. The context parameter ensures that other
+ * ww transactions can perform deadlock backoff if necessary, and that
+ * subsequent attempts to dma_resv_lock() @obj for @ctx will return
+ * -EALREADY.
+ *
+ * Return: true if the lock was acquired, false otherwise.
+ */
+static inline bool __must_check
+dma_resv_trylock_ctx(struct dma_resv *obj, struct ww_acquire_ctx *ctx)
+{
+ return ww_mutex_trylock(&obj->lock, ctx);
+}
+
/**
* dma_resv_trylock - trylock the reservation object
* @obj: the reservation object
@@ -421,7 +442,7 @@ static inline int dma_resv_lock_slow_interruptible(struct dma_resv *obj,
*/
static inline bool __must_check dma_resv_trylock(struct dma_resv *obj)
{
- return ww_mutex_trylock(&obj->lock, NULL);
+ return dma_resv_trylock_ctx(obj, NULL);
}
/**
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (11 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 12/21] dma-buf/dma-resv: Introduce dma_resv_trylock_ctx() Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-22 5:52 ` Christian König
2024-05-21 7:16 ` [RFC PATCH v3 14/21] drm/exec: Introduce a drm_exec_trylock_obj() function Thomas Hellström
` (16 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
If contention and backoff occurs during a drm_exec ww transaction,
the contended lock is not locked again until the next orinary
attempt to lock a dma_resv lock. However, with the introduction of
drm_exec_trylock(), that doesn't work, since the locking of the
contended lock needs to be a sleeping lock. Neither can we ignore
locking the contended lock during a trylock since that would violate
at least the ww_mutex annotations.
So resolve this by actually locking the contended lock during
drm_exec_retry_on_contention(). However, this introduces a new point
of failure since locking the contended lock may return -EINTR.
Hence drm_exec_retry_on_contention() must take an error parameter and
also return a value indicating success.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
.../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++-----
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
drivers/gpu/drm/drm_exec.c | 35 ++++++++++++++-----
drivers/gpu/drm/drm_gpuvm.c | 8 ++---
drivers/gpu/drm/imagination/pvr_job.c | 2 +-
drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
drivers/gpu/drm/xe/xe_vm.c | 10 +++---
include/drm/drm_exec.h | 23 +++++++++---
17 files changed, 92 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index e4d4e55c08ad..4a08a692aa1f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&ctx->exec) {
ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
- drm_exec_retry_on_contention(&ctx->exec);
+ ret = drm_exec_retry_on_contention(&ctx->exec, ret);
if (unlikely(ret))
goto error;
ret = drm_exec_prepare_obj(&ctx->exec, &bo->tbo.base, 1);
- drm_exec_retry_on_contention(&ctx->exec);
+ ret = drm_exec_retry_on_contention(&ctx->exec, ret);
if (unlikely(ret))
goto error;
}
@@ -1199,14 +1199,14 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ret = amdgpu_vm_lock_pd(entry->bo_va->base.vm,
&ctx->exec, 2);
- drm_exec_retry_on_contention(&ctx->exec);
+ ret = drm_exec_retry_on_contention(&ctx->exec, ret);
if (unlikely(ret))
goto error;
++ctx->n_vms;
}
ret = drm_exec_prepare_obj(&ctx->exec, &bo->tbo.base, 1);
- drm_exec_retry_on_contention(&ctx->exec);
+ ret = drm_exec_retry_on_contention(&ctx->exec, ret);
if (unlikely(ret))
goto error;
}
@@ -2619,7 +2619,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
list_for_each_entry(peer_vm, &process_info->vm_list_head,
vm_list_node) {
ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (unlikely(ret))
goto unreserve_out;
}
@@ -2631,7 +2631,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
gobj = &mem->bo->tbo.base;
ret = drm_exec_prepare_obj(&exec, gobj, 1);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (unlikely(ret))
goto unreserve_out;
}
@@ -2875,7 +2875,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
list_for_each_entry(peer_vm, &process_info->vm_list_head,
vm_list_node) {
ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (unlikely(ret)) {
pr_err("Locking VM PD failed, ret: %d\n", ret);
goto ttm_reserve_fail;
@@ -2891,7 +2891,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
gobj = &mem->bo->tbo.base;
ret = drm_exec_prepare_obj(&exec, gobj, 1);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (unlikely(ret)) {
pr_err("drm_exec_prepare_obj failed, ret: %d\n", ret);
goto ttm_reserve_fail;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index ec888fc6ead8..299e46a6d934 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
drm_exec_until_all_locked(&p->exec) {
r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec, 1 + p->gang_size);
- drm_exec_retry_on_contention(&p->exec);
+ r = drm_exec_retry_on_contention(&p->exec, r);
if (unlikely(r))
goto out_free_user_pages;
@@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
/* One fence for TTM and one for each CS job */
r = drm_exec_prepare_obj(&p->exec, &e->bo->tbo.base,
1 + p->gang_size);
- drm_exec_retry_on_contention(&p->exec);
+ r = drm_exec_retry_on_contention(&p->exec, r);
if (unlikely(r))
goto out_free_user_pages;
@@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
if (p->uf_bo) {
r = drm_exec_prepare_obj(&p->exec, &p->uf_bo->tbo.base,
1 + p->gang_size);
- drm_exec_retry_on_contention(&p->exec);
+ r = drm_exec_retry_on_contention(&p->exec, r);
if (unlikely(r))
goto out_free_user_pages;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index cfdf558b48b6..8b2b86c7a6c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r)) {
DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
goto error;
@@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r)) {
DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
goto error;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 67c234bcf89f..17e16c971e21 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -239,12 +239,12 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
r = amdgpu_vm_lock_pd(vm, &exec, 0);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
}
@@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
drm_exec_until_all_locked(&exec) {
if (gobj) {
r = drm_exec_lock_obj(&exec, gobj);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error;
}
r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 5ca5c47ab54e..1b1a5147606e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1221,12 +1221,12 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec,
&ctx_data->meta_data_obj->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error_fini_exec;
r = amdgpu_vm_lock_pd(vm, &exec, 0);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error_fini_exec;
}
@@ -1292,12 +1292,12 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec,
&ctx_data->meta_data_obj->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
r = amdgpu_vm_lock_pd(vm, &exec, 0);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
index e22cb2b5cd92..72b8213e352c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
@@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error;
}
@@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
index e01c1c8e64c4..63392ce43945 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
@@ -89,12 +89,12 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error_fini_exec;
r = amdgpu_vm_lock_pd(vm, &exec, 0);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto error_fini_exec;
}
@@ -152,12 +152,12 @@ static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
r = amdgpu_vm_lock_pd(vm, &exec, 0);
- drm_exec_retry_on_contention(&exec);
+ r = drm_exec_retry_on_contention(&exec, r);
if (unlikely(r))
goto out_unlock;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 386875e6eb96..a3aa7fd22f6a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr)
vm = drm_priv_to_vm(pdd->drm_priv);
r = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
- drm_exec_retry_on_contention(&ctx->exec);
+ r = drm_exec_retry_on_contention(&ctx->exec, r);
if (unlikely(r)) {
pr_debug("failed %d to reserve bo\n", r);
goto unreserve_out;
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index 2da094bdf8a4..3770a5d30213 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -28,12 +28,12 @@
* drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
* drm_exec_until_all_locked(&exec) {
* ret = drm_exec_prepare_obj(&exec, boA, 1);
- * drm_exec_retry_on_contention(&exec);
+ * ret = drm_exec_retry_on_contention(&exec, ret);
* if (ret)
* goto error;
*
* ret = drm_exec_prepare_obj(&exec, boB, 1);
- * drm_exec_retry_on_contention(&exec);
+ * ret = drm_exec_retry_on_contention(&exec, ret);
* if (ret)
* goto error;
* }
@@ -48,7 +48,8 @@
*/
/* Dummy value used to initially enter the retry loop */
-#define DRM_EXEC_DUMMY ((void *)~0)
+#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
+#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
/* Unlock all objects and drop references */
static void drm_exec_unlock_all(struct drm_exec *exec)
@@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec *exec)
return true;
}
- drm_exec_unlock_all(exec);
- exec->num_objects = 0;
+ exec->contended = NULL;
return true;
}
EXPORT_SYMBOL(drm_exec_cleanup);
@@ -194,6 +194,27 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
return ret;
}
+/**
+ * drm_exec_handle_contended() - Perform cleanup before a ww transaction restart
+ * @exec: Pointer to the drm_exec object.
+ *
+ * Unlocks all held resvs and re-locks the contended object.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int drm_exec_handle_contended(struct drm_exec *exec)
+{
+ int ret;
+
+ drm_exec_unlock_all(exec);
+ exec->num_objects = 0;
+ ret = drm_exec_lock_contended(exec);
+ exec->contended = DRM_EXEC_CONTENDED;
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_exec_handle_contended);
+
/**
* drm_exec_lock_obj - lock a GEM object for use
* @exec: the drm_exec object with the state
@@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
{
int ret;
- ret = drm_exec_lock_contended(exec);
- if (unlikely(ret))
- return ret;
-
if (exec->prelocked == obj) {
drm_gem_object_put(exec->prelocked);
exec->prelocked = NULL;
diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
index f9eb56f24bef..0923d6ae18e2 100644
--- a/drivers/gpu/drm/drm_gpuvm.c
+++ b/drivers/gpu/drm/drm_gpuvm.c
@@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
drm_exec_until_all_locked(exec) {
ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
- drm_exec_retry_on_contention(exec);
+ ret = drm_exec_retry_on_contention(exec, ret);
if (ret)
goto err;
ret = drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
- drm_exec_retry_on_contention(exec);
+ ret = drm_exec_retry_on_contention(exec, ret);
if (ret)
goto err;
if (vm_exec->extra.fn) {
ret = vm_exec->extra.fn(vm_exec);
- drm_exec_retry_on_contention(exec);
+ ret = drm_exec_retry_on_contention(exec, ret);
if (ret)
goto err;
}
@@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
drm_exec_until_all_locked(exec) {
ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
vm_exec->num_fences);
- drm_exec_retry_on_contention(exec);
+ ret = drm_exec_retry_on_contention(exec, ret);
if (ret)
goto err;
}
diff --git a/drivers/gpu/drm/imagination/pvr_job.c b/drivers/gpu/drm/imagination/pvr_job.c
index 78c2f3c6dce0..6e0ce6c4576c 100644
--- a/drivers/gpu/drm/imagination/pvr_job.c
+++ b/drivers/gpu/drm/imagination/pvr_job.c
@@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct drm_exec *exec, struct pvr_job_data *job_data,
drm_exec_until_all_locked(exec) {
int err = jobs_lock_all_objs(exec, job_data, job_count);
- drm_exec_retry_on_contention(exec);
+ err = drm_exec_retry_on_contention(exec, err);
if (err)
return err;
}
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index fba78193127d..01992b43ea4b 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -259,7 +259,7 @@ static int submit_lock_objects(struct msm_gem_submit *submit)
for (unsigned i = 0; i < submit->nr_bos; i++) {
struct drm_gem_object *obj = submit->bos[i].obj;
ret = drm_exec_prepare_obj(&submit->exec, obj, 1);
- drm_exec_retry_on_contention(&submit->exec);
+ ret = drm_exec_retry_on_contention(&submit->exec, ret);
if (ret)
goto error;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index ee02cd833c5e..0c871634fdfb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job,
drm_exec_init(exec, vme->flags, 0);
drm_exec_until_all_locked(exec) {
ret = bind_lock_validate(job, exec, vme->num_fences);
- drm_exec_retry_on_contention(exec);
+ ret = drm_exec_retry_on_contention(exec, ret);
if (ret) {
op = list_last_op(&bind_job->ops);
goto unwind;
diff --git a/drivers/gpu/drm/tests/drm_exec_test.c b/drivers/gpu/drm/tests/drm_exec_test.c
index 81f928a429ba..28558fdb08df 100644
--- a/drivers/gpu/drm/tests/drm_exec_test.c
+++ b/drivers/gpu/drm/tests/drm_exec_test.c
@@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
ret = drm_exec_lock_obj(&exec, &gobj);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
@@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit *test)
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
ret = drm_exec_lock_obj(&exec, &gobj);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
drm_exec_unlock_obj(&exec, &gobj);
ret = drm_exec_lock_obj(&exec, &gobj);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
@@ -110,13 +110,13 @@ static void test_duplicates(struct kunit *test)
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
drm_exec_until_all_locked(&exec) {
ret = drm_exec_lock_obj(&exec, &gobj);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
ret = drm_exec_lock_obj(&exec, &gobj);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
@@ -137,7 +137,7 @@ static void test_prepare(struct kunit *test)
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
ret = drm_exec_prepare_obj(&exec, &gobj, 1);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
KUNIT_EXPECT_EQ(test, ret, 0);
if (ret)
break;
diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 040dd142c49c..20ec1ab1b52d 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
ret = xe_pf_begin(&exec, vma, atomic, tile->id);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (ret)
goto unlock_dma_resv;
@@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc)
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
ret = xe_pf_begin(&exec, vma, true, tile->id);
- drm_exec_retry_on_contention(&exec);
+ ret = drm_exec_retry_on_contention(&exec, ret);
if (ret)
break;
}
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index e2ec148c9c33..335524e803e7 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -501,7 +501,7 @@ static void preempt_rebind_work_func(struct work_struct *w)
bool done = false;
err = xe_preempt_work_begin(&exec, vm, &done);
- drm_exec_retry_on_contention(&exec);
+ err = drm_exec_retry_on_contention(&exec, err);
if (err || done) {
drm_exec_fini(&exec);
if (err && xe_vm_validate_should_retry(&exec, err, &end))
@@ -1052,7 +1052,7 @@ static void xe_vma_destroy_unlocked(struct xe_vma *vma)
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
err = xe_vm_lock_vma(&exec, vma);
- drm_exec_retry_on_contention(&exec);
+ err = drm_exec_retry_on_contention(&exec, err);
if (XE_WARN_ON(err))
break;
}
@@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
err = 0;
if (!bo->vm) {
err = drm_exec_lock_obj(&exec, xe_vm_obj(vm));
- drm_exec_retry_on_contention(&exec);
+ err = drm_exec_retry_on_contention(&exec, err);
}
if (!err) {
err = drm_exec_lock_obj(&exec, &bo->ttm.base);
- drm_exec_retry_on_contention(&exec);
+ err = drm_exec_retry_on_contention(&exec, err);
}
if (err) {
drm_exec_fini(&exec);
@@ -2884,7 +2884,7 @@ static int vm_bind_ioctl_ops_execute(struct xe_vm *vm,
DRM_EXEC_IGNORE_DUPLICATES, 0);
drm_exec_until_all_locked(&exec) {
err = vm_bind_ioctl_ops_lock_and_prep(&exec, vm, vops);
- drm_exec_retry_on_contention(&exec);
+ err = drm_exec_retry_on_contention(&exec, err);
if (err)
goto unlock;
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index aa786b828a0a..fafb40d96e38 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -51,6 +51,8 @@ struct drm_exec {
struct drm_gem_object *prelocked;
};
+int drm_exec_handle_contended(struct drm_exec *exec);
+
/**
* drm_exec_obj() - Return the object for a give drm_exec index
* @exec: Pointer to the drm_exec context
@@ -113,15 +115,26 @@ __PASTE(__drm_exec_, __LINE__): \
/**
* drm_exec_retry_on_contention - restart the loop to grap all locks
* @exec: drm_exec object
+ * @_ret: The current error status
*
* Control flow helper to continue when a contention was detected and we need to
* clean up and re-start the loop to prepare all GEM objects.
+ *
+ * Return: If no loop restart occurred: The error status.
*/
-#define drm_exec_retry_on_contention(exec) \
- do { \
- if (unlikely(drm_exec_is_contended(exec))) \
- goto *__drm_exec_retry_ptr; \
- } while (0)
+#define drm_exec_retry_on_contention(exec, _ret) \
+ ({ \
+ struct drm_exec *__exec = (exec); \
+ int __ret = (_ret); \
+ \
+ if (unlikely(drm_exec_is_contended(__exec))) { \
+ WARN_ON(__ret != -EDEADLK); \
+ __ret = drm_exec_handle_contended(__exec); \
+ if (!__ret) \
+ goto *__drm_exec_retry_ptr; \
+ } \
+ __ret; \
+ })
/**
* drm_exec_is_contended - check for contention
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 14/21] drm/exec: Introduce a drm_exec_trylock_obj() function
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (12 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 13/21] drm/exec: Rework contended locking Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability Thomas Hellström
` (15 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
TTM needs to trylock dma_resv objects in a couple of places. However
this functionality is missing in drm_exec. Introduce it.
Note that in addition to the -EBUSY error returned on failure to
take the lock, the operation may return -ENOMEM if there was a
failure to allocate memory for the drm_exec held lock array.
This failure mode could be avoided if the drm_exec structure instead
maintained a linked list of locked objects, similar to i915.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/drm_exec.c | 50 +++++++++++++++++++++++++++++++++++---
include/drm/drm_exec.h | 1 +
2 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index 3770a5d30213..1383680ffa4a 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -139,14 +139,17 @@ EXPORT_SYMBOL(drm_exec_cleanup);
/* Track the locked object in the array */
static int drm_exec_obj_locked(struct drm_exec *exec,
- struct drm_gem_object *obj)
+ struct drm_gem_object *obj,
+ gfp_t gfp)
{
+ might_alloc(gfp);
+
if (unlikely(exec->num_objects == exec->max_objects)) {
size_t size = exec->max_objects * sizeof(void *);
void *tmp;
tmp = kvrealloc(exec->objects, size, size + PAGE_SIZE,
- GFP_KERNEL);
+ gfp);
if (!tmp)
return -ENOMEM;
@@ -179,7 +182,7 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
dma_resv_lock_slow(obj->resv, &exec->ticket);
}
- ret = drm_exec_obj_locked(exec, obj);
+ ret = drm_exec_obj_locked(exec, obj, GFP_KERNEL);
if (unlikely(ret))
goto error_unlock;
@@ -215,6 +218,45 @@ int drm_exec_handle_contended(struct drm_exec *exec)
}
EXPORT_SYMBOL(drm_exec_handle_contended);
+/**
+ * drm_exec_trylock_obj - trylock a GEM object for use
+ * @exec: the drm_exec object with the state.
+ * @obj: the GEM object to lock.
+ *
+ * Trylock a GEM object for use and grab a reference to it.
+ *
+ * Returns: -EALREADY when object is already locked (can be suppressed by
+ * setting the DRM_EXEC_IGNORE_DUPLICATES flag), -ENOMEM when memory
+ * allocation failed, and zero for success. If the object was already
+ * locked, -EBUSY will be returned.
+ */
+int drm_exec_trylock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
+{
+ int ret;
+
+ might_alloc(GFP_ATOMIC);
+
+ if (exec->prelocked == obj) {
+ drm_gem_object_put(exec->prelocked);
+ exec->prelocked = NULL;
+ return 0;
+ }
+
+ if (!dma_resv_trylock_ctx(obj->resv, &exec->ticket)) {
+ if (dma_resv_locking_ctx(obj->resv) == &exec->ticket)
+ return (exec->flags & DRM_EXEC_IGNORE_DUPLICATES) ? 0 : -EALREADY;
+ else
+ return -EBUSY;
+ }
+
+ ret = drm_exec_obj_locked(exec, obj, GFP_ATOMIC | __GFP_NOWARN);
+ if (ret)
+ dma_resv_unlock(obj->resv);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_exec_trylock_obj);
+
/**
* drm_exec_lock_obj - lock a GEM object for use
* @exec: the drm_exec object with the state
@@ -254,7 +296,7 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
if (unlikely(ret))
return ret;
- ret = drm_exec_obj_locked(exec, obj);
+ ret = drm_exec_obj_locked(exec, obj, GFP_KERNEL);
if (ret)
goto error_unlock;
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index fafb40d96e38..ea0f2117ee0c 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -152,6 +152,7 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr);
void drm_exec_fini(struct drm_exec *exec);
bool drm_exec_cleanup(struct drm_exec *exec);
int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj);
+int drm_exec_trylock_obj(struct drm_exec *exec, struct drm_gem_object *obj);
void drm_exec_unlock_obj(struct drm_exec *exec, struct drm_gem_object *obj);
int drm_exec_prepare_obj(struct drm_exec *exec, struct drm_gem_object *obj,
unsigned int num_fences);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (13 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 14/21] drm/exec: Introduce a drm_exec_trylock_obj() function Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-22 11:27 ` Christian König
2024-05-21 7:16 ` [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode Thomas Hellström
` (14 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
When validating a buffer object for submission, we might need to lock
a number of object for eviction to make room for the validation.
This makes it pretty likely that validation will eventually succeed,
since eventually the validating process will hold most dma_resv locks
of the buffer objects residing in the memory type being validated for.
However, once validation of a single object has succeeded it might not
be beneficial to hold on to those locks anymore, and the validator
would want to drop the locks of all objects taken during validation.
Introduce a drm_exec snapshot functionality that can be used to
record the locks held at a certain time, and a restore functionality
that restores the drm_exec state to the snapshot by dropping all
locks.
Snapshots can be nested if needed.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/drm_exec.c | 55 +++++++++++++++++++++++++++++++++++++-
include/drm/drm_exec.h | 23 +++++++++++++++-
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index 1383680ffa4a..9eea5d0d3a98 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -57,6 +57,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
struct drm_gem_object *obj;
unsigned long index;
+ WARN_ON(exec->snap);
drm_exec_for_each_locked_object_reverse(exec, index, obj) {
dma_resv_unlock(obj->resv);
drm_gem_object_put(obj);
@@ -90,6 +91,7 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
exec->num_objects = 0;
exec->contended = DRM_EXEC_DUMMY;
exec->prelocked = NULL;
+ exec->snap = NULL;
}
EXPORT_SYMBOL(drm_exec_init);
@@ -301,7 +303,6 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
goto error_unlock;
return 0;
-
error_unlock:
dma_resv_unlock(obj->resv);
return ret;
@@ -395,5 +396,57 @@ int drm_exec_prepare_array(struct drm_exec *exec,
}
EXPORT_SYMBOL(drm_exec_prepare_array);
+/**
+ * drm_exec_restore() - Restore the drm_exec state to the point of a snapshot.
+ * @exec: The drm_exec object with the state.
+ * @snap: The snapshot state.
+ *
+ * Restores the drm_exec object by means of unlocking and dropping references
+ * to objects locked after the snapshot.
+ */
+void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap)
+{
+ struct drm_gem_object *obj;
+ unsigned int index;
+
+ exec->snap = snap->saved_snap;
+
+ drm_exec_for_each_locked_object_reverse(exec, index, obj) {
+ if (index + 1 == snap->num_locked)
+ break;
+
+ dma_resv_unlock(obj->resv);
+ drm_gem_object_put(obj);
+ exec->objects[index] = NULL;
+ }
+
+ exec->num_objects = snap->num_locked;
+
+ if (!exec->prelocked)
+ exec->prelocked = snap->prelocked;
+ else
+ drm_gem_object_put(snap->prelocked);
+}
+EXPORT_SYMBOL(drm_exec_restore);
+
+/**
+ * drm_exec_snapshot() - Take a snapshot of the drm_exec state
+ * @exec: The drm_exec object with the state.
+ * @snap: The snapshot state.
+ *
+ * Records the @exec state in @snap. The @snap object is typically allocated
+ * in the stack of the caller.
+ */
+void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap)
+{
+ snap->num_locked = exec->num_objects;
+ snap->prelocked = exec->prelocked;
+ if (snap->prelocked)
+ drm_gem_object_get(snap->prelocked);
+ snap->saved_snap = exec->snap;
+ exec->snap = snap;
+}
+EXPORT_SYMBOL(drm_exec_snapshot);
+
MODULE_DESCRIPTION("DRM execution context");
MODULE_LICENSE("Dual MIT/GPL");
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index ea0f2117ee0c..0ce4d749511b 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -19,7 +19,6 @@ struct drm_exec {
* @flags: Flags to control locking behavior
*/
u32 flags;
-
/**
* @ticket: WW ticket used for acquiring locks
*/
@@ -49,6 +48,25 @@ struct drm_exec {
* @prelocked: already locked GEM object due to contention
*/
struct drm_gem_object *prelocked;
+
+ /**
+ * @snap: Pointer to the last snapshot taken or NULL if none.
+ */
+ struct drm_exec_snapshot *snap;
+};
+
+/**
+ * struct drm_exec_snapshot - drm_exec snapshot information
+ */
+struct drm_exec_snapshot {
+ /** @saved_snap: Pointer to the previous snapshot or NULL. */
+ struct drm_exec_snapshot *saved_snap;
+
+ /** @prelocked: Refcounted pointer to the prelocked object at snapshot time. */
+ struct drm_gem_object *prelocked;
+
+ /** @num_locked: Number of locked objects at snapshot time. */
+ unsigned long num_locked;
};
int drm_exec_handle_contended(struct drm_exec *exec);
@@ -160,5 +178,8 @@ int drm_exec_prepare_array(struct drm_exec *exec,
struct drm_gem_object **objects,
unsigned int num_objects,
unsigned int num_fences);
+void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap);
+void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap);
+
#endif
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (14 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-22 13:28 ` Christian König
2024-05-21 7:16 ` [RFC PATCH v3 17/21] drm/ttm: Support drm_exec locking for eviction and swapping Thomas Hellström
` (13 subsequent siblings)
29 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Locking for eviction is in some way different from locking for
submission:
1) We can't lock objects that are already locked for submission,
hence DRM_EXEC_IGNORE_DUPLICATES must be unset.
2) We must be able to re-lock objects locked for eviction,
either for submission or for yet another eviction, in
particular objects sharing a single resv must be considered.
3) There is no point to keep a contending object after the
transaction restart. We don't know whether we actually want to use
it again.
So introduce a drm_exec evict mode, and for now instead of
explicitly setting it using a function call or implement separate
locking functions that use evict mode, assume evict mode if
there is a snapshot registered. This can easily be changed later.
To keep track of resvs locked for eviction, use a pointer set
implemented by an xarray. This is probably not the most efficient
data structure but used as an easy-to-implement first approach.
If the set is empty (evict mode never used), the performance-
and memory usage impact will be very small.
TODO: Probably want to implement the set using an open addressing
hash table.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/drm_exec.c | 77 ++++++++++++++++++++++++++++++++++----
include/drm/drm_exec.h | 15 ++++++++
2 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index 9eea5d0d3a98..ea79d96f5439 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -65,6 +65,10 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
drm_gem_object_put(exec->prelocked);
exec->prelocked = NULL;
+
+ /* garbage collect */
+ xa_destroy(&exec->resv_set);
+ xa_init(&exec->resv_set);
}
/**
@@ -92,6 +96,8 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
exec->contended = DRM_EXEC_DUMMY;
exec->prelocked = NULL;
exec->snap = NULL;
+ exec->drop_contended = false;
+ xa_init(&exec->resv_set);
}
EXPORT_SYMBOL(drm_exec_init);
@@ -110,6 +116,7 @@ void drm_exec_fini(struct drm_exec *exec)
drm_gem_object_put(exec->contended);
ww_acquire_fini(&exec->ticket);
}
+ xa_destroy(&exec->resv_set);
}
EXPORT_SYMBOL(drm_exec_fini);
@@ -139,6 +146,30 @@ bool drm_exec_cleanup(struct drm_exec *exec)
}
EXPORT_SYMBOL(drm_exec_cleanup);
+static unsigned long drm_exec_resv_to_key(const struct dma_resv *resv)
+{
+ return (unsigned long)resv / __alignof__(typeof(*resv));
+}
+
+static void
+drm_exec_resv_set_erase(struct drm_exec *exec, unsigned long key)
+{
+ if (xa_load(&exec->resv_set, key))
+ xa_erase(&exec->resv_set, key);
+}
+
+static bool drm_exec_in_evict_mode(struct drm_exec *exec)
+{
+ return !!exec->snap;
+}
+
+static void drm_exec_set_evict_mode(struct drm_exec *exec,
+ struct drm_exec_snapshot *snap)
+{
+ exec->snap = snap;
+ exec->flags &= ~DRM_EXEC_IGNORE_DUPLICATES;
+}
+
/* Track the locked object in the array */
static int drm_exec_obj_locked(struct drm_exec *exec,
struct drm_gem_object *obj,
@@ -161,6 +192,14 @@ static int drm_exec_obj_locked(struct drm_exec *exec,
drm_gem_object_get(obj);
exec->objects[exec->num_objects++] = obj;
+ /*
+ * Errors here are not fatal, It means the object we locked
+ * for eviction can't be locked again. If that is problematic
+ * we may need to reconsider this.
+ */
+ if (drm_exec_in_evict_mode(exec))
+ (void)xa_store(&exec->resv_set, drm_exec_resv_to_key(obj->resv),
+ obj->resv, gfp | __GFP_NOWARN);
return 0;
}
@@ -184,6 +223,9 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
dma_resv_lock_slow(obj->resv, &exec->ticket);
}
+ if (exec->drop_contended)
+ goto error_unlock;
+
ret = drm_exec_obj_locked(exec, obj, GFP_KERNEL);
if (unlikely(ret))
goto error_unlock;
@@ -245,10 +287,19 @@ int drm_exec_trylock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
}
if (!dma_resv_trylock_ctx(obj->resv, &exec->ticket)) {
- if (dma_resv_locking_ctx(obj->resv) == &exec->ticket)
- return (exec->flags & DRM_EXEC_IGNORE_DUPLICATES) ? 0 : -EALREADY;
- else
+ if (dma_resv_locking_ctx(obj->resv) == &exec->ticket) {
+ unsigned long key = drm_exec_resv_to_key(obj->resv);
+
+ if (exec->flags & DRM_EXEC_IGNORE_DUPLICATES ||
+ xa_load(&exec->resv_set, key)) {
+ if (!drm_exec_in_evict_mode(exec))
+ drm_exec_resv_set_erase(exec, key);
+ return 0;
+ }
+ return -EALREADY;
+ } else {
return -EBUSY;
+ }
}
ret = drm_exec_obj_locked(exec, obj, GFP_ATOMIC | __GFP_NOWARN);
@@ -288,12 +339,20 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
if (unlikely(ret == -EDEADLK)) {
drm_gem_object_get(obj);
exec->contended = obj;
+ exec->drop_contended = drm_exec_in_evict_mode(exec);
return -EDEADLK;
}
- if (unlikely(ret == -EALREADY) &&
- exec->flags & DRM_EXEC_IGNORE_DUPLICATES)
- return 0;
+ if (unlikely(ret == -EALREADY)) {
+ unsigned long key = drm_exec_resv_to_key(obj->resv);
+
+ if (exec->flags & DRM_EXEC_IGNORE_DUPLICATES ||
+ xa_load(&exec->resv_set, key)) {
+ if (!drm_exec_in_evict_mode(exec))
+ drm_exec_resv_set_erase(exec, key);
+ return 0;
+ }
+ }
if (unlikely(ret))
return ret;
@@ -324,6 +383,7 @@ void drm_exec_unlock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
for (i = exec->num_objects; i--;) {
if (exec->objects[i] == obj) {
+ drm_exec_resv_set_erase(exec, drm_exec_resv_to_key(obj->resv));
dma_resv_unlock(obj->resv);
for (++i; i < exec->num_objects; ++i)
exec->objects[i - 1] = exec->objects[i];
@@ -415,12 +475,14 @@ void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap)
if (index + 1 == snap->num_locked)
break;
+ xa_erase(&exec->resv_set, drm_exec_resv_to_key(obj->resv));
dma_resv_unlock(obj->resv);
drm_gem_object_put(obj);
exec->objects[index] = NULL;
}
exec->num_objects = snap->num_locked;
+ exec->flags = snap->flags;
if (!exec->prelocked)
exec->prelocked = snap->prelocked;
@@ -443,8 +505,9 @@ void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap)
snap->prelocked = exec->prelocked;
if (snap->prelocked)
drm_gem_object_get(snap->prelocked);
+ snap->flags = exec->flags;
snap->saved_snap = exec->snap;
- exec->snap = snap;
+ drm_exec_set_evict_mode(exec, snap);
}
EXPORT_SYMBOL(drm_exec_snapshot);
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index 0ce4d749511b..0b6d5ac0c092 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -5,6 +5,7 @@
#include <linux/compiler.h>
#include <linux/ww_mutex.h>
+#include <linux/xarray.h>
#define DRM_EXEC_INTERRUPTIBLE_WAIT BIT(0)
#define DRM_EXEC_IGNORE_DUPLICATES BIT(1)
@@ -53,6 +54,17 @@ struct drm_exec {
* @snap: Pointer to the last snapshot taken or NULL if none.
*/
struct drm_exec_snapshot *snap;
+
+ /**
+ * @resv_set: Set of pointers to locked objects in evict mode.
+ */
+ struct xarray resv_set;
+
+ /**
+ * @drop_contended: Drop the contended object after WW transaction
+ * relaxation.
+ */
+ bool drop_contended;
};
/**
@@ -67,6 +79,9 @@ struct drm_exec_snapshot {
/** @num_locked: Number of locked objects at snapshot time. */
unsigned long num_locked;
+
+ /** @flags: The drm_exec flags at snapshot time. */
+ u32 flags;
};
int drm_exec_handle_contended(struct drm_exec *exec);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 17/21] drm/ttm: Support drm_exec locking for eviction and swapping
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (15 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 18/21] drm/ttm: Convert ttm vm to using drm_exec Thomas Hellström
` (12 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Snapshot the drm_exec state before validation, and perform locking
for eviction and swapping using the passed in drm_exec pointer
if any. Otherwise fall back to trylock / ticketlock.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo.c | 44 ++++++++++++++++++++++-------
drivers/gpu/drm/ttm/ttm_bo_util.c | 47 +++++++++++++++++++++++++------
include/drm/ttm/ttm_bo.h | 5 ++++
3 files changed, 77 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 316afe19a325..8706502edcb1 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -31,6 +31,8 @@
#define pr_fmt(fmt) "[TTM] " fmt
+#include <drm/drm_exec.h>
+
#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
@@ -560,10 +562,16 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
};
long lret;
- evict_walk.walk.trylock_only = true;
- lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
- if (lret || !ticket)
- goto out;
+ /*
+ * If ww_mutex slowpath debugging, skip the drm_exec trylock step
+ * to properly exercise the ww transaction backoff from eviction.
+ */
+ if (!ctx->exec || !IS_ENABLED(CONFIG_DEBUG_WW_MUTEX_SLOWPATH)) {
+ evict_walk.walk.trylock_only = true;
+ lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
+ if (lret || !(ticket || ctx->exec))
+ goto out;
+ }
/* If ticket-locking, repeat while making progress. */
evict_walk.walk.trylock_only = false;
@@ -776,6 +784,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
struct ttm_operation_ctx *ctx)
{
+ struct drm_exec_snapshot snap;
struct ttm_resource *res;
struct ttm_place hop;
bool force_space;
@@ -789,17 +798,24 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
if (!placement->num_placement)
return ttm_bo_pipeline_gutting(bo);
+ if (ctx->exec)
+ drm_exec_snapshot(ctx->exec, &snap);
+
force_space = false;
do {
/* Check whether we need to move buffer. */
if (bo->resource &&
ttm_resource_compatible(bo->resource, placement,
- force_space))
- return 0;
+ force_space)) {
+ ret = 0;
+ goto out;
+ }
/* Moving of pinned BOs is forbidden */
- if (bo->pin_count)
- return -EINVAL;
+ if (bo->pin_count) {
+ ret = -EINVAL;
+ goto out;
+ }
/*
* Determine where to move the buffer.
@@ -816,7 +832,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
if (ret == -ENOSPC)
continue;
if (ret)
- return ret;
+ goto out;
bounce:
ret = ttm_bo_handle_move_mem(bo, res, false, ctx, &hop);
@@ -828,11 +844,14 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
}
if (ret) {
ttm_resource_free(bo, &res);
- return ret;
+ goto out;
}
} while (ret && force_space);
+ if (ctx->exec)
+ drm_exec_restore(ctx->exec, &snap);
+
/* For backward compatibility with userspace */
if (ret == -ENOSPC)
return -ENOMEM;
@@ -846,6 +865,11 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
return ret;
}
return 0;
+out:
+ if (ctx->exec)
+ drm_exec_restore(ctx->exec, &snap);
+
+ return ret;
}
EXPORT_SYMBOL(ttm_bo_validate);
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index f6460024077d..0849a1472e3d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -31,6 +31,8 @@
#include <linux/vmalloc.h>
+#include <drm/drm_exec.h>
+
#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
@@ -814,6 +816,25 @@ static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk,
return ret;
}
+static int ttm_lru_walk_execlock(struct ttm_lru_walk *walk,
+ struct ttm_buffer_object *bo)
+{
+ struct ttm_operation_ctx *ctx = walk->ctx;
+ struct drm_gem_object *obj = &bo->base;
+ struct drm_exec *exec = ctx->exec;
+ int ret;
+
+ if (walk->trylock_only)
+ ret = drm_exec_trylock_obj(exec, obj);
+ else
+ ret = drm_exec_lock_obj(exec, obj);
+
+ if (ret == -EALREADY && bo->base.resv == ctx->resv && ctx->allow_res_evict)
+ return 0;
+
+ return ret;
+}
+
static void ttm_lru_walk_unlock(struct ttm_buffer_object *bo, bool locked)
{
if (locked)
@@ -854,6 +875,7 @@ static void ttm_lru_walk_unlock(struct ttm_buffer_object *bo, bool locked)
long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
struct ttm_resource_manager *man, long target)
{
+ struct drm_exec *exec = walk->ctx->exec;
struct ttm_resource_cursor cursor;
struct ttm_resource *res;
long sofar = 0;
@@ -869,11 +891,14 @@ long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
if (!bo || bo->resource != res)
continue;
- if (ttm_lru_walk_trylock(walk, bo, &bo_needs_unlock))
- bo_locked = true;
- else if ((!walk->ticket) || walk->ctx->no_wait_gpu ||
- walk->trylock_only)
- continue;
+ if (!exec) {
+ if (ttm_lru_walk_trylock(walk, bo, &bo_needs_unlock))
+ bo_locked = true;
+
+ else if (!walk->ticket || walk->ctx->no_wait_gpu ||
+ walk->trylock_only)
+ continue;
+ }
if (!ttm_bo_get_unless_zero(bo)) {
ttm_lru_walk_unlock(bo, bo_needs_unlock);
@@ -884,12 +909,16 @@ long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
spin_unlock(&bdev->lru_lock);
lret = 0;
- if (!bo_locked && walk->ticket)
- lret = ttm_lru_walk_ticketlock(walk, bo, &bo_needs_unlock);
+ if (!bo_locked) {
+ if (exec)
+ lret = ttm_lru_walk_execlock(walk, bo);
+ else
+ lret = ttm_lru_walk_ticketlock(walk, bo, &bo_needs_unlock);
+ }
/*
* Note that in between the release of the lru lock and the
- * ticketlock, the bo may have switched resource,
+ * drm_exec_lock_obj / 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.
@@ -899,7 +928,7 @@ long ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
ttm_lru_walk_unlock(bo, bo_needs_unlock);
ttm_bo_put(bo);
- if (lret == -EBUSY)
+ if (lret == -EBUSY || lret == -EALREADY)
lret = 0;
sofar = (lret < 0) ? lret : sofar + lret;
if (sofar < 0 || sofar >= target)
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index deaedfb060ed..1c9f4880abb9 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -164,6 +164,8 @@ struct ttm_bo_kmap_obj {
struct ttm_buffer_object *bo;
};
+struct drm_exec;
+
/**
* struct ttm_operation_ctx
*
@@ -175,6 +177,8 @@ struct ttm_bo_kmap_obj {
* @force_alloc: Don't check the memory account during suspend or CPU page
* faults. Should only be used by TTM internally.
* @resv: Reservation object to allow reserved evictions with.
+ * @exec: If part of a drm_exec transaction, pointer to the struct drm_exec.
+ * Null otherwise.
* @bytes_moved: Statistics on how many bytes have been moved.
*
* Context for TTM operations like changing buffer placement or general memory
@@ -187,6 +191,7 @@ struct ttm_operation_ctx {
bool allow_res_evict;
bool force_alloc;
struct dma_resv *resv;
+ struct drm_exec *exec;
uint64_t bytes_moved;
};
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 18/21] drm/ttm: Convert ttm vm to using drm_exec
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (16 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 17/21] drm/ttm: Support drm_exec locking for eviction and swapping Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 19/21] drm/xe: Use drm_exec for fault locking Thomas Hellström
` (11 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
TTM faulting may include migration and swapping. Convert
helpers to support drm_exec locking and enable it
by converting the ttm_bo_vm_fault() function to include
a drm_exec loop.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 4 +-
drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 4 +-
drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-
drivers/gpu/drm/radeon/radeon_gem.c | 4 +-
drivers/gpu/drm/ttm/ttm_bo_vm.c | 101 ++++++++++++++-------
drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 6 +-
drivers/gpu/drm/xe/xe_bo.c | 5 +-
include/drm/ttm/ttm_bo.h | 6 +-
8 files changed, 85 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 17e16c971e21..22d61cdb0d88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -52,7 +52,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
vm_fault_t ret;
int idx;
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
if (ret)
return ret;
@@ -64,7 +64,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
}
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT);
+ TTM_BO_VM_NUM_PREFAULT, NULL);
drm_dev_exit(idx);
} else {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index e6f177183c0f..c66e2b54c9a2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -1046,7 +1046,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
area->vm_flags & VM_WRITE))
return VM_FAULT_SIGBUS;
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
if (ret)
return ret;
@@ -1108,7 +1108,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
if (drm_dev_enter(dev, &idx)) {
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT);
+ TTM_BO_VM_NUM_PREFAULT, NULL);
drm_dev_exit(idx);
} else {
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 5a887d67dc0e..bc6901955508 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -46,7 +46,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
pgprot_t prot;
vm_fault_t ret;
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
if (ret)
return ret;
@@ -56,7 +56,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
nouveau_bo_del_io_reserve_lru(bo);
prot = vm_get_page_prot(vma->vm_flags);
- ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
+ ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, NULL);
nouveau_bo_add_io_reserve_lru(bo);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 2ef201a072f1..f29761b7ca97 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -54,7 +54,7 @@ static vm_fault_t radeon_gem_fault(struct vm_fault *vmf)
down_read(&rdev->pm.mclk_lock);
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
if (ret)
goto unlock_mclk;
@@ -63,7 +63,7 @@ static vm_fault_t radeon_gem_fault(struct vm_fault *vmf)
goto unlock_resv;
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT);
+ TTM_BO_VM_NUM_PREFAULT, NULL);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
goto unlock_mclk;
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 4212b8c91dd4..74daa910d0b7 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 <drm/drm_exec.h>
+
#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
@@ -39,7 +41,8 @@
#include <drm/drm_managed.h>
static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
- struct vm_fault *vmf)
+ struct vm_fault *vmf,
+ struct drm_exec *exec)
{
long err = 0;
@@ -63,7 +66,10 @@ static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
(void)dma_resv_wait_timeout(bo->base.resv,
DMA_RESV_USAGE_KERNEL, true,
MAX_SCHEDULE_TIMEOUT);
- dma_resv_unlock(bo->base.resv);
+ if (exec)
+ drm_exec_unlock_obj(exec, &bo->base);
+ else
+ dma_resv_unlock(bo->base.resv);
ttm_bo_put(bo);
return VM_FAULT_RETRY;
}
@@ -96,6 +102,7 @@ static unsigned long ttm_bo_io_mem_pfn(struct ttm_buffer_object *bo,
* ttm_bo_vm_reserve - Reserve a buffer object in a retryable vm callback
* @bo: The buffer object
* @vmf: The fault structure handed to the callback
+ * @exec: The drm_exec locking transaction context. May be NULL.
*
* vm callbacks like fault() and *_mkwrite() allow for the mmap_lock to be dropped
* during long waits, and after the wait the callback will be restarted. This
@@ -114,15 +121,16 @@ static unsigned long ttm_bo_io_mem_pfn(struct ttm_buffer_object *bo,
* VM_FAULT_NOPAGE if blocking wait and retrying was not allowed.
*/
vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
- struct vm_fault *vmf)
+ struct vm_fault *vmf, struct drm_exec *exec)
{
- /*
- * Work around locking order reversal in fault / nopfn
- * between mmap_lock and bo_reserve: Perform a trylock operation
- * for reserve, and if it fails, retry the fault after waiting
- * for the buffer to become unreserved.
- */
- if (unlikely(!dma_resv_trylock(bo->base.resv))) {
+ int ret;
+
+ if (exec)
+ ret = drm_exec_trylock_obj(exec, &bo->base);
+ else
+ ret = dma_resv_trylock(bo->base.resv) ? 0 : -EBUSY;
+
+ if (unlikely(ret == -EBUSY)) {
/*
* If the fault allows retry and this is the first
* fault attempt, we try to release the mmap_lock
@@ -132,16 +140,26 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
ttm_bo_get(bo);
mmap_read_unlock(vmf->vma->vm_mm);
- if (!dma_resv_lock_interruptible(bo->base.resv,
- NULL))
- dma_resv_unlock(bo->base.resv);
+ if (exec) {
+ ret = drm_exec_lock_obj(exec, &bo->base);
+ if (!ret)
+ drm_exec_unlock_obj(exec, &bo->base);
+ } else {
+ if (!dma_resv_lock_interruptible(bo->base.resv,
+ NULL))
+ dma_resv_unlock(bo->base.resv);
+ }
ttm_bo_put(bo);
}
return VM_FAULT_RETRY;
}
- if (dma_resv_lock_interruptible(bo->base.resv, NULL))
+ if (exec)
+ ret = drm_exec_lock_obj(exec, &bo->base);
+ else
+ ret = dma_resv_lock_interruptible(bo->base.resv, NULL);
+ if (ret)
return VM_FAULT_NOPAGE;
}
@@ -151,7 +169,10 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
*/
if (bo->ttm && (bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL)) {
if (!(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE)) {
- dma_resv_unlock(bo->base.resv);
+ if (exec)
+ drm_exec_unlock_obj(exec, &bo->base);
+ else
+ dma_resv_unlock(bo->base.resv);
return VM_FAULT_SIGBUS;
}
}
@@ -167,6 +188,7 @@ EXPORT_SYMBOL(ttm_bo_vm_reserve);
* @num_prefault: Maximum number of prefault pages. The caller may want to
* specify this based on madvice settings and the size of the GPU object
* backed by the memory.
+ * @exec: The struct drm_exec locking transaction context. May be NULL.
*
* This function inserts one or more page table entries pointing to the
* memory backing the buffer object, and then returns a return code
@@ -180,7 +202,8 @@ EXPORT_SYMBOL(ttm_bo_vm_reserve);
*/
vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
pgprot_t prot,
- pgoff_t num_prefault)
+ pgoff_t num_prefault,
+ struct drm_exec *exec)
{
struct vm_area_struct *vma = vmf->vma;
struct ttm_buffer_object *bo = vma->vm_private_data;
@@ -199,7 +222,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
* Wait for buffer data in transit, due to a pipelined
* move.
*/
- ret = ttm_bo_vm_fault_idle(bo, vmf);
+ ret = ttm_bo_vm_fault_idle(bo, vmf, exec);
if (unlikely(ret != 0))
return ret;
@@ -220,7 +243,8 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
struct ttm_operation_ctx ctx = {
.interruptible = true,
.no_wait_gpu = false,
- .force_alloc = true
+ .force_alloc = true,
+ .exec = exec,
};
ttm = bo->ttm;
@@ -324,25 +348,34 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
pgprot_t prot;
struct ttm_buffer_object *bo = vma->vm_private_data;
struct drm_device *ddev = bo->base.dev;
+ struct drm_exec exec;
vm_fault_t ret;
- int idx;
-
- ret = ttm_bo_vm_reserve(bo, vmf);
- if (ret)
- return ret;
-
- prot = vma->vm_page_prot;
- if (drm_dev_enter(ddev, &idx)) {
- ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
- drm_dev_exit(idx);
- } else {
- ret = ttm_bo_vm_dummy_page(vmf, prot);
+ int idx, err;
+
+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 16);
+ drm_exec_until_all_locked(&exec) {
+ ret = ttm_bo_vm_reserve(bo, vmf, &exec);
+ err = drm_exec_retry_on_contention(&exec, 0);
+ if (err)
+ ret = VM_FAULT_NOPAGE;
+ if (ret)
+ goto out;
+
+ prot = vma->vm_page_prot;
+ if (drm_dev_enter(ddev, &idx)) {
+ ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT,
+ &exec);
+ drm_dev_exit(idx);
+ err = drm_exec_retry_on_contention(&exec, 0);
+ if (err)
+ ret = VM_FAULT_NOPAGE;
+ } else {
+ ret = ttm_bo_vm_dummy_page(vmf, prot);
+ }
}
- if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
- return ret;
-
- dma_resv_unlock(bo->base.resv);
+out:
+ drm_exec_fini(&exec);
return ret;
}
EXPORT_SYMBOL(ttm_bo_vm_fault);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
index 74ff2812d66a..fc275afd000c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
@@ -388,7 +388,7 @@ vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf)
*/
save_flags = vmf->flags;
vmf->flags &= ~FAULT_FLAG_ALLOW_RETRY;
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
vmf->flags = save_flags;
if (ret)
return ret;
@@ -423,7 +423,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf)
pgprot_t prot;
vm_fault_t ret;
- ret = ttm_bo_vm_reserve(bo, vmf);
+ ret = ttm_bo_vm_reserve(bo, vmf, NULL);
if (ret)
return ret;
@@ -457,7 +457,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf)
else
prot = vm_get_page_prot(vma->vm_flags);
- ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault);
+ ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault, NULL);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
return ret;
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 9a0ca2cab7b6..3c56858e0751 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1223,7 +1223,7 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
if (needs_rpm)
xe_pm_runtime_get(xe);
- ret = ttm_bo_vm_reserve(tbo, vmf);
+ ret = ttm_bo_vm_reserve(tbo, vmf, NULL);
if (ret)
goto out;
@@ -1231,7 +1231,8 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
trace_xe_bo_cpu_fault(bo);
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT);
+ TTM_BO_VM_NUM_PREFAULT,
+ NULL);
drm_dev_exit(idx);
} else {
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
index 1c9f4880abb9..d749de3aa936 100644
--- a/include/drm/ttm/ttm_bo.h
+++ b/include/drm/ttm/ttm_bo.h
@@ -427,10 +427,12 @@ int ttm_bo_evict_first(struct ttm_device *bdev,
struct ttm_resource_manager *man,
struct ttm_operation_ctx *ctx);
vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
- struct vm_fault *vmf);
+ struct vm_fault *vmf,
+ struct drm_exec *exec);
vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
pgprot_t prot,
- pgoff_t num_prefault);
+ pgoff_t num_prefault,
+ struct drm_exec *exec);
vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf);
void ttm_bo_vm_open(struct vm_area_struct *vma);
void ttm_bo_vm_close(struct vm_area_struct *vma);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 19/21] drm/xe: Use drm_exec for fault locking
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (17 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 18/21] drm/ttm: Convert ttm vm to using drm_exec Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 20/21] drm/ttm: Use drm_exec_trylock for bo initialization Thomas Hellström
` (10 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Similar to how TTM vm does this, convert the drm/xe fault
handler to use drm_exec locking.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/xe/xe_bo.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 3c56858e0751..27d7d36401b5 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1217,29 +1217,37 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
struct xe_device *xe = to_xe_device(ddev);
struct xe_bo *bo = ttm_to_xe_bo(tbo);
bool needs_rpm = bo->flags & XE_BO_FLAG_VRAM_MASK;
+ struct drm_exec exec;
vm_fault_t ret;
- int idx;
+ int idx, err;
if (needs_rpm)
xe_pm_runtime_get(xe);
- ret = ttm_bo_vm_reserve(tbo, vmf, NULL);
- if (ret)
- goto out;
+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 16);
+ drm_exec_until_all_locked(&exec) {
+ ret = ttm_bo_vm_reserve(tbo, vmf, &exec);
+ err = drm_exec_retry_on_contention(&exec, 0);
+ if (err)
+ ret = VM_FAULT_NOPAGE;
+ if (ret)
+ goto out;
- if (drm_dev_enter(ddev, &idx)) {
- trace_xe_bo_cpu_fault(bo);
+ if (drm_dev_enter(ddev, &idx)) {
+ trace_xe_bo_cpu_fault(bo);
- ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT,
- NULL);
- drm_dev_exit(idx);
- } else {
- ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
+ ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
+ TTM_BO_VM_NUM_PREFAULT,
+ &exec);
+ drm_dev_exit(idx);
+ err = drm_exec_retry_on_contention(&exec, 0);
+ if (err)
+ ret = VM_FAULT_NOPAGE;
+ } else {
+ ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
+ }
}
- if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
- goto out;
/*
* ttm_bo_vm_reserve() already has dma_resv_lock.
*/
@@ -1250,8 +1258,8 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
mutex_unlock(&xe->mem_access.vram_userfault.lock);
}
- dma_resv_unlock(tbo->base.resv);
out:
+ drm_exec_fini(&exec);
if (needs_rpm)
xe_pm_runtime_put(xe);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 20/21] drm/ttm: Use drm_exec_trylock for bo initialization
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (18 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 19/21] drm/xe: Use drm_exec for fault locking Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 21/21] drm/xe: Initial support for drm exec locking during validate Thomas Hellström
` (9 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Buffer object initialization may be part of a drm_exec transaction.
Rather than using dma_resv_trylock, use drm_exec_trylock_obj().
RFC: This patch indicates to me that we should avoid the -ENOMEM failure
for drm_exec_trylock, Could probably use a sleeping lock here without
problems.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_bo.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8706502edcb1..70af66b5b86e 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -942,10 +942,17 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo,
/* passed reservation objects should already be locked,
* since otherwise lockdep will be angered in radeon.
*/
- if (!resv)
- WARN_ON(!dma_resv_trylock(bo->base.resv));
- else
+ if (!resv) {
+ if (ctx->exec) {
+ ret = drm_exec_trylock_obj(ctx->exec, &bo->base);
+ if (ret)
+ goto err_put;
+ } else {
+ WARN_ON(!dma_resv_trylock(bo->base.resv));
+ }
+ } else {
dma_resv_assert_held(resv);
+ }
ret = ttm_bo_validate(bo, placement, ctx);
if (unlikely(ret))
@@ -954,8 +961,12 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo,
return 0;
err_unlock:
- if (!resv)
- dma_resv_unlock(bo->base.resv);
+ if (!resv) {
+ if (ctx->exec)
+ drm_exec_unlock_obj(ctx->exec, &bo->base);
+ else
+ dma_resv_unlock(bo->base.resv);
+ }
err_put:
ttm_bo_put(bo);
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RFC PATCH v3 21/21] drm/xe: Initial support for drm exec locking during validate
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (19 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 20/21] drm/ttm: Use drm_exec_trylock for bo initialization Thomas Hellström
@ 2024-05-21 7:16 ` Thomas Hellström
2024-05-21 7:22 ` [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (8 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:16 UTC (permalink / raw)
To: intel-xe
Cc: Thomas Hellström, Christian König,
Somalapuram Amaranath, Matthew Brost, dri-devel
Initial stab at converting xe_bo validation to drm_exec locking
where it matters most. (Low hanging fruit). For a couple of call
sites as well as for bo allocation, the passing down the call
chaing of the drm_exec object may turn out a bit tricky.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/xe/display/xe_fb_pin.c | 2 +-
drivers/gpu/drm/xe/tests/xe_bo.c | 6 +++---
drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 ++--
drivers/gpu/drm/xe/tests/xe_migrate.c | 2 +-
drivers/gpu/drm/xe/xe_bo.c | 8 +++++---
drivers/gpu/drm/xe/xe_bo.h | 4 +++-
drivers/gpu/drm/xe/xe_dma_buf.c | 2 +-
drivers/gpu/drm/xe/xe_ggtt.c | 2 +-
drivers/gpu/drm/xe/xe_gt_pagefault.c | 2 +-
drivers/gpu/drm/xe/xe_vm.c | 4 ++--
10 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index 36e15c4961c1..85f37dd7ecb1 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -289,7 +289,7 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb,
if (IS_DGFX(xe))
ret = xe_bo_migrate(bo, XE_PL_VRAM0);
else
- ret = xe_bo_validate(bo, NULL, true);
+ ret = xe_bo_validate(bo, NULL, true, NULL);
if (!ret)
ttm_bo_pin(&bo->ttm);
ttm_bo_unreserve(&bo->ttm);
diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
index 7576d362020f..410579f75a39 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo.c
@@ -30,7 +30,7 @@ static int ccs_test_migrate(struct xe_tile *tile, struct xe_bo *bo,
u32 offset;
/* Move bo to VRAM if not already there. */
- ret = xe_bo_validate(bo, NULL, false);
+ ret = xe_bo_validate(bo, NULL, false, NULL);
if (ret) {
KUNIT_FAIL(test, "Failed to validate bo.\n");
return ret;
@@ -276,7 +276,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
if (i) {
down_read(&vm->lock);
xe_vm_lock(vm, false);
- err = xe_bo_validate(bo, bo->vm, false);
+ err = xe_bo_validate(bo, bo->vm, false, NULL);
xe_vm_unlock(vm);
up_read(&vm->lock);
if (err) {
@@ -285,7 +285,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
goto cleanup_all;
}
xe_bo_lock(external, false);
- err = xe_bo_validate(external, NULL, false);
+ err = xe_bo_validate(external, NULL, false, NULL);
xe_bo_unlock(external);
if (err) {
KUNIT_FAIL(test, "external bo valid err=%pe\n",
diff --git a/drivers/gpu/drm/xe/tests/xe_dma_buf.c b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
index e7f9b531c465..ef88b4dd184c 100644
--- a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
@@ -81,7 +81,7 @@ static void check_residency(struct kunit *test, struct xe_bo *exported,
}
/* Re-validate the importer. This should move also exporter in. */
- ret = xe_bo_validate(imported, NULL, false);
+ ret = xe_bo_validate(imported, NULL, false, NULL);
if (ret) {
if (ret != -EINTR && ret != -ERESTARTSYS)
KUNIT_FAIL(test, "Validating importer failed with err=%d.\n",
@@ -157,7 +157,7 @@ static void xe_test_dmabuf_import_same_driver(struct xe_device *xe)
/* Is everything where we expect it to be? */
xe_bo_lock(import_bo, false);
- err = xe_bo_validate(import_bo, NULL, false);
+ err = xe_bo_validate(import_bo, NULL, false, NULL);
/* Pinning in VRAM is not allowed. */
if (!is_dynamic(params) &&
diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
index b6e7f80c3774..0feb99d3ef7d 100644
--- a/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -90,7 +90,7 @@ static void test_copy(struct xe_migrate *m, struct xe_bo *bo,
return;
}
- err = xe_bo_validate(remote, NULL, false);
+ err = xe_bo_validate(remote, NULL, false, NULL);
if (err) {
KUNIT_FAIL(test, "Failed to validate system bo for %s: %i\n",
str, err);
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 27d7d36401b5..f33120f3a829 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1755,7 +1755,7 @@ int xe_bo_pin_external(struct xe_bo *bo)
xe_assert(xe, xe_bo_is_user(bo));
if (!xe_bo_is_pinned(bo)) {
- err = xe_bo_validate(bo, NULL, false);
+ err = xe_bo_validate(bo, NULL, false, NULL);
if (err)
return err;
@@ -1801,7 +1801,7 @@ int xe_bo_pin(struct xe_bo *bo)
/* We only expect at most 1 pin */
xe_assert(xe, !xe_bo_is_pinned(bo));
- err = xe_bo_validate(bo, NULL, false);
+ err = xe_bo_validate(bo, NULL, false, NULL);
if (err)
return err;
@@ -1917,11 +1917,13 @@ void xe_bo_unpin(struct xe_bo *bo)
* Return: 0 on success, negative error code on failure. May return
* -EINTR or -ERESTARTSYS if internal waits are interrupted by a signal.
*/
-int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict,
+ struct drm_exec *exec)
{
struct ttm_operation_ctx ctx = {
.interruptible = true,
.no_wait_gpu = false,
+ .exec = exec,
};
if (vm) {
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 220e71086e65..a6ddaff8ce74 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -62,6 +62,7 @@
#define XE_BO_PROPS_INVALID (-1)
+struct drm_exec;
struct sg_table;
struct xe_ttm_lru_walk;
@@ -164,7 +165,8 @@ int xe_bo_pin_external(struct xe_bo *bo);
int xe_bo_pin(struct xe_bo *bo);
void xe_bo_unpin_external(struct xe_bo *bo);
void xe_bo_unpin(struct xe_bo *bo);
-int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict);
+int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict,
+ struct drm_exec *exec);
static inline bool xe_bo_is_pinned(struct xe_bo *bo)
{
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index 68f309f5e981..ce84aa70cca8 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -102,7 +102,7 @@ static struct sg_table *xe_dma_buf_map(struct dma_buf_attachment *attach,
if (!attach->peer2peer)
r = xe_bo_migrate(bo, XE_PL_TT);
else
- r = xe_bo_validate(bo, NULL, false);
+ r = xe_bo_validate(bo, NULL, false, NULL);
if (r)
return ERR_PTR(r);
}
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index 0d541f55b4fc..ba9b2c3236ab 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -400,7 +400,7 @@ static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
return 0;
}
- err = xe_bo_validate(bo, NULL, false);
+ err = xe_bo_validate(bo, NULL, false, NULL);
if (err)
return err;
diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 20ec1ab1b52d..3971bf567f78 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -117,7 +117,7 @@ static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
return err;
} else if (bo) {
/* Create backing store if needed */
- err = xe_bo_validate(bo, vm, true);
+ err = xe_bo_validate(bo, vm, true, NULL);
if (err)
return err;
}
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 335524e803e7..ea2308ff76c4 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -380,7 +380,7 @@ static int xe_gpuvm_validate(struct drm_gpuvm_bo *vm_bo, struct drm_exec *exec)
list_move_tail(&gpuva_to_vma(gpuva)->combined_links.rebind,
&vm->rebind_list);
- ret = xe_bo_validate(gem_to_xe_bo(vm_bo->obj), vm, false);
+ ret = xe_bo_validate(gem_to_xe_bo(vm_bo->obj), vm, false, exec);
if (ret)
return ret;
@@ -2698,7 +2698,7 @@ static int vma_lock_and_validate(struct drm_exec *exec, struct xe_vma *vma,
if (!bo->vm)
err = drm_exec_lock_obj(exec, &bo->ttm.base);
if (!err && validate)
- err = xe_bo_validate(bo, xe_vma_vm(vma), true);
+ err = xe_bo_validate(bo, xe_vma_vm(vma), true, exec);
}
return err;
--
2.44.0
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (20 preceding siblings ...)
2024-05-21 7:16 ` [RFC PATCH v3 21/21] drm/xe: Initial support for drm exec locking during validate Thomas Hellström
@ 2024-05-21 7:22 ` Thomas Hellström
2024-05-21 7:23 ` ✓ CI.Patch_applied: success for TTM shrinker helpers and xe buffer object shrinker (rev3) Patchwork
` (7 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-21 7:22 UTC (permalink / raw)
To: intel-xe
Cc: Somalapuram Amaranath, Christian König, Matthew Brost,
dri-devel
Hi, all
On Tue, 2024-05-21 at 09:16 +0200, Thomas Hellström wrote:
> This series implements TTM shrinker / eviction helpers and an xe bo
> shrinker. It builds on two previous series, *and obsoletes these*.
> First
>
> https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg484425.html
>
> Second the previous TTM shrinker series
>
> https://lore.kernel.org/linux-mm/b7491378-defd-4f1c-31e2-29e4c77e2d67@amd.com/T/
>
> Where the comment about layering
> https://lore.kernel.org/linux-mm/b7491378-defd-4f1c-31e2-29e4c77e2d67@amd.com/T/#ma918844aa8a6efe8768fdcda0c6590d5c93850c9
>
> now addressed, and this version also implements shmem objects for
> backup
> rather than direct swap-cache insertions, which was used in the
> previuos
> series. It turns out that with per-page backup / shrinking, shmem
> objects
> appears to work just as well as direct swap-cache insertions with the
> added benefit that was introduced in the previous TTM shrinker series
> to
> avoid running out of swap entries isn't really needed.
>
> Patch 1-4 implements restartable LRU list iteration.
>
> Patch 5 implements a LRU walker + resv locking helper
>
> Patch 6 moves TTM swapping over to the walker.
>
> Patch 7 moves TTM eviction over to the walker.
>
> Patch 8 could in theory be skipped but introduces a possibility to
> easily
> add or test multiple backup backends, like the direct swap-cache
> insertion or even files into fast dedicated nvme storage for for
> example.
>
> Patch 9 introduces helpers in the ttm_pool code for page-by-page
> shrinking
> and recovery. It avoids having to temporarily allocate a huge amount
> of
> memory to be able to shrink a buffer object. It also introduces the
> possibility to immediately write-back pages if needed, since that
> tends
> to be a bit delayed when left to kswapd.
>
> Patch 10 Adds a simple error injection to the above code to help
> increase
> test coverage.
>
> Patch 11 Implements an xe bo shrinker and a common helper in TTM for
> shrinking.
>
> Patch 12-21 are really a separate POC series, for introducing
> drm_exec locking
> in TTM. The patch touches both drm_exec and dma-buf and is for now
> marked as
> an RFC:
>
> Patch 12 Introduces dma_resv_trylock_ctx.
>
> Patches 13-14 deal with introducing drm_exec_trylock.
>
> Patch 15 adds a snapshot capability to drm_exec.
>
> Patch 16 adds an evict mode locking capability to drm_exec
>
> Patch 17 converts the LRU + locking walker to drm_exec.
>
> Patch 18 converts TTM vm to use drm_exec.
>
> Patch 19 converts the xe fault handler to drm_exec.
>
> Patch 20 converts bo initialization locking to drm_exec
>
> Patch 21 introduces drm_exec locking around some of the
> bo validation callsites in drm_exec.
>
> v2:
> - Squash obsolete revision history in the patch commit messages.
> - Fix a couple of review comments by Christian
> - Don't store the mem_type in the TTM managers but in the
> resource cursor.
> - Rename introduced TTM *back_up* function names to *backup*
> - Add ttm pool recovery fault injection.
> - Shrinker xe kunit test
> - Various bugfixes
>
> v3:
> - Address some review comments from Matthew Brost and Christian
> König.
> - Use the restartable LRU walk for TTM swapping and eviction.
> - Provide a POC drm_exec locking implementation for exhaustive
> eviction. (Christian König).
>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
Now with a POC available how the drm_exec locking could be done in TTM
(the RFC part) I think the best approach is to get patch 1-11 reviewed
and pushed, and we could then settle on a solution for the drm_exec
part as a follow-up. Undoubtedly there are a couple of things that need
discussion there, in particular the resv_set, the snapshot and the
trylock memory allocation.
/Thomas
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✓ CI.Patch_applied: success for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (21 preceding siblings ...)
2024-05-21 7:22 ` [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
@ 2024-05-21 7:23 ` Patchwork
2024-05-21 7:24 ` ✗ CI.checkpatch: warning " Patchwork
` (6 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:23 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : success
== Summary ==
=== Applying kernel patches on branch 'drm-tip' with base: ===
Base commit: 3addfb8584a4 drm-tip: 2024y-05m-20d-20h-25m-45s UTC integration manifest
=== git am output follows ===
Applying: drm/ttm: Allow TTM LRU list nodes of different types
Applying: drm/ttm: Slightly clean up LRU list iteration
Applying: drm/ttm: Use LRU hitches
Applying: drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves
Applying: drm/ttm: Provide a generic LRU walker helper
Applying: drm/ttm: Use the LRU walker helper for swapping
Applying: drm/ttm: Use the LRU walker for eviction
Applying: drm/ttm: Add a virtual base class for graphics memory backup
Applying: drm/ttm/pool: Provide a helper to shrink pages
Applying: drm/ttm: Use fault-injection to test error paths
Applying: drm/ttm, drm/xe: Add a shrinker for xe bos
Applying: dma-buf/dma-resv: Introduce dma_resv_trylock_ctx()
Applying: drm/exec: Rework contended locking
Applying: drm/exec: Introduce a drm_exec_trylock_obj() function
Applying: drm/exec: Add a snapshot capability
Applying: drm/exec: Introduce an evict mode
Applying: drm/ttm: Support drm_exec locking for eviction and swapping
Applying: drm/ttm: Convert ttm vm to using drm_exec
Applying: drm/xe: Use drm_exec for fault locking
Applying: drm/ttm: Use drm_exec_trylock for bo initialization
Applying: drm/xe: Initial support for drm exec locking during validate
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✗ CI.checkpatch: warning for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (22 preceding siblings ...)
2024-05-21 7:23 ` ✓ CI.Patch_applied: success for TTM shrinker helpers and xe buffer object shrinker (rev3) Patchwork
@ 2024-05-21 7:24 ` Patchwork
2024-05-21 7:25 ` ✓ CI.KUnit: success " Patchwork
` (5 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:24 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : warning
== Summary ==
+ KERNEL=/kernel
+ git clone https://gitlab.freedesktop.org/drm/maintainer-tools mt
Cloning into 'mt'...
warning: redirecting to https://gitlab.freedesktop.org/drm/maintainer-tools.git/
+ git -C mt rev-list -n1 origin/master
57b97a66dd129aea93991dc66cd10477f7a05cf8
+ cd /kernel
+ git config --global --add safe.directory /kernel
+ git log -n1
commit a2a83023383e589ca5cd9014b7774e114c72113c
Author: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Date: Tue May 21 09:16:39 2024 +0200
drm/xe: Initial support for drm exec locking during validate
Initial stab at converting xe_bo validation to drm_exec locking
where it matters most. (Low hanging fruit). For a couple of call
sites as well as for bo allocation, the passing down the call
chaing of the drm_exec object may turn out a bit tricky.
Cc: Christian König <christian.koenig@amd.com>
Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+ /mt/dim checkpatch 3addfb8584a4fcbff8123461682e5bdfd8785bde drm-intel
d85889a69853 drm/ttm: Allow TTM LRU list nodes of different types
66041a5863ae drm/ttm: Slightly clean up LRU list iteration
82429235b0b1 drm/ttm: Use LRU hitches
05e808ddb479 drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves
4213221743ab drm/ttm: Provide a generic LRU walker helper
b500130e527c drm/ttm: Use the LRU walker helper for swapping
d5efbff5f8ab drm/ttm: Use the LRU walker for eviction
1c357d0a5a46 drm/ttm: Add a virtual base class for graphics memory backup
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:42: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#42:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 281 lines checked
80a0fd8242ae drm/ttm/pool: Provide a helper to shrink pages
cae6f8df5cbd drm/ttm: Use fault-injection to test error paths
-:28: WARNING:CONFIG_DESCRIPTION: please write a help paragraph that fully describes the config symbol
#28: FILE: drivers/gpu/drm/Kconfig:261:
+config DRM_TTM_BACKUP_FAULT_INJECT
+ bool "Enable fault injection during TTM backup"
+ depends on DRM_TTM
+ default n
+ help
+ Inject recoverable failures during TTM backup and recovery of
+ backed-up objects. For DRM driver developers only.
+
+ If in doubt, choose N.
+
total: 0 errors, 1 warnings, 0 checks, 51 lines checked
38b0b3dbbb42 drm/ttm, drm/xe: Add a shrinker for xe bos
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:615: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#615:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 773 lines checked
e95dfa47c33a dma-buf/dma-resv: Introduce dma_resv_trylock_ctx()
5b3e84b60efb drm/exec: Rework contended locking
-:596: WARNING:MACRO_WITH_FLOW_CONTROL: Macros with flow control statements should be avoided
#596: FILE: include/drm/drm_exec.h:125:
+#define drm_exec_retry_on_contention(exec, _ret) \
+ ({ \
+ struct drm_exec *__exec = (exec); \
+ int __ret = (_ret); \
+ \
+ if (unlikely(drm_exec_is_contended(__exec))) { \
+ WARN_ON(__ret != -EDEADLK); \
+ __ret = drm_exec_handle_contended(__exec); \
+ if (!__ret) \
+ goto *__drm_exec_retry_ptr; \
+ } \
+ __ret; \
+ })
total: 0 errors, 1 warnings, 0 checks, 472 lines checked
6a5fa5c482ca drm/exec: Introduce a drm_exec_trylock_obj() function
ea2f6c762e28 drm/exec: Add a snapshot capability
2aa04d5b57e8 drm/exec: Introduce an evict mode
905c698fe3c3 drm/ttm: Support drm_exec locking for eviction and swapping
88faea843270 drm/ttm: Convert ttm vm to using drm_exec
b171e6399324 drm/xe: Use drm_exec for fault locking
d7975d8efd8c drm/ttm: Use drm_exec_trylock for bo initialization
a2a83023383e drm/xe: Initial support for drm exec locking during validate
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✓ CI.KUnit: success for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (23 preceding siblings ...)
2024-05-21 7:24 ` ✗ CI.checkpatch: warning " Patchwork
@ 2024-05-21 7:25 ` Patchwork
2024-05-21 7:37 ` ✓ CI.Build: " Patchwork
` (4 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:25 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : success
== Summary ==
+ trap cleanup EXIT
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
[07:24:36] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[07:24:40] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make ARCH=um O=.kunit --jobs=48
../arch/x86/um/user-offsets.c:17:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
17 | void foo(void)
| ^~~
In file included from ../arch/um/kernel/asm-offsets.c:1:
../arch/x86/um/shared/sysdep/kernel-offsets.h:9:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
9 | void foo(void)
| ^~~
../arch/x86/um/bugs_64.c:9:6: warning: no previous prototype for ‘arch_check_bugs’ [-Wmissing-prototypes]
9 | void arch_check_bugs(void)
| ^~~~~~~~~~~~~~~
../arch/x86/um/bugs_64.c:13:6: warning: no previous prototype for ‘arch_examine_signal’ [-Wmissing-prototypes]
13 | void arch_examine_signal(int sig, struct uml_pt_regs *regs)
| ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/fault.c:18:5: warning: no previous prototype for ‘arch_fixup’ [-Wmissing-prototypes]
18 | int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
| ^~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:16:5: warning: no previous prototype for ‘__vdso_clock_gettime’ [-Wmissing-prototypes]
16 | int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
| ^~~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:30:5: warning: no previous prototype for ‘__vdso_gettimeofday’ [-Wmissing-prototypes]
30 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
| ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:44:21: warning: no previous prototype for ‘__vdso_time’ [-Wmissing-prototypes]
44 | __kernel_old_time_t __vdso_time(__kernel_old_time_t *t)
| ^~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:57:1: warning: no previous prototype for ‘__vdso_getcpu’ [-Wmissing-prototypes]
57 | __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
| ^~~~~~~~~~~~~
../arch/x86/um/os-Linux/registers.c:146:15: warning: no previous prototype for ‘get_thread_reg’ [-Wmissing-prototypes]
146 | unsigned long get_thread_reg(int reg, jmp_buf *buf)
| ^~~~~~~~~~~~~~
../arch/x86/um/os-Linux/mcontext.c:7:6: warning: no previous prototype for ‘get_regs_from_mc’ [-Wmissing-prototypes]
7 | void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
| ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:107:6: warning: no previous prototype for ‘wait_stub_done’ [-Wmissing-prototypes]
107 | void wait_stub_done(int pid)
| ^~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:683:6: warning: no previous prototype for ‘__switch_mm’ [-Wmissing-prototypes]
683 | void __switch_mm(struct mm_id *mm_idp)
| ^~~~~~~~~~~
../arch/x86/um/ptrace_64.c:111:5: warning: no previous prototype for ‘poke_user’ [-Wmissing-prototypes]
111 | int poke_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/x86/um/ptrace_64.c:171:5: warning: no previous prototype for ‘peek_user’ [-Wmissing-prototypes]
171 | int peek_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/um/kernel/skas/mmu.c:17:5: warning: no previous prototype for ‘init_new_context’ [-Wmissing-prototypes]
17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:60:6: warning: no previous prototype for ‘destroy_context’ [-Wmissing-prototypes]
60 | void destroy_context(struct mm_struct *mm)
| ^~~~~~~~~~~~~~~
../arch/x86/um/signal.c:560:6: warning: no previous prototype for ‘sys_rt_sigreturn’ [-Wmissing-prototypes]
560 | long sys_rt_sigreturn(void)
| ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/main.c:187:7: warning: no previous prototype for ‘__wrap_malloc’ [-Wmissing-prototypes]
187 | void *__wrap_malloc(int size)
| ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:208:7: warning: no previous prototype for ‘__wrap_calloc’ [-Wmissing-prototypes]
208 | void *__wrap_calloc(int n, int size)
| ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:222:6: warning: no previous prototype for ‘__wrap_free’ [-Wmissing-prototypes]
222 | void __wrap_free(void *ptr)
| ^~~~~~~~~~~
../arch/um/os-Linux/mem.c:28:6: warning: no previous prototype for ‘kasan_map_memory’ [-Wmissing-prototypes]
28 | void kasan_map_memory(void *start, size_t len)
| ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/mem.c:212:13: warning: no previous prototype for ‘check_tmpexec’ [-Wmissing-prototypes]
212 | void __init check_tmpexec(void)
| ^~~~~~~~~~~~~
../arch/um/kernel/skas/process.c:36:12: warning: no previous prototype for ‘start_uml’ [-Wmissing-prototypes]
36 | int __init start_uml(void)
| ^~~~~~~~~
../arch/um/os-Linux/signal.c:75:6: warning: no previous prototype for ‘sig_handler’ [-Wmissing-prototypes]
75 | void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
| ^~~~~~~~~~~
../arch/um/os-Linux/signal.c:111:6: warning: no previous prototype for ‘timer_alarm_handler’ [-Wmissing-prototypes]
111 | void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
| ^~~~~~~~~~~~~~~~~~~
../arch/um/os-Linux/start_up.c:301:12: warning: no previous prototype for ‘parse_iomem’ [-Wmissing-prototypes]
301 | int __init parse_iomem(char *str, int *add)
| ^~~~~~~~~~~
../arch/x86/um/syscalls_64.c:48:6: warning: no previous prototype for ‘arch_switch_to’ [-Wmissing-prototypes]
48 | void arch_switch_to(struct task_struct *to)
| ^~~~~~~~~~~~~~
../arch/um/kernel/mem.c:202:8: warning: no previous prototype for ‘pgd_alloc’ [-Wmissing-prototypes]
202 | pgd_t *pgd_alloc(struct mm_struct *mm)
| ^~~~~~~~~
../arch/um/kernel/mem.c:215:7: warning: no previous prototype for ‘uml_kmalloc’ [-Wmissing-prototypes]
215 | void *uml_kmalloc(int size, int flags)
| ^~~~~~~~~~~
../arch/um/kernel/process.c:51:5: warning: no previous prototype for ‘pid_to_processor_id’ [-Wmissing-prototypes]
51 | int pid_to_processor_id(int pid)
| ^~~~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:87:7: warning: no previous prototype for ‘__switch_to’ [-Wmissing-prototypes]
87 | void *__switch_to(struct task_struct *from, struct task_struct *to)
| ^~~~~~~~~~~
../arch/um/kernel/process.c:140:6: warning: no previous prototype for ‘fork_handler’ [-Wmissing-prototypes]
140 | void fork_handler(void)
| ^~~~~~~~~~~~
../arch/um/kernel/process.c:217:6: warning: no previous prototype for ‘arch_cpu_idle’ [-Wmissing-prototypes]
217 | void arch_cpu_idle(void)
| ^~~~~~~~~~~~~
../arch/um/kernel/process.c:253:5: warning: no previous prototype for ‘copy_to_user_proc’ [-Wmissing-prototypes]
253 | int copy_to_user_proc(void __user *to, void *from, int size)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:263:5: warning: no previous prototype for ‘clear_user_proc’ [-Wmissing-prototypes]
263 | int clear_user_proc(void __user *buf, int size)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/process.c:271:6: warning: no previous prototype for ‘set_using_sysemu’ [-Wmissing-prototypes]
271 | void set_using_sysemu(int value)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:278:5: warning: no previous prototype for ‘get_using_sysemu’ [-Wmissing-prototypes]
278 | int get_using_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:316:12: warning: no previous prototype for ‘make_proc_sysemu’ [-Wmissing-prototypes]
316 | int __init make_proc_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:348:15: warning: no previous prototype for ‘arch_align_stack’ [-Wmissing-prototypes]
348 | unsigned long arch_align_stack(unsigned long sp)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:45:6: warning: no previous prototype for ‘machine_restart’ [-Wmissing-prototypes]
45 | void machine_restart(char * __unused)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:51:6: warning: no previous prototype for ‘machine_power_off’ [-Wmissing-prototypes]
51 | void machine_power_off(void)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:57:6: warning: no previous prototype for ‘machine_halt’ [-Wmissing-prototypes]
57 | void machine_halt(void)
| ^~~~~~~~~~~~
../arch/um/kernel/tlb.c:579:6: warning: no previous prototype for ‘flush_tlb_mm_range’ [-Wmissing-prototypes]
579 | void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
| ^~~~~~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:594:6: warning: no previous prototype for ‘force_flush_all’ [-Wmissing-prototypes]
594 | void force_flush_all(void)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/um_arch.c:408:19: warning: no previous prototype for ‘read_initrd’ [-Wmissing-prototypes]
408 | int __init __weak read_initrd(void)
| ^~~~~~~~~~~
../arch/um/kernel/um_arch.c:461:7: warning: no previous prototype for ‘text_poke’ [-Wmissing-prototypes]
461 | void *text_poke(void *addr, const void *opcode, size_t len)
| ^~~~~~~~~
../arch/um/kernel/um_arch.c:473:6: warning: no previous prototype for ‘text_poke_sync’ [-Wmissing-prototypes]
473 | void text_poke_sync(void)
| ^~~~~~~~~~~~~~
../arch/um/kernel/kmsg_dump.c:60:12: warning: no previous prototype for ‘kmsg_dumper_stdout_init’ [-Wmissing-prototypes]
60 | int __init kmsg_dumper_stdout_init(void)
| ^~~~~~~~~~~~~~~~~~~~~~~
../lib/iomap.c:156:5: warning: no previous prototype for ‘ioread64_lo_hi’ [-Wmissing-prototypes]
156 | u64 ioread64_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:163:5: warning: no previous prototype for ‘ioread64_hi_lo’ [-Wmissing-prototypes]
163 | u64 ioread64_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:170:5: warning: no previous prototype for ‘ioread64be_lo_hi’ [-Wmissing-prototypes]
170 | u64 ioread64be_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:178:5: warning: no previous prototype for ‘ioread64be_hi_lo’ [-Wmissing-prototypes]
178 | u64 ioread64be_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:264:6: warning: no previous prototype for ‘iowrite64_lo_hi’ [-Wmissing-prototypes]
264 | void iowrite64_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:272:6: warning: no previous prototype for ‘iowrite64_hi_lo’ [-Wmissing-prototypes]
272 | void iowrite64_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:280:6: warning: no previous prototype for ‘iowrite64be_lo_hi’ [-Wmissing-prototypes]
280 | void iowrite64be_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
../lib/iomap.c:288:6: warning: no previous prototype for ‘iowrite64be_hi_lo’ [-Wmissing-prototypes]
288 | void iowrite64be_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
stty: 'standard input': Inappropriate ioctl for device
[07:25:06] Starting KUnit Kernel (1/1)...
[07:25:06] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[07:25:06] =================== guc_dbm (7 subtests) ===================
[07:25:06] [PASSED] test_empty
[07:25:06] [PASSED] test_default
[07:25:06] ======================== test_size ========================
[07:25:06] [PASSED] 4
[07:25:06] [PASSED] 8
[07:25:06] [PASSED] 32
[07:25:06] [PASSED] 256
[07:25:06] ==================== [PASSED] test_size ====================
[07:25:06] ======================= test_reuse ========================
[07:25:06] [PASSED] 4
[07:25:06] [PASSED] 8
[07:25:06] [PASSED] 32
[07:25:06] [PASSED] 256
[07:25:06] =================== [PASSED] test_reuse ====================
[07:25:06] =================== test_range_overlap ====================
[07:25:06] [PASSED] 4
[07:25:06] [PASSED] 8
[07:25:06] [PASSED] 32
[07:25:06] [PASSED] 256
[07:25:06] =============== [PASSED] test_range_overlap ================
[07:25:06] =================== test_range_compact ====================
[07:25:06] [PASSED] 4
[07:25:06] [PASSED] 8
[07:25:06] [PASSED] 32
[07:25:06] [PASSED] 256
[07:25:06] =============== [PASSED] test_range_compact ================
[07:25:06] ==================== test_range_spare =====================
[07:25:06] [PASSED] 4
[07:25:06] [PASSED] 8
[07:25:06] [PASSED] 32
[07:25:06] [PASSED] 256
[07:25:06] ================ [PASSED] test_range_spare =================
[07:25:06] ===================== [PASSED] guc_dbm =====================
[07:25:06] =================== guc_idm (6 subtests) ===================
[07:25:06] [PASSED] bad_init
[07:25:06] [PASSED] no_init
[07:25:06] [PASSED] init_fini
[07:25:06] [PASSED] check_used
[07:25:06] [PASSED] check_quota
[07:25:06] [PASSED] check_all
[07:25:06] ===================== [PASSED] guc_idm =====================
[07:25:06] ================== no_relay (3 subtests) ===================
[07:25:06] [PASSED] xe_drops_guc2pf_if_not_ready
[07:25:06] [PASSED] xe_drops_guc2vf_if_not_ready
[07:25:06] [PASSED] xe_rejects_send_if_not_ready
[07:25:06] ==================== [PASSED] no_relay =====================
[07:25:06] ================== pf_relay (14 subtests) ==================
[07:25:06] [PASSED] pf_rejects_guc2pf_too_short
[07:25:06] [PASSED] pf_rejects_guc2pf_too_long
[07:25:06] [PASSED] pf_rejects_guc2pf_no_payload
[07:25:06] [PASSED] pf_fails_no_payload
[07:25:06] [PASSED] pf_fails_bad_origin
[07:25:06] [PASSED] pf_fails_bad_type
[07:25:06] [PASSED] pf_txn_reports_error
[07:25:06] [PASSED] pf_txn_sends_pf2guc
[07:25:06] [PASSED] pf_sends_pf2guc
[07:25:06] [SKIPPED] pf_loopback_nop
[07:25:06] [SKIPPED] pf_loopback_echo
[07:25:06] [SKIPPED] pf_loopback_fail
[07:25:06] [SKIPPED] pf_loopback_busy
[07:25:06] [SKIPPED] pf_loopback_retry
[07:25:06] ==================== [PASSED] pf_relay =====================
[07:25:06] ================== vf_relay (3 subtests) ===================
[07:25:06] [PASSED] vf_rejects_guc2vf_too_short
[07:25:06] [PASSED] vf_rejects_guc2vf_too_long
[07:25:06] [PASSED] vf_rejects_guc2vf_no_payload
[07:25:06] ==================== [PASSED] vf_relay =====================
[07:25:06] ================= pf_service (11 subtests) =================
[07:25:06] [PASSED] pf_negotiate_any
[07:25:06] [PASSED] pf_negotiate_base_match
[07:25:06] [PASSED] pf_negotiate_base_newer
[07:25:06] [PASSED] pf_negotiate_base_next
[07:25:06] [SKIPPED] pf_negotiate_base_older
[07:25:06] [PASSED] pf_negotiate_base_prev
[07:25:06] [PASSED] pf_negotiate_latest_match
[07:25:06] [PASSED] pf_negotiate_latest_newer
[07:25:06] [PASSED] pf_negotiate_latest_next
[07:25:06] [SKIPPED] pf_negotiate_latest_older
[07:25:06] [SKIPPED] pf_negotiate_latest_prev
[07:25:06] =================== [PASSED] pf_service ====================
[07:25:06] ===================== lmtt (1 subtest) =====================
[07:25:06] ======================== test_ops =========================
[07:25:06] [PASSED] 2-level
[07:25:06] [PASSED] multi-level
[07:25:06] ==================== [PASSED] test_ops =====================
[07:25:06] ====================== [PASSED] lmtt =======================
[07:25:06] ==================== xe_bo (3 subtests) ====================
[07:25:06] [SKIPPED] xe_ccs_migrate_kunit
[07:25:06] [SKIPPED] xe_bo_evict_kunit
[07:25:06] [SKIPPED] xe_bo_shrink_kunit
[07:25:06] ===================== [SKIPPED] xe_bo ======================
[07:25:06] ================== xe_dma_buf (1 subtest) ==================
[07:25:06] [SKIPPED] xe_dma_buf_kunit
[07:25:06] =================== [SKIPPED] xe_dma_buf ===================
[07:25:06] ================== xe_migrate (1 subtest) ==================
[07:25:06] [SKIPPED] xe_migrate_sanity_kunit
[07:25:06] =================== [SKIPPED] xe_migrate ===================
[07:25:06] =================== xe_mocs (2 subtests) ===================
[07:25:06] [SKIPPED] xe_live_mocs_kernel_kunit
[07:25:06] [SKIPPED] xe_live_mocs_reset_kunit
[07:25:06] ==================== [SKIPPED] xe_mocs =====================
[07:25:06] ==================== args (11 subtests) ====================
[07:25:06] [PASSED] count_args_test
[07:25:06] [PASSED] call_args_example
[07:25:06] [PASSED] call_args_test
[07:25:06] [PASSED] drop_first_arg_example
[07:25:06] [PASSED] drop_first_arg_test
[07:25:06] [PASSED] first_arg_example
[07:25:06] [PASSED] first_arg_test
[07:25:06] [PASSED] last_arg_example
[07:25:06] [PASSED] last_arg_test
[07:25:06] [PASSED] pick_arg_example
[07:25:06] [PASSED] sep_comma_example
[07:25:06] ====================== [PASSED] args =======================
[07:25:06] =================== xe_pci (2 subtests) ====================
[07:25:06] [PASSED] xe_gmdid_graphics_ip
[07:25:06] [PASSED] xe_gmdid_media_ip
[07:25:06] ===================== [PASSED] xe_pci ======================
[07:25:06] ==================== xe_rtp (1 subtest) ====================
[07:25:06] ================== xe_rtp_process_tests ===================
[07:25:06] [PASSED] coalesce-same-reg
[07:25:06] [PASSED] no-match-no-add
[07:25:06] [PASSED] no-match-no-add-multiple-rules
[07:25:06] [PASSED] two-regs-two-entries
[07:25:06] [PASSED] clr-one-set-other
[07:25:06] [PASSED] set-field
[07:25:06] [PASSED] conflict-duplicate
[07:25:06] [PASSED] conflict-not-disjoint
[07:25:06] [PASSED] conflict-reg-type
[07:25:06] ============== [PASSED] xe_rtp_process_tests ===============
[07:25:06] ===================== [PASSED] xe_rtp ======================
[07:25:06] ==================== xe_wa (1 subtest) =====================
[07:25:06] ======================== xe_wa_gt =========================
[07:25:06] [PASSED] TIGERLAKE (B0)
[07:25:06] [PASSED] DG1 (A0)
[07:25:06] [PASSED] DG1 (B0)
[07:25:06] [PASSED] ALDERLAKE_S (A0)
[07:25:06] [PASSED] ALDERLAKE_S (B0)
[07:25:06] [PASSED] ALDERLAKE_S (C0)
[07:25:06] [PASSED] ALDERLAKE_S (D0)
[07:25:06] [PASSED] ALDERLAKE_P (A0)
[07:25:06] [PASSED] ALDERLAKE_P (B0)
[07:25:06] [PASSED] ALDERLAKE_P (C0)
[07:25:06] [PASSED] ALDERLAKE_S_RPLS (D0)
[07:25:06] [PASSED] ALDERLAKE_P_RPLU (E0)
[07:25:06] [PASSED] DG2_G10 (C0)
[07:25:06] [PASSED] DG2_G11 (B1)
[07:25:06] [PASSED] DG2_G12 (A1)
[07:25:06] [PASSED] METEORLAKE (g:A0, m:A0)
[07:25:06] [PASSED] METEORLAKE (g:A0, m:A0)
[07:25:06] [PASSED] METEORLAKE (g:A0, m:A0)
[07:25:06] [PASSED] LUNARLAKE (g:A0, m:A0)
[07:25:06] [PASSED] LUNARLAKE (g:B0, m:A0)
[07:25:06] ==================== [PASSED] xe_wa_gt =====================
[07:25:06] ====================== [PASSED] xe_wa ======================
[07:25:06] ============================================================
[07:25:06] Testing complete. Ran 110 tests: passed: 95, skipped: 15
[07:25:06] Elapsed time: 30.215s total, 4.278s configuring, 25.667s building, 0.222s running
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/tests/.kunitconfig
[07:25:06] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[07:25:08] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make ARCH=um O=.kunit --jobs=48
In file included from ../arch/um/kernel/asm-offsets.c:1:
../arch/x86/um/shared/sysdep/kernel-offsets.h:9:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
9 | void foo(void)
| ^~~
../arch/x86/um/ptrace_64.c:111:5: warning: no previous prototype for ‘poke_user’ [-Wmissing-prototypes]
111 | int poke_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/x86/um/ptrace_64.c:171:5: warning: no previous prototype for ‘peek_user’ [-Wmissing-prototypes]
171 | int peek_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/um/kernel/mem.c:202:8: warning: no previous prototype for ‘pgd_alloc’ [-Wmissing-prototypes]
202 | pgd_t *pgd_alloc(struct mm_struct *mm)
| ^~~~~~~~~
../arch/um/kernel/mem.c:215:7: warning: no previous prototype for ‘uml_kmalloc’ [-Wmissing-prototypes]
215 | void *uml_kmalloc(int size, int flags)
| ^~~~~~~~~~~
../arch/x86/um/signal.c:560:6: warning: no previous prototype for ‘sys_rt_sigreturn’ [-Wmissing-prototypes]
560 | long sys_rt_sigreturn(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:51:5: warning: no previous prototype for ‘pid_to_processor_id’ [-Wmissing-prototypes]
51 | int pid_to_processor_id(int pid)
| ^~~~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:87:7: warning: no previous prototype for ‘__switch_to’ [-Wmissing-prototypes]
87 | void *__switch_to(struct task_struct *from, struct task_struct *to)
| ^~~~~~~~~~~
../arch/um/kernel/process.c:140:6: warning: no previous prototype for ‘fork_handler’ [-Wmissing-prototypes]
140 | void fork_handler(void)
| ^~~~~~~~~~~~
../arch/um/kernel/process.c:217:6: warning: no previous prototype for ‘arch_cpu_idle’ [-Wmissing-prototypes]
217 | void arch_cpu_idle(void)
| ^~~~~~~~~~~~~
../arch/um/kernel/process.c:253:5: warning: no previous prototype for ‘copy_to_user_proc’ [-Wmissing-prototypes]
253 | int copy_to_user_proc(void __user *to, void *from, int size)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:263:5: warning: no previous prototype for ‘clear_user_proc’ [-Wmissing-prototypes]
263 | int clear_user_proc(void __user *buf, int size)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/process.c:271:6: warning: no previous prototype for ‘set_using_sysemu’ [-Wmissing-prototypes]
271 | void set_using_sysemu(int value)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:278:5: warning: no previous prototype for ‘get_using_sysemu’ [-Wmissing-prototypes]
278 | int get_using_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:316:12: warning: no previous prototype for ‘make_proc_sysemu’ [-Wmissing-prototypes]
316 | int __init make_proc_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:348:15: warning: no previous prototype for ‘arch_align_stack’ [-Wmissing-prototypes]
348 | unsigned long arch_align_stack(unsigned long sp)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:45:6: warning: no previous prototype for ‘machine_restart’ [-Wmissing-prototypes]
45 | void machine_restart(char * __unused)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:51:6: warning: no previous prototype for ‘machine_power_off’ [-Wmissing-prototypes]
51 | void machine_power_off(void)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:57:6: warning: no previous prototype for ‘machine_halt’ [-Wmissing-prototypes]
57 | void machine_halt(void)
| ^~~~~~~~~~~~
../arch/x86/um/syscalls_64.c:48:6: warning: no previous prototype for ‘arch_switch_to’ [-Wmissing-prototypes]
48 | void arch_switch_to(struct task_struct *to)
| ^~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:579:6: warning: no previous prototype for ‘flush_tlb_mm_range’ [-Wmissing-prototypes]
579 | void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
| ^~~~~~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:594:6: warning: no previous prototype for ‘force_flush_all’ [-Wmissing-prototypes]
594 | void force_flush_all(void)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/um_arch.c:408:19: warning: no previous prototype for ‘read_initrd’ [-Wmissing-prototypes]
408 | int __init __weak read_initrd(void)
| ^~~~~~~~~~~
../arch/um/kernel/um_arch.c:461:7: warning: no previous prototype for ‘text_poke’ [-Wmissing-prototypes]
461 | void *text_poke(void *addr, const void *opcode, size_t len)
| ^~~~~~~~~
../arch/um/kernel/um_arch.c:473:6: warning: no previous prototype for ‘text_poke_sync’ [-Wmissing-prototypes]
473 | void text_poke_sync(void)
| ^~~~~~~~~~~~~~
../arch/um/kernel/kmsg_dump.c:60:12: warning: no previous prototype for ‘kmsg_dumper_stdout_init’ [-Wmissing-prototypes]
60 | int __init kmsg_dumper_stdout_init(void)
| ^~~~~~~~~~~~~~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:17:5: warning: no previous prototype for ‘init_new_context’ [-Wmissing-prototypes]
17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:60:6: warning: no previous prototype for ‘destroy_context’ [-Wmissing-prototypes]
60 | void destroy_context(struct mm_struct *mm)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/skas/process.c:36:12: warning: no previous prototype for ‘start_uml’ [-Wmissing-prototypes]
36 | int __init start_uml(void)
| ^~~~~~~~~
../lib/iomap.c:156:5: warning: no previous prototype for ‘ioread64_lo_hi’ [-Wmissing-prototypes]
156 | u64 ioread64_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:163:5: warning: no previous prototype for ‘ioread64_hi_lo’ [-Wmissing-prototypes]
163 | u64 ioread64_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:170:5: warning: no previous prototype for ‘ioread64be_lo_hi’ [-Wmissing-prototypes]
170 | u64 ioread64be_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:178:5: warning: no previous prototype for ‘ioread64be_hi_lo’ [-Wmissing-prototypes]
178 | u64 ioread64be_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:264:6: warning: no previous prototype for ‘iowrite64_lo_hi’ [-Wmissing-prototypes]
264 | void iowrite64_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:272:6: warning: no previous prototype for ‘iowrite64_hi_lo’ [-Wmissing-prototypes]
272 | void iowrite64_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:280:6: warning: no previous prototype for ‘iowrite64be_lo_hi’ [-Wmissing-prototypes]
280 | void iowrite64be_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
../lib/iomap.c:288:6: warning: no previous prototype for ‘iowrite64be_hi_lo’ [-Wmissing-prototypes]
288 | void iowrite64be_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
[07:25:30] Starting KUnit Kernel (1/1)...
[07:25:30] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[07:25:30] ============ drm_test_pick_cmdline (2 subtests) ============
[07:25:30] [PASSED] drm_test_pick_cmdline_res_1920_1080_60
[07:25:30] =============== drm_test_pick_cmdline_named ===============
[07:25:30] [PASSED] NTSC
[07:25:30] [PASSED] NTSC-J
[07:25:30] [PASSED] PAL
[07:25:30] [PASSED] PAL-M
[07:25:30] =========== [PASSED] drm_test_pick_cmdline_named ===========
[07:25:30] ============== [PASSED] drm_test_pick_cmdline ==============
[07:25:30] ================== drm_buddy (7 subtests) ==================
[07:25:30] [PASSED] drm_test_buddy_alloc_limit
[07:25:30] [PASSED] drm_test_buddy_alloc_optimistic
[07:25:30] [PASSED] drm_test_buddy_alloc_pessimistic
[07:25:30] [PASSED] drm_test_buddy_alloc_pathological
[07:25:30] [PASSED] drm_test_buddy_alloc_contiguous
[07:25:30] [PASSED] drm_test_buddy_alloc_clear
[07:25:30] [PASSED] drm_test_buddy_alloc_range_bias
[07:25:30] ==================== [PASSED] drm_buddy ====================
[07:25:30] ============= drm_cmdline_parser (40 subtests) =============
[07:25:30] [PASSED] drm_test_cmdline_force_d_only
[07:25:30] [PASSED] drm_test_cmdline_force_D_only_dvi
[07:25:30] [PASSED] drm_test_cmdline_force_D_only_hdmi
[07:25:30] [PASSED] drm_test_cmdline_force_D_only_not_digital
[07:25:30] [PASSED] drm_test_cmdline_force_e_only
[07:25:30] [PASSED] drm_test_cmdline_res
[07:25:30] [PASSED] drm_test_cmdline_res_vesa
[07:25:30] [PASSED] drm_test_cmdline_res_vesa_rblank
[07:25:30] [PASSED] drm_test_cmdline_res_rblank
[07:25:30] [PASSED] drm_test_cmdline_res_bpp
[07:25:30] [PASSED] drm_test_cmdline_res_refresh
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_margins
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_force_off
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_analog
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_digital
[07:25:30] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on
[07:25:30] [PASSED] drm_test_cmdline_res_margins_force_on
[07:25:30] [PASSED] drm_test_cmdline_res_vesa_margins
[07:25:30] [PASSED] drm_test_cmdline_name
[07:25:30] [PASSED] drm_test_cmdline_name_bpp
[07:25:30] [PASSED] drm_test_cmdline_name_option
[07:25:30] [PASSED] drm_test_cmdline_name_bpp_option
[07:25:30] [PASSED] drm_test_cmdline_rotate_0
[07:25:30] [PASSED] drm_test_cmdline_rotate_90
[07:25:30] [PASSED] drm_test_cmdline_rotate_180
[07:25:30] [PASSED] drm_test_cmdline_rotate_270
[07:25:30] [PASSED] drm_test_cmdline_hmirror
[07:25:30] [PASSED] drm_test_cmdline_vmirror
[07:25:30] [PASSED] drm_test_cmdline_margin_options
[07:25:30] [PASSED] drm_test_cmdline_multiple_options
[07:25:30] [PASSED] drm_test_cmdline_bpp_extra_and_option
[07:25:30] [PASSED] drm_test_cmdline_extra_and_option
[07:25:30] [PASSED] drm_test_cmdline_freestanding_options
[07:25:30] [PASSED] drm_test_cmdline_freestanding_force_e_and_options
[07:25:30] [PASSED] drm_test_cmdline_panel_orientation
[07:25:30] ================ drm_test_cmdline_invalid =================
[07:25:30] [PASSED] margin_only
[07:25:30] [PASSED] interlace_only
[07:25:30] [PASSED] res_missing_x
[07:25:30] [PASSED] res_missing_y
[07:25:30] [PASSED] res_bad_y
[07:25:30] [PASSED] res_missing_y_bpp
[07:25:30] [PASSED] res_bad_bpp
[07:25:30] [PASSED] res_bad_refresh
[07:25:30] [PASSED] res_bpp_refresh_force_on_off
[07:25:30] [PASSED] res_invalid_mode
[07:25:30] [PASSED] res_bpp_wrong_place_mode
[07:25:30] [PASSED] name_bpp_refresh
[07:25:30] [PASSED] name_refresh
[07:25:30] [PASSED] name_refresh_wrong_mode
[07:25:30] [PASSED] name_refresh_invalid_mode
[07:25:30] [PASSED] rotate_multiple
[07:25:30] [PASSED] rotate_invalid_val
[07:25:30] [PASSED] rotate_truncated
[07:25:30] [PASSED] invalid_option
[07:25:30] [PASSED] invalid_tv_option
[07:25:30] [PASSED] truncated_tv_option
[07:25:30] ============ [PASSED] drm_test_cmdline_invalid =============
[07:25:30] =============== drm_test_cmdline_tv_options ===============
[07:25:30] [PASSED] NTSC
[07:25:30] [PASSED] NTSC_443
[07:25:30] [PASSED] NTSC_J
[07:25:30] [PASSED] PAL
[07:25:30] [PASSED] PAL_M
[07:25:30] [PASSED] PAL_N
[07:25:30] [PASSED] SECAM
[07:25:30] =========== [PASSED] drm_test_cmdline_tv_options ===========
[07:25:30] =============== [PASSED] drm_cmdline_parser ================
[07:25:30] ============= drmm_connector_init (3 subtests) =============
[07:25:30] [PASSED] drm_test_drmm_connector_init
[07:25:30] [PASSED] drm_test_drmm_connector_init_null_ddc
[07:25:30] ========= drm_test_drmm_connector_init_type_valid =========
[07:25:30] [PASSED] Unknown
[07:25:30] [PASSED] VGA
[07:25:30] [PASSED] DVI-I
[07:25:30] [PASSED] DVI-D
[07:25:30] [PASSED] DVI-A
[07:25:30] [PASSED] Composite
[07:25:30] [PASSED] SVIDEO
[07:25:30] [PASSED] LVDS
[07:25:30] [PASSED] Component
[07:25:30] [PASSED] DIN
[07:25:30] [PASSED] DP
[07:25:30] [PASSED] HDMI-A
[07:25:30] [PASSED] HDMI-B
[07:25:30] [PASSED] TV
[07:25:30] [PASSED] eDP
[07:25:30] [PASSED] Virtual
[07:25:30] [PASSED] DSI
[07:25:30] [PASSED] DPI
[07:25:30] [PASSED] Writeback
[07:25:30] [PASSED] SPI
[07:25:30] [PASSED] USB
[07:25:30] ===== [PASSED] drm_test_drmm_connector_init_type_valid =====
[07:25:30] =============== [PASSED] drmm_connector_init ===============
[07:25:30] ========== drm_get_tv_mode_from_name (2 subtests) ==========
[07:25:30] ========== drm_test_get_tv_mode_from_name_valid ===========
[07:25:30] [PASSED] NTSC
[07:25:30] [PASSED] NTSC-443
[07:25:30] [PASSED] NTSC-J
[07:25:30] [PASSED] PAL
[07:25:30] [PASSED] PAL-M
[07:25:30] [PASSED] PAL-N
[07:25:30] [PASSED] SECAM
[07:25:30] ====== [PASSED] drm_test_get_tv_mode_from_name_valid =======
[07:25:30] [PASSED] drm_test_get_tv_mode_from_name_truncated
[07:25:30] ============ [PASSED] drm_get_tv_mode_from_name ============
[07:25:30] ============= drm_damage_helper (21 subtests) ==============
[07:25:30] [PASSED] drm_test_damage_iter_no_damage
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_fractional_src
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_src_moved
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_fractional_src_moved
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_not_visible
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_no_crtc
[07:25:30] [PASSED] drm_test_damage_iter_no_damage_no_fb
[07:25:30] [PASSED] drm_test_damage_iter_simple_damage
[07:25:30] [PASSED] drm_test_damage_iter_single_damage
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_intersect_src
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_outside_src
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_fractional_src
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_intersect_fractional_src
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_outside_fractional_src
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_src_moved
[07:25:30] [PASSED] drm_test_damage_iter_single_damage_fractional_src_moved
[07:25:30] [PASSED] drm_test_damage_iter_damage
[07:25:30] [PASSED] drm_test_damage_iter_damage_one_intersect
[07:25:30] [PASSED] drm_test_damage_iter_damage_one_outside
[07:25:30] [PASSED] drm_test_damage_iter_damage_src_moved
[07:25:30] [PASSED] drm_test_damage_iter_damage_not_visible
[07:25:30] ================ [PASSED] drm_damage_helper ================
[07:25:30] ============== drm_dp_mst_helper (3 subtests) ==============
[07:25:30] ============== drm_test_dp_mst_calc_pbn_mode ==============
[07:25:30] [PASSED] Clock 154000 BPP 30 DSC disabled
[07:25:30] [PASSED] Clock 234000 BPP 30 DSC disabled
[07:25:30] [PASSED] Clock 297000 BPP 24 DSC disabled
[07:25:30] [PASSED] Clock 332880 BPP 24 DSC enabled
[07:25:30] [PASSED] Clock 324540 BPP 24 DSC enabled
[07:25:30] ========== [PASSED] drm_test_dp_mst_calc_pbn_mode ==========
[07:25:30] ============== drm_test_dp_mst_calc_pbn_div ===============
[07:25:30] [PASSED] Link rate 2000000 lane count 4
[07:25:30] [PASSED] Link rate 2000000 lane count 2
[07:25:30] [PASSED] Link rate 2000000 lane count 1
[07:25:30] [PASSED] Link rate 1350000 lane count 4
[07:25:30] [PASSED] Link rate 1350000 lane count 2
[07:25:30] [PASSED] Link rate 1350000 lane count 1
[07:25:30] [PASSED] Link rate 1000000 lane count 4
[07:25:30] [PASSED] Link rate 1000000 lane count 2
[07:25:30] [PASSED] Link rate 1000000 lane count 1
[07:25:30] [PASSED] Link rate 810000 lane count 4
[07:25:30] [PASSED] Link rate 810000 lane count 2
[07:25:30] [PASSED] Link rate 810000 lane count 1
[07:25:30] [PASSED] Link rate 540000 lane count 4
[07:25:30] [PASSED] Link rate 540000 lane count 2
[07:25:30] [PASSED] Link rate 540000 lane count 1
[07:25:30] [PASSED] Link rate 270000 lane count 4
[07:25:30] [PASSED] Link rate 270000 lane count 2
[07:25:30] [PASSED] Link rate 270000 lane count 1
[07:25:30] [PASSED] Link rate 162000 lane count 4
[07:25:30] [PASSED] Link rate 162000 lane count 2
[07:25:30] [PASSED] Link rate 162000 lane count 1
[07:25:30] ========== [PASSED] drm_test_dp_mst_calc_pbn_div ===========
[07:25:30] ========= drm_test_dp_mst_sideband_msg_req_decode =========
[07:25:30] [PASSED] DP_ENUM_PATH_RESOURCES with port number
[07:25:30] [PASSED] DP_POWER_UP_PHY with port number
[07:25:30] [PASSED] DP_POWER_DOWN_PHY with port number
[07:25:30] [PASSED] DP_ALLOCATE_PAYLOAD with SDP stream sinks
[07:25:30] [PASSED] DP_ALLOCATE_PAYLOAD with port number
[07:25:30] [PASSED] DP_ALLOCATE_PAYLOAD with VCPI
[07:25:30] [PASSED] DP_ALLOCATE_PAYLOAD with PBN
[07:25:30] [PASSED] DP_QUERY_PAYLOAD with port number
[07:25:30] [PASSED] DP_QUERY_PAYLOAD with VCPI
[07:25:30] [PASSED] DP_REMOTE_DPCD_READ with port number
[07:25:30] [PASSED] DP_REMOTE_DPCD_READ with DPCD address
[07:25:30] [PASSED] DP_REMOTE_DPCD_READ with max number of bytes
[07:25:30] [PASSED] DP_REMOTE_DPCD_WRITE with port number
[07:25:30] [PASSED] DP_REMOTE_DPCD_WRITE with DPCD address
[07:25:30] [PASSED] DP_REMOTE_DPCD_WRITE with data array
[07:25:30] [PASSED] DP_REMOTE_I2C_READ with port number
[07:25:30] [PASSED] DP_REMOTE_I2C_READ with I2C device ID
[07:25:30] [PASSED] DP_REMOTE_I2C_READ with transactions array
[07:25:30] [PASSED] DP_REMOTE_I2C_WRITE with port number
[07:25:30] [PASSED] DP_REMOTE_I2C_WRITE with I2C device ID
[07:25:30] [PASSED] DP_REMOTE_I2C_WRITE with data array
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream ID
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with client ID
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream event
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with valid stream event
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream behavior
[07:25:30] [PASSED] DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior
[07:25:30] ===== [PASSED] drm_test_dp_mst_sideband_msg_req_decode =====
[07:25:30] ================ [PASSED] drm_dp_mst_helper ================
[07:25:30] ================== drm_exec (7 subtests) ===================
[07:25:30] [PASSED] sanitycheck
[07:25:30] [PASSED] test_lock
[07:25:30] [PASSED] test_lock_unlock
[07:25:30] [PASSED] test_duplicates
[07:25:30] [PASSED] test_prepare
[07:25:30] [PASSED] test_prepare_array
[07:25:30] [PASSED] test_multiple_loops
[07:25:30] ==================== [PASSED] drm_exec =====================
[07:25:30] =========== drm_format_helper_test (17 subtests) ===========
[07:25:30] ============== drm_test_fb_xrgb8888_to_gray8 ==============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ========== [PASSED] drm_test_fb_xrgb8888_to_gray8 ==========
[07:25:30] ============= drm_test_fb_xrgb8888_to_rgb332 ==============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb332 ==========
[07:25:30] ============= drm_test_fb_xrgb8888_to_rgb565 ==============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb565 ==========
[07:25:30] ============ drm_test_fb_xrgb8888_to_xrgb1555 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_xrgb1555 =========
[07:25:30] ============ drm_test_fb_xrgb8888_to_argb1555 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_argb1555 =========
[07:25:30] ============ drm_test_fb_xrgb8888_to_rgba5551 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_rgba5551 =========
[07:25:30] ============= drm_test_fb_xrgb8888_to_rgb888 ==============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb888 ==========
[07:25:30] ============ drm_test_fb_xrgb8888_to_argb8888 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_argb8888 =========
[07:25:30] =========== drm_test_fb_xrgb8888_to_xrgb2101010 ===========
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======= [PASSED] drm_test_fb_xrgb8888_to_xrgb2101010 =======
[07:25:30] =========== drm_test_fb_xrgb8888_to_argb2101010 ===========
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======= [PASSED] drm_test_fb_xrgb8888_to_argb2101010 =======
[07:25:30] ============== drm_test_fb_xrgb8888_to_mono ===============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ========== [PASSED] drm_test_fb_xrgb8888_to_mono ===========
[07:25:30] ==================== drm_test_fb_swab =====================
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ================ [PASSED] drm_test_fb_swab =================
[07:25:30] ============ drm_test_fb_xrgb8888_to_xbgr8888 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_xbgr8888 =========
[07:25:30] ============ drm_test_fb_xrgb8888_to_abgr8888 =============
[07:25:30] [PASSED] single_pixel_source_buffer
[07:25:30] [PASSED] single_pixel_clip_rectangle
[07:25:30] [PASSED] well_known_colors
[07:25:30] [PASSED] destination_pitch
[07:25:30] ======== [PASSED] drm_test_fb_xrgb8888_to_abgr8888 =========
[07:25:30] ================= drm_test_fb_clip_offset =================
[07:25:30] [PASSED] pass through
[07:25:30] [PASSED] horizontal offset
[07:25:30] [PASSED] vertical offset
[07:25:30] [PASSED] horizontal and vertical offset
[07:25:30] [PASSED] horizontal offset (custom pitch)
[07:25:30] [PASSED] vertical offset (custom pitch)
[07:25:30] [PASSED] horizontal and vertical offset (custom pitch)
[07:25:30] ============= [PASSED] drm_test_fb_clip_offset =============
[07:25:30] ============== drm_test_fb_build_fourcc_list ==============
[07:25:30] [PASSED] no native formats
[07:25:30] [PASSED] XRGB8888 as native format
[07:25:30] [PASSED] remove duplicates
[07:25:30] [PASSED] convert alpha formats
[07:25:30] [PASSED] random formats
[07:25:30] ========== [PASSED] drm_test_fb_build_fourcc_list ==========
[07:25:30] =================== drm_test_fb_memcpy ====================
[07:25:30] [PASSED] single_pixel_source_buffer: XR24 little-endian (0x34325258)
[07:25:30] [PASSED] single_pixel_source_buffer: XRA8 little-endian (0x38415258)
[07:25:30] [PASSED] single_pixel_source_buffer: YU24 little-endian (0x34325559)
[07:25:30] [PASSED] single_pixel_clip_rectangle: XB24 little-endian (0x34324258)
[07:25:30] [PASSED] single_pixel_clip_rectangle: XRA8 little-endian (0x38415258)
[07:25:30] [PASSED] single_pixel_clip_rectangle: YU24 little-endian (0x34325559)
[07:25:30] [PASSED] well_known_colors: XB24 little-endian (0x34324258)
[07:25:30] [PASSED] well_known_colors: XRA8 little-endian (0x38415258)
[07:25:30] [PASSED] well_known_colors: YU24 little-endian (0x34325559)
[07:25:30] [PASSED] destination_pitch: XB24 little-endian (0x34324258)
[07:25:30] [PASSED] destination_pitch: XRA8 little-endian (0x38415258)
[07:25:30] [PASSED] destination_pitch: YU24 little-endian (0x34325559)
[07:25:30] =============== [PASSED] drm_test_fb_memcpy ================
[07:25:30] ============= [PASSED] drm_format_helper_test ==============
[07:25:30] ================= drm_format (18 subtests) =================
[07:25:30] [PASSED] drm_test_format_block_width_invalid
[07:25:30] [PASSED] drm_test_format_block_width_one_plane
[07:25:30] [PASSED] drm_test_format_block_width_two_plane
[07:25:30] [PASSED] drm_test_format_block_width_three_plane
[07:25:30] [PASSED] drm_test_format_block_width_tiled
[07:25:30] [PASSED] drm_test_format_block_height_invalid
[07:25:30] [PASSED] drm_test_format_block_height_one_plane
[07:25:30] [PASSED] drm_test_format_block_height_two_plane
[07:25:30] [PASSED] drm_test_format_block_height_three_plane
[07:25:30] [PASSED] drm_test_format_block_height_tiled
[07:25:30] [PASSED] drm_test_format_min_pitch_invalid
[07:25:30] [PASSED] drm_test_format_min_pitch_one_plane_8bpp
[07:25:30] [PASSED] drm_test_format_min_pitch_one_plane_16bpp
[07:25:30] [PASSED] drm_test_format_min_pitch_one_plane_24bpp
[07:25:30] [PASSED] drm_test_format_min_pitch_one_plane_32bpp
[07:25:30] [PASSED] drm_test_format_min_pitch_two_plane
[07:25:30] [PASSED] drm_test_format_min_pitch_three_plane_8bpp
[07:25:30] [PASSED] drm_test_format_min_pitch_tiled
[07:25:30] =================== [PASSED] drm_format ====================
[07:25:30] =============== drm_framebuffer (1 subtest) ================
[07:25:30] =============== drm_test_framebuffer_create ===============
[07:25:30] [PASSED] ABGR8888 normal sizes
[07:25:30] [PASSED] ABGR8888 max sizes
[07:25:30] [PASSED] ABGR8888 pitch greater than min required
[07:25:30] [PASSED] ABGR8888 pitch less than min required
[07:25:30] [PASSED] ABGR8888 Invalid width
[07:25:30] [PASSED] ABGR8888 Invalid buffer handle
[07:25:30] [PASSED] No pixel format
[07:25:30] [PASSED] ABGR8888 Width 0
[07:25:30] [PASSED] ABGR8888 Height 0
[07:25:30] [PASSED] ABGR8888 Out of bound height * pitch combination
[07:25:30] [PASSED] ABGR8888 Large buffer offset
[07:25:30] [PASSED] ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers
[07:25:30] [PASSED] ABGR8888 Valid buffer modifier
[07:25:30] [PASSED] ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
[07:25:30] [PASSED] ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] NV12 Normal sizes
[07:25:30] [PASSED] NV12 Max sizes
[07:25:30] [PASSED] NV12 Invalid pitch
[07:25:30] [PASSED] NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag
[07:25:30] [PASSED] NV12 different modifier per-plane
[07:25:30] [PASSED] NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
[07:25:30] [PASSED] NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] NV12 Modifier for inexistent plane
[07:25:30] [PASSED] NV12 Handle for inexistent plane
[07:25:30] [PASSED] NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] YVU420 DRM_MODE_FB_MODIFIERS set without modifier
[07:25:30] [PASSED] YVU420 Normal sizes
[07:25:30] [PASSED] YVU420 Max sizes
[07:25:30] [PASSED] YVU420 Invalid pitch
[07:25:30] [PASSED] YVU420 Different pitches
[07:25:30] [PASSED] YVU420 Different buffer offsets/pitches
[07:25:30] [PASSED] YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS
[07:25:30] [PASSED] YVU420 Valid modifier
[07:25:30] [PASSED] YVU420 Different modifiers per plane
[07:25:30] [PASSED] YVU420 Modifier for inexistent plane
[07:25:30] [PASSED] X0L2 Normal sizes
[07:25:30] [PASSED] X0L2 Max sizes
[07:25:30] [PASSED] X0L2 Invalid pitch
[07:25:30] [PASSED] X0L2 Pitch greater than minimum required
[07:25:30] [PASSED] X0L2 Handle for inexistent plane
[07:25:30] [PASSED] X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set
[07:25:30] [PASSED] X0L2 Modifier without DRM_MODE_FB_MODIFIERS set
[07:25:30] [PASSED] X0L2 Valid modifier
[07:25:30] [PASSED] X0L2 Modifier for inexistent plane
[07:25:30] =========== [PASSED] drm_test_framebuffer_create ===========
[07:25:30] ================= [PASSED] drm_framebuffer =================
[07:25:30] ================ drm_gem_shmem (8 subtests) ================
[07:25:30] [PASSED] drm_gem_shmem_test_obj_create
[07:25:30] [PASSED] drm_gem_shmem_test_obj_create_private
[07:25:30] [PASSED] drm_gem_shmem_test_pin_pages
[07:25:30] [PASSED] drm_gem_shmem_test_vmap
[07:25:30] [PASSED] drm_gem_shmem_test_get_pages_sgt
[07:25:30] [PASSED] drm_gem_shmem_test_get_sg_table
[07:25:30] [PASSED] drm_gem_shmem_test_madvise
[07:25:30] [PASSED] drm_gem_shmem_test_purge
[07:25:30] ================== [PASSED] drm_gem_shmem ==================
[07:25:30] ================= drm_managed (2 subtests) =================
[07:25:30] [PASSED] drm_test_managed_release_action
[07:25:30] [PASSED] drm_test_managed_run_action
[07:25:30] =================== [PASSED] drm_managed ===================
[07:25:30] =================== drm_mm (6 subtests) ====================
[07:25:30] [PASSED] drm_test_mm_init
[07:25:30] [PASSED] drm_test_mm_debug
[07:25:30] [PASSED] drm_test_mm_align32
[07:25:30] [PASSED] drm_test_mm_align64
[07:25:30] [PASSED] drm_test_mm_lowest
[07:25:30] [PASSED] drm_test_mm_highest
[07:25:30] ===================== [PASSED] drm_mm ======================
[07:25:30] ============= drm_modes_analog_tv (4 subtests) =============
[07:25:30] [PASSED] drm_test_modes_analog_tv_ntsc_480i
[07:25:30] [PASSED] drm_test_modes_analog_tv_ntsc_480i_inlined
[07:25:30] [PASSED] drm_test_modes_analog_tv_pal_576i
[07:25:30] [PASSED] drm_test_modes_analog_tv_pal_576i_inlined
[07:25:30] =============== [PASSED] drm_modes_analog_tv ===============
[07:25:30] ============== drm_plane_helper (2 subtests) ===============
[07:25:30] =============== drm_test_check_plane_state ================
[07:25:30] [PASSED] clipping_simple
[07:25:30] [PASSED] clipping_rotate_reflect
[07:25:30] [PASSED] positioning_simple
[07:25:30] [PASSED] upscaling
[07:25:30] [PASSED] downscaling
[07:25:30] [PASSED] rounding1
[07:25:30] [PASSED] rounding2
[07:25:30] [PASSED] rounding3
[07:25:30] [PASSED] rounding4
[07:25:30] =========== [PASSED] drm_test_check_plane_state ============
[07:25:30] =========== drm_test_check_invalid_plane_state ============
[07:25:30] [PASSED] positioning_invalid
[07:25:30] [PASSED] upscaling_invalid
[07:25:30] [PASSED] downscaling_invalid
[07:25:30] ======= [PASSED] drm_test_check_invalid_plane_state ========
[07:25:30] ================ [PASSED] drm_plane_helper =================
[07:25:30] ====== drm_connector_helper_tv_get_modes (1 subtest) =======
[07:25:30] ====== drm_test_connector_helper_tv_get_modes_check =======
[07:25:30] [PASSED] None
[07:25:30] [PASSED] PAL
[07:25:30] [PASSED] NTSC
[07:25:30] [PASSED] Both, NTSC Default
[07:25:30] [PASSED] Both, PAL Default
[07:25:30] [PASSED] Both, NTSC Default, with PAL on command-line
[07:25:30] [PASSED] Both, PAL Default, with NTSC on command-line
[07:25:30] == [PASSED] drm_test_connector_helper_tv_get_modes_check ===
[07:25:30] ======== [PASSED] drm_connector_helper_tv_get_modes ========
[07:25:30] ================== drm_rect (9 subtests) ===================
[07:25:30] [PASSED] drm_test_rect_clip_scaled_div_by_zero
[07:25:30] [PASSED] drm_test_rect_clip_scaled_not_clipped
[07:25:30] [PASSED] drm_test_rect_clip_scaled_clipped
stty: 'standard input': Inappropriate ioctl for device
[07:25:30] [PASSED] drm_test_rect_clip_scaled_signed_vs_unsigned
[07:25:30] ================= drm_test_rect_intersect =================
[07:25:30] [PASSED] top-left x bottom-right: 2x2+1+1 x 2x2+0+0
[07:25:30] [PASSED] top-right x bottom-left: 2x2+0+0 x 2x2+1-1
[07:25:30] [PASSED] bottom-left x top-right: 2x2+1-1 x 2x2+0+0
[07:25:30] [PASSED] bottom-right x top-left: 2x2+0+0 x 2x2+1+1
[07:25:30] [PASSED] right x left: 2x1+0+0 x 3x1+1+0
[07:25:30] [PASSED] left x right: 3x1+1+0 x 2x1+0+0
[07:25:30] [PASSED] up x bottom: 1x2+0+0 x 1x3+0-1
[07:25:30] [PASSED] bottom x up: 1x3+0-1 x 1x2+0+0
[07:25:30] [PASSED] touching corner: 1x1+0+0 x 2x2+1+1
[07:25:30] [PASSED] touching side: 1x1+0+0 x 1x1+1+0
[07:25:30] [PASSED] equal rects: 2x2+0+0 x 2x2+0+0
[07:25:30] [PASSED] inside another: 2x2+0+0 x 1x1+1+1
[07:25:30] [PASSED] far away: 1x1+0+0 x 1x1+3+6
[07:25:30] [PASSED] points intersecting: 0x0+5+10 x 0x0+5+10
[07:25:30] [PASSED] points not intersecting: 0x0+0+0 x 0x0+5+10
[07:25:30] ============= [PASSED] drm_test_rect_intersect =============
[07:25:30] ================ drm_test_rect_calc_hscale ================
[07:25:30] [PASSED] normal use
[07:25:30] [PASSED] out of max range
[07:25:30] [PASSED] out of min range
[07:25:30] [PASSED] zero dst
[07:25:30] [PASSED] negative src
[07:25:30] [PASSED] negative dst
[07:25:30] ============ [PASSED] drm_test_rect_calc_hscale ============
[07:25:30] ================ drm_test_rect_calc_vscale ================
[07:25:30] [PASSED] normal use
[07:25:30] [PASSED] out of max range
[07:25:30] [PASSED] out of min range
[07:25:30] [PASSED] zero dst
[07:25:30] [PASSED] negative src
[07:25:30] [PASSED] negative dst
[07:25:30] ============ [PASSED] drm_test_rect_calc_vscale ============
[07:25:30] ================== drm_test_rect_rotate ===================
[07:25:30] [PASSED] reflect-x
[07:25:30] [PASSED] reflect-y
[07:25:30] [PASSED] rotate-0
[07:25:30] [PASSED] rotate-90
[07:25:30] [PASSED] rotate-180
[07:25:30] [PASSED] rotate-270
[07:25:30] ============== [PASSED] drm_test_rect_rotate ===============
[07:25:30] ================ drm_test_rect_rotate_inv =================
[07:25:30] [PASSED] reflect-x
[07:25:30] [PASSED] reflect-y
[07:25:30] [PASSED] rotate-0
[07:25:30] [PASSED] rotate-90
[07:25:30] [PASSED] rotate-180
[07:25:30] [PASSED] rotate-270
[07:25:30] ============ [PASSED] drm_test_rect_rotate_inv =============
[07:25:30] ==================== [PASSED] drm_rect =====================
[07:25:30] ============================================================
[07:25:30] Testing complete. Ran 417 tests: passed: 417
[07:25:30] Elapsed time: 23.830s total, 1.724s configuring, 21.936s building, 0.148s running
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✓ CI.Build: success for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (24 preceding siblings ...)
2024-05-21 7:25 ` ✓ CI.KUnit: success " Patchwork
@ 2024-05-21 7:37 ` Patchwork
2024-05-21 7:39 ` ✗ CI.Hooks: failure " Patchwork
` (3 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:37 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : success
== Summary ==
lib/modules/6.9.0-xe/kernel/sound/pci/hda/snd-hda-intel.ko
lib/modules/6.9.0-xe/kernel/sound/core/
lib/modules/6.9.0-xe/kernel/sound/core/seq/
lib/modules/6.9.0-xe/kernel/sound/core/seq/snd-seq.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd-seq-device.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd-hwdep.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd-pcm.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd-compress.ko
lib/modules/6.9.0-xe/kernel/sound/core/snd-timer.ko
lib/modules/6.9.0-xe/kernel/sound/soundcore.ko
lib/modules/6.9.0-xe/kernel/sound/soc/
lib/modules/6.9.0-xe/kernel/sound/soc/intel/
lib/modules/6.9.0-xe/kernel/sound/soc/intel/atom/
lib/modules/6.9.0-xe/kernel/sound/soc/intel/atom/snd-soc-sst-atom-hifi2-platform.ko
lib/modules/6.9.0-xe/kernel/sound/soc/intel/atom/sst/
lib/modules/6.9.0-xe/kernel/sound/soc/intel/atom/sst/snd-intel-sst-acpi.ko
lib/modules/6.9.0-xe/kernel/sound/soc/intel/atom/sst/snd-intel-sst-core.ko
lib/modules/6.9.0-xe/kernel/sound/soc/intel/common/
lib/modules/6.9.0-xe/kernel/sound/soc/intel/common/snd-soc-acpi-intel-match.ko
lib/modules/6.9.0-xe/kernel/sound/soc/amd/
lib/modules/6.9.0-xe/kernel/sound/soc/amd/snd-acp-config.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-pci-intel-tgl.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-intel-hda-mlink.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-pci-intel-lnl.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-intel-hda-common.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-intel-hda.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/intel/snd-sof-pci-intel-mtl.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/amd/
lib/modules/6.9.0-xe/kernel/sound/soc/sof/amd/snd-sof-amd-renoir.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/amd/snd-sof-amd-acp.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/snd-sof-utils.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/snd-sof-pci.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/snd-sof.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/snd-sof-probes.ko
lib/modules/6.9.0-xe/kernel/sound/soc/sof/xtensa/
lib/modules/6.9.0-xe/kernel/sound/soc/sof/xtensa/snd-sof-xtensa-dsp.ko
lib/modules/6.9.0-xe/kernel/sound/soc/snd-soc-core.ko
lib/modules/6.9.0-xe/kernel/sound/soc/snd-soc-acpi.ko
lib/modules/6.9.0-xe/kernel/sound/soc/codecs/
lib/modules/6.9.0-xe/kernel/sound/soc/codecs/snd-soc-hdac-hda.ko
lib/modules/6.9.0-xe/kernel/sound/hda/
lib/modules/6.9.0-xe/kernel/sound/hda/snd-intel-sdw-acpi.ko
lib/modules/6.9.0-xe/kernel/sound/hda/ext/
lib/modules/6.9.0-xe/kernel/sound/hda/ext/snd-hda-ext-core.ko
lib/modules/6.9.0-xe/kernel/sound/hda/snd-intel-dspcfg.ko
lib/modules/6.9.0-xe/kernel/sound/hda/snd-hda-core.ko
lib/modules/6.9.0-xe/kernel/arch/
lib/modules/6.9.0-xe/kernel/arch/x86/
lib/modules/6.9.0-xe/kernel/arch/x86/kernel/
lib/modules/6.9.0-xe/kernel/arch/x86/kernel/msr.ko
lib/modules/6.9.0-xe/kernel/arch/x86/kernel/cpuid.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/sha512-ssse3.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/crct10dif-pclmul.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/ghash-clmulni-intel.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/sha1-ssse3.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/crc32-pclmul.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/sha256-ssse3.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/aesni-intel.ko
lib/modules/6.9.0-xe/kernel/arch/x86/crypto/polyval-clmulni.ko
lib/modules/6.9.0-xe/kernel/arch/x86/events/
lib/modules/6.9.0-xe/kernel/arch/x86/events/intel/
lib/modules/6.9.0-xe/kernel/arch/x86/events/intel/intel-cstate.ko
lib/modules/6.9.0-xe/kernel/arch/x86/events/rapl.ko
lib/modules/6.9.0-xe/kernel/arch/x86/kvm/
lib/modules/6.9.0-xe/kernel/arch/x86/kvm/kvm.ko
lib/modules/6.9.0-xe/kernel/arch/x86/kvm/kvm-intel.ko
lib/modules/6.9.0-xe/kernel/crypto/
lib/modules/6.9.0-xe/kernel/crypto/crypto_simd.ko
lib/modules/6.9.0-xe/kernel/crypto/cmac.ko
lib/modules/6.9.0-xe/kernel/crypto/ccm.ko
lib/modules/6.9.0-xe/kernel/crypto/cryptd.ko
lib/modules/6.9.0-xe/kernel/crypto/polyval-generic.ko
lib/modules/6.9.0-xe/kernel/crypto/async_tx/
lib/modules/6.9.0-xe/kernel/crypto/async_tx/async_xor.ko
lib/modules/6.9.0-xe/kernel/crypto/async_tx/async_tx.ko
lib/modules/6.9.0-xe/kernel/crypto/async_tx/async_memcpy.ko
lib/modules/6.9.0-xe/kernel/crypto/async_tx/async_pq.ko
lib/modules/6.9.0-xe/kernel/crypto/async_tx/async_raid6_recov.ko
lib/modules/6.9.0-xe/build
lib/modules/6.9.0-xe/modules.alias.bin
lib/modules/6.9.0-xe/modules.builtin
lib/modules/6.9.0-xe/modules.softdep
lib/modules/6.9.0-xe/modules.alias
lib/modules/6.9.0-xe/modules.order
lib/modules/6.9.0-xe/modules.symbols
lib/modules/6.9.0-xe/modules.dep.bin
+ mv kernel-nodebug.tar.gz ..
+ cd ..
+ rm -rf archive
++ date +%s
+ echo -e '\e[0Ksection_end:1716277017:package_x86_64_nodebug\r\e[0K'
+ sync
^[[0Ksection_end:1716277017:package_x86_64_nodebug
^[[0K
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✗ CI.Hooks: failure for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (25 preceding siblings ...)
2024-05-21 7:37 ` ✓ CI.Build: " Patchwork
@ 2024-05-21 7:39 ` Patchwork
2024-05-21 7:41 ` ✗ CI.checksparse: warning " Patchwork
` (2 subsequent siblings)
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:39 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : failure
== Summary ==
run-parts: executing /workspace/ci/hooks/00-showenv
+ export
+ grep -Ei '(^|\W)CI_'
declare -x CI_KERNEL_BUILD_DIR="/workspace/kernel/build64-default"
declare -x CI_KERNEL_SRC_DIR="/workspace/kernel"
declare -x CI_TOOLS_SRC_DIR="/workspace/ci"
declare -x CI_WORKSPACE_DIR="/workspace"
run-parts: executing /workspace/ci/hooks/10-build-W1
+ SRC_DIR=/workspace/kernel
+ RESTORE_DISPLAY_CONFIG=0
+ '[' -n /workspace/kernel/build64-default ']'
+ BUILD_DIR=/workspace/kernel/build64-default
+ cd /workspace/kernel
++ nproc
+ make -j48 O=/workspace/kernel/build64-default modules_prepare
make[1]: Entering directory '/workspace/kernel/build64-default'
GEN Makefile
UPD include/generated/compile.h
UPD include/config/kernel.release
mkdir -p /workspace/kernel/build64-default/tools/objtool && make O=/workspace/kernel/build64-default subdir=tools/objtool --no-print-directory -C objtool
UPD include/generated/utsrelease.h
HOSTCC /workspace/kernel/build64-default/tools/objtool/fixdep.o
CALL ../scripts/checksyscalls.sh
HOSTLD /workspace/kernel/build64-default/tools/objtool/fixdep-in.o
LINK /workspace/kernel/build64-default/tools/objtool/fixdep
INSTALL libsubcmd_headers
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/exec-cmd.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/help.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/pager.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/parse-options.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/run-command.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/sigchain.o
CC /workspace/kernel/build64-default/tools/objtool/libsubcmd/subcmd-config.o
LD /workspace/kernel/build64-default/tools/objtool/libsubcmd/libsubcmd-in.o
AR /workspace/kernel/build64-default/tools/objtool/libsubcmd/libsubcmd.a
CC /workspace/kernel/build64-default/tools/objtool/weak.o
CC /workspace/kernel/build64-default/tools/objtool/check.o
CC /workspace/kernel/build64-default/tools/objtool/special.o
CC /workspace/kernel/build64-default/tools/objtool/builtin-check.o
CC /workspace/kernel/build64-default/tools/objtool/elf.o
CC /workspace/kernel/build64-default/tools/objtool/objtool.o
CC /workspace/kernel/build64-default/tools/objtool/orc_gen.o
CC /workspace/kernel/build64-default/tools/objtool/orc_dump.o
CC /workspace/kernel/build64-default/tools/objtool/libstring.o
CC /workspace/kernel/build64-default/tools/objtool/libctype.o
CC /workspace/kernel/build64-default/tools/objtool/str_error_r.o
CC /workspace/kernel/build64-default/tools/objtool/librbtree.o
CC /workspace/kernel/build64-default/tools/objtool/arch/x86/special.o
CC /workspace/kernel/build64-default/tools/objtool/arch/x86/decode.o
CC /workspace/kernel/build64-default/tools/objtool/arch/x86/orc.o
LD /workspace/kernel/build64-default/tools/objtool/arch/x86/objtool-in.o
LD /workspace/kernel/build64-default/tools/objtool/objtool-in.o
LINK /workspace/kernel/build64-default/tools/objtool/objtool
make[1]: Leaving directory '/workspace/kernel/build64-default'
++ nproc
+ make -j48 O=/workspace/kernel/build64-default M=drivers/gpu/drm/xe W=1
make[1]: Entering directory '/workspace/kernel/build64-default'
CC [M] drivers/gpu/drm/xe/xe_bb.o
CC [M] drivers/gpu/drm/xe/xe_bo.o
CC [M] drivers/gpu/drm/xe/xe_bo_evict.o
CC [M] drivers/gpu/drm/xe/xe_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_devcoredump.o
CC [M] drivers/gpu/drm/xe/xe_device.o
CC [M] drivers/gpu/drm/xe/xe_device_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_dma_buf.o
CC [M] drivers/gpu/drm/xe/xe_drm_client.o
CC [M] drivers/gpu/drm/xe/xe_exec.o
CC [M] drivers/gpu/drm/xe/xe_execlist.o
CC [M] drivers/gpu/drm/xe/xe_exec_queue.o
CC [M] drivers/gpu/drm/xe/xe_force_wake.o
CC [M] drivers/gpu/drm/xe/xe_ggtt.o
CC [M] drivers/gpu/drm/xe/xe_gpu_scheduler.o
HOSTCC drivers/gpu/drm/xe/xe_gen_wa_oob
CC [M] drivers/gpu/drm/xe/xe_gsc_proxy.o
CC [M] drivers/gpu/drm/xe/xe_gsc_submit.o
CC [M] drivers/gpu/drm/xe/xe_gt.o
CC [M] drivers/gpu/drm/xe/xe_gt_ccs_mode.o
CC [M] drivers/gpu/drm/xe/xe_gt_clock.o
CC [M] drivers/gpu/drm/xe/xe_gt_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_gt_freq.o
CC [M] drivers/gpu/drm/xe/xe_gt_idle.o
CC [M] drivers/gpu/drm/xe/xe_gt_mcr.o
CC [M] drivers/gpu/drm/xe/xe_gt_pagefault.o
CC [M] drivers/gpu/drm/xe/xe_gt_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_gt_throttle_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_gt_tlb_invalidation.o
CC [M] drivers/gpu/drm/xe/xe_gt_topology.o
CC [M] drivers/gpu/drm/xe/xe_guc_ct.o
CC [M] drivers/gpu/drm/xe/xe_guc_db_mgr.o
CC [M] drivers/gpu/drm/xe/xe_guc_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_guc_hwconfig.o
CC [M] drivers/gpu/drm/xe/xe_guc_id_mgr.o
CC [M] drivers/gpu/drm/xe/xe_guc_klv_helpers.o
CC [M] drivers/gpu/drm/xe/xe_guc_log.o
CC [M] drivers/gpu/drm/xe/xe_guc_pc.o
CC [M] drivers/gpu/drm/xe/xe_guc_submit.o
CC [M] drivers/gpu/drm/xe/xe_heci_gsc.o
CC [M] drivers/gpu/drm/xe/xe_hw_engine.o
CC [M] drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_hw_fence.o
CC [M] drivers/gpu/drm/xe/xe_huc.o
CC [M] drivers/gpu/drm/xe/xe_huc_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_irq.o
CC [M] drivers/gpu/drm/xe/xe_lrc.o
GEN xe_wa_oob.c xe_wa_oob.h
CC [M] drivers/gpu/drm/xe/xe_mmio.o
CC [M] drivers/gpu/drm/xe/xe_mocs.o
CC [M] drivers/gpu/drm/xe/xe_module.o
CC [M] drivers/gpu/drm/xe/xe_pat.o
CC [M] drivers/gpu/drm/xe/xe_pci.o
CC [M] drivers/gpu/drm/xe/xe_pcode.o
CC [M] drivers/gpu/drm/xe/xe_pm.o
CC [M] drivers/gpu/drm/xe/xe_preempt_fence.o
CC [M] drivers/gpu/drm/xe/xe_pt.o
CC [M] drivers/gpu/drm/xe/xe_pt_walk.o
CC [M] drivers/gpu/drm/xe/xe_query.o
CC [M] drivers/gpu/drm/xe/xe_range_fence.o
CC [M] drivers/gpu/drm/xe/xe_reg_sr.o
CC [M] drivers/gpu/drm/xe/xe_reg_whitelist.o
CC [M] drivers/gpu/drm/xe/xe_rtp.o
CC [M] drivers/gpu/drm/xe/xe_ring_ops.o
CC [M] drivers/gpu/drm/xe/xe_sa.o
CC [M] drivers/gpu/drm/xe/xe_sched_job.o
CC [M] drivers/gpu/drm/xe/xe_shrinker.o
CC [M] drivers/gpu/drm/xe/xe_step.o
CC [M] drivers/gpu/drm/xe/xe_sync.o
CC [M] drivers/gpu/drm/xe/xe_tile.o
CC [M] drivers/gpu/drm/xe/xe_tile_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_trace.o
CC [M] drivers/gpu/drm/xe/xe_ttm_sys_mgr.o
CC [M] drivers/gpu/drm/xe/xe_ttm_stolen_mgr.o
CC [M] drivers/gpu/drm/xe/xe_ttm_vram_mgr.o
CC [M] drivers/gpu/drm/xe/xe_tuning.o
CC [M] drivers/gpu/drm/xe/xe_uc.o
CC [M] drivers/gpu/drm/xe/xe_uc_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_uc_fw.o
CC [M] drivers/gpu/drm/xe/xe_vm.o
CC [M] drivers/gpu/drm/xe/xe_vram_freq.o
CC [M] drivers/gpu/drm/xe/xe_wait_user_fence.o
CC [M] drivers/gpu/drm/xe/xe_wa.o
CC [M] drivers/gpu/drm/xe/xe_wopcm.o
CC [M] drivers/gpu/drm/xe/xe_hmm.o
CC [M] drivers/gpu/drm/xe/xe_hwmon.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_vf.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_guc_relay.o
CC [M] drivers/gpu/drm/xe/xe_memirq.o
CC [M] drivers/gpu/drm/xe/xe_sriov.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_config.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_control.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_pf_service.o
CC [M] drivers/gpu/drm/xe/xe_lmtt.o
CC [M] drivers/gpu/drm/xe/xe_lmtt_2l.o
CC [M] drivers/gpu/drm/xe/xe_lmtt_ml.o
CC [M] drivers/gpu/drm/xe/xe_pci_sriov.o
CC [M] drivers/gpu/drm/xe/xe_sriov_pf.o
CC [M] drivers/gpu/drm/xe/tests/xe_kunit_helpers.o
CC [M] drivers/gpu/drm/xe/display/ext/i915_irq.o
CC [M] drivers/gpu/drm/xe/display/ext/i915_utils.o
CC [M] drivers/gpu/drm/xe/display/intel_fb_bo.o
CC [M] drivers/gpu/drm/xe/display/intel_fbdev_fb.o
CC [M] drivers/gpu/drm/xe/display/xe_display.o
CC [M] drivers/gpu/drm/xe/display/xe_display_misc.o
CC [M] drivers/gpu/drm/xe/display/xe_display_rps.o
CC [M] drivers/gpu/drm/xe/display/xe_dsb_buffer.o
CC [M] drivers/gpu/drm/xe/display/xe_fb_pin.o
CC [M] drivers/gpu/drm/xe/display/xe_hdcp_gsc.o
CC [M] drivers/gpu/drm/xe/display/xe_plane_initial.o
CC [M] drivers/gpu/drm/xe/display/xe_tdf.o
CC [M] drivers/gpu/drm/xe/i915-soc/intel_dram.o
CC [M] drivers/gpu/drm/xe/i915-soc/intel_pch.o
CC [M] drivers/gpu/drm/xe/i915-display/icl_dsi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_atomic.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_atomic_plane.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_audio.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_backlight.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_bios.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_bw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cdclk.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_color.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_combo_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_connector.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_crtc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_crtc_state_dump.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cursor.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cx0_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_ddi.o
../drivers/gpu/drm/xe/xe_bo.c:1922: warning: Function parameter or struct member 'exec' not described in 'xe_bo_validate'
CC [M] drivers/gpu/drm/xe/i915-display/intel_ddi_buf_trans.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_device.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_driver.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_irq.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_params.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power_map.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power_well.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_trace.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_wa.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dkl_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dmc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_aux.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_aux_backlight.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_hdcp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_link_training.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_mst.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpll.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpll_mgr.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpt_common.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_drrs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsb.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi_dcs_backlight.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi_vbt.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fb.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fbc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fdi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fifo_underrun.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_frontbuffer.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_global_state.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_gmbus.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdcp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdcp_gsc_message.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdmi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hotplug.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hotplug_irq.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hti.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_link_bw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_lspcon.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_lock.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_setup.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_verify.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_panel.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pmdemand.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pps.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_psr.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_qp_tables.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_quirks.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_snps_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_tc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vblank.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vdsc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vga.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vrr.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dmc_wl.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_wm.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_scaler.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_universal_plane.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_watermark.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_acpi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_opregion.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fbdev.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_debugfs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_debugfs_params.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pipe_crc.o
HDRTEST drivers/gpu/drm/xe/abi/gsc_proxy_commands_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_klvs_abi.h
HDRTEST drivers/gpu/drm/xe/abi/gsc_command_header_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_actions_sriov_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_errors_abi.h
CC [M] drivers/gpu/drm/xe/tests/xe_live_test_mod.o
HDRTEST drivers/gpu/drm/xe/abi/guc_actions_slpc_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_relay_actions_abi.h
CC [M] drivers/gpu/drm/xe/tests/xe_bo_test.o
HDRTEST drivers/gpu/drm/xe/abi/gsc_mkhi_commands_abi.h
CC [M] drivers/gpu/drm/xe/tests/xe_dma_buf_test.o
HDRTEST drivers/gpu/drm/xe/abi/gsc_pxp_commands_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_relay_communication_abi.h
CC [M] drivers/gpu/drm/xe/tests/xe_migrate_test.o
HDRTEST drivers/gpu/drm/xe/abi/guc_communication_mmio_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_actions_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_communication_ctb_abi.h
HDRTEST drivers/gpu/drm/xe/abi/guc_messages_abi.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_vma_types.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_irq.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/vlv_sideband_reg.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h
CC [M] drivers/gpu/drm/xe/tests/xe_mocs_test.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_reg_defs.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_trace.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_reg.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_active_types.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_config.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/vlv_sideband.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_mchbar_regs.h
CC [M] drivers/gpu/drm/xe/tests/xe_test_mod.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_gpu_error.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/soc/intel_pch.h
CC [M] drivers/gpu/drm/xe/tests/xe_args_test.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/soc/intel_dram.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/soc/intel_gmch.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_vgpu.h
CC [M] drivers/gpu/drm/xe/tests/xe_pci_test.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
CC [M] drivers/gpu/drm/xe/tests/xe_rtp_test.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
CC [M] drivers/gpu/drm/xe/tests/xe_wa_test.o
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_pci_config.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/gt/intel_rps.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_clock_gating.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/intel_gt_types.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
HDRTEST drivers/gpu/drm/xe/compat-i915-headers/i915_active.h
HDRTEST drivers/gpu/drm/xe/display/xe_display.h
HDRTEST drivers/gpu/drm/xe/display/intel_fb_bo.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_gfx_state_commands.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_instr_defs.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_gsc_commands.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_gfxpipe_commands.h
HDRTEST drivers/gpu/drm/xe/instructions/xe_mi_commands.h
HDRTEST drivers/gpu/drm/xe/regs/xe_gsc_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_reg_defs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_guc_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_gt_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_pcode_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_sriov_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_lrc_layout.h
HDRTEST drivers/gpu/drm/xe/regs/xe_mchbar_regs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_gtt_defs.h
HDRTEST drivers/gpu/drm/xe/regs/xe_engine_regs.h
HDRTEST drivers/gpu/drm/xe/tests/xe_test.h
HDRTEST drivers/gpu/drm/xe/tests/xe_kunit_helpers.h
HDRTEST drivers/gpu/drm/xe/tests/xe_pci_test.h
HDRTEST drivers/gpu/drm/xe/tests/xe_migrate_test.h
HDRTEST drivers/gpu/drm/xe/tests/xe_dma_buf_test.h
HDRTEST drivers/gpu/drm/xe/tests/xe_mocs_test.h
HDRTEST drivers/gpu/drm/xe/tests/xe_bo_test.h
HDRTEST drivers/gpu/drm/xe/xe_args.h
HDRTEST drivers/gpu/drm/xe/xe_assert.h
LD [M] drivers/gpu/drm/xe/tests/xe_live_test.o
HDRTEST drivers/gpu/drm/xe/xe_bb.h
HDRTEST drivers/gpu/drm/xe/xe_bb_types.h
HDRTEST drivers/gpu/drm/xe/xe_bo.h
HDRTEST drivers/gpu/drm/xe/xe_bo_doc.h
HDRTEST drivers/gpu/drm/xe/xe_bo_evict.h
HDRTEST drivers/gpu/drm/xe/xe_bo_types.h
HDRTEST drivers/gpu/drm/xe/xe_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_devcoredump.h
HDRTEST drivers/gpu/drm/xe/xe_devcoredump_types.h
HDRTEST drivers/gpu/drm/xe/xe_device.h
HDRTEST drivers/gpu/drm/xe/xe_device_sysfs.h
HDRTEST drivers/gpu/drm/xe/xe_device_types.h
HDRTEST drivers/gpu/drm/xe/xe_dma_buf.h
HDRTEST drivers/gpu/drm/xe/xe_drm_client.h
HDRTEST drivers/gpu/drm/xe/xe_drv.h
HDRTEST drivers/gpu/drm/xe/xe_exec.h
HDRTEST drivers/gpu/drm/xe/xe_exec_queue.h
HDRTEST drivers/gpu/drm/xe/xe_exec_queue_types.h
HDRTEST drivers/gpu/drm/xe/xe_execlist.h
HDRTEST drivers/gpu/drm/xe/xe_execlist_types.h
HDRTEST drivers/gpu/drm/xe/xe_force_wake.h
HDRTEST drivers/gpu/drm/xe/xe_force_wake_types.h
HDRTEST drivers/gpu/drm/xe/xe_ggtt.h
HDRTEST drivers/gpu/drm/xe/xe_ggtt_types.h
HDRTEST drivers/gpu/drm/xe/xe_gpu_scheduler.h
HDRTEST drivers/gpu/drm/xe/xe_gpu_scheduler_types.h
HDRTEST drivers/gpu/drm/xe/xe_gsc.h
HDRTEST drivers/gpu/drm/xe/xe_gsc_proxy.h
HDRTEST drivers/gpu/drm/xe/xe_gsc_submit.h
HDRTEST drivers/gpu/drm/xe/xe_gsc_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt.h
HDRTEST drivers/gpu/drm/xe/xe_gt_ccs_mode.h
HDRTEST drivers/gpu/drm/xe/xe_gt_clock.h
HDRTEST drivers/gpu/drm/xe/xe_gt_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_gt_freq.h
HDRTEST drivers/gpu/drm/xe/xe_gt_idle.h
HDRTEST drivers/gpu/drm/xe/xe_gt_idle_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_mcr.h
HDRTEST drivers/gpu/drm/xe/xe_gt_pagefault.h
HDRTEST drivers/gpu/drm/xe/xe_gt_printk.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_config_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_helpers.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_monitor_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_policy_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_service.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_service_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_printk.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_vf.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sysfs.h
HDRTEST drivers/gpu/drm/xe/xe_gt_sysfs_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_throttle_sysfs.h
HDRTEST drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
HDRTEST drivers/gpu/drm/xe/xe_gt_tlb_invalidation_types.h
HDRTEST drivers/gpu/drm/xe/xe_gt_topology.h
HDRTEST drivers/gpu/drm/xe/xe_gt_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc.h
HDRTEST drivers/gpu/drm/xe/xe_guc_ads.h
HDRTEST drivers/gpu/drm/xe/xe_guc_ads_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_ct.h
HDRTEST drivers/gpu/drm/xe/xe_guc_ct_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_db_mgr.h
HDRTEST drivers/gpu/drm/xe/xe_guc_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_fwif.h
HDRTEST drivers/gpu/drm/xe/xe_guc_hwconfig.h
HDRTEST drivers/gpu/drm/xe/xe_guc_hxg_helpers.h
HDRTEST drivers/gpu/drm/xe/xe_guc_id_mgr.h
HDRTEST drivers/gpu/drm/xe/xe_guc_klv_helpers.h
HDRTEST drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h
HDRTEST drivers/gpu/drm/xe/xe_guc_klv_thresholds_set_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_log.h
HDRTEST drivers/gpu/drm/xe/xe_guc_log_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_pc.h
HDRTEST drivers/gpu/drm/xe/xe_guc_pc_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_relay.h
HDRTEST drivers/gpu/drm/xe/xe_guc_relay_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_submit.h
HDRTEST drivers/gpu/drm/xe/xe_guc_submit_types.h
HDRTEST drivers/gpu/drm/xe/xe_guc_types.h
HDRTEST drivers/gpu/drm/xe/xe_heci_gsc.h
HDRTEST drivers/gpu/drm/xe/xe_hmm.h
HDRTEST drivers/gpu/drm/xe/xe_huc.h
LD [M] drivers/gpu/drm/xe/tests/xe_test.o
HDRTEST drivers/gpu/drm/xe/xe_huc_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_huc_types.h
HDRTEST drivers/gpu/drm/xe/xe_hw_engine.h
HDRTEST drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h
HDRTEST drivers/gpu/drm/xe/xe_hw_engine_types.h
HDRTEST drivers/gpu/drm/xe/xe_hw_fence.h
HDRTEST drivers/gpu/drm/xe/xe_hw_fence_types.h
HDRTEST drivers/gpu/drm/xe/xe_hwmon.h
HDRTEST drivers/gpu/drm/xe/xe_irq.h
HDRTEST drivers/gpu/drm/xe/xe_lmtt.h
HDRTEST drivers/gpu/drm/xe/xe_lmtt_types.h
HDRTEST drivers/gpu/drm/xe/xe_lrc.h
HDRTEST drivers/gpu/drm/xe/xe_lrc_types.h
HDRTEST drivers/gpu/drm/xe/xe_macros.h
HDRTEST drivers/gpu/drm/xe/xe_map.h
HDRTEST drivers/gpu/drm/xe/xe_memirq.h
HDRTEST drivers/gpu/drm/xe/xe_memirq_types.h
HDRTEST drivers/gpu/drm/xe/xe_migrate.h
HDRTEST drivers/gpu/drm/xe/xe_migrate_doc.h
HDRTEST drivers/gpu/drm/xe/xe_mmio.h
HDRTEST drivers/gpu/drm/xe/xe_mocs.h
HDRTEST drivers/gpu/drm/xe/xe_module.h
HDRTEST drivers/gpu/drm/xe/xe_pat.h
HDRTEST drivers/gpu/drm/xe/xe_pci.h
HDRTEST drivers/gpu/drm/xe/xe_pci_sriov.h
HDRTEST drivers/gpu/drm/xe/xe_pci_types.h
HDRTEST drivers/gpu/drm/xe/xe_pcode.h
HDRTEST drivers/gpu/drm/xe/xe_pcode_api.h
HDRTEST drivers/gpu/drm/xe/xe_platform_types.h
HDRTEST drivers/gpu/drm/xe/xe_pm.h
HDRTEST drivers/gpu/drm/xe/xe_preempt_fence.h
HDRTEST drivers/gpu/drm/xe/xe_preempt_fence_types.h
HDRTEST drivers/gpu/drm/xe/xe_pt.h
HDRTEST drivers/gpu/drm/xe/xe_pt_types.h
HDRTEST drivers/gpu/drm/xe/xe_pt_walk.h
HDRTEST drivers/gpu/drm/xe/xe_query.h
HDRTEST drivers/gpu/drm/xe/xe_range_fence.h
HDRTEST drivers/gpu/drm/xe/xe_reg_sr.h
HDRTEST drivers/gpu/drm/xe/xe_reg_sr_types.h
HDRTEST drivers/gpu/drm/xe/xe_reg_whitelist.h
HDRTEST drivers/gpu/drm/xe/xe_res_cursor.h
HDRTEST drivers/gpu/drm/xe/xe_ring_ops.h
HDRTEST drivers/gpu/drm/xe/xe_ring_ops_types.h
HDRTEST drivers/gpu/drm/xe/xe_rtp.h
HDRTEST drivers/gpu/drm/xe/xe_rtp_types.h
HDRTEST drivers/gpu/drm/xe/xe_sa.h
HDRTEST drivers/gpu/drm/xe/xe_sa_types.h
HDRTEST drivers/gpu/drm/xe/xe_sched_job.h
HDRTEST drivers/gpu/drm/xe/xe_sched_job_types.h
HDRTEST drivers/gpu/drm/xe/xe_shrinker.h
HDRTEST drivers/gpu/drm/xe/xe_sriov.h
HDRTEST drivers/gpu/drm/xe/xe_sriov_pf.h
HDRTEST drivers/gpu/drm/xe/xe_sriov_pf_helpers.h
HDRTEST drivers/gpu/drm/xe/xe_sriov_printk.h
HDRTEST drivers/gpu/drm/xe/xe_sriov_types.h
HDRTEST drivers/gpu/drm/xe/xe_step.h
HDRTEST drivers/gpu/drm/xe/xe_step_types.h
HDRTEST drivers/gpu/drm/xe/xe_sync.h
HDRTEST drivers/gpu/drm/xe/xe_sync_types.h
HDRTEST drivers/gpu/drm/xe/xe_tile.h
HDRTEST drivers/gpu/drm/xe/xe_tile_sysfs.h
HDRTEST drivers/gpu/drm/xe/xe_tile_sysfs_types.h
HDRTEST drivers/gpu/drm/xe/xe_trace.h
HDRTEST drivers/gpu/drm/xe/xe_ttm_stolen_mgr.h
HDRTEST drivers/gpu/drm/xe/xe_ttm_sys_mgr.h
HDRTEST drivers/gpu/drm/xe/xe_ttm_vram_mgr.h
HDRTEST drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h
HDRTEST drivers/gpu/drm/xe/xe_tuning.h
HDRTEST drivers/gpu/drm/xe/xe_uc.h
HDRTEST drivers/gpu/drm/xe/xe_uc_debugfs.h
HDRTEST drivers/gpu/drm/xe/xe_uc_fw.h
HDRTEST drivers/gpu/drm/xe/xe_uc_fw_abi.h
HDRTEST drivers/gpu/drm/xe/xe_uc_fw_types.h
HDRTEST drivers/gpu/drm/xe/xe_uc_types.h
HDRTEST drivers/gpu/drm/xe/xe_vm.h
HDRTEST drivers/gpu/drm/xe/xe_vm_doc.h
HDRTEST drivers/gpu/drm/xe/xe_vm_types.h
HDRTEST drivers/gpu/drm/xe/xe_vram_freq.h
HDRTEST drivers/gpu/drm/xe/xe_wa.h
HDRTEST drivers/gpu/drm/xe/xe_wait_user_fence.h
HDRTEST drivers/gpu/drm/xe/xe_wopcm.h
HDRTEST drivers/gpu/drm/xe/xe_wopcm_types.h
CC [M] drivers/gpu/drm/xe/xe_gsc.o
CC [M] drivers/gpu/drm/xe/xe_guc.o
CC [M] drivers/gpu/drm/xe/xe_guc_ads.o
CC [M] drivers/gpu/drm/xe/xe_migrate.o
LD [M] drivers/gpu/drm/xe/xe.o
MODPOST drivers/gpu/drm/xe/Module.symvers
CC [M] drivers/gpu/drm/xe/xe.mod.o
CC [M] drivers/gpu/drm/xe/tests/xe_live_test.mod.o
CC [M] drivers/gpu/drm/xe/tests/xe_test.mod.o
LD [M] drivers/gpu/drm/xe/tests/xe_test.ko
LD [M] drivers/gpu/drm/xe/tests/xe_live_test.ko
LD [M] drivers/gpu/drm/xe/xe.ko
make[1]: Leaving directory '/workspace/kernel/build64-default'
run-parts: executing /workspace/ci/hooks/11-build-32b
+++ realpath /workspace/ci/hooks/11-build-32b
++ dirname /workspace/ci/hooks/11-build-32b
+ THIS_SCRIPT_DIR=/workspace/ci/hooks
+ SRC_DIR=/workspace/kernel
+ TOOLS_SRC_DIR=/workspace/ci
+ '[' -n /workspace/kernel/build64-default ']'
+ BUILD_DIR=/workspace/kernel/build64-default
+ BUILD_DIR=/workspace/kernel/build64-default/build32
+ cd /workspace/kernel
+ mkdir -p /workspace/kernel/build64-default/build32
++ nproc
+ make -j48 ARCH=i386 O=/workspace/kernel/build64-default/build32 defconfig
make[1]: Entering directory '/workspace/kernel/build64-default/build32'
GEN Makefile
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/menu.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTLD scripts/kconfig/conf
*** Default configuration is based on 'i386_defconfig'
#
# configuration written to .config
#
make[1]: Leaving directory '/workspace/kernel/build64-default/build32'
+ cd /workspace/kernel/build64-default/build32
+ /workspace/kernel/scripts/kconfig/merge_config.sh .config /workspace/ci/kernel/10-xe.fragment
Using .config as base
Merging /workspace/ci/kernel/10-xe.fragment
Value of CONFIG_DRM_XE is redefined by fragment /workspace/ci/kernel/10-xe.fragment:
Previous value: # CONFIG_DRM_XE is not set
New value: CONFIG_DRM_XE=m
Value of CONFIG_SND_DEBUG is redefined by fragment /workspace/ci/kernel/10-xe.fragment:
Previous value: # CONFIG_SND_DEBUG is not set
New value: CONFIG_SND_DEBUG=y
Value of CONFIG_SND_HDA_INTEL is redefined by fragment /workspace/ci/kernel/10-xe.fragment:
Previous value: CONFIG_SND_HDA_INTEL=y
New value: CONFIG_SND_HDA_INTEL=m
Value of CONFIG_SND_HDA_CODEC_HDMI is redefined by fragment /workspace/ci/kernel/10-xe.fragment:
Previous value: # CONFIG_SND_HDA_CODEC_HDMI is not set
New value: CONFIG_SND_HDA_CODEC_HDMI=m
GEN Makefile
WARNING: unmet direct dependencies detected for FB_IOMEM_HELPERS
Depends on [n]: HAS_IOMEM [=y] && FB_CORE [=n]
Selected by [m]:
- DRM_XE_DISPLAY [=y] && HAS_IOMEM [=y] && DRM [=y] && DRM_XE [=m] && DRM_XE [=m]=m
#
# configuration written to .config
#
Value requested for CONFIG_HAVE_UID16 not in final .config
Requested value: CONFIG_HAVE_UID16=y
Actual value:
Value requested for CONFIG_UID16 not in final .config
Requested value: CONFIG_UID16=y
Actual value:
Value requested for CONFIG_X86_32 not in final .config
Requested value: CONFIG_X86_32=y
Actual value:
Value requested for CONFIG_OUTPUT_FORMAT not in final .config
Requested value: CONFIG_OUTPUT_FORMAT="elf32-i386"
Actual value: CONFIG_OUTPUT_FORMAT="elf64-x86-64"
Value requested for CONFIG_ARCH_MMAP_RND_BITS_MIN not in final .config
Requested value: CONFIG_ARCH_MMAP_RND_BITS_MIN=8
Actual value: CONFIG_ARCH_MMAP_RND_BITS_MIN=28
Value requested for CONFIG_ARCH_MMAP_RND_BITS_MAX not in final .config
Requested value: CONFIG_ARCH_MMAP_RND_BITS_MAX=16
Actual value: CONFIG_ARCH_MMAP_RND_BITS_MAX=32
Value requested for CONFIG_PGTABLE_LEVELS not in final .config
Requested value: CONFIG_PGTABLE_LEVELS=2
Actual value: CONFIG_PGTABLE_LEVELS=5
Value requested for CONFIG_X86_BIGSMP not in final .config
Requested value: # CONFIG_X86_BIGSMP is not set
Actual value:
Value requested for CONFIG_X86_INTEL_QUARK not in final .config
Requested value: # CONFIG_X86_INTEL_QUARK is not set
Actual value:
Value requested for CONFIG_X86_RDC321X not in final .config
Requested value: # CONFIG_X86_RDC321X is not set
Actual value:
Value requested for CONFIG_X86_32_NON_STANDARD not in final .config
Requested value: # CONFIG_X86_32_NON_STANDARD is not set
Actual value:
Value requested for CONFIG_X86_32_IRIS not in final .config
Requested value: # CONFIG_X86_32_IRIS is not set
Actual value:
Value requested for CONFIG_M486SX not in final .config
Requested value: # CONFIG_M486SX is not set
Actual value:
Value requested for CONFIG_M486 not in final .config
Requested value: # CONFIG_M486 is not set
Actual value:
Value requested for CONFIG_M586 not in final .config
Requested value: # CONFIG_M586 is not set
Actual value:
Value requested for CONFIG_M586TSC not in final .config
Requested value: # CONFIG_M586TSC is not set
Actual value:
Value requested for CONFIG_M586MMX not in final .config
Requested value: # CONFIG_M586MMX is not set
Actual value:
Value requested for CONFIG_M686 not in final .config
Requested value: CONFIG_M686=y
Actual value:
Value requested for CONFIG_MPENTIUMII not in final .config
Requested value: # CONFIG_MPENTIUMII is not set
Actual value:
Value requested for CONFIG_MPENTIUMIII not in final .config
Requested value: # CONFIG_MPENTIUMIII is not set
Actual value:
Value requested for CONFIG_MPENTIUMM not in final .config
Requested value: # CONFIG_MPENTIUMM is not set
Actual value:
Value requested for CONFIG_MPENTIUM4 not in final .config
Requested value: # CONFIG_MPENTIUM4 is not set
Actual value:
Value requested for CONFIG_MK6 not in final .config
Requested value: # CONFIG_MK6 is not set
Actual value:
Value requested for CONFIG_MK7 not in final .config
Requested value: # CONFIG_MK7 is not set
Actual value:
Value requested for CONFIG_MCRUSOE not in final .config
Requested value: # CONFIG_MCRUSOE is not set
Actual value:
Value requested for CONFIG_MEFFICEON not in final .config
Requested value: # CONFIG_MEFFICEON is not set
Actual value:
Value requested for CONFIG_MWINCHIPC6 not in final .config
Requested value: # CONFIG_MWINCHIPC6 is not set
Actual value:
Value requested for CONFIG_MWINCHIP3D not in final .config
Requested value: # CONFIG_MWINCHIP3D is not set
Actual value:
Value requested for CONFIG_MELAN not in final .config
Requested value: # CONFIG_MELAN is not set
Actual value:
Value requested for CONFIG_MGEODEGX1 not in final .config
Requested value: # CONFIG_MGEODEGX1 is not set
Actual value:
Value requested for CONFIG_MGEODE_LX not in final .config
Requested value: # CONFIG_MGEODE_LX is not set
Actual value:
Value requested for CONFIG_MCYRIXIII not in final .config
Requested value: # CONFIG_MCYRIXIII is not set
Actual value:
Value requested for CONFIG_MVIAC3_2 not in final .config
Requested value: # CONFIG_MVIAC3_2 is not set
Actual value:
Value requested for CONFIG_MVIAC7 not in final .config
Requested value: # CONFIG_MVIAC7 is not set
Actual value:
Value requested for CONFIG_X86_GENERIC not in final .config
Requested value: # CONFIG_X86_GENERIC is not set
Actual value:
Value requested for CONFIG_X86_INTERNODE_CACHE_SHIFT not in final .config
Requested value: CONFIG_X86_INTERNODE_CACHE_SHIFT=5
Actual value: CONFIG_X86_INTERNODE_CACHE_SHIFT=6
Value requested for CONFIG_X86_L1_CACHE_SHIFT not in final .config
Requested value: CONFIG_X86_L1_CACHE_SHIFT=5
Actual value: CONFIG_X86_L1_CACHE_SHIFT=6
Value requested for CONFIG_X86_USE_PPRO_CHECKSUM not in final .config
Requested value: CONFIG_X86_USE_PPRO_CHECKSUM=y
Actual value:
Value requested for CONFIG_X86_MINIMUM_CPU_FAMILY not in final .config
Requested value: CONFIG_X86_MINIMUM_CPU_FAMILY=6
Actual value: CONFIG_X86_MINIMUM_CPU_FAMILY=64
Value requested for CONFIG_CPU_SUP_TRANSMETA_32 not in final .config
Requested value: CONFIG_CPU_SUP_TRANSMETA_32=y
Actual value:
Value requested for CONFIG_CPU_SUP_VORTEX_32 not in final .config
Requested value: CONFIG_CPU_SUP_VORTEX_32=y
Actual value:
Value requested for CONFIG_HPET_TIMER not in final .config
Requested value: # CONFIG_HPET_TIMER is not set
Actual value: CONFIG_HPET_TIMER=y
Value requested for CONFIG_NR_CPUS_RANGE_END not in final .config
Requested value: CONFIG_NR_CPUS_RANGE_END=8
Actual value: CONFIG_NR_CPUS_RANGE_END=512
Value requested for CONFIG_NR_CPUS_DEFAULT not in final .config
Requested value: CONFIG_NR_CPUS_DEFAULT=8
Actual value: CONFIG_NR_CPUS_DEFAULT=64
Value requested for CONFIG_X86_ANCIENT_MCE not in final .config
Requested value: # CONFIG_X86_ANCIENT_MCE is not set
Actual value:
Value requested for CONFIG_X86_LEGACY_VM86 not in final .config
Requested value: # CONFIG_X86_LEGACY_VM86 is not set
Actual value:
Value requested for CONFIG_X86_ESPFIX32 not in final .config
Requested value: CONFIG_X86_ESPFIX32=y
Actual value:
Value requested for CONFIG_TOSHIBA not in final .config
Requested value: # CONFIG_TOSHIBA is not set
Actual value:
Value requested for CONFIG_X86_REBOOTFIXUPS not in final .config
Requested value: # CONFIG_X86_REBOOTFIXUPS is not set
Actual value:
Value requested for CONFIG_MICROCODE_INITRD32 not in final .config
Requested value: CONFIG_MICROCODE_INITRD32=y
Actual value:
Value requested for CONFIG_NOHIGHMEM not in final .config
Requested value: # CONFIG_NOHIGHMEM is not set
Actual value:
Value requested for CONFIG_HIGHMEM4G not in final .config
Requested value: CONFIG_HIGHMEM4G=y
Actual value:
Value requested for CONFIG_HIGHMEM64G not in final .config
Requested value: # CONFIG_HIGHMEM64G is not set
Actual value:
Value requested for CONFIG_PAGE_OFFSET not in final .config
Requested value: CONFIG_PAGE_OFFSET=0xC0000000
Actual value:
Value requested for CONFIG_HIGHMEM not in final .config
Requested value: CONFIG_HIGHMEM=y
Actual value:
Value requested for CONFIG_X86_PAE not in final .config
Requested value: # CONFIG_X86_PAE is not set
Actual value:
Value requested for CONFIG_ARCH_FLATMEM_ENABLE not in final .config
Requested value: CONFIG_ARCH_FLATMEM_ENABLE=y
Actual value:
Value requested for CONFIG_ARCH_SELECT_MEMORY_MODEL not in final .config
Requested value: CONFIG_ARCH_SELECT_MEMORY_MODEL=y
Actual value:
Value requested for CONFIG_ILLEGAL_POINTER_VALUE not in final .config
Requested value: CONFIG_ILLEGAL_POINTER_VALUE=0
Actual value: CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
Value requested for CONFIG_HIGHPTE not in final .config
Requested value: # CONFIG_HIGHPTE is not set
Actual value:
Value requested for CONFIG_COMPAT_VDSO not in final .config
Requested value: # CONFIG_COMPAT_VDSO is not set
Actual value:
Value requested for CONFIG_FUNCTION_PADDING_CFI not in final .config
Requested value: CONFIG_FUNCTION_PADDING_CFI=0
Actual value: CONFIG_FUNCTION_PADDING_CFI=11
Value requested for CONFIG_FUNCTION_PADDING_BYTES not in final .config
Requested value: CONFIG_FUNCTION_PADDING_BYTES=4
Actual value: CONFIG_FUNCTION_PADDING_BYTES=16
Value requested for CONFIG_APM not in final .config
Requested value: # CONFIG_APM is not set
Actual value:
Value requested for CONFIG_X86_POWERNOW_K6 not in final .config
Requested value: # CONFIG_X86_POWERNOW_K6 is not set
Actual value:
Value requested for CONFIG_X86_POWERNOW_K7 not in final .config
Requested value: # CONFIG_X86_POWERNOW_K7 is not set
Actual value:
Value requested for CONFIG_X86_GX_SUSPMOD not in final .config
Requested value: # CONFIG_X86_GX_SUSPMOD is not set
Actual value:
Value requested for CONFIG_X86_SPEEDSTEP_ICH not in final .config
Requested value: # CONFIG_X86_SPEEDSTEP_ICH is not set
Actual value:
Value requested for CONFIG_X86_SPEEDSTEP_SMI not in final .config
Requested value: # CONFIG_X86_SPEEDSTEP_SMI is not set
Actual value:
Value requested for CONFIG_X86_CPUFREQ_NFORCE2 not in final .config
Requested value: # CONFIG_X86_CPUFREQ_NFORCE2 is not set
Actual value:
Value requested for CONFIG_X86_LONGRUN not in final .config
Requested value: # CONFIG_X86_LONGRUN is not set
Actual value:
Value requested for CONFIG_X86_LONGHAUL not in final .config
Requested value: # CONFIG_X86_LONGHAUL is not set
Actual value:
Value requested for CONFIG_X86_E_POWERSAVER not in final .config
Requested value: # CONFIG_X86_E_POWERSAVER is not set
Actual value:
Value requested for CONFIG_PCI_GOBIOS not in final .config
Requested value: # CONFIG_PCI_GOBIOS is not set
Actual value:
Value requested for CONFIG_PCI_GOMMCONFIG not in final .config
Requested value: # CONFIG_PCI_GOMMCONFIG is not set
Actual value:
Value requested for CONFIG_PCI_GODIRECT not in final .config
Requested value: # CONFIG_PCI_GODIRECT is not set
Actual value:
Value requested for CONFIG_PCI_GOANY not in final .config
Requested value: CONFIG_PCI_GOANY=y
Actual value:
Value requested for CONFIG_PCI_BIOS not in final .config
Requested value: CONFIG_PCI_BIOS=y
Actual value:
Value requested for CONFIG_ISA not in final .config
Requested value: # CONFIG_ISA is not set
Actual value:
Value requested for CONFIG_SCx200 not in final .config
Requested value: # CONFIG_SCx200 is not set
Actual value:
Value requested for CONFIG_OLPC not in final .config
Requested value: # CONFIG_OLPC is not set
Actual value:
Value requested for CONFIG_ALIX not in final .config
Requested value: # CONFIG_ALIX is not set
Actual value:
Value requested for CONFIG_NET5501 not in final .config
Requested value: # CONFIG_NET5501 is not set
Actual value:
Value requested for CONFIG_GEOS not in final .config
Requested value: # CONFIG_GEOS is not set
Actual value:
Value requested for CONFIG_COMPAT_32 not in final .config
Requested value: CONFIG_COMPAT_32=y
Actual value:
Value requested for CONFIG_HAVE_ATOMIC_IOMAP not in final .config
Requested value: CONFIG_HAVE_ATOMIC_IOMAP=y
Actual value:
Value requested for CONFIG_ARCH_32BIT_OFF_T not in final .config
Requested value: CONFIG_ARCH_32BIT_OFF_T=y
Actual value:
Value requested for CONFIG_ARCH_WANT_IPC_PARSE_VERSION not in final .config
Requested value: CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
Actual value:
Value requested for CONFIG_MODULES_USE_ELF_REL not in final .config
Requested value: CONFIG_MODULES_USE_ELF_REL=y
Actual value:
Value requested for CONFIG_ARCH_MMAP_RND_BITS not in final .config
Requested value: CONFIG_ARCH_MMAP_RND_BITS=8
Actual value: CONFIG_ARCH_MMAP_RND_BITS=28
Value requested for CONFIG_CLONE_BACKWARDS not in final .config
Requested value: CONFIG_CLONE_BACKWARDS=y
Actual value:
Value requested for CONFIG_OLD_SIGSUSPEND3 not in final .config
Requested value: CONFIG_OLD_SIGSUSPEND3=y
Actual value:
Value requested for CONFIG_OLD_SIGACTION not in final .config
Requested value: CONFIG_OLD_SIGACTION=y
Actual value:
Value requested for CONFIG_ARCH_SPLIT_ARG64 not in final .config
Requested value: CONFIG_ARCH_SPLIT_ARG64=y
Actual value:
Value requested for CONFIG_FUNCTION_ALIGNMENT not in final .config
Requested value: CONFIG_FUNCTION_ALIGNMENT=4
Actual value: CONFIG_FUNCTION_ALIGNMENT=16
Value requested for CONFIG_SELECT_MEMORY_MODEL not in final .config
Requested value: CONFIG_SELECT_MEMORY_MODEL=y
Actual value:
Value requested for CONFIG_FLATMEM_MANUAL not in final .config
Requested value: CONFIG_FLATMEM_MANUAL=y
Actual value:
Value requested for CONFIG_SPARSEMEM_MANUAL not in final .config
Requested value: # CONFIG_SPARSEMEM_MANUAL is not set
Actual value:
Value requested for CONFIG_FLATMEM not in final .config
Requested value: CONFIG_FLATMEM=y
Actual value:
Value requested for CONFIG_SPARSEMEM_STATIC not in final .config
Requested value: CONFIG_SPARSEMEM_STATIC=y
Actual value:
Value requested for CONFIG_BOUNCE not in final .config
Requested value: CONFIG_BOUNCE=y
Actual value:
Value requested for CONFIG_KMAP_LOCAL not in final .config
Requested value: CONFIG_KMAP_LOCAL=y
Actual value:
Value requested for CONFIG_HOTPLUG_PCI_COMPAQ not in final .config
Requested value: # CONFIG_HOTPLUG_PCI_COMPAQ is not set
Actual value:
Value requested for CONFIG_HOTPLUG_PCI_IBM not in final .config
Requested value: # CONFIG_HOTPLUG_PCI_IBM is not set
Actual value:
Value requested for CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH not in final .config
Requested value: CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH=y
Actual value:
Value requested for CONFIG_PCH_PHUB not in final .config
Requested value: # CONFIG_PCH_PHUB is not set
Actual value:
Value requested for CONFIG_SCSI_NSP32 not in final .config
Requested value: # CONFIG_SCSI_NSP32 is not set
Actual value:
Value requested for CONFIG_PATA_CS5520 not in final .config
Requested value: # CONFIG_PATA_CS5520 is not set
Actual value:
Value requested for CONFIG_PATA_CS5530 not in final .config
Requested value: # CONFIG_PATA_CS5530 is not set
Actual value:
Value requested for CONFIG_PATA_CS5535 not in final .config
Requested value: # CONFIG_PATA_CS5535 is not set
Actual value:
Value requested for CONFIG_PATA_CS5536 not in final .config
Requested value: # CONFIG_PATA_CS5536 is not set
Actual value:
Value requested for CONFIG_PATA_SC1200 not in final .config
Requested value: # CONFIG_PATA_SC1200 is not set
Actual value:
Value requested for CONFIG_PCH_GBE not in final .config
Requested value: # CONFIG_PCH_GBE is not set
Actual value:
Value requested for CONFIG_INPUT_WISTRON_BTNS not in final .config
Requested value: # CONFIG_INPUT_WISTRON_BTNS is not set
Actual value:
Value requested for CONFIG_SERIAL_TIMBERDALE not in final .config
Requested value: # CONFIG_SERIAL_TIMBERDALE is not set
Actual value:
Value requested for CONFIG_SERIAL_PCH_UART not in final .config
Requested value: # CONFIG_SERIAL_PCH_UART is not set
Actual value:
Value requested for CONFIG_HW_RANDOM_GEODE not in final .config
Requested value: CONFIG_HW_RANDOM_GEODE=y
Actual value:
Value requested for CONFIG_SONYPI not in final .config
Requested value: # CONFIG_SONYPI is not set
Actual value:
Value requested for CONFIG_PC8736x_GPIO not in final .config
Requested value: # CONFIG_PC8736x_GPIO is not set
Actual value:
Value requested for CONFIG_NSC_GPIO not in final .config
Requested value: # CONFIG_NSC_GPIO is not set
Actual value:
Value requested for CONFIG_I2C_EG20T not in final .config
Requested value: # CONFIG_I2C_EG20T is not set
Actual value:
Value requested for CONFIG_SCx200_ACB not in final .config
Requested value: # CONFIG_SCx200_ACB is not set
Actual value:
Value requested for CONFIG_PTP_1588_CLOCK_PCH not in final .config
Requested value: # CONFIG_PTP_1588_CLOCK_PCH is not set
Actual value:
Value requested for CONFIG_SBC8360_WDT not in final .config
Requested value: # CONFIG_SBC8360_WDT is not set
Actual value:
Value requested for CONFIG_SBC7240_WDT not in final .config
Requested value: # CONFIG_SBC7240_WDT is not set
Actual value:
Value requested for CONFIG_MFD_CS5535 not in final .config
Requested value: # CONFIG_MFD_CS5535 is not set
Actual value:
Value requested for CONFIG_AGP_ALI not in final .config
Requested value: # CONFIG_AGP_ALI is not set
Actual value:
Value requested for CONFIG_AGP_ATI not in final .config
Requested value: # CONFIG_AGP_ATI is not set
Actual value:
Value requested for CONFIG_AGP_AMD not in final .config
Requested value: # CONFIG_AGP_AMD is not set
Actual value:
Value requested for CONFIG_AGP_NVIDIA not in final .config
Requested value: # CONFIG_AGP_NVIDIA is not set
Actual value:
Value requested for CONFIG_AGP_SWORKS not in final .config
Requested value: # CONFIG_AGP_SWORKS is not set
Actual value:
Value requested for CONFIG_AGP_EFFICEON not in final .config
Requested value: # CONFIG_AGP_EFFICEON is not set
Actual value:
Value requested for CONFIG_SND_PCM not in final .config
Requested value: CONFIG_SND_PCM=y
Actual value: CONFIG_SND_PCM=m
Value requested for CONFIG_SND_HWDEP not in final .config
Requested value: CONFIG_SND_HWDEP=y
Actual value: CONFIG_SND_HWDEP=m
Value requested for CONFIG_SND_DYNAMIC_MINORS not in final .config
Requested value: # CONFIG_SND_DYNAMIC_MINORS is not set
Actual value: CONFIG_SND_DYNAMIC_MINORS=y
Value requested for CONFIG_SND_CS5530 not in final .config
Requested value: # CONFIG_SND_CS5530 is not set
Actual value:
Value requested for CONFIG_SND_CS5535AUDIO not in final .config
Requested value: # CONFIG_SND_CS5535AUDIO is not set
Actual value:
Value requested for CONFIG_SND_SIS7019 not in final .config
Requested value: # CONFIG_SND_SIS7019 is not set
Actual value:
Value requested for CONFIG_SND_HDA not in final .config
Requested value: CONFIG_SND_HDA=y
Actual value: CONFIG_SND_HDA=m
Value requested for CONFIG_SND_HDA_CORE not in final .config
Requested value: CONFIG_SND_HDA_CORE=y
Actual value: CONFIG_SND_HDA_CORE=m
Value requested for CONFIG_SND_INTEL_DSP_CONFIG not in final .config
Requested value: CONFIG_SND_INTEL_DSP_CONFIG=y
Actual value: CONFIG_SND_INTEL_DSP_CONFIG=m
Value requested for CONFIG_SND_INTEL_SOUNDWIRE_ACPI not in final .config
Requested value: CONFIG_SND_INTEL_SOUNDWIRE_ACPI=y
Actual value: CONFIG_SND_INTEL_SOUNDWIRE_ACPI=m
Value requested for CONFIG_LEDS_OT200 not in final .config
Requested value: # CONFIG_LEDS_OT200 is not set
Actual value:
Value requested for CONFIG_PCH_DMA not in final .config
Requested value: # CONFIG_PCH_DMA is not set
Actual value:
Value requested for CONFIG_CLKSRC_I8253 not in final .config
Requested value: CONFIG_CLKSRC_I8253=y
Actual value:
Value requested for CONFIG_MAILBOX not in final .config
Requested value: # CONFIG_MAILBOX is not set
Actual value: CONFIG_MAILBOX=y
Value requested for CONFIG_CRYPTO_SERPENT_SSE2_586 not in final .config
Requested value: # CONFIG_CRYPTO_SERPENT_SSE2_586 is not set
Actual value:
Value requested for CONFIG_CRYPTO_TWOFISH_586 not in final .config
Requested value: # CONFIG_CRYPTO_TWOFISH_586 is not set
Actual value:
Value requested for CONFIG_CRYPTO_DEV_GEODE not in final .config
Requested value: # CONFIG_CRYPTO_DEV_GEODE is not set
Actual value:
Value requested for CONFIG_CRYPTO_DEV_HIFN_795X not in final .config
Requested value: # CONFIG_CRYPTO_DEV_HIFN_795X is not set
Actual value:
Value requested for CONFIG_CRYPTO_LIB_POLY1305_RSIZE not in final .config
Requested value: CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
Actual value: CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11
Value requested for CONFIG_AUDIT_GENERIC not in final .config
Requested value: CONFIG_AUDIT_GENERIC=y
Actual value:
Value requested for CONFIG_GENERIC_VDSO_32 not in final .config
Requested value: CONFIG_GENERIC_VDSO_32=y
Actual value:
Value requested for CONFIG_DEBUG_KMAP_LOCAL not in final .config
Requested value: # CONFIG_DEBUG_KMAP_LOCAL is not set
Actual value:
Value requested for CONFIG_DEBUG_HIGHMEM not in final .config
Requested value: # CONFIG_DEBUG_HIGHMEM is not set
Actual value:
Value requested for CONFIG_HAVE_DEBUG_STACKOVERFLOW not in final .config
Requested value: CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
Actual value:
Value requested for CONFIG_DEBUG_STACKOVERFLOW not in final .config
Requested value: # CONFIG_DEBUG_STACKOVERFLOW is not set
Actual value:
Value requested for CONFIG_HAVE_FUNCTION_GRAPH_TRACER not in final .config
Requested value: CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
Actual value:
Value requested for CONFIG_HAVE_FUNCTION_GRAPH_RETVAL not in final .config
Requested value: CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y
Actual value:
Value requested for CONFIG_DRM_KUNIT_TEST not in final .config
Requested value: CONFIG_DRM_KUNIT_TEST=m
Actual value:
Value requested for CONFIG_DRM_XE_WERROR not in final .config
Requested value: CONFIG_DRM_XE_WERROR=y
Actual value:
Value requested for CONFIG_DRM_XE_DEBUG not in final .config
Requested value: CONFIG_DRM_XE_DEBUG=y
Actual value:
Value requested for CONFIG_DRM_XE_DEBUG_MEM not in final .config
Requested value: CONFIG_DRM_XE_DEBUG_MEM=y
Actual value:
Value requested for CONFIG_DRM_XE_KUNIT_TEST not in final .config
Requested value: CONFIG_DRM_XE_KUNIT_TEST=m
Actual value:
++ nproc
+ make -j48 ARCH=i386 olddefconfig
GEN Makefile
WARNING: unmet direct dependencies detected for FB_IOMEM_HELPERS
Depends on [n]: HAS_IOMEM [=y] && FB_CORE [=n]
Selected by [m]:
- DRM_XE_DISPLAY [=y] && HAS_IOMEM [=y] && DRM [=y] && DRM_XE [=m] && DRM_XE [=m]=m
#
# configuration written to .config
#
++ nproc
+ make -j48 ARCH=i386
SYNC include/config/auto.conf.cmd
GEN Makefile
WARNING: unmet direct dependencies detected for FB_IOMEM_HELPERS
Depends on [n]: HAS_IOMEM [=y] && FB_CORE [=n]
Selected by [m]:
- DRM_XE_DISPLAY [=y] && HAS_IOMEM [=y] && DRM [=y] && DRM_XE [=m] && DRM_XE [=m]=m
WARNING: unmet direct dependencies detected for FB_IOMEM_HELPERS
Depends on [n]: HAS_IOMEM [=y] && FB_CORE [=n]
Selected by [m]:
- DRM_XE_DISPLAY [=y] && HAS_IOMEM [=y] && DRM [=y] && DRM_XE [=m] && DRM_XE [=m]=m
WARNING: unmet direct dependencies detected for FB_IOMEM_HELPERS
Depends on [n]: HAS_IOMEM [=y] && FB_CORE [=n]
Selected by [m]:
- DRM_XE_DISPLAY [=y] && HAS_IOMEM [=y] && DRM [=y] && DRM_XE [=m] && DRM_XE [=m]=m
GEN Makefile
WRAP arch/x86/include/generated/uapi/asm/bpf_perf_event.h
WRAP arch/x86/include/generated/uapi/asm/errno.h
WRAP arch/x86/include/generated/uapi/asm/fcntl.h
UPD include/generated/uapi/linux/version.h
WRAP arch/x86/include/generated/uapi/asm/ioctl.h
WRAP arch/x86/include/generated/uapi/asm/ioctls.h
WRAP arch/x86/include/generated/uapi/asm/ipcbuf.h
WRAP arch/x86/include/generated/uapi/asm/param.h
WRAP arch/x86/include/generated/uapi/asm/poll.h
WRAP arch/x86/include/generated/uapi/asm/resource.h
WRAP arch/x86/include/generated/uapi/asm/socket.h
WRAP arch/x86/include/generated/uapi/asm/sockios.h
WRAP arch/x86/include/generated/uapi/asm/termbits.h
WRAP arch/x86/include/generated/uapi/asm/types.h
WRAP arch/x86/include/generated/uapi/asm/termios.h
SYSHDR arch/x86/include/generated/uapi/asm/unistd_32.h
SYSHDR arch/x86/include/generated/uapi/asm/unistd_64.h
SYSHDR arch/x86/include/generated/uapi/asm/unistd_x32.h
SYSTBL arch/x86/include/generated/asm/syscalls_32.h
WRAP arch/x86/include/generated/asm/early_ioremap.h
UPD include/generated/compile.h
WRAP arch/x86/include/generated/asm/mcs_spinlock.h
WRAP arch/x86/include/generated/asm/irq_regs.h
HOSTCC arch/x86/tools/relocs_32.o
WRAP arch/x86/include/generated/asm/kmap_size.h
HOSTCC arch/x86/tools/relocs_64.o
WRAP arch/x86/include/generated/asm/local64.h
WRAP arch/x86/include/generated/asm/mmiowb.h
HOSTCC arch/x86/tools/relocs_common.o
WRAP arch/x86/include/generated/asm/module.lds.h
WRAP arch/x86/include/generated/asm/rwonce.h
WRAP arch/x86/include/generated/asm/unaligned.h
HOSTCC scripts/kallsyms
HOSTCC scripts/asn1_compiler
HOSTCC scripts/sorttable
HOSTCC scripts/selinux/mdp/mdp
HOSTCC scripts/selinux/genheaders/genheaders
HOSTLD arch/x86/tools/relocs
UPD include/config/kernel.release
UPD include/generated/utsrelease.h
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
CC scripts/mod/devicetable-offsets.s
UPD scripts/mod/devicetable-offsets.h
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTCC scripts/mod/symsearch.o
HOSTLD scripts/mod/modpost
CHKSHA1 /workspace/kernel/include/linux/atomic/atomic-arch-fallback.h
CC kernel/bounds.s
CHKSHA1 /workspace/kernel/include/linux/atomic/atomic-instrumented.h
CHKSHA1 /workspace/kernel/include/linux/atomic/atomic-long.h
UPD include/generated/timeconst.h
UPD include/generated/bounds.h
CC arch/x86/kernel/asm-offsets.s
UPD include/generated/asm-offsets.h
CALL /workspace/kernel/scripts/checksyscalls.sh
LDS scripts/module.lds
CC ipc/util.o
CC ipc/msgutil.o
HOSTCC usr/gen_init_cpio
CC ipc/msg.o
CC ipc/sem.o
CC ipc/shm.o
CC ipc/syscall.o
CC io_uring/io_uring.o
CC certs/system_keyring.o
CC init/main.o
CC ipc/ipc_sysctl.o
CC io_uring/xattr.o
CC ipc/mqueue.o
AS arch/x86/lib/atomic64_cx8_32.o
CC io_uring/nop.o
CC arch/x86/pci/i386.o
AS arch/x86/lib/checksum_32.o
AR virt/lib/built-in.a
CC ipc/namespace.o
CC mm/filemap.o
UPD init/utsversion-tmp.h
CC arch/x86/power/cpu.o
AR net/802/built-in.a
CC net/sched/sch_generic.o
CC net/netlink/af_netlink.o
AR arch/x86/net/built-in.a
CC arch/x86/realmode/init.o
AR virt/built-in.a
GEN security/selinux/flask.h security/selinux/av_permissions.h
CC net/ethernet/eth.o
AR arch/x86/crypto/built-in.a
CC security/integrity/iint.o
CC security/keys/gc.o
AR net/bpf/built-in.a
AR drivers/cache/built-in.a
CC block/partitions/core.o
CC arch/x86/events/amd/core.o
CC net/core/sock.o
AR arch/x86/platform/atom/built-in.a
CC arch/x86/mm/pat/set_memory.o
CC sound/core/seq/seq.o
AR sound/i2c/other/built-in.a
CC security/selinux/avc.o
CC init/do_mounts.o
CC sound/core/seq/seq_lock.o
CC fs/notify/dnotify/dnotify.o
CC init/do_mounts_initrd.o
AS arch/x86/realmode/rm/header.o
AR arch/x86/virt/svm/built-in.a
CC arch/x86/kernel/fpu/init.o
AR sound/i2c/built-in.a
CC arch/x86/kernel/fpu/bugs.o
AR drivers/irqchip/built-in.a
CC arch/x86/lib/cmdline.o
CC init/initramfs.o
AR arch/x86/platform/ce4100/built-in.a
CC fs/nfs_common/nfsacl.o
AR arch/x86/virt/vmx/built-in.a
CC arch/x86/entry/vdso/vma.o
CC lib/math/div64.o
AS arch/x86/realmode/rm/trampoline_32.o
AR arch/x86/virt/built-in.a
CC kernel/sched/core.o
AR drivers/pwm/built-in.a
CC arch/x86/platform/efi/memmap.o
AR drivers/bus/mhi/built-in.a
CC arch/x86/mm/init.o
CC kernel/sched/fair.o
AR drivers/bus/built-in.a
AS arch/x86/realmode/rm/stack.o
CC crypto/asymmetric_keys/asymmetric_type.o
CC drivers/pci/msi/pcidev_msi.o
AS arch/x86/realmode/rm/reboot.o
CC kernel/sched/build_policy.o
AS arch/x86/lib/cmpxchg8b_emu.o
CC lib/math/gcd.o
AS arch/x86/realmode/rm/wakeup_asm.o
CC arch/x86/lib/cpu.o
CC arch/x86/realmode/rm/wakemain.o
CC lib/math/lcm.o
CC arch/x86/realmode/rm/video-mode.o
GEN usr/initramfs_data.cpio
CC lib/math/int_log.o
COPY usr/initramfs_inc_data
AS usr/initramfs_data.o
AR usr/built-in.a
HOSTCC certs/extract-cert
CC lib/math/int_pow.o
CC arch/x86/kernel/fpu/core.o
CC security/keys/key.o
CC ipc/mq_sysctl.o
AS arch/x86/realmode/rm/copy.o
CC lib/math/int_sqrt.o
AS arch/x86/realmode/rm/bioscall.o
CC crypto/asymmetric_keys/restrict.o
CC arch/x86/realmode/rm/regs.o
CC lib/math/reciprocal_div.o
CC arch/x86/kernel/fpu/regset.o
CC sound/core/seq/seq_clientmgr.o
CC arch/x86/realmode/rm/video-vga.o
CC arch/x86/kernel/fpu/signal.o
CC arch/x86/lib/delay.o
CC lib/math/rational.o
CERT certs/x509_certificate_list
CC arch/x86/realmode/rm/video-vesa.o
CERT certs/signing_key.x509
AS certs/system_certificates.o
CC security/integrity/integrity_audit.o
AR certs/built-in.a
CC arch/x86/events/amd/lbr.o
CC kernel/locking/mutex.o
CC kernel/power/qos.o
CC arch/x86/pci/init.o
CC fs/nfs_common/grace.o
CC arch/x86/realmode/rm/video-bios.o
CC arch/x86/power/hibernate_32.o
CC kernel/power/main.o
CC drivers/pci/msi/api.o
CC arch/x86/entry/vdso/extable.o
CC kernel/power/console.o
AR fs/notify/dnotify/built-in.a
CC fs/notify/inotify/inotify_fsnotify.o
CC kernel/power/process.o
CC init/calibrate.o
CC arch/x86/platform/efi/quirks.o
CC arch/x86/mm/pat/memtype.o
PASYMS arch/x86/realmode/rm/pasyms.h
LDS arch/x86/realmode/rm/realmode.lds
LD arch/x86/realmode/rm/realmode.elf
RELOCS arch/x86/realmode/rm/realmode.relocs
OBJCOPY arch/x86/realmode/rm/realmode.bin
AS arch/x86/realmode/rmpiggy.o
AR arch/x86/realmode/built-in.a
AS arch/x86/lib/getuser.o
CC kernel/power/suspend.o
CC crypto/asymmetric_keys/signature.o
CC security/commoncap.o
CC block/partitions/msdos.o
GEN arch/x86/lib/inat-tables.c
AR lib/math/built-in.a
LDS arch/x86/entry/vdso/vdso32/vdso32.lds
CC arch/x86/lib/insn-eval.o
CC lib/crypto/mpi/generic_mpih-lshift.o
CC arch/x86/mm/init_32.o
CC lib/crypto/mpi/generic_mpih-mul1.o
CC arch/x86/mm/fault.o
CC arch/x86/pci/pcbios.o
CC lib/crypto/mpi/generic_mpih-mul2.o
CC arch/x86/events/amd/ibs.o
CC sound/core/seq/seq_memory.o
CC net/sched/sch_mq.o
CC arch/x86/mm/pat/memtype_interval.o
AR net/ethernet/built-in.a
CC arch/x86/mm/ioremap.o
CC fs/notify/inotify/inotify_user.o
CC arch/x86/pci/mmconfig_32.o
CC arch/x86/pci/direct.o
AR security/integrity/built-in.a
CC crypto/asymmetric_keys/public_key.o
CC lib/crypto/mpi/generic_mpih-mul3.o
AS arch/x86/power/hibernate_asm_32.o
AR fs/nfs_common/built-in.a
CC security/keys/keyring.o
CC security/lsm_syscalls.o
CC init/init_task.o
CC arch/x86/power/hibernate.o
CC block/partitions/efi.o
CC drivers/pci/msi/msi.o
CC fs/iomap/trace.o
AS arch/x86/entry/vdso/vdso32/note.o
CC security/min_addr.o
AS arch/x86/entry/vdso/vdso32/system_call.o
CC io_uring/fs.o
AS arch/x86/entry/vdso/vdso32/sigreturn.o
CC arch/x86/platform/efi/efi.o
CC arch/x86/entry/vdso/vdso32/vclock_gettime.o
AR ipc/built-in.a
CC security/security.o
CC security/selinux/hooks.o
CC arch/x86/kernel/fpu/xstate.o
CC arch/x86/events/amd/uncore.o
CC drivers/pci/pcie/portdrv.o
AR fs/notify/fanotify/built-in.a
CC lib/crypto/mpi/generic_mpih-rshift.o
CC lib/crypto/mpi/generic_mpih-sub1.o
ASN.1 crypto/asymmetric_keys/x509.asn1.[ch]
CC lib/crypto/mpi/generic_mpih-add1.o
ASN.1 crypto/asymmetric_keys/x509_akid.asn1.[ch]
CC arch/x86/lib/insn.o
CC security/lsm_audit.o
CC sound/core/seq/seq_queue.o
CC kernel/power/hibernate.o
CC drivers/pci/hotplug/pci_hotplug_core.o
CC arch/x86/lib/kaslr.o
CC drivers/pci/hotplug/acpi_pcihp.o
AR arch/x86/mm/pat/built-in.a
CC kernel/locking/semaphore.o
CC kernel/sched/build_utility.o
CC net/sched/sch_frag.o
CC arch/x86/mm/extable.o
CC lib/crypto/mpi/ec.o
CC security/device_cgroup.o
CC crypto/asymmetric_keys/x509_loader.o
CC kernel/power/snapshot.o
CC arch/x86/pci/mmconfig-shared.o
CC fs/iomap/iter.o
CC fs/iomap/buffered-io.o
CC arch/x86/lib/memcpy_32.o
CC arch/x86/entry/vdso/vdso32/vgetcpu.o
CC init/version.o
AR arch/x86/power/built-in.a
AS arch/x86/lib/memmove_32.o
CC lib/crypto/memneq.o
CC arch/x86/lib/misc.o
CC lib/crypto/utils.o
CC crypto/asymmetric_keys/x509_public_key.o
HOSTCC arch/x86/entry/vdso/vdso2c
CC drivers/pci/pcie/rcec.o
CC arch/x86/lib/pc-conf-reg.o
AR fs/notify/inotify/built-in.a
CC kernel/power/swap.o
CC fs/notify/fsnotify.o
CC fs/notify/notification.o
AS arch/x86/lib/putuser.o
CC fs/notify/group.o
CC io_uring/splice.o
AR init/built-in.a
CC lib/crypto/mpi/mpicoder.o
AS arch/x86/lib/retpoline.o
CC net/ethtool/ioctl.o
CC arch/x86/lib/string_32.o
CC net/netlink/genetlink.o
CC net/netlink/policy.o
CC arch/x86/lib/strstr_32.o
CC drivers/pci/msi/irqdomain.o
CC arch/x86/lib/usercopy.o
CC arch/x86/lib/usercopy_32.o
AR block/partitions/built-in.a
CC block/bdev.o
CC arch/x86/entry/vdso/vdso32-setup.o
CC net/netfilter/core.o
CC arch/x86/platform/efi/efi_32.o
CC net/netfilter/nf_log.o
CC lib/crypto/chacha.o
CC kernel/printk/printk.o
CC sound/core/seq/seq_fifo.o
CC io_uring/sync.o
CC kernel/locking/rwsem.o
AR drivers/pci/hotplug/built-in.a
CC security/keys/keyctl.o
CC io_uring/advise.o
CC kernel/printk/printk_safe.o
VDSO arch/x86/entry/vdso/vdso32.so.dbg
AR arch/x86/entry/vsyscall/built-in.a
CC net/ethtool/common.o
AR arch/x86/events/amd/built-in.a
CC mm/mempool.o
OBJCOPY arch/x86/entry/vdso/vdso32.so
CC arch/x86/lib/msr-smp.o
VDSO2C arch/x86/entry/vdso/vdso-image-32.c
CC arch/x86/entry/vdso/vdso-image-32.o
AR arch/x86/kernel/fpu/built-in.a
CC arch/x86/events/intel/core.o
ASN.1 crypto/asymmetric_keys/pkcs7.asn1.[ch]
CC arch/x86/kernel/cpu/mce/core.o
CC crypto/asymmetric_keys/pkcs7_trust.o
CC drivers/pci/pcie/aspm.o
CC arch/x86/kernel/cpu/mce/severity.o
CC arch/x86/mm/mmap.o
CC kernel/printk/nbcon.o
CC lib/crypto/mpi/mpi-add.o
CC mm/oom_kill.o
CC arch/x86/pci/fixup.o
CC net/core/request_sock.o
AR arch/x86/entry/vdso/built-in.a
CC net/core/skbuff.o
AS arch/x86/entry/entry.o
CC arch/x86/lib/cache-smp.o
CC fs/notify/mark.o
CC arch/x86/pci/acpi.o
AS arch/x86/entry/entry_32.o
CC net/sched/sch_api.o
CC arch/x86/entry/syscall_32.o
CC crypto/asymmetric_keys/pkcs7_verify.o
CC net/sched/sch_blackhole.o
AR drivers/pci/msi/built-in.a
CC arch/x86/mm/pgtable.o
CC security/selinux/selinuxfs.o
CC arch/x86/lib/msr.o
CC security/selinux/netlink.o
AS arch/x86/platform/efi/efi_stub_32.o
CC kernel/power/user.o
CC arch/x86/platform/efi/runtime-map.o
CC arch/x86/kernel/cpu/mce/genpool.o
CC sound/core/seq/seq_prioq.o
AR arch/x86/platform/geode/built-in.a
CC kernel/printk/printk_ringbuffer.o
AR arch/x86/platform/iris/built-in.a
CC mm/fadvise.o
CC kernel/locking/percpu-rwsem.o
CC net/ethtool/netlink.o
CC arch/x86/kernel/cpu/mtrr/mtrr.o
CC lib/crypto/aes.o
CC arch/x86/events/zhaoxin/core.o
CC io_uring/filetable.o
CC crypto/asymmetric_keys/x509.asn1.o
CC kernel/power/poweroff.o
CC crypto/asymmetric_keys/x509_akid.asn1.o
CC lib/crypto/mpi/mpi-bit.o
CC crypto/asymmetric_keys/x509_cert_parser.o
CC kernel/printk/sysctl.o
CC block/fops.o
CC arch/x86/kernel/acpi/boot.o
CC arch/x86/kernel/apic/apic.o
CC arch/x86/kernel/kprobes/core.o
CC security/keys/permission.o
CC net/netfilter/nf_queue.o
CC arch/x86/pci/legacy.o
CC arch/x86/kernel/kprobes/opt.o
CC arch/x86/kernel/acpi/sleep.o
CC security/keys/process_keys.o
CC arch/x86/mm/physaddr.o
CC arch/x86/kernel/cpu/mce/intel.o
CC arch/x86/kernel/cpu/mce/amd.o
AR net/netlink/built-in.a
AS arch/x86/kernel/acpi/wakeup_32.o
CC arch/x86/events/core.o
CC sound/core/seq/seq_timer.o
CC fs/notify/fdinfo.o
CC arch/x86/events/probe.o
CC net/core/datagram.o
CC arch/x86/mm/tlb.o
AR kernel/power/built-in.a
CC drivers/pci/pcie/pme.o
AS arch/x86/lib/msr-reg.o
CC arch/x86/kernel/cpu/mtrr/if.o
CC fs/iomap/direct-io.o
AR arch/x86/platform/efi/built-in.a
CC arch/x86/lib/msr-reg-export.o
CC arch/x86/kernel/cpu/mtrr/generic.o
CC arch/x86/platform/intel/iosf_mbi.o
CC kernel/locking/spinlock.o
CC arch/x86/entry/common.o
LDS arch/x86/kernel/vmlinux.lds
CC lib/crypto/arc4.o
CC mm/maccess.o
CC crypto/asymmetric_keys/pkcs7.asn1.o
AS arch/x86/lib/hweight.o
CC crypto/asymmetric_keys/pkcs7_parser.o
CC arch/x86/kernel/cpu/mtrr/cleanup.o
CC arch/x86/lib/iomem.o
CC kernel/locking/osq_lock.o
CC lib/crypto/mpi/mpi-cmp.o
CC sound/core/seq/seq_system.o
CC security/selinux/nlmsgtab.o
AR arch/x86/events/zhaoxin/built-in.a
CC arch/x86/pci/irq.o
CC block/bio.o
CC mm/page-writeback.o
CC io_uring/openclose.o
CC arch/x86/pci/common.o
CC security/selinux/netif.o
CC lib/crypto/mpi/mpi-sub-ui.o
CC mm/folio-compat.o
CC kernel/locking/qspinlock.o
CC mm/readahead.o
CC arch/x86/mm/cpu_entry_area.o
AR kernel/printk/built-in.a
CC sound/core/seq/seq_ports.o
AR fs/notify/built-in.a
CC arch/x86/events/utils.o
CC block/elevator.o
CC sound/core/seq/seq_info.o
AS arch/x86/entry/thunk_32.o
CC arch/x86/lib/atomic64_32.o
CC fs/quota/dquot.o
CC net/ethtool/bitset.o
CC fs/proc/task_mmu.o
CC arch/x86/lib/inat.o
CC fs/kernfs/mount.o
AR arch/x86/kernel/kprobes/built-in.a
CC fs/proc/inode.o
AR drivers/pci/pcie/built-in.a
AR crypto/asymmetric_keys/built-in.a
CC fs/sysfs/file.o
CC crypto/api.o
AR drivers/pci/controller/dwc/built-in.a
AR arch/x86/platform/intel/built-in.a
CC arch/x86/kernel/acpi/cstate.o
AR drivers/pci/controller/mobiveil/built-in.a
AR arch/x86/platform/intel-mid/built-in.a
AR drivers/pci/controller/built-in.a
AR arch/x86/platform/intel-quark/built-in.a
AR arch/x86/lib/built-in.a
AR drivers/pci/switch/built-in.a
CC sound/core/seq/seq_dummy.o
CC drivers/pci/access.o
AR arch/x86/lib/lib.a
AR arch/x86/platform/olpc/built-in.a
CC crypto/cipher.o
CC mm/swap.o
AR arch/x86/platform/scx200/built-in.a
CC security/selinux/netnode.o
AR arch/x86/platform/ts5500/built-in.a
CC block/blk-core.o
AR arch/x86/platform/uv/built-in.a
AR arch/x86/entry/built-in.a
CC security/keys/request_key.o
AR arch/x86/platform/built-in.a
CC security/keys/request_key_auth.o
CC security/selinux/netport.o
CC drivers/pci/bus.o
CC kernel/locking/rtmutex_api.o
CC arch/x86/kernel/cpu/microcode/core.o
CC net/sched/cls_api.o
CC arch/x86/kernel/cpu/mtrr/amd.o
CC lib/crypto/mpi/mpi-div.o
CC net/netfilter/nf_sockopt.o
CC arch/x86/mm/maccess.o
CC arch/x86/kernel/cpu/microcode/intel.o
CC fs/iomap/fiemap.o
CC arch/x86/kernel/cpu/microcode/amd.o
CC fs/devpts/inode.o
CC fs/netfs/buffered_read.o
CC sound/core/sound.o
AR sound/drivers/opl3/built-in.a
AR sound/drivers/opl4/built-in.a
CC arch/x86/events/rapl.o
CC lib/zlib_inflate/inffast.o
AR sound/drivers/mpu401/built-in.a
AR arch/x86/kernel/acpi/built-in.a
AR sound/drivers/vx/built-in.a
CC arch/x86/events/msr.o
AR sound/drivers/pcsp/built-in.a
AR sound/drivers/built-in.a
AR kernel/sched/built-in.a
CC arch/x86/mm/pgprot.o
AS arch/x86/kernel/head_32.o
CC io_uring/uring_cmd.o
AR sound/core/seq/built-in.a
CC security/selinux/status.o
CC arch/x86/kernel/apic/apic_common.o
CC arch/x86/events/intel/bts.o
CC arch/x86/kernel/head32.o
CC arch/x86/kernel/ebda.o
CC arch/x86/kernel/cpu/mce/threshold.o
CC fs/sysfs/dir.o
CC lib/zlib_inflate/inflate.o
CC fs/kernfs/inode.o
CC sound/core/init.o
CC arch/x86/kernel/apic/apic_noop.o
CC arch/x86/pci/early.o
CC fs/kernfs/dir.o
CC crypto/compress.o
CC arch/x86/kernel/cpu/mtrr/cyrix.o
CC lib/zlib_inflate/infutil.o
CC mm/truncate.o
CC kernel/irq/irqdesc.o
CC kernel/rcu/update.o
CC lib/crypto/mpi/mpi-inv.o
CC kernel/rcu/sync.o
CC drivers/pci/probe.o
CC security/keys/user_defined.o
CC crypto/algapi.o
CC fs/iomap/seek.o
AR kernel/livepatch/built-in.a
CC net/ethtool/strset.o
CC kernel/dma/mapping.o
CC arch/x86/kernel/apic/ipi.o
CC sound/core/memory.o
CC lib/crypto/mpi/mpi-mod.o
CC arch/x86/mm/pgtable_32.o
CC security/selinux/ss/ebitmap.o
CC kernel/locking/qrwlock.o
CC kernel/dma/direct.o
AR arch/x86/kernel/cpu/microcode/built-in.a
AR fs/devpts/built-in.a
CC net/ethtool/linkinfo.o
CC kernel/irq/handle.o
CC mm/vmscan.o
CC arch/x86/kernel/apic/vector.o
CC fs/sysfs/symlink.o
CC net/core/stream.o
CC net/netfilter/utils.o
CC fs/iomap/swapfile.o
CC net/ethtool/linkmodes.o
CC security/keys/proc.o
CC lib/zlib_inflate/inftrees.o
CC block/blk-sysfs.o
CC arch/x86/kernel/cpu/mtrr/centaur.o
CC arch/x86/pci/bus_numa.o
CC kernel/entry/common.o
CC lib/zlib_inflate/inflate_syms.o
CC kernel/module/main.o
CC arch/x86/pci/amd_bus.o
CC kernel/time/time.o
CC fs/proc/root.o
CC drivers/pci/host-bridge.o
CC arch/x86/events/intel/ds.o
CC mm/shrinker.o
CC fs/netfs/buffered_write.o
CC lib/crypto/mpi/mpi-mul.o
AR kernel/locking/built-in.a
CC fs/proc/base.o
CC security/keys/sysctl.o
CC arch/x86/events/intel/knc.o
CC kernel/irq/manage.o
CC block/blk-flush.o
CC sound/core/control.o
CC kernel/time/timer.o
CC fs/kernfs/file.o
CC fs/quota/quota_v2.o
CC arch/x86/mm/iomap_32.o
CC fs/kernfs/symlink.o
AR arch/x86/kernel/cpu/mce/built-in.a
AR lib/zlib_inflate/built-in.a
CC arch/x86/kernel/cpu/mtrr/legacy.o
CC arch/x86/kernel/apic/init.o
CC drivers/pci/remove.o
CC io_uring/epoll.o
CC lib/zlib_deflate/deflate.o
CC fs/sysfs/mount.o
CC lib/lzo/lzo1x_compress.o
CC io_uring/statx.o
AR fs/iomap/built-in.a
CC lib/lzo/lzo1x_decompress_safe.o
AR sound/isa/ad1816a/built-in.a
CC kernel/dma/ops_helpers.o
AR sound/isa/ad1848/built-in.a
CC io_uring/net.o
AR sound/isa/cs423x/built-in.a
AR sound/isa/es1688/built-in.a
AR sound/isa/galaxy/built-in.a
CC security/keys/keyctl_pkey.o
AR sound/isa/gus/built-in.a
AR sound/pci/ac97/built-in.a
AR sound/isa/msnd/built-in.a
CC lib/crypto/mpi/mpih-cmp.o
AR sound/pci/ali5451/built-in.a
AR sound/isa/opti9xx/built-in.a
AR sound/ppc/built-in.a
CC crypto/scatterwalk.o
AR sound/pci/asihpi/built-in.a
AR sound/pci/au88x0/built-in.a
AR sound/pci/aw2/built-in.a
AR sound/isa/sb/built-in.a
CC kernel/dma/dummy.o
AR arch/x86/kernel/cpu/mtrr/built-in.a
CC arch/x86/kernel/apic/hw_nmi.o
CC kernel/irq/spurious.o
AR sound/isa/wavefront/built-in.a
AR sound/pci/ctxfi/built-in.a
CC arch/x86/kernel/cpu/cacheinfo.o
AR sound/isa/wss/built-in.a
AR sound/pci/ca0106/built-in.a
AR sound/isa/built-in.a
AR sound/pci/cs46xx/built-in.a
AR arch/x86/pci/built-in.a
AR sound/pci/cs5535audio/built-in.a
CC net/sched/act_api.o
AR sound/pci/lola/built-in.a
AR sound/arm/built-in.a
CC arch/x86/kernel/cpu/scattered.o
CC net/sched/sch_fifo.o
CC arch/x86/kernel/cpu/topology_common.o
AR sound/pci/lx6464es/built-in.a
CC net/ethtool/rss.o
AR sound/pci/echoaudio/built-in.a
CC arch/x86/kernel/cpu/topology_ext.o
CC security/selinux/ss/hashtab.o
CC arch/x86/mm/hugetlbpage.o
AR sound/pci/emu10k1/built-in.a
CC arch/x86/mm/dump_pagetables.o
AR sound/pci/hda/built-in.a
CC [M] sound/pci/hda/hda_bind.o
CC arch/x86/events/intel/lbr.o
CC arch/x86/mm/highmem_32.o
CC fs/quota/quota_tree.o
CC net/core/scm.o
CC net/netfilter/nfnetlink.o
CC kernel/entry/syscall_user_dispatch.o
CC arch/x86/events/intel/p4.o
AR lib/lzo/built-in.a
CC arch/x86/events/intel/p6.o
CC net/netfilter/nfnetlink_log.o
CC lib/lz4/lz4_decompress.o
CC drivers/pci/pci.o
CC block/blk-settings.o
CC fs/quota/quota.o
CC crypto/proc.o
CC drivers/pci/pci-driver.o
AR fs/kernfs/built-in.a
CC arch/x86/kernel/cpu/topology_amd.o
CC security/selinux/ss/symtab.o
CC net/core/gen_stats.o
AR security/keys/built-in.a
CC lib/crypto/mpi/mpih-div.o
CC fs/sysfs/group.o
AR sound/sh/built-in.a
CC crypto/aead.o
CC lib/zlib_deflate/deftree.o
CC lib/crypto/mpi/mpih-mul.o
CC crypto/geniv.o
CC arch/x86/kernel/cpu/common.o
CC lib/crypto/mpi/mpi-pow.o
CC kernel/dma/remap.o
CC net/core/gen_estimator.o
CC lib/crypto/mpi/mpiutil.o
CC arch/x86/kernel/apic/io_apic.o
CC block/blk-ioc.o
CC security/selinux/ss/sidtab.o
CC security/selinux/ss/avtab.o
CC kernel/rcu/srcutree.o
CC sound/core/misc.o
CC fs/netfs/direct_read.o
CC kernel/irq/resend.o
AR kernel/entry/built-in.a
CC kernel/rcu/tree.o
CC fs/proc/generic.o
CC io_uring/msg_ring.o
AR arch/x86/mm/built-in.a
CC [M] sound/pci/hda/hda_codec.o
CC arch/x86/kernel/cpu/rdrand.o
CC arch/x86/events/intel/pt.o
CC net/ethtool/linkstate.o
CC fs/quota/kqid.o
CC sound/core/device.o
CC sound/core/info.o
CC lib/zlib_deflate/deflate_syms.o
AR sound/synth/emux/built-in.a
AR sound/synth/built-in.a
AR sound/usb/misc/built-in.a
CC arch/x86/events/intel/uncore.o
AR kernel/dma/built-in.a
AR sound/usb/usx2y/built-in.a
CC arch/x86/events/intel/uncore_nhmex.o
AR sound/usb/caiaq/built-in.a
AR fs/sysfs/built-in.a
CC fs/proc/array.o
AR sound/usb/6fire/built-in.a
CC io_uring/timeout.o
CC fs/ext4/balloc.o
AR sound/usb/hiface/built-in.a
CC fs/proc/fd.o
AR sound/usb/bcd2000/built-in.a
CC io_uring/sqpoll.o
AR sound/usb/built-in.a
CC kernel/module/strict_rwx.o
CC arch/x86/events/intel/uncore_snb.o
CC arch/x86/events/intel/uncore_snbep.o
AR lib/crypto/mpi/built-in.a
CC kernel/irq/chip.o
CC lib/crypto/gf128mul.o
CC fs/jbd2/transaction.o
CC fs/ext4/bitmap.o
CC lib/crypto/blake2s.o
CC fs/ext4/block_validity.o
CC crypto/lskcipher.o
CC block/blk-map.o
CC kernel/time/hrtimer.o
CC fs/jbd2/commit.o
AR lib/zlib_deflate/built-in.a
AR sound/firewire/built-in.a
AR sound/sparc/built-in.a
AR sound/spi/built-in.a
CC kernel/futex/core.o
AR lib/lz4/built-in.a
CC kernel/cgroup/cgroup.o
CC kernel/trace/trace_clock.o
CC sound/core/isadma.o
CC net/netfilter/nf_conntrack_core.o
AR sound/parisc/built-in.a
CC sound/core/vmaster.o
CC fs/quota/netlink.o
CC sound/core/ctljack.o
CC net/core/net_namespace.o
CC kernel/futex/syscalls.o
CC fs/netfs/direct_write.o
CC arch/x86/kernel/platform-quirks.o
CC arch/x86/events/intel/uncore_discovery.o
CC mm/shmem.o
CC mm/util.o
CC net/netfilter/nf_conntrack_standalone.o
CC net/sched/cls_cgroup.o
CC arch/x86/kernel/cpu/match.o
CC kernel/bpf/core.o
CC kernel/module/kmod.o
CC io_uring/fdinfo.o
CC mm/mmzone.o
CC security/selinux/ss/policydb.o
CC kernel/trace/ring_buffer.o
CC lib/crypto/blake2s-generic.o
CC net/ethtool/debug.o
CC net/ethtool/wol.o
CC sound/core/jack.o
CC kernel/rcu/rcu_segcblist.o
AR sound/pci/ice1712/built-in.a
CC arch/x86/kernel/process_32.o
CC kernel/cgroup/rstat.o
CC arch/x86/kernel/cpu/bugs.o
CC net/sched/ematch.o
CC arch/x86/events/intel/cstate.o
CC sound/core/timer.o
CC kernel/irq/dummychip.o
CC fs/proc/proc_tty.o
CC arch/x86/kernel/apic/msi.o
CC arch/x86/kernel/signal.o
CC fs/proc/cmdline.o
CC arch/x86/kernel/signal_32.o
AR fs/quota/built-in.a
CC io_uring/tctx.o
CC crypto/skcipher.o
CC fs/ramfs/inode.o
CC fs/ramfs/file-mmu.o
CC lib/crypto/sha1.o
CC mm/vmstat.o
CC block/blk-merge.o
CC fs/netfs/io.o
AR sound/pcmcia/vx/built-in.a
CC kernel/futex/pi.o
AR sound/pcmcia/pdaudiocf/built-in.a
AR sound/pcmcia/built-in.a
AR sound/mips/built-in.a
AR sound/soc/built-in.a
AR sound/atmel/built-in.a
AR sound/hda/built-in.a
CC [M] sound/hda/hda_bus_type.o
CC kernel/futex/requeue.o
CC kernel/irq/devres.o
CC [M] sound/hda/hdac_bus.o
CC kernel/module/tree_lookup.o
CC [M] sound/hda/hdac_device.o
CC [M] sound/hda/hdac_sysfs.o
CC fs/jbd2/recovery.o
CC mm/backing-dev.o
CC lib/crypto/sha256.o
CC kernel/time/timekeeping.o
CC fs/hugetlbfs/inode.o
CC drivers/pci/search.o
CC fs/fat/cache.o
CC fs/proc/consoles.o
CC drivers/pci/rom.o
CC fs/jbd2/checkpoint.o
CC [M] sound/pci/hda/hda_jack.o
CC drivers/video/console/dummycon.o
CC net/ethtool/features.o
CC net/core/secure_seq.o
CC drivers/video/console/vgacon.o
CC kernel/futex/waitwake.o
CC drivers/video/backlight/backlight.o
CC kernel/cgroup/namespace.o
CC arch/x86/kernel/apic/probe_32.o
AR fs/ramfs/built-in.a
CC kernel/trace/trace.o
CC arch/x86/kernel/traps.o
CC kernel/trace/trace_output.o
AR net/sched/built-in.a
AR drivers/video/fbdev/core/built-in.a
CC kernel/irq/autoprobe.o
CC kernel/trace/trace_seq.o
AR drivers/video/fbdev/omap/built-in.a
AR drivers/video/fbdev/omap2/omapfb/dss/built-in.a
AR drivers/video/fbdev/omap2/omapfb/displays/built-in.a
AR drivers/video/fbdev/omap2/omapfb/built-in.a
AR drivers/video/fbdev/omap2/built-in.a
AR drivers/video/fbdev/built-in.a
CC drivers/video/aperture.o
CC drivers/video/cmdline.o
CC io_uring/poll.o
CC sound/core/hrtimer.o
CC fs/isofs/namei.o
AR arch/x86/events/intel/built-in.a
CC kernel/module/kallsyms.o
AR arch/x86/events/built-in.a
CC kernel/module/procfs.o
AR lib/crypto/built-in.a
CC fs/ext4/dir.o
CC fs/proc/cpuinfo.o
CC lib/zstd/zstd_decompress_module.o
AR arch/x86/kernel/apic/built-in.a
CC kernel/events/core.o
CC lib/xz/xz_dec_syms.o
CC crypto/seqiv.o
CC lib/xz/xz_dec_stream.o
CC arch/x86/kernel/cpu/aperfmperf.o
CC fs/proc/devices.o
CC drivers/pci/setup-res.o
CC kernel/events/ring_buffer.o
CC fs/fat/dir.o
CC kernel/events/callchain.o
CC kernel/irq/irqdomain.o
CC net/netfilter/nf_conntrack_expect.o
CC [M] sound/hda/hdac_regmap.o
AR kernel/futex/built-in.a
CC lib/xz/xz_dec_lzma2.o
CC arch/x86/kernel/cpu/cpuid-deps.o
CC fs/netfs/iterator.o
CC block/blk-timeout.o
CC arch/x86/kernel/cpu/umwait.o
CC mm/mm_init.o
CC sound/core/seq_device.o
CC crypto/echainiv.o
CC lib/zstd/decompress/huf_decompress.o
AR drivers/video/backlight/built-in.a
CC [M] sound/pci/hda/hda_auto_parser.o
CC fs/isofs/inode.o
CC net/ethtool/privflags.o
CC fs/proc/interrupts.o
CC fs/jbd2/revoke.o
CC crypto/ahash.o
AR drivers/video/console/built-in.a
CC kernel/module/sysfs.o
CC drivers/video/nomodeset.o
CC drivers/video/hdmi.o
CC mm/percpu.o
CC lib/xz/xz_dec_bcj.o
CC fs/jbd2/journal.o
CC kernel/events/hw_breakpoint.o
CC fs/isofs/dir.o
CC lib/zstd/decompress/zstd_ddict.o
CC block/blk-lib.o
AR fs/hugetlbfs/built-in.a
CC kernel/trace/trace_stat.o
CC fs/nfs/client.o
CC net/ethtool/rings.o
CC net/core/flow_dissector.o
CC fs/nfs/dir.o
CC kernel/time/ntp.o
CC fs/proc/loadavg.o
CC fs/proc/meminfo.o
MKCAP arch/x86/kernel/cpu/capflags.c
CC drivers/pci/irq.o
CC security/selinux/ss/services.o
CC lib/zstd/decompress/zstd_decompress.o
CC mm/slab_common.o
CC fs/ext4/ext4_jbd2.o
AR kernel/bpf/built-in.a
CC [M] sound/core/hwdep.o
CC security/selinux/ss/conditional.o
CC kernel/events/uprobes.o
CC security/selinux/ss/mls.o
CC [M] sound/hda/hdac_controller.o
CC crypto/shash.o
CC fs/ext4/extents.o
CC fs/ext4/extents_status.o
AR lib/xz/built-in.a
CC fs/proc/stat.o
CC kernel/cgroup/cgroup-v1.o
CC lib/dim/dim.o
CC fs/netfs/locking.o
AR kernel/module/built-in.a
CC lib/dim/net_dim.o
CC kernel/irq/proc.o
AR kernel/rcu/built-in.a
CC fs/proc/uptime.o
CC block/blk-mq.o
AR drivers/video/built-in.a
CC fs/ext4/file.o
CC fs/ext4/fsmap.o
CC arch/x86/kernel/cpu/powerflags.o
CC arch/x86/kernel/cpu/topology.o
CC arch/x86/kernel/cpu/proc.o
CC fs/proc/util.o
CC kernel/irq/migration.o
CC [M] sound/pci/hda/hda_sysfs.o
CC fs/fat/fatent.o
CC net/core/sysctl_net_core.o
CC drivers/pci/vpd.o
CC fs/ext4/fsync.o
CC fs/ext4/hash.o
CC net/netfilter/nf_conntrack_helper.o
CC io_uring/cancel.o
CC kernel/time/clocksource.o
CC arch/x86/kernel/cpu/feat_ctl.o
CC fs/isofs/util.o
CC [M] sound/core/pcm.o
CC kernel/time/jiffies.o
CC kernel/fork.o
CC net/ethtool/channels.o
CC lib/dim/rdma_dim.o
CC lib/zstd/decompress/zstd_decompress_block.o
CC [M] sound/hda/hdac_stream.o
AR sound/pci/korg1212/built-in.a
AR sound/pci/mixart/built-in.a
CC fs/proc/version.o
AR sound/pci/nm256/built-in.a
CC lib/zstd/zstd_common_module.o
CC crypto/akcipher.o
AR sound/pci/oxygen/built-in.a
CC lib/zstd/common/debug.o
CC net/ethtool/coalesce.o
CC fs/proc/softirqs.o
CC net/ethtool/pause.o
CC kernel/irq/cpuhotplug.o
CC fs/netfs/main.o
CC fs/exportfs/expfs.o
CC fs/nfs/file.o
CC fs/lockd/clntlock.o
AR sound/pci/pcxhr/built-in.a
CC arch/x86/kernel/cpu/intel.o
AR lib/dim/built-in.a
CC fs/isofs/rock.o
CC mm/compaction.o
CC [M] sound/pci/hda/hda_controller.o
CC fs/isofs/export.o
CC fs/netfs/misc.o
CC crypto/sig.o
CC fs/netfs/objects.o
AR sound/x86/built-in.a
CC kernel/cgroup/freezer.o
CC fs/proc/namespaces.o
CC drivers/pci/setup-bus.o
CC drivers/pci/vc.o
CC fs/netfs/output.o
CC fs/proc/self.o
CC kernel/time/timer_list.o
CC arch/x86/kernel/cpu/intel_pconfig.o
CC mm/show_mem.o
CC io_uring/kbuf.o
CC fs/fat/file.o
CC [M] sound/core/pcm_native.o
CC arch/x86/kernel/cpu/tsx.o
CC fs/isofs/joliet.o
CC kernel/cgroup/legacy_freezer.o
AR fs/exportfs/built-in.a
CC crypto/kpp.o
CC security/selinux/ss/context.o
CC net/core/dev.o
CC [M] sound/hda/array.o
CC kernel/irq/pm.o
ASN.1 crypto/rsapubkey.asn1.[ch]
CC net/ethtool/eee.o
CC fs/isofs/compress.o
CC net/netfilter/nf_conntrack_proto.o
CC net/ethtool/tsinfo.o
CC kernel/trace/trace_printk.o
CC lib/zstd/common/entropy_common.o
CC fs/nls/nls_base.o
CC net/netfilter/nf_conntrack_proto_generic.o
AR fs/unicode/built-in.a
CC fs/proc/thread_self.o
CC fs/nls/nls_cp437.o
CC [M] sound/core/pcm_lib.o
CC kernel/cgroup/pids.o
ASN.1 crypto/rsaprivkey.asn1.[ch]
CC [M] sound/core/pcm_misc.o
AR fs/jbd2/built-in.a
CC kernel/cgroup/rdma.o
CC drivers/pci/mmap.o
CC drivers/pci/devres.o
CC drivers/pci/proc.o
CC kernel/time/timeconv.o
CC kernel/time/timecounter.o
CC [M] sound/hda/hdmi_chmap.o
CC fs/lockd/clntproc.o
CC net/core/dev_addr_lists.o
CC kernel/time/alarmtimer.o
CC drivers/pci/pci-sysfs.o
CC fs/ext4/ialloc.o
CC arch/x86/kernel/cpu/intel_epb.o
CC net/core/dst.o
AR fs/netfs/built-in.a
AR sound/pci/riptide/built-in.a
CC fs/nls/nls_ascii.o
CC fs/autofs/init.o
CC net/core/netevent.o
CC fs/autofs/inode.o
CC [M] sound/hda/trace.o
CC mm/shmem_quota.o
CC crypto/rsa.o
CC kernel/irq/msi.o
CC kernel/time/posix-timers.o
CC fs/fat/inode.o
CC [M] sound/pci/hda/hda_proc.o
CC arch/x86/kernel/cpu/amd.o
CC fs/proc/proc_sysctl.o
CC security/selinux/netlabel.o
AR fs/isofs/built-in.a
CC arch/x86/kernel/cpu/hygon.o
CC lib/zstd/common/error_private.o
CC io_uring/rsrc.o
CC fs/nls/nls_iso8859-1.o
CC drivers/pci/slot.o
CC lib/zstd/common/fse_decompress.o
CC net/netfilter/nf_conntrack_proto_tcp.o
CC kernel/time/posix-cpu-timers.o
CC fs/fat/misc.o
CC arch/x86/kernel/cpu/centaur.o
CC kernel/cgroup/cpuset.o
CC kernel/trace/pid_list.o
CC fs/nls/nls_utf8.o
CC lib/fonts/fonts.o
CC net/ethtool/cabletest.o
CC lib/fonts/font_8x16.o
CC drivers/pci/pci-acpi.o
CC kernel/time/posix-clock.o
CC kernel/cgroup/misc.o
CC net/netfilter/nf_conntrack_proto_udp.o
AR sound/pci/rme9652/built-in.a
CC crypto/rsa_helper.o
CC net/netfilter/nf_conntrack_proto_icmp.o
CC kernel/exec_domain.o
CC fs/autofs/root.o
CC [M] sound/hda/hdac_component.o
AR fs/nls/built-in.a
CC [M] sound/hda/hdac_i915.o
AR sound/pci/trident/built-in.a
CC crypto/rsa-pkcs1pad.o
CC fs/9p/vfs_super.o
AR sound/pci/ymfpci/built-in.a
CC fs/9p/vfs_inode.o
CC fs/autofs/symlink.o
CC fs/9p/vfs_inode_dotl.o
CC fs/nfs/getroot.o
CC lib/zstd/common/zstd_common.o
AR lib/fonts/built-in.a
CC fs/9p/vfs_addr.o
CC kernel/time/itimer.o
AR lib/zstd/built-in.a
CC lib/argv_split.o
CC net/core/neighbour.o
CC [M] sound/hda/intel-dsp-config.o
CC net/ipv4/netfilter/nf_defrag_ipv4.o
CC [M] sound/hda/intel-nhlt.o
CC arch/x86/kernel/cpu/transmeta.o
CC net/ipv4/netfilter/nf_reject_ipv4.o
CC net/core/rtnetlink.o
CC crypto/acompress.o
CC block/blk-mq-tag.o
CC net/netfilter/nf_conntrack_extend.o
CC drivers/pci/iomap.o
CC kernel/irq/affinity.o
CC [M] sound/pci/hda/hda_hwdep.o
CC fs/lockd/clntxdr.o
CC kernel/trace/trace_sched_switch.o
CC lib/bug.o
CC lib/buildid.o
CC fs/lockd/host.o
CC lib/clz_tab.o
CC [M] sound/hda/intel-sdw-acpi.o
CC drivers/pci/quirks.o
CC drivers/pci/pci-label.o
CC kernel/panic.o
CC fs/fat/nfs.o
CC kernel/irq/matrix.o
CC fs/nfs/inode.o
AR security/selinux/built-in.a
AR security/built-in.a
CC net/ethtool/tunnels.o
CC block/blk-stat.o
CC mm/interval_tree.o
CC fs/autofs/waitq.o
CC net/ethtool/fec.o
CC [M] sound/core/pcm_memory.o
LD [M] sound/hda/snd-hda-core.o
CC [M] sound/core/memalloc.o
CC fs/proc/proc_net.o
CC mm/list_lru.o
CC io_uring/rw.o
CC net/xfrm/xfrm_policy.o
CC fs/9p/vfs_file.o
CC mm/workingset.o
CC net/unix/af_unix.o
CC arch/x86/kernel/idt.o
CC arch/x86/kernel/irq.o
CC fs/9p/vfs_dir.o
CC net/netfilter/nf_conntrack_acct.o
CC kernel/time/clockevents.o
CC lib/cmdline.o
CC fs/nfs/super.o
CC [M] sound/pci/hda/patch_hdmi.o
LD [M] sound/hda/snd-intel-dspcfg.o
CC crypto/scompress.o
CC lib/cpumask.o
CC lib/ctype.o
LD [M] sound/hda/snd-intel-sdw-acpi.o
CC kernel/time/tick-common.o
AR sound/xen/built-in.a
CC lib/dec_and_lock.o
AR sound/virtio/built-in.a
CC crypto/algboss.o
CC lib/decompress.o
CC net/netfilter/nf_conntrack_seqadj.o
CC net/ipv6/netfilter/ip6_tables.o
CC net/ipv6/af_inet6.o
CC [M] sound/pci/hda/hda_eld.o
CC lib/decompress_bunzip2.o
AR kernel/events/built-in.a
CC [M] sound/core/pcm_timer.o
CC block/blk-mq-sysfs.o
CC fs/fat/namei_vfat.o
CC net/ipv6/netfilter/ip6table_filter.o
CC kernel/trace/trace_nop.o
CC block/blk-mq-cpumap.o
CC fs/autofs/expire.o
CC net/ipv4/netfilter/ip_tables.o
LD [M] sound/core/snd-hwdep.o
CC net/ipv4/route.o
CC kernel/cpu.o
CC net/netfilter/nf_conntrack_proto_icmpv6.o
CC net/netfilter/nf_conntrack_netlink.o
CC net/unix/garbage.o
CC mm/debug.o
CC fs/proc/kcore.o
CC fs/ext4/indirect.o
CC fs/9p/vfs_dentry.o
CC kernel/time/tick-broadcast.o
CC drivers/pci/vgaarb.o
CC fs/fat/namei_msdos.o
CC kernel/time/tick-broadcast-hrtimer.o
CC kernel/trace/blktrace.o
CC kernel/cgroup/debug.o
CC fs/lockd/svc.o
CC net/unix/sysctl_net_unix.o
CC arch/x86/kernel/cpu/zhaoxin.o
AR kernel/irq/built-in.a
CC kernel/exit.o
CC net/ethtool/eeprom.o
AR sound/core/built-in.a
LD [M] sound/core/snd-pcm.o
CC arch/x86/kernel/irq_32.o
CC sound/sound_core.o
CC lib/decompress_inflate.o
CC arch/x86/kernel/dumpstack_32.o
CC crypto/testmgr.o
CC kernel/time/tick-oneshot.o
CC [M] sound/pci/hda/hda_intel.o
CC block/blk-mq-sched.o
CC sound/last.o
CC arch/x86/kernel/cpu/vortex.o
CC fs/lockd/svclock.o
CC io_uring/opdef.o
CC crypto/cmac.o
CC fs/9p/v9fs.o
CC fs/autofs/dev-ioctl.o
CC fs/9p/fid.o
CC arch/x86/kernel/time.o
CC net/netfilter/nf_conntrack_ftp.o
AR kernel/cgroup/built-in.a
CC kernel/softirq.o
CC fs/nfs/io.o
CC mm/gup.o
CC fs/9p/xattr.o
CC fs/proc/vmcore.o
CC crypto/hmac.o
CC lib/decompress_unlz4.o
AR fs/fat/built-in.a
CC kernel/resource.o
CC arch/x86/kernel/cpu/perfctr-watchdog.o
CC fs/lockd/svcshare.o
CC kernel/time/tick-sched.o
CC arch/x86/kernel/cpu/vmware.o
CC arch/x86/kernel/cpu/hypervisor.o
CC lib/decompress_unlzma.o
CC block/ioctl.o
CC fs/nfs/direct.o
CC block/genhd.o
CC fs/nfs/pagelist.o
AR drivers/pci/built-in.a
CC fs/nfs/read.o
AR drivers/idle/built-in.a
AR drivers/char/ipmi/built-in.a
CC io_uring/notif.o
CC io_uring/waitid.o
CC drivers/acpi/acpica/dsargs.o
CC io_uring/register.o
CC drivers/acpi/acpica/dscontrol.o
CC fs/ext4/inline.o
CC net/ipv6/netfilter/ip6table_mangle.o
CC lib/decompress_unlzo.o
CC net/ethtool/stats.o
CC arch/x86/kernel/cpu/mshyperv.o
CC arch/x86/kernel/cpu/debugfs.o
CC net/ipv6/anycast.o
CC net/ipv4/netfilter/iptable_filter.o
CC kernel/sysctl.o
CC net/core/utils.o
AR fs/9p/built-in.a
CC kernel/capability.o
CC kernel/ptrace.o
CC crypto/crypto_null.o
AR net/unix/built-in.a
AR fs/autofs/built-in.a
CC net/packet/af_packet.o
AR fs/hostfs/built-in.a
CC drivers/acpi/acpica/dsdebug.o
CC fs/debugfs/inode.o
AR net/dsa/built-in.a
CC drivers/acpi/acpica/dsfield.o
CC net/sunrpc/auth_gss/auth_gss.o
CC net/sunrpc/clnt.o
CC crypto/md5.o
CC kernel/trace/trace_events.o
CC fs/lockd/svcproc.o
CC lib/decompress_unxz.o
CC fs/tracefs/inode.o
CC kernel/user.o
CC drivers/acpi/acpica/dsinit.o
CC fs/proc/kmsg.o
CC fs/lockd/svcsubs.o
AR drivers/amba/built-in.a
CC drivers/pnp/pnpacpi/core.o
CC fs/lockd/mon.o
CC fs/proc/page.o
CC net/sunrpc/auth_gss/gss_generic_token.o
CC kernel/time/timer_migration.o
LD [M] sound/pci/hda/snd-hda-codec.o
LD [M] sound/pci/hda/snd-hda-codec-hdmi.o
LD [M] sound/pci/hda/snd-hda-intel.o
CC net/ipv4/inetpeer.o
CC drivers/pnp/core.o
AR sound/pci/vx222/built-in.a
AR sound/pci/built-in.a
CC net/ipv4/protocol.o
CC net/ipv4/ip_input.o
CC net/ipv6/ip6_output.o
CC fs/lockd/trace.o
AR sound/built-in.a
CC net/netfilter/nf_conntrack_irc.o
CC kernel/signal.o
CC arch/x86/kernel/cpu/capflags.o
AR arch/x86/kernel/cpu/built-in.a
CC crypto/sha256_generic.o
CC net/netfilter/nf_conntrack_sip.o
CC net/ipv4/netfilter/iptable_mangle.o
CC arch/x86/kernel/ioport.o
CC net/ethtool/phc_vclocks.o
CC io_uring/truncate.o
CC block/ioprio.o
CC lib/decompress_unzstd.o
CC drivers/acpi/acpica/dsmethod.o
CC fs/lockd/xdr.o
CC net/xfrm/xfrm_state.o
CC net/core/link_watch.o
CC net/ipv6/netfilter/nf_defrag_ipv6_hooks.o
CC net/ipv6/netfilter/nf_conntrack_reasm.o
CC net/core/filter.o
CC net/ethtool/mm.o
CC drivers/pnp/pnpacpi/rsparser.o
CC fs/debugfs/file.o
CC block/badblocks.o
CC net/core/sock_diag.o
CC mm/mmap_lock.o
CC net/ipv4/netfilter/ipt_REJECT.o
CC fs/tracefs/event_inode.o
CC net/ipv6/netfilter/nf_reject_ipv6.o
AR fs/proc/built-in.a
CC crypto/sha512_generic.o
CC io_uring/io-wq.o
CC fs/lockd/clnt4xdr.o
CC drivers/acpi/acpica/dsmthdat.o
CC fs/ext4/inode.o
CC io_uring/futex.o
CC lib/dump_stack.o
CC fs/lockd/xdr4.o
CC kernel/sys.o
CC arch/x86/kernel/dumpstack.o
AR net/wireless/tests/built-in.a
CC net/wireless/core.o
CC net/netlabel/netlabel_user.o
AR net/mac80211/tests/built-in.a
CC net/ipv4/ip_fragment.o
CC net/mac80211/main.o
CC arch/x86/kernel/nmi.o
CC arch/x86/kernel/ldt.o
CC net/wireless/sysfs.o
CC drivers/acpi/acpica/dsobject.o
CC net/core/dev_ioctl.o
CC net/netlabel/netlabel_kapi.o
CC net/mac80211/status.o
CC net/ipv4/ip_forward.o
CC net/rfkill/core.o
AR drivers/acpi/pmic/built-in.a
CC drivers/acpi/dptf/int340x_thermal.o
AR drivers/pnp/pnpacpi/built-in.a
CC fs/nfs/symlink.o
CC drivers/pnp/card.o
CC block/blk-rq-qos.o
CC net/core/tso.o
CC lib/earlycpio.o
CC net/netfilter/nf_nat_core.o
CC net/mac80211/driver-ops.o
CC mm/highmem.o
CC net/ethtool/module.o
CC lib/extable.o
AR fs/debugfs/built-in.a
CC fs/nfs/unlink.o
AR fs/tracefs/built-in.a
CC arch/x86/kernel/setup.o
CC net/rfkill/input.o
CC drivers/acpi/acpica/dsopcode.o
CC kernel/time/vsyscall.o
CC crypto/sha3_generic.o
CC [M] net/ipv4/netfilter/iptable_nat.o
CC fs/ext4/ioctl.o
CC net/sunrpc/auth_gss/gss_mech_switch.o
CC net/netlabel/netlabel_domainhash.o
AR drivers/acpi/dptf/built-in.a
CC io_uring/napi.o
CC kernel/time/timekeeping_debug.o
CC net/ethtool/pse-pd.o
CC drivers/acpi/acpica/dspkginit.o
CC lib/flex_proportions.o
CC arch/x86/kernel/x86_init.o
CC net/netlabel/netlabel_addrlist.o
CC net/ipv6/netfilter/ip6t_ipv6header.o
CC kernel/time/namespace.o
CC drivers/acpi/acpica/dsutils.o
CC net/netfilter/nf_nat_proto.o
CC net/ethtool/plca.o
CC kernel/trace/trace_export.o
CC fs/lockd/svc4proc.o
CC drivers/pnp/driver.o
CC crypto/ecb.o
CC net/netfilter/nf_nat_helper.o
CC fs/ext4/mballoc.o
CC block/disk-events.o
CC drivers/acpi/acpica/dswexec.o
AR net/rfkill/built-in.a
CC net/sunrpc/auth_gss/svcauth_gss.o
CC lib/idr.o
CC net/ipv4/ip_options.o
CC fs/nfs/write.o
CC kernel/umh.o
CC crypto/cbc.o
CC mm/memory.o
CC mm/mincore.o
CC mm/mlock.o
AR net/packet/built-in.a
CC net/9p/mod.o
CC net/9p/client.o
CC net/dns_resolver/dns_key.o
CC net/9p/error.o
CC net/dns_resolver/dns_query.o
CC block/blk-ia-ranges.o
CC net/ipv4/ip_output.o
CC drivers/pnp/resource.o
CC net/handshake/alert.o
CC drivers/pnp/manager.o
CC drivers/acpi/acpica/dswload.o
CC arch/x86/kernel/i8259.o
AR net/ipv4/netfilter/built-in.a
AR kernel/time/built-in.a
CC net/handshake/genl.o
CC net/9p/protocol.o
CC net/ipv4/ip_sockglue.o
CC kernel/trace/trace_event_perf.o
CC crypto/ctr.o
CC lib/irq_regs.o
CC net/sunrpc/xprt.o
CC net/devres.o
CC mm/mmap.o
CC arch/x86/kernel/irqinit.o
CC drivers/pnp/support.o
CC lib/is_single_threaded.o
CC net/xfrm/xfrm_hash.o
CC drivers/pnp/interface.o
CC net/netlabel/netlabel_mgmt.o
CC drivers/pnp/quirks.o
AR net/ethtool/built-in.a
CC block/early-lookup.o
CC drivers/acpi/acpica/dswload2.o
CC drivers/pnp/system.o
CC net/ipv6/netfilter/ip6t_REJECT.o
AR io_uring/built-in.a
AR net/dns_resolver/built-in.a
CC net/netlabel/netlabel_unlabeled.o
CC block/bounce.o
CC net/socket.o
CC mm/mmu_gather.o
CC arch/x86/kernel/jump_label.o
CC fs/lockd/procfs.o
CC drivers/acpi/acpica/dswscope.o
CC net/ipv6/ip6_input.o
CC crypto/gcm.o
CC net/9p/trans_common.o
CC lib/klist.o
CC lib/kobject.o
CC net/handshake/netlink.o
CC drivers/acpi/acpica/dswstate.o
CC net/netfilter/nf_nat_masquerade.o
CC fs/open.o
CC net/core/sock_reuseport.o
CC [M] fs/efivarfs/inode.o
CC net/xfrm/xfrm_input.o
CC net/core/fib_notifier.o
CC [M] fs/efivarfs/file.o
CC kernel/trace/trace_events_filter.o
CC drivers/acpi/tables.o
CC fs/ext4/migrate.o
CC fs/ext4/mmp.o
CC net/wireless/radiotap.o
CC net/sysctl_net.o
AR drivers/pnp/built-in.a
CC fs/read_write.o
CC lib/kobject_uevent.o
CC block/bsg.o
CC fs/nfs/namespace.o
CC arch/x86/kernel/irq_work.o
CC net/handshake/request.o
CC net/9p/trans_fd.o
CC drivers/acpi/acpica/evevent.o
CC net/wireless/util.o
AR fs/lockd/built-in.a
CC fs/file_table.o
CC net/ipv6/addrconf.o
CC net/sunrpc/auth_gss/gss_rpc_upcall.o
CC net/handshake/tlshd.o
CC lib/logic_pio.o
CC [M] fs/efivarfs/super.o
CC net/sunrpc/auth_gss/gss_rpc_xdr.o
CC [M] fs/efivarfs/vars.o
CC net/netlabel/netlabel_cipso_v4.o
CC net/netlabel/netlabel_calipso.o
CC net/mac80211/sta_info.o
CC crypto/ccm.o
AR net/ipv6/netfilter/built-in.a
CC drivers/acpi/acpica/evgpe.o
CC net/ipv6/addrlabel.o
CC net/sunrpc/auth_gss/trace.o
CC block/blk-cgroup.o
CC mm/mprotect.o
CC mm/mremap.o
CC net/mac80211/wep.o
CC net/sunrpc/auth_gss/gss_krb5_mech.o
CC net/ipv4/inet_hashtables.o
CC net/core/xdp.o
CC block/blk-ioprio.o
CC block/blk-iolatency.o
CC net/handshake/trace.o
CC net/wireless/reg.o
CC crypto/aes_generic.o
CC kernel/trace/trace_events_trigger.o
CC drivers/acpi/acpica/evgpeblk.o
CC net/netfilter/nf_nat_ftp.o
CC lib/maple_tree.o
CC net/wireless/scan.o
CC arch/x86/kernel/probe_roms.o
CC drivers/acpi/blacklist.o
CC block/blk-iocost.o
CC net/ipv4/inet_timewait_sock.o
CC mm/msync.o
CC net/sunrpc/auth_gss/gss_krb5_seal.o
CC net/xfrm/xfrm_output.o
LD [M] fs/efivarfs/efivarfs.o
CC net/9p/trans_virtio.o
AR drivers/clk/actions/built-in.a
CC net/wireless/nl80211.o
AR drivers/clk/analogbits/built-in.a
AR drivers/clk/bcm/built-in.a
CC fs/ext4/move_extent.o
CC net/sunrpc/auth_gss/gss_krb5_unseal.o
AR drivers/clk/imgtec/built-in.a
CC net/sunrpc/auth_gss/gss_krb5_wrap.o
AR drivers/clk/imx/built-in.a
CC fs/nfs/mount_clnt.o
AR drivers/clk/ingenic/built-in.a
CC fs/nfs/nfstrace.o
CC drivers/acpi/acpica/evgpeinit.o
AR drivers/clk/mediatek/built-in.a
CC fs/nfs/export.o
AR drivers/clk/microchip/built-in.a
CC kernel/trace/trace_eprobe.o
AR drivers/clk/mstar/built-in.a
CC net/core/flow_offload.o
CC fs/nfs/sysfs.o
CC fs/nfs/fs_context.o
AR drivers/clk/mvebu/built-in.a
CC crypto/crc32c_generic.o
AR net/netlabel/built-in.a
CC fs/nfs/nfsroot.o
AR drivers/clk/ralink/built-in.a
CC lib/memcat_p.o
CC net/wireless/mlme.o
CC fs/nfs/sysctl.o
AR drivers/clk/renesas/built-in.a
CC net/wireless/ibss.o
AR drivers/clk/socfpga/built-in.a
AR drivers/clk/sprd/built-in.a
AR drivers/clk/starfive/built-in.a
CC block/mq-deadline.o
CC crypto/authenc.o
AR drivers/clk/sunxi-ng/built-in.a
CC block/kyber-iosched.o
AR drivers/clk/ti/built-in.a
CC arch/x86/kernel/sys_ia32.o
AR drivers/clk/versatile/built-in.a
AR drivers/clk/xilinx/built-in.a
AR drivers/clk/built-in.a
CC block/blk-mq-pci.o
CC drivers/acpi/acpica/evgpeutil.o
CC block/blk-mq-virtio.o
CC crypto/authencesn.o
CC net/sunrpc/auth_gss/gss_krb5_crypto.o
CC mm/page_vma_mapped.o
CC fs/super.o
CC net/ipv6/route.o
CC net/sunrpc/socklib.o
CC net/wireless/sme.o
CC kernel/trace/trace_kprobe.o
CC net/netfilter/nf_nat_irc.o
CC net/sunrpc/auth_gss/gss_krb5_keys.o
CC mm/pagewalk.o
CC block/blk-mq-debugfs.o
CC fs/ext4/namei.o
CC drivers/acpi/acpica/evglock.o
CC net/core/gro.o
CC arch/x86/kernel/ksysfs.o
AR net/handshake/built-in.a
CC arch/x86/kernel/bootflag.o
AR net/9p/built-in.a
CC fs/nfs/nfs2super.o
CC arch/x86/kernel/e820.o
CC net/ipv6/ip6_fib.o
CC net/netfilter/nf_nat_sip.o
CC net/ipv6/ipv6_sockglue.o
CC mm/pgtable-generic.o
CC arch/x86/kernel/pci-dma.o
CC crypto/lzo.o
CC net/xfrm/xfrm_sysctl.o
CC net/mac80211/aead_api.o
CC drivers/acpi/acpica/evhandler.o
CC net/ipv4/inet_connection_sock.o
CC mm/rmap.o
CC net/mac80211/wpa.o
CC net/ipv4/tcp.o
CC fs/ext4/page-io.o
CC crypto/lzo-rle.o
CC lib/nmi_backtrace.o
CC lib/objpool.o
CC net/core/netdev-genl.o
CC kernel/trace/error_report-traces.o
AR net/sunrpc/auth_gss/built-in.a
CC mm/vmalloc.o
CC arch/x86/kernel/quirks.o
CC arch/x86/kernel/topology.o
CC net/sunrpc/xprtsock.o
CC lib/plist.o
CC drivers/acpi/acpica/evmisc.o
CC lib/radix-tree.o
CC net/xfrm/xfrm_replay.o
CC net/netfilter/x_tables.o
CC net/mac80211/scan.o
CC net/sunrpc/sched.o
CC net/core/netdev-genl-gen.o
CC arch/x86/kernel/kdebugfs.o
CC fs/char_dev.o
CC drivers/acpi/acpica/evregion.o
CC crypto/rng.o
CC net/mac80211/offchannel.o
CC kernel/trace/power-traces.o
CC lib/ratelimit.o
CC arch/x86/kernel/alternative.o
CC arch/x86/kernel/i8253.o
CC drivers/dma/dw/core.o
CC drivers/dma/hsu/hsu.o
CC drivers/dma/dw/dw.o
CC kernel/trace/rpm-traces.o
AR drivers/dma/idxd/built-in.a
AR drivers/dma/mediatek/built-in.a
CC crypto/drbg.o
AR drivers/dma/qcom/built-in.a
CC net/mac80211/ht.o
CC block/blk-pm.o
CC net/core/gso.o
CC drivers/acpi/acpica/evrgnini.o
CC mm/process_vm_access.o
AR drivers/soc/apple/built-in.a
CC net/core/net-sysfs.o
CC drivers/virtio/virtio.o
AR drivers/soc/aspeed/built-in.a
AR drivers/soc/bcm/built-in.a
AR drivers/soc/fsl/built-in.a
AR drivers/soc/fujitsu/built-in.a
AR drivers/soc/hisilicon/built-in.a
AR drivers/soc/imx/built-in.a
AR drivers/soc/ixp4xx/built-in.a
CC drivers/virtio/virtio_ring.o
AR drivers/soc/loongson/built-in.a
CC arch/x86/kernel/hw_breakpoint.o
AR drivers/soc/mediatek/built-in.a
CC fs/ext4/readpage.o
AR drivers/soc/microchip/built-in.a
AR drivers/soc/nuvoton/built-in.a
AR drivers/soc/pxa/built-in.a
CC net/ipv6/ndisc.o
CC net/core/hotdata.o
AR drivers/soc/amlogic/built-in.a
CC arch/x86/kernel/tsc.o
AR drivers/soc/qcom/built-in.a
AR drivers/soc/renesas/built-in.a
CC drivers/dma/dw/idma32.o
CC kernel/trace/trace_dynevent.o
AR drivers/soc/rockchip/built-in.a
CC kernel/trace/trace_probe.o
AR drivers/soc/sunxi/built-in.a
AR drivers/soc/ti/built-in.a
AR drivers/soc/xilinx/built-in.a
AR drivers/soc/built-in.a
CC lib/rbtree.o
CC drivers/acpi/acpica/evsci.o
CC net/ipv6/udp.o
CC net/core/net-procfs.o
CC kernel/workqueue.o
CC drivers/tty/vt/vt_ioctl.o
CC net/xfrm/xfrm_device.o
AR drivers/dma/hsu/built-in.a
CC drivers/tty/vt/vc_screen.o
CC drivers/dma/dw/acpi.o
CC net/mac80211/agg-tx.o
CC drivers/tty/hvc/hvc_console.o
CC block/holder.o
CC lib/seq_buf.o
CC net/xfrm/xfrm_algo.o
CC lib/siphash.o
CC crypto/jitterentropy.o
CC drivers/acpi/acpica/evxface.o
CC drivers/virtio/virtio_anchor.o
CC mm/page_alloc.o
CC crypto/jitterentropy-kcapi.o
CC kernel/pid.o
CC net/mac80211/agg-rx.o
CC net/mac80211/vht.o
CC lib/string.o
CC net/ipv6/udplite.o
CC drivers/acpi/osi.o
CC net/core/netpoll.o
CC kernel/trace/trace_uprobe.o
CC crypto/ghash-generic.o
CC net/netfilter/xt_tcpudp.o
CC kernel/trace/rethook.o
CC net/wireless/chan.o
AR drivers/dma/ti/built-in.a
AR drivers/dma/dw/built-in.a
CC fs/nfs/proc.o
AR drivers/dma/xilinx/built-in.a
CC drivers/dma/dmaengine.o
CC drivers/acpi/acpica/evxfevnt.o
CC drivers/acpi/acpica/evxfgpe.o
CC fs/ext4/resize.o
CC arch/x86/kernel/tsc_msr.o
CC drivers/virtio/virtio_pci_modern_dev.o
CC net/core/fib_rules.o
CC net/netfilter/xt_CONNSECMARK.o
AR block/built-in.a
CC drivers/acpi/acpica/evxfregn.o
CC crypto/hash_info.o
CC net/sunrpc/auth.o
CC drivers/tty/vt/selection.o
AR drivers/tty/hvc/built-in.a
CC net/netfilter/xt_NFLOG.o
CC fs/nfs/nfs2xdr.o
CC net/core/net-traces.o
CC drivers/acpi/acpica/exconcat.o
CC net/mac80211/he.o
CC crypto/rsapubkey.asn1.o
CC fs/nfs/nfs3super.o
CC crypto/rsaprivkey.asn1.o
AR crypto/built-in.a
CC net/wireless/ethtool.o
CC drivers/char/hw_random/core.o
CC arch/x86/kernel/io_delay.o
CC drivers/char/hw_random/intel-rng.o
CC drivers/char/hw_random/amd-rng.o
CC arch/x86/kernel/rtc.o
CC net/xfrm/xfrm_user.o
CC net/wireless/mesh.o
CC drivers/acpi/osl.o
CC fs/ext4/super.o
CC drivers/char/agp/backend.o
CC mm/init-mm.o
CC net/wireless/ap.o
CC drivers/acpi/acpica/exconfig.o
CC net/ipv6/raw.o
CC arch/x86/kernel/resource.o
CC net/ipv6/icmp.o
CC drivers/virtio/virtio_pci_legacy_dev.o
CC net/ipv4/tcp_input.o
CC drivers/tty/vt/keyboard.o
CC lib/timerqueue.o
CC net/mac80211/s1g.o
CC fs/nfs/nfs3client.o
CC drivers/char/hw_random/geode-rng.o
CC net/netfilter/xt_SECMARK.o
CC drivers/char/agp/generic.o
CC drivers/acpi/acpica/exconvrt.o
CC lib/vsprintf.o
CC drivers/acpi/utils.o
AS arch/x86/kernel/irqflags.o
CC drivers/char/hw_random/via-rng.o
CC net/netfilter/xt_TCPMSS.o
CC kernel/task_work.o
CC net/mac80211/ibss.o
CC kernel/extable.o
CC arch/x86/kernel/static_call.o
CC net/core/selftests.o
CC drivers/dma/virt-dma.o
CC fs/ext4/symlink.o
CC drivers/char/agp/isoch.o
CC drivers/char/agp/amd64-agp.o
CC drivers/char/agp/intel-agp.o
CC net/core/ptp_classifier.o
CC drivers/virtio/virtio_pci_modern.o
CC net/mac80211/iface.o
CC fs/nfs/nfs3proc.o
AR kernel/trace/built-in.a
CC drivers/acpi/acpica/excreate.o
CC fs/nfs/nfs3xdr.o
CC net/netfilter/xt_conntrack.o
CC arch/x86/kernel/process.o
AR drivers/iommu/amd/built-in.a
AR drivers/iommu/intel/built-in.a
AR drivers/iommu/arm/arm-smmu/built-in.a
AR drivers/char/hw_random/built-in.a
AR drivers/iommu/arm/arm-smmu-v3/built-in.a
AR drivers/iommu/iommufd/built-in.a
AR drivers/iommu/arm/built-in.a
CC drivers/iommu/iommu.o
CC drivers/acpi/acpica/exdebug.o
CC drivers/acpi/reboot.o
CC net/ipv6/mcast.o
CC kernel/params.o
CC net/core/netprio_cgroup.o
CC drivers/acpi/acpica/exdump.o
CC drivers/dma/acpi-dma.o
CC net/core/netclassid_cgroup.o
CC kernel/kthread.o
CC fs/nfs/nfs3acl.o
CC drivers/char/mem.o
CC fs/nfs/nfs4proc.o
CC net/ipv4/tcp_output.o
CC fs/stat.o
CC drivers/char/agp/intel-gtt.o
CC net/wireless/trace.o
AR drivers/gpu/host1x/built-in.a
CC net/wireless/ocb.o
CC kernel/sys_ni.o
AR drivers/gpu/vga/built-in.a
CC kernel/nsproxy.o
CC drivers/acpi/acpica/exfield.o
CC drivers/acpi/acpica/exfldio.o
CC drivers/virtio/virtio_pci_common.o
CC drivers/acpi/acpica/exmisc.o
AR drivers/gpu/drm/tests/built-in.a
CC drivers/tty/vt/vt.o
AR drivers/gpu/drm/arm/built-in.a
CC fs/exec.o
CC drivers/gpu/drm/display/drm_display_helper_mod.o
CC drivers/gpu/drm/display/drm_dp_dual_mode_helper.o
CC fs/pipe.o
CC drivers/gpu/drm/display/drm_dp_helper.o
CC kernel/notifier.o
CC mm/memblock.o
CC drivers/connector/cn_queue.o
CC drivers/base/power/sysfs.o
CC net/netfilter/xt_policy.o
CC drivers/base/power/generic_ops.o
AR drivers/dma/built-in.a
CC drivers/block/loop.o
CC drivers/acpi/acpica/exmutex.o
CC drivers/block/virtio_blk.o
CC drivers/gpu/drm/ttm/ttm_tt.o
CC kernel/ksysfs.o
AR net/xfrm/built-in.a
AR drivers/misc/eeprom/built-in.a
AR drivers/misc/cb710/built-in.a
AR drivers/misc/ti-st/built-in.a
CC mm/slub.o
CC net/wireless/pmsr.o
AR drivers/misc/lis3lv02d/built-in.a
CC net/core/dst_cache.o
AR drivers/misc/cardreader/built-in.a
AR drivers/misc/built-in.a
GEN net/wireless/shipped-certs.c
AR drivers/mfd/built-in.a
CC drivers/virtio/virtio_pci_legacy.o
CC drivers/gpu/drm/ttm/ttm_bo.o
AR drivers/nfc/built-in.a
CC drivers/virtio/virtio_pci_admin_legacy_io.o
CC drivers/gpu/drm/i915/i915_config.o
AR drivers/char/agp/built-in.a
CC drivers/char/random.o
CC drivers/iommu/iommu-traces.o
CC fs/nfs/nfs4xdr.o
CC drivers/iommu/iommu-sysfs.o
CC drivers/iommu/dma-iommu.o
CC drivers/acpi/acpica/exnames.o
CC arch/x86/kernel/ptrace.o
CC arch/x86/kernel/tls.o
CC drivers/base/power/common.o
CC net/netfilter/xt_state.o
AR drivers/gpu/drm/renesas/rcar-du/built-in.a
AR drivers/gpu/drm/renesas/rz-du/built-in.a
AR drivers/gpu/drm/renesas/built-in.a
CC net/core/gro_cells.o
CC net/wireless/shipped-certs.o
CC drivers/gpu/drm/i915/i915_driver.o
CC drivers/connector/connector.o
CC lib/win_minmax.o
CC drivers/iommu/iova.o
CC fs/nfs/nfs4state.o
CC net/sunrpc/auth_null.o
CC kernel/cred.o
CC drivers/connector/cn_proc.o
CC drivers/acpi/acpica/exoparg1.o
CC net/ipv6/reassembly.o
CC drivers/gpu/drm/display/drm_dp_mst_topology.o
CC drivers/virtio/virtio_input.o
CC drivers/virtio/virtio_dma_buf.o
CC lib/xarray.o
CC drivers/base/power/qos.o
CC [M] net/netfilter/nf_log_syslog.o
CC drivers/base/power/runtime.o
CC mm/madvise.o
CC fs/nfs/nfs4renewd.o
CC drivers/gpu/drm/ttm/ttm_bo_util.o
CC net/core/failover.o
AR drivers/dax/hmem/built-in.a
AR drivers/dax/built-in.a
CC drivers/dma-buf/dma-buf.o
CC fs/ext4/sysfs.o
CC drivers/acpi/acpica/exoparg2.o
CC drivers/dma-buf/dma-fence.o
CC net/mac80211/link.o
CC drivers/base/power/wakeirq.o
CC arch/x86/kernel/step.o
CC mm/page_io.o
CC net/sunrpc/auth_tls.o
CC drivers/gpu/drm/ttm/ttm_bo_vm.o
CC drivers/char/misc.o
CC net/sunrpc/auth_unix.o
CC drivers/gpu/drm/i915/i915_drm_client.o
AR drivers/block/built-in.a
CC [M] net/netfilter/xt_mark.o
CC [M] net/netfilter/xt_nat.o
CC net/mac80211/rate.o
CC net/mac80211/michael.o
AR drivers/virtio/built-in.a
CC drivers/dma-buf/dma-fence-array.o
AR drivers/cxl/core/built-in.a
AR drivers/cxl/built-in.a
CC kernel/reboot.o
CC mm/swap_state.o
CC drivers/acpi/acpica/exoparg3.o
CC net/sunrpc/svc.o
AR drivers/iommu/built-in.a
AR drivers/connector/built-in.a
CC drivers/macintosh/mac_hid.o
COPY drivers/tty/vt/defkeymap.c
AR drivers/scsi/pcmcia/built-in.a
CC drivers/scsi/scsi.o
CC drivers/tty/vt/consolemap.o
CC drivers/dma-buf/dma-fence-chain.o
CC drivers/gpu/drm/ttm/ttm_module.o
CC arch/x86/kernel/i8237.o
CC arch/x86/kernel/stacktrace.o
HOSTCC drivers/tty/vt/conmakehash
CC drivers/gpu/drm/ttm/ttm_execbuf_util.o
AR net/core/built-in.a
CC drivers/gpu/drm/ttm/ttm_range_manager.o
CC drivers/base/power/main.o
CC drivers/acpi/acpica/exoparg6.o
CC drivers/char/virtio_console.o
CC lib/lockref.o
CC arch/x86/kernel/reboot.o
CC net/sunrpc/svcsock.o
CC net/ipv6/tcp_ipv6.o
CC net/ipv4/tcp_timer.o
CC net/ipv6/ping.o
CC drivers/scsi/hosts.o
CC drivers/gpu/drm/ttm/ttm_resource.o
CC arch/x86/kernel/msr.o
CC kernel/async.o
CC net/ipv6/exthdrs.o
CC drivers/dma-buf/dma-fence-unwrap.o
CC net/ipv4/tcp_ipv4.o
CC drivers/gpu/drm/i915/i915_getparam.o
CC lib/bcd.o
CC mm/swapfile.o
CC mm/swap_slots.o
AR drivers/macintosh/built-in.a
CC lib/sort.o
AR drivers/gpu/drm/omapdrm/built-in.a
CC net/sunrpc/svcauth.o
CC drivers/tty/vt/defkeymap.o
AR drivers/gpu/drm/tilcdc/built-in.a
CC net/mac80211/tkip.o
CC net/mac80211/aes_cmac.o
CC lib/parser.o
CC drivers/acpi/acpica/exprep.o
CC [M] net/netfilter/xt_LOG.o
CC drivers/gpu/drm/ttm/ttm_pool.o
CC lib/debug_locks.o
CC [M] net/netfilter/xt_MASQUERADE.o
CC drivers/scsi/scsi_ioctl.o
CC arch/x86/kernel/cpuid.o
CONMK drivers/tty/vt/consolemap_deftbl.c
CC drivers/tty/vt/consolemap_deftbl.o
CC kernel/range.o
CC lib/random32.o
CC kernel/smpboot.o
CC drivers/gpu/drm/ttm/ttm_device.o
CC net/sunrpc/svcauth_unix.o
CC drivers/acpi/acpica/exregion.o
AR drivers/tty/vt/built-in.a
CC arch/x86/kernel/early-quirks.o
CC drivers/tty/serial/8250/8250_core.o
CC arch/x86/kernel/smp.o
CC drivers/dma-buf/dma-resv.o
CC drivers/tty/serial/8250/8250_pnp.o
CC drivers/acpi/acpica/exresnte.o
CC mm/dmapool.o
CC arch/x86/kernel/smpboot.o
CC net/ipv4/tcp_minisocks.o
CC lib/bust_spinlocks.o
CC drivers/base/power/wakeup.o
CC mm/hugetlb.o
CC drivers/gpu/drm/ttm/ttm_sys_manager.o
CC drivers/dma-buf/sync_file.o
CC drivers/gpu/drm/ttm/ttm_backup_shmem.o
CC lib/kasprintf.o
AR drivers/nvme/common/built-in.a
AR drivers/nvme/host/built-in.a
CC lib/bitmap.o
AR drivers/nvme/target/built-in.a
AR drivers/nvme/built-in.a
CC drivers/base/power/wakeup_stats.o
CC net/sunrpc/addr.o
CC kernel/ucount.o
CC drivers/acpi/acpica/exresolv.o
CC drivers/gpu/drm/i915/i915_ioctl.o
CC drivers/char/hpet.o
CC net/ipv6/datagram.o
CC drivers/gpu/drm/ttm/ttm_agp_backend.o
CC lib/scatterlist.o
CC drivers/ata/libata-core.o
CC drivers/scsi/scsicam.o
AR drivers/net/phy/qcom/built-in.a
CC drivers/net/phy/mdio-boardinfo.o
CC drivers/gpu/drm/display/drm_dsc_helper.o
CC drivers/gpu/drm/display/drm_hdcp_helper.o
AR drivers/net/pse-pd/built-in.a
CC drivers/tty/serial/8250/8250_port.o
CC drivers/ata/libata-scsi.o
CC drivers/base/firmware_loader/builtin/main.o
CC drivers/scsi/scsi_error.o
CC drivers/ata/libata-eh.o
CC drivers/ata/libata-transport.o
CC lib/list_sort.o
CC net/ipv4/tcp_cong.o
CC drivers/acpi/acpica/exresop.o
CC drivers/acpi/acpica/exserial.o
CC drivers/base/power/trace.o
CC drivers/acpi/acpica/exstore.o
CC kernel/regset.o
CC fs/nfs/nfs4super.o
AR drivers/dma-buf/built-in.a
CC [M] net/netfilter/xt_addrtype.o
CC fs/nfs/nfs4file.o
CC net/sunrpc/rpcb_clnt.o
CC drivers/base/firmware_loader/main.o
CC net/mac80211/aes_gmac.o
CC drivers/gpu/drm/virtio/virtgpu_drv.o
CC lib/uuid.o
AR drivers/base/firmware_loader/builtin/built-in.a
CC drivers/gpu/drm/virtio/virtgpu_kms.o
CC arch/x86/kernel/tsc_sync.o
CC net/mac80211/fils_aead.o
CC net/ipv6/ip6_flowlabel.o
AR drivers/gpu/drm/ttm/built-in.a
CC drivers/base/regmap/regmap.o
CC drivers/gpu/drm/display/drm_hdmi_helper.o
CC kernel/ksyms_common.o
AR drivers/base/test/built-in.a
CC kernel/groups.o
CC drivers/acpi/acpica/exstoren.o
CC net/mac80211/cfg.o
CC drivers/gpu/drm/i915/i915_irq.o
CC drivers/char/nvram.o
AR drivers/tty/ipwireless/built-in.a
CC drivers/gpu/drm/display/drm_scdc_helper.o
CC drivers/tty/tty_io.o
CC drivers/net/phy/stubs.o
CC drivers/gpu/drm/i915/i915_mitigations.o
CC drivers/tty/n_tty.o
CC mm/mmu_notifier.o
CC drivers/acpi/acpica/exstorob.o
AR drivers/base/power/built-in.a
CC drivers/base/component.o
CC drivers/base/core.o
CC lib/iov_iter.o
CC drivers/acpi/acpica/exsystem.o
CC arch/x86/kernel/setup_percpu.o
AR drivers/gpu/drm/imx/built-in.a
CC drivers/acpi/acpica/extrace.o
CC drivers/tty/tty_ioctl.o
CC drivers/ata/libata-trace.o
CC net/ipv6/inet6_connection_sock.o
CC drivers/gpu/drm/virtio/virtgpu_gem.o
CC drivers/ata/libata-sata.o
CC net/ipv4/tcp_metrics.o
AR drivers/base/firmware_loader/built-in.a
CC drivers/base/bus.o
CC kernel/kcmp.o
AR drivers/gpu/drm/i2c/built-in.a
CC drivers/acpi/acpica/exutils.o
CC net/mac80211/ethtool.o
AR drivers/gpu/drm/panel/built-in.a
CC net/sunrpc/timer.o
CC drivers/ata/libata-sff.o
CC net/ipv6/udp_offload.o
CC drivers/gpu/drm/virtio/virtgpu_vram.o
CC fs/namei.o
CC arch/x86/kernel/mpparse.o
AR drivers/char/built-in.a
CC net/ipv4/tcp_fastopen.o
CC drivers/firewire/init_ohci1394_dma.o
AR drivers/gpu/drm/display/built-in.a
CC drivers/scsi/scsi_lib.o
AR net/netfilter/built-in.a
CC drivers/cdrom/cdrom.o
CC fs/fcntl.o
CC net/ipv4/tcp_rate.o
CC fs/nfs/delegation.o
CC drivers/net/phy/mdio_devres.o
CC arch/x86/kernel/trace_clock.o
CC drivers/tty/serial/8250/8250_dma.o
CC drivers/acpi/acpica/hwacpi.o
CC net/sunrpc/xdr.o
CC drivers/scsi/constants.o
CC net/mac80211/rx.o
CC drivers/scsi/scsi_lib_dma.o
CC net/sunrpc/sunrpc_syms.o
CC fs/nfs/nfs4idmap.o
CC drivers/scsi/scsi_scan.o
CC drivers/tty/tty_ldisc.o
AR drivers/auxdisplay/built-in.a
CC drivers/pcmcia/cs.o
CC drivers/usb/common/common.o
CC drivers/acpi/acpica/hwesleep.o
CC kernel/freezer.o
CC drivers/usb/common/debug.o
CC arch/x86/kernel/trace.o
CC drivers/gpu/drm/virtio/virtgpu_display.o
CC drivers/gpu/drm/i915/i915_module.o
AR drivers/firewire/built-in.a
CC net/sunrpc/cache.o
CC mm/migrate.o
CC drivers/tty/tty_buffer.o
CC arch/x86/kernel/rethook.o
CC kernel/profile.o
CC drivers/tty/tty_port.o
CC drivers/tty/serial/8250/8250_dwlib.o
CC fs/ext4/xattr.o
CC drivers/pcmcia/socket_sysfs.o
CC drivers/tty/serial/8250/8250_pcilib.o
CC drivers/net/phy/phy.o
CC arch/x86/kernel/vmcore_info_32.o
CC drivers/ata/libata-pmp.o
CC drivers/acpi/acpica/hwgpe.o
CC drivers/net/phy/phy-c45.o
GEN drivers/scsi/scsi_devinfo_tbl.c
CC drivers/scsi/scsi_devinfo.o
CC net/ipv6/seg6.o
CC drivers/net/mdio/acpi_mdio.o
CC drivers/base/regmap/regcache.o
CC drivers/base/regmap/regcache-rbtree.o
AR drivers/usb/common/built-in.a
CC drivers/base/regmap/regcache-flat.o
CC net/sunrpc/rpc_pipe.o
CC net/ipv4/tcp_recovery.o
CC drivers/usb/core/usb.o
CC net/ipv4/tcp_ulp.o
AR drivers/usb/phy/built-in.a
CC drivers/ata/libata-acpi.o
CC drivers/ata/libata-pata-timings.o
CC lib/clz_ctz.o
CC lib/bsearch.o
CC drivers/ata/ahci.o
CC mm/page_counter.o
CC drivers/acpi/acpica/hwregs.o
CC drivers/gpu/drm/virtio/virtgpu_vq.o
CC arch/x86/kernel/machine_kexec_32.o
CC drivers/acpi/acpica/hwsleep.o
CC drivers/gpu/drm/i915/i915_params.o
CC drivers/gpu/drm/i915/i915_pci.o
CC drivers/scsi/scsi_sysctl.o
CC drivers/tty/serial/8250/8250_early.o
CC drivers/usb/core/hub.o
CC drivers/base/regmap/regcache-maple.o
CC kernel/stacktrace.o
CC drivers/pcmcia/cardbus.o
CC drivers/net/phy/phy-core.o
CC drivers/base/regmap/regmap-debugfs.o
CC net/mac80211/spectmgmt.o
AR drivers/cdrom/built-in.a
CC drivers/input/serio/serio.o
CC drivers/gpu/drm/i915/i915_scatterlist.o
CC drivers/usb/core/hcd.o
CC drivers/scsi/scsi_proc.o
CC drivers/net/phy/phy_device.o
CC net/mac80211/tx.o
CC drivers/input/serio/i8042.o
CC drivers/net/mdio/fwnode_mdio.o
CC drivers/acpi/acpica/hwvalid.o
CC lib/find_bit.o
CC drivers/ata/libahci.o
CC drivers/ata/ata_piix.o
CC drivers/ata/pata_amd.o
CC mm/hugetlb_cgroup.o
CC net/ipv6/fib6_notifier.o
CC drivers/ata/pata_oldpiix.o
CC drivers/usb/core/urb.o
CC drivers/tty/serial/8250/8250_exar.o
CC kernel/dma.o
AS arch/x86/kernel/relocate_kernel_32.o
CC lib/llist.o
CC arch/x86/kernel/crash_dump_32.o
CC fs/nfs/callback.o
CC fs/nfs/callback_xdr.o
CC lib/lwq.o
CC drivers/tty/serial/8250/8250_lpss.o
CC drivers/acpi/acpica/hwxface.o
CC mm/early_ioremap.o
CC drivers/pcmcia/ds.o
CC fs/nfs/callback_proc.o
CC drivers/ata/pata_sch.o
CC arch/x86/kernel/crash.o
CC net/ipv6/rpl.o
CC drivers/ata/pata_mpiix.o
CC lib/memweight.o
AR drivers/base/regmap/built-in.a
CC drivers/base/dd.o
CC drivers/tty/serial/8250/8250_mid.o
CC drivers/input/serio/serport.o
CC net/mac80211/key.o
CC net/ipv4/tcp_offload.o
CC lib/kfifo.o
CC drivers/net/phy/linkmode.o
CC drivers/acpi/acpica/hwxfsleep.o
CC drivers/gpu/drm/i915/i915_suspend.o
CC drivers/gpu/drm/virtio/virtgpu_fence.o
CC fs/ioctl.o
CC drivers/scsi/scsi_debugfs.o
CC kernel/smp.o
CC drivers/scsi/scsi_trace.o
CC net/sunrpc/sysfs.o
AR drivers/gpu/drm/bridge/analogix/built-in.a
AR drivers/net/mdio/built-in.a
AR drivers/gpu/drm/bridge/cadence/built-in.a
AR drivers/gpu/drm/hisilicon/built-in.a
AR drivers/gpu/drm/bridge/imx/built-in.a
AR drivers/net/pcs/built-in.a
AR drivers/gpu/drm/bridge/synopsys/built-in.a
AR drivers/gpu/drm/bridge/built-in.a
CC net/sunrpc/svc_xprt.o
AR drivers/net/ethernet/3com/built-in.a
CC net/sunrpc/xprtmultipath.o
CC drivers/net/ethernet/8390/ne2k-pci.o
CC fs/ext4/xattr_hurd.o
AR drivers/net/ethernet/adaptec/built-in.a
CC drivers/acpi/acpica/hwpci.o
CC fs/ext4/xattr_trusted.o
CC drivers/usb/core/message.o
AR drivers/net/ethernet/agere/built-in.a
CC drivers/tty/tty_mutex.o
AR drivers/net/ethernet/alacritech/built-in.a
CC net/sunrpc/stats.o
AR drivers/net/ethernet/alteon/built-in.a
AR drivers/net/ethernet/amazon/built-in.a
CC net/sunrpc/sysctl.o
CC mm/secretmem.o
CC drivers/ata/ata_generic.o
CC arch/x86/kernel/module.o
CC arch/x86/kernel/doublefault_32.o
CC net/ipv6/ioam6.o
CC arch/x86/kernel/early_printk.o
CC drivers/input/serio/libps2.o
AR drivers/net/wireless/admtek/built-in.a
AR drivers/net/wireless/ath/built-in.a
AR drivers/net/wireless/atmel/built-in.a
CC drivers/usb/mon/mon_main.o
AR drivers/net/wireless/broadcom/built-in.a
CC drivers/tty/serial/8250/8250_pci.o
AR drivers/net/wireless/intel/built-in.a
AR drivers/net/wireless/intersil/built-in.a
CC drivers/usb/mon/mon_stat.o
AR drivers/net/wireless/marvell/built-in.a
CC lib/percpu-refcount.o
CC drivers/usb/mon/mon_text.o
AR drivers/net/wireless/mediatek/built-in.a
CC drivers/net/mii.o
AR drivers/net/usb/built-in.a
AR drivers/net/wireless/microchip/built-in.a
AR drivers/net/wireless/purelifi/built-in.a
AR drivers/net/wireless/quantenna/built-in.a
CC arch/x86/kernel/hpet.o
CC fs/nfs/nfs4namespace.o
AR drivers/net/wireless/ralink/built-in.a
CC drivers/pcmcia/pcmcia_resource.o
CC drivers/base/syscore.o
CC drivers/acpi/acpica/nsaccess.o
AR drivers/net/wireless/realtek/built-in.a
CC net/ipv6/sysctl_net_ipv6.o
AR drivers/net/wireless/rsi/built-in.a
AR drivers/net/wireless/silabs/built-in.a
CC drivers/gpu/drm/virtio/virtgpu_object.o
AR drivers/net/wireless/st/built-in.a
CC drivers/tty/serial/8250/8250_pericom.o
AR drivers/net/wireless/ti/built-in.a
CC drivers/tty/tty_ldsem.o
AR drivers/net/wireless/zydas/built-in.a
AR drivers/net/wireless/virtual/built-in.a
CC drivers/scsi/scsi_logging.o
AR drivers/net/wireless/built-in.a
CC drivers/gpu/drm/virtio/virtgpu_debugfs.o
AR drivers/net/ethernet/amd/built-in.a
CC drivers/usb/mon/mon_bin.o
CC fs/ext4/xattr_user.o
CC drivers/net/phy/mdio_bus.o
CC drivers/tty/tty_baudrate.o
CC drivers/base/driver.o
CC arch/x86/kernel/amd_nb.o
CC lib/rhashtable.o
CC lib/base64.o
AR drivers/net/ethernet/aquantia/built-in.a
CC drivers/usb/host/pci-quirks.o
CC drivers/acpi/nvs.o
CC drivers/gpu/drm/i915/i915_switcheroo.o
CC lib/once.o
CC drivers/usb/host/ehci-hcd.o
AR drivers/ata/built-in.a
CC mm/hmm.o
CC net/ipv4/tcp_plb.o
CC drivers/acpi/acpica/nsalloc.o
CC mm/memfd.o
CC drivers/net/ethernet/8390/8390.o
CC kernel/uid16.o
AR drivers/input/serio/built-in.a
CC drivers/acpi/acpica/nsarguments.o
CC drivers/usb/host/ehci-pci.o
CC net/mac80211/util.o
CC drivers/gpu/drm/i915/i915_sysfs.o
CC drivers/pcmcia/cistpl.o
CC arch/x86/kernel/kvm.o
CC drivers/input/keyboard/atkbd.o
CC drivers/input/mouse/psmouse-base.o
CC fs/readdir.o
CC drivers/usb/core/driver.o
CC drivers/base/class.o
CC drivers/base/platform.o
AR drivers/net/ethernet/arc/built-in.a
CC drivers/base/cpu.o
CC kernel/kallsyms.o
AR net/wireless/built-in.a
CC kernel/acct.o
CC drivers/tty/tty_jobctrl.o
CC drivers/gpu/drm/virtio/virtgpu_plane.o
CC drivers/gpu/drm/virtio/virtgpu_ioctl.o
CC drivers/acpi/acpica/nsconvert.o
AR drivers/input/joystick/built-in.a
CC drivers/input/mouse/synaptics.o
CC mm/ptdump.o
CC fs/ext4/fast_commit.o
CC drivers/usb/class/usblp.o
CC drivers/scsi/scsi_pm.o
CC drivers/scsi/scsi_bsg.o
CC drivers/usb/storage/scsiglue.o
CC drivers/input/mouse/focaltech.o
AR drivers/usb/misc/built-in.a
CC arch/x86/kernel/kvmclock.o
CC drivers/input/mouse/alps.o
AR drivers/tty/serial/8250/built-in.a
CC drivers/tty/serial/serial_core.o
CC net/mac80211/parse.o
CC fs/nfs/nfs4getroot.o
CC drivers/base/firmware.o
AR drivers/usb/mon/built-in.a
CC drivers/usb/core/config.o
CC drivers/usb/host/ohci-hcd.o
CC drivers/tty/serial/serial_base_bus.o
CC drivers/acpi/acpica/nsdump.o
CC drivers/input/mouse/byd.o
CC net/ipv6/xfrm6_policy.o
CC kernel/vmcore_info.o
CC lib/refcount.o
CC lib/rcuref.o
CC drivers/gpu/drm/i915/i915_utils.o
CC drivers/net/phy/mdio_device.o
AR mm/built-in.a
CC drivers/tty/serial/serial_ctrl.o
CC net/mac80211/wme.o
CC drivers/usb/host/ohci-pci.o
AR drivers/net/ethernet/8390/built-in.a
CC drivers/acpi/acpica/nseval.o
AR drivers/net/ethernet/asix/built-in.a
AR drivers/input/keyboard/built-in.a
AR drivers/net/ethernet/atheros/built-in.a
CC lib/usercopy.o
CC drivers/acpi/acpica/nsinit.o
CC kernel/elfcorehdr.o
CC net/ipv6/xfrm6_state.o
AR drivers/net/ethernet/cadence/built-in.a
CC net/ipv6/xfrm6_input.o
CC net/ipv4/datagram.o
CC drivers/net/ethernet/broadcom/bnx2.o
CC net/ipv6/xfrm6_output.o
CC drivers/input/mouse/logips2pp.o
CC drivers/base/init.o
CC drivers/net/ethernet/broadcom/tg3.o
AR drivers/input/tablet/built-in.a
CC drivers/gpu/drm/i915/intel_clock_gating.o
CC drivers/scsi/scsi_common.o
CC drivers/gpu/drm/virtio/virtgpu_prime.o
CC net/ipv6/xfrm6_protocol.o
CC drivers/base/map.o
CC net/ipv4/raw.o
CC net/ipv4/udp.o
CC arch/x86/kernel/paravirt.o
CC drivers/pcmcia/pcmcia_cis.o
CC drivers/usb/storage/protocol.o
AR drivers/usb/class/built-in.a
CC drivers/usb/storage/transport.o
CC drivers/net/loopback.o
CC lib/errseq.o
CC drivers/usb/host/uhci-hcd.o
CC drivers/usb/host/xhci.o
CC drivers/acpi/acpica/nsload.o
CC drivers/tty/serial/serial_port.o
CC fs/select.o
CC lib/bucket_locks.o
CC fs/dcache.o
CC kernel/crash_reserve.o
CC drivers/net/phy/swphy.o
CC drivers/base/devres.o
CC arch/x86/kernel/pvclock.o
CC drivers/scsi/scsi_transport_spi.o
CC drivers/input/mouse/lifebook.o
CC drivers/usb/host/xhci-mem.o
CC fs/nfs/nfs4client.o
CC drivers/input/mouse/trackpoint.o
AR net/sunrpc/built-in.a
CC drivers/usb/host/xhci-ext-caps.o
CC drivers/base/attribute_container.o
CC drivers/usb/core/file.o
CC drivers/usb/core/buffer.o
CC drivers/acpi/acpica/nsnames.o
CC lib/generic-radix-tree.o
CC drivers/gpu/drm/i915/intel_device_info.o
CC drivers/gpu/drm/virtio/virtgpu_trace_points.o
CC drivers/rtc/lib.o
CC net/ipv6/netfilter.o
CC drivers/gpu/drm/virtio/virtgpu_submit.o
CC net/ipv6/proc.o
CC drivers/i2c/algos/i2c-algo-bit.o
CC drivers/i2c/busses/i2c-i801.o
AR drivers/i3c/built-in.a
AR drivers/i2c/muxes/built-in.a
CC drivers/i2c/i2c-boardinfo.o
AR drivers/input/touchscreen/built-in.a
CC kernel/kexec_core.o
CC kernel/crash_core.o
CC arch/x86/kernel/pcspeaker.o
CC drivers/pcmcia/rsrc_mgr.o
CC lib/bitmap-str.o
CC drivers/acpi/acpica/nsobject.o
CC kernel/kexec.o
CC drivers/base/transport_class.o
CC drivers/usb/storage/usb.o
CC drivers/net/phy/fixed_phy.o
CC drivers/net/phy/realtek.o
CC drivers/i2c/i2c-core-base.o
CC drivers/usb/early/ehci-dbgp.o
CC drivers/i2c/i2c-core-smbus.o
CC drivers/input/mouse/cypress_ps2.o
CC drivers/i2c/i2c-core-acpi.o
CC drivers/usb/core/sysfs.o
CC drivers/net/netconsole.o
CC kernel/utsname.o
AR drivers/input/misc/built-in.a
CC drivers/usb/core/endpoint.o
CC drivers/rtc/class.o
CC drivers/tty/serial/earlycon.o
CC arch/x86/kernel/check.o
CC arch/x86/kernel/uprobes.o
CC drivers/acpi/acpica/nsparse.o
CC drivers/usb/host/xhci-ring.o
CC drivers/base/topology.o
CC drivers/gpu/drm/i915/intel_memory_region.o
CC net/ipv4/udplite.o
CC drivers/pcmcia/rsrc_nonstatic.o
CC drivers/i2c/i2c-smbus.o
AR drivers/gpu/drm/virtio/built-in.a
CC lib/string_helpers.o
AR drivers/gpu/drm/mxsfb/built-in.a
CC drivers/gpu/drm/i915/intel_pcode.o
CC drivers/pcmcia/yenta_socket.o
CC drivers/gpu/drm/i915/intel_region_ttm.o
AR drivers/i2c/algos/built-in.a
CC drivers/gpu/drm/i915/intel_runtime_pm.o
CC drivers/input/mouse/psmouse-smbus.o
CC fs/nfs/nfs4session.o
CC kernel/pid_namespace.o
CC fs/ext4/orphan.o
CC drivers/gpu/drm/i915/intel_sbi.o
AR drivers/net/ethernet/brocade/built-in.a
CC net/ipv4/udp_offload.o
CC drivers/acpi/acpica/nspredef.o
AR drivers/gpu/drm/tiny/built-in.a
CC drivers/scsi/virtio_scsi.o
CC kernel/stop_machine.o
AR drivers/net/ethernet/cavium/common/built-in.a
CC net/ipv4/arp.o
AR drivers/net/ethernet/cavium/thunder/built-in.a
AR drivers/net/ethernet/cavium/liquidio/built-in.a
CC lib/hexdump.o
CC drivers/rtc/interface.o
AR drivers/net/ethernet/cavium/octeon/built-in.a
AR drivers/net/ethernet/cavium/built-in.a
CC drivers/acpi/wakeup.o
CC drivers/scsi/sd.o
AR drivers/net/ethernet/chelsio/built-in.a
AR drivers/net/ethernet/cisco/built-in.a
CC net/ipv4/icmp.o
AR drivers/usb/early/built-in.a
AR drivers/net/ethernet/cortina/built-in.a
CC drivers/scsi/sr.o
CC drivers/rtc/nvmem.o
AR drivers/net/ethernet/dec/tulip/built-in.a
AR drivers/net/ethernet/dec/built-in.a
CC drivers/usb/storage/initializers.o
AR drivers/net/phy/built-in.a
CC drivers/tty/n_null.o
CC fs/inode.o
AR drivers/i2c/busses/built-in.a
CC drivers/net/virtio_net.o
AR drivers/tty/serial/built-in.a
AR drivers/gpu/drm/xlnx/built-in.a
CC drivers/net/net_failover.o
CC net/ipv4/devinet.o
CC lib/kstrtox.o
CC drivers/base/container.o
CC drivers/usb/storage/sierra_ms.o
AR drivers/net/ethernet/dlink/built-in.a
CC drivers/usb/core/devio.o
CC arch/x86/kernel/perf_regs.o
CC drivers/usb/core/notify.o
CC net/ipv6/syncookies.o
CC net/mac80211/chan.o
CC drivers/acpi/acpica/nsprepkg.o
CC drivers/acpi/acpica/nsrepair.o
CC drivers/acpi/sleep.o
CC fs/attr.o
CC drivers/base/property.o
CC drivers/usb/host/xhci-hub.o
CC drivers/usb/host/xhci-dbg.o
CC drivers/usb/core/generic.o
AR drivers/input/mouse/built-in.a
CC drivers/base/cacheinfo.o
CC drivers/input/input.o
CC lib/iomap.o
CC drivers/input/input-compat.o
CC arch/x86/kernel/tracepoint.o
CC drivers/acpi/acpica/nsrepair2.o
CC kernel/audit.o
CC arch/x86/kernel/itmt.o
CC drivers/tty/pty.o
CC drivers/input/input-mt.o
CC drivers/input/input-poller.o
CC drivers/tty/tty_audit.o
CC drivers/acpi/acpica/nssearch.o
CC fs/ext4/acl.o
CC net/ipv4/af_inet.o
CC drivers/rtc/dev.o
CC arch/x86/kernel/umip.o
CC fs/nfs/dns_resolve.o
AR drivers/pcmcia/built-in.a
CC drivers/usb/core/quirks.o
AR drivers/i2c/built-in.a
CC drivers/rtc/proc.o
CC net/ipv4/igmp.o
CC drivers/usb/storage/option_ms.o
CC arch/x86/kernel/unwind_frame.o
CC drivers/gpu/drm/i915/intel_step.o
CC net/mac80211/trace.o
CC drivers/usb/core/devices.o
CC net/ipv4/fib_frontend.o
CC fs/nfs/nfs4trace.o
CC drivers/tty/sysrq.o
AR drivers/media/i2c/built-in.a
AR drivers/media/tuners/built-in.a
CC drivers/acpi/acpica/nsutils.o
AR drivers/pps/clients/built-in.a
AR drivers/pps/generators/built-in.a
CC drivers/acpi/acpica/nswalk.o
AR drivers/media/rc/keymaps/built-in.a
CC drivers/pps/pps.o
AR drivers/media/rc/built-in.a
CC drivers/pps/kapi.o
AR drivers/media/common/b2c2/built-in.a
CC kernel/auditfilter.o
CC drivers/base/swnode.o
AR drivers/media/common/saa7146/built-in.a
CC drivers/acpi/acpica/nsxfeval.o
AR drivers/media/common/siano/built-in.a
CC drivers/usb/core/phy.o
AR drivers/media/common/v4l2-tpg/built-in.a
AR drivers/gpu/drm/gud/built-in.a
AR drivers/media/common/videobuf2/built-in.a
CC drivers/usb/core/port.o
AR drivers/media/common/built-in.a
CC lib/iomap_copy.o
AR drivers/media/platform/allegro-dvt/built-in.a
CC drivers/usb/core/hcd-pci.o
AR drivers/media/platform/amlogic/meson-ge2d/built-in.a
AR drivers/media/platform/amlogic/built-in.a
CC drivers/usb/core/usb-acpi.o
CC net/ipv6/calipso.o
AR drivers/media/platform/amphion/built-in.a
AR drivers/media/pci/ttpci/built-in.a
AR drivers/media/platform/aspeed/built-in.a
CC net/ipv6/ah6.o
CC drivers/input/ff-core.o
AR drivers/media/platform/atmel/built-in.a
AR drivers/media/pci/b2c2/built-in.a
CC drivers/rtc/sysfs.o
CC drivers/pps/sysfs.o
AR drivers/media/pci/pluto2/built-in.a
AR drivers/media/platform/cadence/built-in.a
AR drivers/media/pci/dm1105/built-in.a
AR drivers/media/platform/chips-media/coda/built-in.a
AR drivers/media/pci/pt1/built-in.a
AR drivers/media/platform/chips-media/wave5/built-in.a
CC lib/devres.o
CC kernel/auditsc.o
AR drivers/media/platform/chips-media/built-in.a
AR drivers/media/pci/pt3/built-in.a
CC kernel/audit_watch.o
AR drivers/media/platform/intel/built-in.a
AR drivers/media/pci/mantis/built-in.a
CC drivers/acpi/acpica/nsxfname.o
AR drivers/media/pci/ngene/built-in.a
AR drivers/media/platform/marvell/built-in.a
CC kernel/audit_fsnotify.o
AR drivers/media/pci/ddbridge/built-in.a
CC fs/ext4/xattr_security.o
AR drivers/media/platform/mediatek/jpeg/built-in.a
CC kernel/audit_tree.o
AR drivers/media/pci/saa7146/built-in.a
AR drivers/media/platform/mediatek/mdp/built-in.a
AR drivers/media/pci/smipcie/built-in.a
CC drivers/usb/storage/usual-tables.o
AR drivers/media/pci/netup_unidvb/built-in.a
AR drivers/media/platform/mediatek/vpu/built-in.a
AR drivers/media/platform/mediatek/vcodec/common/built-in.a
AR drivers/media/platform/microchip/built-in.a
AR drivers/media/platform/mediatek/vcodec/encoder/built-in.a
AR drivers/media/pci/intel/ivsc/built-in.a
AR drivers/media/pci/intel/ipu3/built-in.a
AR arch/x86/kernel/built-in.a
AR drivers/media/platform/mediatek/vcodec/decoder/built-in.a
AR drivers/media/pci/intel/built-in.a
AR drivers/media/platform/nuvoton/built-in.a
AR drivers/media/platform/mediatek/vcodec/built-in.a
AR drivers/media/pci/built-in.a
CC drivers/input/touchscreen.o
CC fs/nfs/nfs4sysctl.o
AR arch/x86/built-in.a
CC drivers/acpi/device_sysfs.o
AR drivers/media/platform/mediatek/mdp3/built-in.a
AR drivers/media/platform/mediatek/built-in.a
AR drivers/gpu/drm/solomon/built-in.a
CC drivers/rtc/rtc-mc146818-lib.o
AR drivers/media/platform/nvidia/tegra-vde/built-in.a
CC [M] drivers/gpu/drm/scheduler/sched_main.o
CC drivers/base/auxiliary.o
CC drivers/base/devtmpfs.o
AR drivers/media/platform/nvidia/built-in.a
CC [M] drivers/gpu/drm/scheduler/sched_fence.o
AR drivers/media/platform/nxp/dw100/built-in.a
AR drivers/media/platform/nxp/imx-jpeg/built-in.a
AR drivers/media/platform/nxp/imx8-isi/built-in.a
AR drivers/media/platform/nxp/built-in.a
AR drivers/pps/built-in.a
CC drivers/gpu/drm/i915/intel_uncore.o
AR drivers/media/platform/qcom/camss/built-in.a
CC drivers/base/module.o
CC drivers/ptp/ptp_clock.o
AR drivers/media/platform/qcom/venus/built-in.a
CC drivers/ptp/ptp_chardev.o
AR drivers/media/platform/renesas/rcar-vin/built-in.a
AR drivers/media/platform/qcom/built-in.a
AR drivers/media/platform/renesas/rzg2l-cru/built-in.a
AR drivers/media/platform/renesas/vsp1/built-in.a
CC drivers/input/ff-memless.o
AR drivers/media/platform/renesas/built-in.a
AR drivers/media/platform/rockchip/rga/built-in.a
AR drivers/media/platform/rockchip/rkisp1/built-in.a
AR drivers/media/platform/rockchip/built-in.a
CC fs/bad_inode.o
AR drivers/media/platform/samsung/exynos-gsc/built-in.a
AR drivers/tty/built-in.a
CC drivers/power/supply/power_supply_core.o
CC drivers/hwmon/hwmon.o
CC drivers/scsi/sr_ioctl.o
CC drivers/acpi/acpica/nsxfobj.o
CC lib/check_signature.o
AR drivers/media/platform/samsung/exynos4-is/built-in.a
AR drivers/media/platform/samsung/s3c-camif/built-in.a
CC drivers/scsi/sr_vendor.o
AR drivers/media/platform/samsung/s5p-g2d/built-in.a
AR drivers/media/platform/samsung/s5p-jpeg/built-in.a
AR drivers/media/platform/samsung/s5p-mfc/built-in.a
CC drivers/usb/host/xhci-trace.o
AR drivers/media/platform/st/sti/bdisp/built-in.a
CC net/ipv4/fib_semantics.o
AR drivers/media/platform/samsung/built-in.a
CC drivers/usb/host/xhci-debugfs.o
AR drivers/media/platform/st/sti/c8sectpfe/built-in.a
CC lib/interval_tree.o
AR drivers/media/platform/st/sti/delta/built-in.a
CC lib/assoc_array.o
AR drivers/media/platform/st/sti/hva/built-in.a
AR drivers/media/platform/st/stm32/built-in.a
AR drivers/usb/storage/built-in.a
AR drivers/media/platform/st/built-in.a
CC lib/bitrev.o
CC drivers/rtc/rtc-cmos.o
AR drivers/media/platform/sunxi/sun4i-csi/built-in.a
CC drivers/scsi/sg.o
CC lib/crc-ccitt.o
AR drivers/media/platform/ti/am437x/built-in.a
AR drivers/media/platform/sunxi/sun6i-mipi-csi2/built-in.a
AR drivers/media/platform/sunxi/sun6i-csi/built-in.a
AR drivers/media/platform/ti/cal/built-in.a
CC [M] drivers/gpu/drm/scheduler/sched_entity.o
AR drivers/media/platform/ti/vpe/built-in.a
AR drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/built-in.a
AR drivers/usb/core/built-in.a
CC fs/file.o
AR drivers/media/platform/sunxi/sun8i-di/built-in.a
AR drivers/media/platform/ti/davinci/built-in.a
AR drivers/thermal/broadcom/built-in.a
AR drivers/media/platform/ti/j721e-csi2rx/built-in.a
AR drivers/media/platform/sunxi/sun8i-rotate/built-in.a
AR drivers/thermal/samsung/built-in.a
AR drivers/media/platform/ti/omap/built-in.a
CC drivers/thermal/intel/intel_tcc.o
CC drivers/power/supply/power_supply_sysfs.o
AR drivers/media/platform/sunxi/built-in.a
AR drivers/thermal/st/built-in.a
CC drivers/thermal/intel/therm_throt.o
AR drivers/media/platform/ti/omap3isp/built-in.a
CC drivers/acpi/acpica/psargs.o
AR drivers/media/platform/ti/built-in.a
AR drivers/thermal/qcom/built-in.a
AR drivers/media/platform/verisilicon/built-in.a
AR drivers/thermal/tegra/built-in.a
AR drivers/media/platform/via/built-in.a
CC drivers/acpi/acpica/psloop.o
AR drivers/media/platform/xilinx/built-in.a
AR fs/ext4/built-in.a
AR drivers/media/usb/b2c2/built-in.a
AR drivers/media/mmc/siano/built-in.a
AR drivers/media/platform/built-in.a
AR drivers/media/firewire/built-in.a
CC [M] drivers/thermal/intel/x86_pkg_temp_thermal.o
AR drivers/media/usb/dvb-usb/built-in.a
AR drivers/media/mmc/built-in.a
CC drivers/input/sparse-keymap.o
CC drivers/acpi/acpica/psobject.o
CC drivers/ptp/ptp_sysfs.o
AR drivers/media/usb/dvb-usb-v2/built-in.a
CC drivers/ptp/ptp_vclock.o
AR drivers/media/usb/s2255/built-in.a
CC drivers/input/vivaldi-fmap.o
AR drivers/media/usb/siano/built-in.a
CC lib/crc16.o
AR drivers/media/usb/ttusb-budget/built-in.a
CC net/ipv4/fib_trie.o
CC drivers/power/supply/power_supply_leds.o
AR drivers/media/usb/ttusb-dec/built-in.a
AR drivers/media/usb/built-in.a
CC kernel/kprobes.o
AR drivers/media/spi/built-in.a
AR drivers/media/test-drivers/built-in.a
CC drivers/input/input-leds.o
AR drivers/media/built-in.a
CC kernel/seccomp.o
CC net/ipv4/fib_notifier.o
CC drivers/base/devcoredump.o
CC drivers/base/platform-msi.o
CC kernel/relay.o
CC net/ipv4/inet_fragment.o
CC net/ipv6/esp6.o
CC drivers/acpi/acpica/psopcode.o
CC drivers/acpi/acpica/psopinfo.o
CC drivers/base/physical_location.o
CC drivers/ptp/ptp_kvm_x86.o
CC drivers/acpi/acpica/psparse.o
CC drivers/acpi/acpica/psscope.o
CC drivers/base/trace.o
CC net/ipv4/ping.o
CC drivers/acpi/acpica/pstree.o
AR drivers/watchdog/built-in.a
CC drivers/input/evdev.o
CC drivers/acpi/device_pm.o
CC kernel/utsname_sysctl.o
HOSTCC lib/gen_crc32table
CC drivers/ptp/ptp_kvm_common.o
CC drivers/power/supply/power_supply_hwmon.o
CC drivers/acpi/proc.o
CC net/ipv6/sit.o
CC drivers/md/md.o
CC lib/xxhash.o
CC drivers/md/md-bitmap.o
CC drivers/scsi/scsi_sysfs.o
LD [M] drivers/gpu/drm/scheduler/gpu-sched.o
CC lib/genalloc.o
CC net/ipv4/ip_tunnel_core.o
CC drivers/md/md-autodetect.o
CC drivers/gpu/drm/drm_aperture.o
CC fs/filesystems.o
CC net/ipv4/gre_offload.o
AR drivers/hwmon/built-in.a
CC net/ipv4/metrics.o
AR drivers/net/ethernet/emulex/built-in.a
CC drivers/md/dm.o
AR drivers/rtc/built-in.a
CC drivers/acpi/acpica/psutils.o
AR drivers/net/ethernet/engleder/built-in.a
CC drivers/acpi/bus.o
AR drivers/net/ethernet/ezchip/built-in.a
CC drivers/cpufreq/cpufreq.o
CC drivers/md/dm-table.o
CC drivers/cpufreq/freq_table.o
CC net/ipv4/netlink.o
CC kernel/delayacct.o
CC fs/namespace.o
CC net/ipv4/nexthop.o
CC [M] drivers/gpu/drm/xe/xe_bb.o
AR drivers/thermal/intel/built-in.a
AR drivers/thermal/mediatek/built-in.a
AR drivers/power/supply/built-in.a
CC drivers/thermal/thermal_core.o
AR drivers/power/built-in.a
CC drivers/acpi/acpica/pswalk.o
CC drivers/acpi/acpica/psxface.o
CC drivers/gpu/drm/drm_atomic.o
CC lib/percpu_counter.o
AR drivers/base/built-in.a
CC drivers/usb/host/xhci-pci.o
CC kernel/taskstats.o
CC drivers/md/dm-target.o
CC lib/audit.o
CC kernel/tsacct.o
AR drivers/ptp/built-in.a
CC drivers/cpuidle/governors/menu.o
CC fs/seq_file.o
CC drivers/cpuidle/cpuidle.o
AR drivers/net/ethernet/fujitsu/built-in.a
CC drivers/acpi/glue.o
AR drivers/net/ethernet/fungible/built-in.a
CC drivers/acpi/scan.o
CC drivers/cpuidle/governors/haltpoll.o
CC drivers/acpi/acpica/rsaddr.o
AR drivers/input/built-in.a
CC lib/syscall.o
CC kernel/tracepoint.o
CC drivers/md/dm-linear.o
CC drivers/acpi/mipi-disco-img.o
CC fs/xattr.o
CC drivers/thermal/thermal_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_bo.o
CC drivers/md/dm-stripe.o
AR drivers/net/ethernet/google/built-in.a
CC lib/errname.o
CC drivers/gpu/drm/i915/intel_wakeref.o
CC drivers/acpi/acpica/rscalc.o
CC drivers/gpu/drm/i915/vlv_sideband.o
CC drivers/thermal/thermal_trip.o
AR drivers/net/ethernet/huawei/built-in.a
CC [M] drivers/gpu/drm/xe/xe_bo_evict.o
AR drivers/mmc/built-in.a
AR drivers/ufs/built-in.a
CC drivers/acpi/acpica/rscreate.o
CC net/ipv4/udp_tunnel_stub.o
CC drivers/acpi/acpica/rsdumpinfo.o
CC [M] drivers/gpu/drm/xe/xe_debugfs.o
AR drivers/leds/trigger/built-in.a
CC lib/nlattr.o
CC [M] drivers/gpu/drm/xe/xe_devcoredump.o
AR fs/nfs/built-in.a
AR drivers/leds/blink/built-in.a
CC net/ipv4/ip_tunnel.o
AR drivers/leds/simple/built-in.a
CC drivers/leds/led-core.o
CC fs/libfs.o
CC drivers/leds/led-class.o
AR drivers/scsi/built-in.a
CC net/ipv4/sysctl_net_ipv4.o
AR drivers/firmware/arm_ffa/built-in.a
AR drivers/firmware/arm_scmi/built-in.a
CC lib/cpu_rmap.o
AR drivers/firmware/broadcom/built-in.a
AR drivers/firmware/cirrus/built-in.a
AR drivers/firmware/meson/built-in.a
CC net/ipv6/addrconf_core.o
AR drivers/firmware/microchip/built-in.a
CC lib/dynamic_queue_limits.o
CC drivers/firmware/efi/efi-bgrt.o
CC drivers/firmware/efi/libstub/efi-stub-helper.o
CC drivers/leds/led-triggers.o
CC drivers/firmware/efi/efi.o
CC drivers/md/dm-ioctl.o
CC kernel/irq_work.o
CC drivers/acpi/resource.o
CC drivers/acpi/acpica/rsinfo.o
CC drivers/md/dm-io.o
CC drivers/thermal/thermal_helpers.o
CC drivers/acpi/acpica/rsio.o
CC drivers/thermal/thermal_hwmon.o
CC drivers/acpi/acpica/rsirq.o
CC drivers/md/dm-kcopyd.o
AR drivers/firmware/imx/built-in.a
CC drivers/thermal/gov_step_wise.o
CC net/ipv4/proc.o
CC drivers/md/dm-sysfs.o
AR drivers/firmware/psci/built-in.a
AR drivers/cpuidle/governors/built-in.a
CC drivers/cpuidle/driver.o
AR drivers/firmware/qcom/built-in.a
CC net/ipv6/exthdrs_core.o
CC fs/fs-writeback.o
CC drivers/gpu/drm/drm_atomic_uapi.o
CC drivers/firmware/efi/vars.o
CC drivers/md/dm-stats.o
CC drivers/thermal/gov_user_space.o
CC drivers/net/ethernet/intel/e1000/e1000_main.o
CC drivers/net/ethernet/intel/e1000/e1000_hw.o
CC drivers/firmware/efi/libstub/gop.o
CC drivers/acpi/acpica/rslist.o
CC drivers/cpufreq/cpufreq_performance.o
CC drivers/firmware/efi/libstub/secureboot.o
AR drivers/usb/host/built-in.a
AR drivers/usb/built-in.a
CC drivers/firmware/efi/reboot.o
CC [M] drivers/gpu/drm/xe/xe_device.o
CC drivers/acpi/acpica/rsmemory.o
CC drivers/firmware/efi/memattr.o
CC drivers/firmware/efi/libstub/tpm.o
CC drivers/acpi/acpica/rsmisc.o
CC drivers/gpu/drm/i915/vlv_suspend.o
CC drivers/acpi/acpica/rsserial.o
AR drivers/crypto/stm32/built-in.a
CC drivers/acpi/acpica/rsutils.o
AR drivers/crypto/xilinx/built-in.a
CC fs/pnode.o
CC kernel/static_call.o
AR drivers/crypto/hisilicon/built-in.a
AR drivers/crypto/intel/keembay/built-in.a
AR drivers/leds/built-in.a
AR drivers/crypto/intel/ixp4xx/built-in.a
CC drivers/clocksource/acpi_pm.o
CC drivers/net/ethernet/intel/e1000/e1000_ethtool.o
AR drivers/crypto/intel/built-in.a
CC drivers/cpuidle/governor.o
CC drivers/hid/usbhid/hid-core.o
AR drivers/crypto/starfive/built-in.a
AR drivers/crypto/built-in.a
AR drivers/net/ethernet/i825xx/built-in.a
CC drivers/clocksource/i8253.o
CC drivers/hid/usbhid/hiddev.o
AR drivers/thermal/built-in.a
CC drivers/hid/usbhid/hid-pidff.o
CC lib/glob.o
CC drivers/cpuidle/sysfs.o
CC drivers/cpuidle/poll_state.o
CC drivers/md/dm-rq.o
CC drivers/cpufreq/cpufreq_userspace.o
CC net/mac80211/mlme.o
AR drivers/net/ethernet/microsoft/built-in.a
CC drivers/firmware/efi/tpm.o
CC drivers/gpu/drm/i915/soc/intel_dram.o
CC drivers/firmware/efi/memmap.o
CC kernel/padata.o
CC drivers/acpi/acpica/rsxface.o
CC lib/strncpy_from_user.o
CC drivers/firmware/efi/capsule.o
CC drivers/cpuidle/cpuidle-haltpoll.o
CC drivers/acpi/acpica/tbdata.o
CC drivers/firmware/efi/esrt.o
CC net/ipv6/ip6_checksum.o
CC fs/splice.o
CC kernel/jump_label.o
CC lib/strnlen_user.o
CC lib/net_utils.o
CC drivers/md/dm-io-rewind.o
CC lib/sg_pool.o
CC kernel/context_tracking.o
CC drivers/firmware/efi/runtime-wrappers.o
CC drivers/firmware/efi/libstub/file.o
CC drivers/cpufreq/cpufreq_ondemand.o
CC drivers/gpu/drm/i915/soc/intel_gmch.o
CC fs/sync.o
AR drivers/clocksource/built-in.a
AR drivers/net/ethernet/litex/built-in.a
CC fs/utimes.o
AR drivers/net/ethernet/mellanox/built-in.a
AR drivers/net/ethernet/marvell/octeon_ep/built-in.a
AR drivers/platform/x86/amd/built-in.a
AR drivers/net/ethernet/marvell/octeon_ep_vf/built-in.a
AR drivers/platform/surface/built-in.a
AR drivers/platform/x86/intel/built-in.a
CC drivers/platform/x86/wmi.o
CC drivers/cpufreq/cpufreq_governor.o
AR drivers/net/ethernet/marvell/octeontx2/built-in.a
AR drivers/net/ethernet/micrel/built-in.a
CC drivers/cpufreq/cpufreq_governor_attr_set.o
AR drivers/net/ethernet/marvell/prestera/built-in.a
CC drivers/net/ethernet/marvell/sky2.o
CC drivers/platform/x86/wmi-bmof.o
CC drivers/firmware/efi/libstub/mem.o
AR drivers/cpuidle/built-in.a
CC drivers/md/dm-builtin.o
CC drivers/md/dm-raid1.o
CC net/mac80211/tdls.o
CC net/ipv6/ip6_icmp.o
CC net/ipv4/fib_rules.o
CC drivers/acpi/acpica/tbfadt.o
CC net/ipv6/output_core.o
CC [M] drivers/gpu/drm/xe/xe_device_sysfs.o
CC net/ipv6/protocol.o
CC drivers/platform/x86/eeepc-laptop.o
CC lib/stackdepot.o
CC drivers/firmware/efi/libstub/random.o
CC lib/asn1_decoder.o
CC drivers/md/dm-log.o
CC drivers/firmware/efi/capsule-loader.o
AR drivers/net/ethernet/broadcom/built-in.a
CC drivers/gpu/drm/i915/soc/intel_pch.o
AR drivers/net/ethernet/microchip/built-in.a
CC drivers/md/dm-region-hash.o
GEN lib/oid_registry_data.c
CC lib/ucs2_string.o
CC kernel/iomem.o
CC drivers/firmware/efi/libstub/randomalloc.o
CC net/ipv6/ip6_offload.o
CC drivers/md/dm-zero.o
CC drivers/gpu/drm/i915/i915_memcpy.o
CC drivers/platform/x86/p2sb.o
CC drivers/gpu/drm/i915/i915_mm.o
AR drivers/hid/usbhid/built-in.a
CC drivers/acpi/acpica/tbfind.o
CC drivers/hid/hid-core.o
CC drivers/gpu/drm/i915/i915_sw_fence.o
CC drivers/acpi/acpica/tbinstal.o
CC kernel/rseq.o
CC lib/sbitmap.o
CC drivers/firmware/efi/earlycon.o
CC drivers/cpufreq/acpi-cpufreq.o
CC drivers/cpufreq/amd-pstate.o
CC [M] drivers/gpu/drm/xe/xe_dma_buf.o
AR drivers/net/ethernet/mscc/built-in.a
CC fs/d_path.o
CC net/ipv6/tcpv6_offload.o
CC drivers/firmware/efi/libstub/pci.o
CC drivers/gpu/drm/i915/i915_sw_fence_work.o
CC lib/group_cpus.o
CC [M] drivers/gpu/drm/xe/xe_drm_client.o
CC net/ipv6/exthdrs_offload.o
CC drivers/cpufreq/amd-pstate-trace.o
CC net/ipv4/ipmr.o
CC drivers/acpi/acpica/tbprint.o
AR drivers/net/ethernet/myricom/built-in.a
AR drivers/net/ethernet/natsemi/built-in.a
AR drivers/net/ethernet/neterion/built-in.a
CC drivers/firmware/efi/libstub/skip_spaces.o
AR drivers/net/ethernet/netronome/built-in.a
CC fs/stack.o
AR drivers/net/ethernet/ni/built-in.a
CC drivers/net/ethernet/nvidia/forcedeth.o
CC fs/fs_struct.o
CC drivers/net/ethernet/intel/e100.o
CC drivers/net/ethernet/intel/e1000e/82571.o
CC drivers/firmware/efi/libstub/lib-cmdline.o
CC drivers/acpi/acpica/tbutils.o
CC drivers/net/ethernet/intel/e1000/e1000_param.o
CC drivers/net/ethernet/intel/e1000e/ich8lan.o
CC lib/fw_table.o
AR drivers/net/ethernet/oki-semi/built-in.a
CC drivers/gpu/drm/i915/i915_syncmap.o
CC drivers/firmware/efi/libstub/lib-ctype.o
CC net/ipv4/ipmr_base.o
CC net/ipv6/inet6_hashtables.o
CC drivers/net/ethernet/intel/e1000e/80003es2lan.o
AR lib/lib.a
CC drivers/mailbox/mailbox.o
CC net/ipv6/mcast_snoop.o
CC drivers/gpu/drm/drm_auth.o
CC drivers/mailbox/pcc.o
CC net/mac80211/ocb.o
CC drivers/firmware/efi/libstub/alignedmem.o
GEN lib/crc32table.h
CC drivers/gpu/drm/drm_blend.o
AR drivers/perf/built-in.a
AR drivers/platform/x86/built-in.a
CC drivers/net/ethernet/intel/e1000e/mac.o
CC net/ipv4/syncookies.o
AR drivers/platform/built-in.a
CC lib/oid_registry.o
AR drivers/hwtracing/intel_th/built-in.a
CC fs/statfs.o
AR drivers/android/built-in.a
AR drivers/firmware/efi/built-in.a
AR drivers/nvmem/layouts/built-in.a
CC drivers/gpu/drm/drm_bridge.o
CC drivers/nvmem/core.o
CC drivers/gpu/drm/drm_cache.o
CC drivers/acpi/acpi_processor.o
CC drivers/gpu/drm/drm_client.o
CC drivers/acpi/acpica/tbxface.o
CC drivers/cpufreq/intel_pstate.o
CC fs/fs_pin.o
CC drivers/acpi/processor_core.o
CC drivers/gpu/drm/i915/i915_user_extensions.o
AR kernel/built-in.a
CC drivers/acpi/acpica/tbxfload.o
CC drivers/acpi/processor_pdc.o
CC drivers/firmware/efi/libstub/relocate.o
CC drivers/net/ethernet/intel/e1000e/manage.o
CC net/ipv4/tunnel4.o
CC net/ipv4/ipconfig.o
CC lib/crc32.o
CC net/ipv4/netfilter.o
CC net/ipv4/tcp_cubic.o
CC drivers/hid/hid-input.o
CC [M] drivers/gpu/drm/xe/xe_exec.o
CC [M] drivers/gpu/drm/xe/xe_execlist.o
AR drivers/mailbox/built-in.a
CC drivers/acpi/ec.o
CC drivers/gpu/drm/i915/i915_debugfs.o
CC drivers/gpu/drm/drm_client_modeset.o
CC drivers/acpi/dock.o
CC net/mac80211/airtime.o
CC drivers/gpu/drm/drm_color_mgmt.o
CC drivers/acpi/acpica/tbxfroot.o
CC drivers/gpu/drm/drm_connector.o
CC fs/nsfs.o
CC [M] drivers/gpu/drm/xe/xe_exec_queue.o
CC drivers/net/ethernet/intel/e1000e/nvm.o
CC drivers/gpu/drm/i915/i915_debugfs_params.o
CC drivers/gpu/drm/i915/i915_pmu.o
CC drivers/hid/hid-quirks.o
CC fs/fs_types.o
AR drivers/md/built-in.a
CC [M] drivers/gpu/drm/xe/xe_force_wake.o
AR drivers/net/ethernet/intel/e1000/built-in.a
CC [M] drivers/gpu/drm/xe/xe_ggtt.o
CC drivers/firmware/efi/libstub/printk.o
CC drivers/gpu/drm/drm_crtc.o
CC drivers/gpu/drm/drm_displayid.o
AR lib/built-in.a
CC drivers/gpu/drm/drm_drv.o
CC drivers/net/ethernet/intel/e1000e/phy.o
CC drivers/hid/hid-debug.o
CC drivers/acpi/pci_root.o
CC drivers/acpi/acpica/utaddress.o
AR drivers/firmware/smccc/built-in.a
CC drivers/net/ethernet/intel/e1000e/param.o
AR drivers/firmware/tegra/built-in.a
AR drivers/firmware/xilinx/built-in.a
CC drivers/firmware/dmi_scan.o
AR drivers/nvmem/built-in.a
CC net/mac80211/eht.o
AR net/ipv6/built-in.a
CC drivers/acpi/pci_link.o
CC net/mac80211/led.o
CC drivers/net/ethernet/intel/e1000e/ethtool.o
CC [M] drivers/gpu/drm/xe/xe_gpu_scheduler.o
CC fs/fs_context.o
CC drivers/net/ethernet/intel/e1000e/netdev.o
CC drivers/gpu/drm/drm_dumb_buffers.o
CC drivers/gpu/drm/drm_edid.o
AR drivers/net/ethernet/packetengines/built-in.a
CC net/ipv4/tcp_sigpool.o
CC net/ipv4/cipso_ipv4.o
AR drivers/net/ethernet/marvell/built-in.a
CC drivers/acpi/acpica/utalloc.o
CC drivers/firmware/efi/libstub/vsprintf.o
CC net/ipv4/xfrm4_policy.o
AR drivers/net/ethernet/qlogic/built-in.a
CC fs/fs_parser.o
CC drivers/net/ethernet/intel/e1000e/ptp.o
CC fs/fsopen.o
CC drivers/firmware/efi/libstub/x86-stub.o
CC net/mac80211/pm.o
HOSTCC drivers/gpu/drm/xe/xe_gen_wa_oob
CC drivers/gpu/drm/i915/gt/gen2_engine_cs.o
CC drivers/gpu/drm/drm_eld.o
CC [M] drivers/gpu/drm/xe/xe_gsc_proxy.o
CC net/mac80211/rc80211_minstrel_ht.o
CC drivers/acpi/pci_irq.o
CC drivers/acpi/acpi_lpss.o
CC [M] drivers/gpu/drm/xe/xe_gsc_submit.o
CC [M] drivers/gpu/drm/xe/xe_gt.o
CC drivers/acpi/acpi_apd.o
CC drivers/gpu/drm/drm_encoder.o
CC net/ipv4/xfrm4_state.o
CC drivers/acpi/acpica/utascii.o
CC net/mac80211/wbrf.o
CC fs/init.o
CC drivers/gpu/drm/drm_file.o
CC drivers/acpi/acpi_platform.o
CC drivers/acpi/acpica/utbuffer.o
CC drivers/acpi/acpi_pnp.o
CC net/ipv4/xfrm4_input.o
CC drivers/gpu/drm/drm_fourcc.o
CC drivers/acpi/power.o
CC drivers/gpu/drm/drm_framebuffer.o
CC drivers/firmware/dmi-id.o
CC drivers/acpi/event.o
CC drivers/gpu/drm/i915/gt/gen6_engine_cs.o
CC drivers/hid/hidraw.o
CC drivers/acpi/acpica/utcksum.o
CC drivers/acpi/acpica/utcopy.o
AR drivers/cpufreq/built-in.a
AR drivers/net/ethernet/qualcomm/emac/built-in.a
CC fs/kernel_read_file.o
AR drivers/net/ethernet/qualcomm/built-in.a
CC drivers/acpi/evged.o
CC net/ipv4/xfrm4_output.o
CC [M] drivers/gpu/drm/xe/xe_gt_ccs_mode.o
CC drivers/net/ethernet/realtek/8139too.o
CC fs/mnt_idmapping.o
CC fs/remap_range.o
CC [M] drivers/gpu/drm/xe/xe_gt_clock.o
CC net/ipv4/xfrm4_protocol.o
AR drivers/net/ethernet/nvidia/built-in.a
CC drivers/acpi/sysfs.o
CC drivers/gpu/drm/drm_gem.o
STUBCPY drivers/firmware/efi/libstub/alignedmem.stub.o
CC [M] drivers/gpu/drm/xe/xe_gt_debugfs.o
CC drivers/gpu/drm/drm_ioctl.o
CC drivers/hid/hid-generic.o
STUBCPY drivers/firmware/efi/libstub/efi-stub-helper.stub.o
STUBCPY drivers/firmware/efi/libstub/file.stub.o
STUBCPY drivers/firmware/efi/libstub/gop.stub.o
STUBCPY drivers/firmware/efi/libstub/lib-cmdline.stub.o
STUBCPY drivers/firmware/efi/libstub/lib-ctype.stub.o
CC drivers/gpu/drm/drm_lease.o
CC drivers/acpi/property.o
STUBCPY drivers/firmware/efi/libstub/mem.stub.o
STUBCPY drivers/firmware/efi/libstub/pci.stub.o
CC drivers/acpi/acpi_cmos_rtc.o
CC drivers/firmware/memmap.o
CC drivers/hid/hid-a4tech.o
STUBCPY drivers/firmware/efi/libstub/printk.stub.o
CC drivers/acpi/x86/apple.o
STUBCPY drivers/firmware/efi/libstub/random.stub.o
CC drivers/acpi/x86/utils.o
STUBCPY drivers/firmware/efi/libstub/randomalloc.stub.o
STUBCPY drivers/firmware/efi/libstub/relocate.stub.o
CC drivers/acpi/x86/s2idle.o
CC drivers/net/ethernet/realtek/r8169_main.o
STUBCPY drivers/firmware/efi/libstub/secureboot.stub.o
CC drivers/acpi/acpica/utexcep.o
CC drivers/acpi/debugfs.o
STUBCPY drivers/firmware/efi/libstub/skip_spaces.stub.o
CC drivers/acpi/acpi_lpat.o
STUBCPY drivers/firmware/efi/libstub/tpm.stub.o
CC fs/pidfs.o
STUBCPY drivers/firmware/efi/libstub/vsprintf.stub.o
STUBCPY drivers/firmware/efi/libstub/x86-stub.stub.o
CC drivers/acpi/acpica/utdebug.o
CC drivers/acpi/acpica/utdecode.o
AR drivers/firmware/efi/libstub/lib.a
CC [M] drivers/gpu/drm/xe/xe_gt_freq.o
CC drivers/hid/hid-apple.o
CC drivers/acpi/acpi_pcc.o
CC drivers/acpi/ac.o
CC drivers/gpu/drm/drm_managed.o
CC drivers/gpu/drm/i915/gt/gen6_ppgtt.o
CC drivers/acpi/acpica/utdelete.o
CC fs/buffer.o
CC fs/mpage.o
CC drivers/acpi/button.o
CC drivers/hid/hid-belkin.o
CC drivers/acpi/acpica/uterror.o
CC drivers/net/ethernet/realtek/r8169_firmware.o
CC drivers/acpi/fan_core.o
CC [M] drivers/gpu/drm/xe/xe_gt_idle.o
CC drivers/acpi/fan_attr.o
CC drivers/acpi/acpi_video.o
CC drivers/gpu/drm/i915/gt/gen7_renderclear.o
CC drivers/gpu/drm/i915/gt/gen8_engine_cs.o
CC drivers/acpi/video_detect.o
CC drivers/gpu/drm/drm_mm.o
CC drivers/acpi/processor_driver.o
CC [M] drivers/gpu/drm/xe/xe_gt_mcr.o
CC drivers/net/ethernet/realtek/r8169_phy_config.o
CC drivers/hid/hid-cherry.o
CC drivers/acpi/processor_thermal.o
AR drivers/firmware/built-in.a
CC drivers/hid/hid-chicony.o
CC [M] drivers/gpu/drm/xe/xe_gt_pagefault.o
CC drivers/gpu/drm/drm_mode_config.o
CC fs/proc_namespace.o
CC [M] drivers/gpu/drm/xe/xe_gt_sysfs.o
CC drivers/hid/hid-cypress.o
CC drivers/acpi/processor_idle.o
CC drivers/acpi/acpica/uteval.o
CC drivers/gpu/drm/drm_mode_object.o
CC drivers/gpu/drm/i915/gt/gen8_ppgtt.o
CC drivers/gpu/drm/i915/gt/intel_breadcrumbs.o
CC fs/direct-io.o
CC drivers/acpi/acpica/utglobal.o
CC drivers/acpi/processor_throttling.o
CC fs/eventpoll.o
CC drivers/acpi/processor_perflib.o
CC drivers/acpi/container.o
AR drivers/net/ethernet/renesas/built-in.a
CC drivers/acpi/thermal_lib.o
AR drivers/net/ethernet/rdc/built-in.a
AR drivers/net/ethernet/rocker/built-in.a
AR drivers/net/ethernet/samsung/built-in.a
AR net/ipv4/built-in.a
CC drivers/hid/hid-ezkey.o
AR drivers/net/ethernet/seeq/built-in.a
AR drivers/net/ethernet/silan/built-in.a
AR drivers/net/ethernet/sis/built-in.a
AR drivers/net/ethernet/sfc/built-in.a
CC drivers/acpi/acpica/uthex.o
AR drivers/net/ethernet/smsc/built-in.a
CC drivers/gpu/drm/drm_modes.o
CC drivers/acpi/acpica/utids.o
CC drivers/acpi/thermal.o
CC fs/anon_inodes.o
CC drivers/acpi/acpi_memhotplug.o
CC drivers/hid/hid-gyration.o
CC drivers/acpi/ioapic.o
CC drivers/hid/hid-ite.o
CC [M] drivers/gpu/drm/xe/xe_gt_throttle_sysfs.o
CC drivers/acpi/acpica/utinit.o
AR drivers/net/ethernet/socionext/built-in.a
AR drivers/net/ethernet/stmicro/built-in.a
CC drivers/acpi/battery.o
AR drivers/net/ethernet/sun/built-in.a
CC drivers/gpu/drm/i915/gt/intel_context.o
CC drivers/hid/hid-kensington.o
CC drivers/hid/hid-lg.o
CC drivers/acpi/bgrt.o
CC [M] drivers/gpu/drm/xe/xe_gt_tlb_invalidation.o
CC drivers/acpi/spcr.o
CC drivers/hid/hid-lgff.o
CC fs/signalfd.o
CC [M] drivers/gpu/drm/xe/xe_gt_topology.o
CC drivers/gpu/drm/i915/gt/intel_context_sseu.o
GEN xe_wa_oob.c xe_wa_oob.h
CC drivers/acpi/acpica/utlock.o
CC fs/timerfd.o
CC drivers/acpi/acpica/utmath.o
CC drivers/acpi/acpica/utmisc.o
CC drivers/hid/hid-lg4ff.o
CC drivers/gpu/drm/drm_modeset_lock.o
CC drivers/gpu/drm/i915/gt/intel_engine_cs.o
CC fs/eventfd.o
AR drivers/net/ethernet/tehuti/built-in.a
CC drivers/gpu/drm/drm_plane.o
CC drivers/acpi/acpica/utmutex.o
CC [M] drivers/gpu/drm/xe/xe_guc_ct.o
CC [M] drivers/gpu/drm/xe/xe_guc_db_mgr.o
CC drivers/gpu/drm/i915/gt/intel_engine_heartbeat.o
CC drivers/gpu/drm/i915/gt/intel_engine_pm.o
CC [M] drivers/gpu/drm/xe/xe_guc_debugfs.o
CC drivers/gpu/drm/i915/gt/intel_engine_user.o
CC [M] drivers/gpu/drm/xe/xe_guc_hwconfig.o
CC [M] drivers/gpu/drm/xe/xe_guc_id_mgr.o
CC fs/aio.o
CC fs/locks.o
CC fs/binfmt_misc.o
CC fs/binfmt_script.o
CC fs/binfmt_elf.o
CC [M] drivers/gpu/drm/xe/xe_guc_klv_helpers.o
CC drivers/gpu/drm/drm_prime.o
CC fs/mbcache.o
CC drivers/gpu/drm/drm_print.o
CC drivers/acpi/acpica/utnonansi.o
AR drivers/net/ethernet/ti/built-in.a
AR drivers/net/ethernet/vertexcom/built-in.a
AR drivers/net/ethernet/via/built-in.a
AR drivers/net/ethernet/wangxun/built-in.a
CC drivers/hid/hid-lg-g15.o
AR drivers/net/ethernet/wiznet/built-in.a
AR drivers/net/ethernet/xilinx/built-in.a
AR drivers/net/ethernet/xircom/built-in.a
CC fs/posix_acl.o
CC drivers/acpi/acpica/utobject.o
AR drivers/net/ethernet/synopsys/built-in.a
AR drivers/net/ethernet/pensando/built-in.a
CC drivers/acpi/acpica/utosi.o
CC [M] drivers/gpu/drm/xe/xe_guc_log.o
CC [M] drivers/gpu/drm/xe/xe_guc_pc.o
CC [M] drivers/gpu/drm/xe/xe_guc_submit.o
CC drivers/hid/hid-microsoft.o
CC [M] drivers/gpu/drm/xe/xe_heci_gsc.o
CC drivers/gpu/drm/drm_property.o
CC fs/coredump.o
CC [M] drivers/gpu/drm/xe/xe_hw_engine.o
CC fs/drop_caches.o
CC drivers/gpu/drm/i915/gt/intel_execlists_submission.o
CC [M] drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.o
CC drivers/hid/hid-monterey.o
CC drivers/hid/hid-ntrig.o
CC drivers/gpu/drm/i915/gt/intel_ggtt.o
CC fs/sysctls.o
CC [M] drivers/gpu/drm/xe/xe_hw_fence.o
CC [M] drivers/gpu/drm/xe/xe_huc.o
CC fs/fhandle.o
CC drivers/gpu/drm/drm_syncobj.o
CC drivers/acpi/acpica/utownerid.o
CC drivers/gpu/drm/drm_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_huc_debugfs.o
CC drivers/gpu/drm/i915/gt/intel_ggtt_fencing.o
CC drivers/gpu/drm/drm_trace_points.o
CC drivers/gpu/drm/drm_vblank.o
CC drivers/gpu/drm/drm_vblank_work.o
CC drivers/gpu/drm/drm_vma_manager.o
CC drivers/gpu/drm/drm_writeback.o
CC drivers/gpu/drm/i915/gt/intel_gt.o
CC [M] drivers/gpu/drm/xe/xe_irq.o
AR drivers/net/ethernet/intel/e1000e/built-in.a
CC drivers/hid/hid-pl.o
AR drivers/net/ethernet/intel/built-in.a
CC drivers/hid/hid-petalynx.o
CC drivers/acpi/acpica/utpredef.o
CC drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.o
CC drivers/gpu/drm/drm_panel.o
CC drivers/gpu/drm/drm_pci.o
CC [M] drivers/gpu/drm/xe/xe_lrc.o
CC [M] drivers/gpu/drm/xe/xe_migrate.o
CC drivers/acpi/acpica/utresdecode.o
AR net/mac80211/built-in.a
AR net/built-in.a
AR drivers/net/ethernet/realtek/built-in.a
CC drivers/acpi/acpica/utresrc.o
AR drivers/net/ethernet/built-in.a
CC drivers/gpu/drm/drm_debugfs.o
CC drivers/gpu/drm/drm_debugfs_crc.o
CC drivers/hid/hid-redragon.o
CC drivers/hid/hid-samsung.o
CC drivers/hid/hid-sony.o
CC [M] drivers/gpu/drm/xe/xe_mmio.o
CC [M] drivers/gpu/drm/xe/xe_mocs.o
AR drivers/net/built-in.a
CC drivers/hid/hid-sunplus.o
CC drivers/acpi/acpica/utstate.o
CC drivers/hid/hid-topseed.o
CC drivers/gpu/drm/drm_panel_orientation_quirks.o
CC drivers/gpu/drm/drm_buddy.o
CC [M] drivers/gpu/drm/xe/xe_module.o
CC drivers/gpu/drm/drm_gem_shmem_helper.o
CC drivers/acpi/acpica/utstring.o
CC [M] drivers/gpu/drm/xe/xe_pat.o
CC drivers/gpu/drm/drm_atomic_helper.o
CC drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.o
CC drivers/acpi/acpica/utstrsuppt.o
CC drivers/acpi/acpica/utstrtoul64.o
CC drivers/gpu/drm/drm_atomic_state_helper.o
CC [M] drivers/gpu/drm/xe/xe_pci.o
CC drivers/acpi/acpica/utxface.o
CC drivers/gpu/drm/drm_bridge_connector.o
CC drivers/gpu/drm/drm_crtc_helper.o
CC drivers/gpu/drm/drm_damage_helper.o
CC drivers/gpu/drm/drm_encoder_slave.o
CC drivers/gpu/drm/i915/gt/intel_gt_clock_utils.o
CC drivers/gpu/drm/drm_flip_work.o
CC drivers/gpu/drm/drm_format_helper.o
CC drivers/acpi/acpica/utxfinit.o
CC [M] drivers/gpu/drm/xe/xe_pcode.o
CC [M] drivers/gpu/drm/xe/xe_pm.o
CC drivers/gpu/drm/drm_gem_atomic_helper.o
CC [M] drivers/gpu/drm/xe/xe_preempt_fence.o
CC drivers/acpi/acpica/utxferror.o
CC drivers/acpi/acpica/utxfmutex.o
CC [M] drivers/gpu/drm/xe/xe_pt.o
CC drivers/gpu/drm/i915/gt/intel_gt_debugfs.o
CC drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_pt_walk.o
CC drivers/gpu/drm/drm_gem_framebuffer_helper.o
CC drivers/gpu/drm/i915/gt/intel_gt_irq.o
CC drivers/gpu/drm/i915/gt/intel_gt_mcr.o
CC drivers/gpu/drm/drm_kms_helper_common.o
CC drivers/gpu/drm/i915/gt/intel_gt_pm.o
CC drivers/gpu/drm/drm_modeset_helper.o
CC drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.o
CC drivers/gpu/drm/drm_plane_helper.o
CC drivers/gpu/drm/i915/gt/intel_gt_pm_irq.o
CC drivers/gpu/drm/drm_probe_helper.o
CC drivers/gpu/drm/drm_rect.o
CC drivers/gpu/drm/drm_self_refresh_helper.o
CC drivers/gpu/drm/drm_simple_kms_helper.o
AR fs/built-in.a
CC drivers/gpu/drm/bridge/panel.o
CC drivers/gpu/drm/drm_mipi_dsi.o
CC [M] drivers/gpu/drm/xe/xe_query.o
AR drivers/acpi/acpica/built-in.a
CC [M] drivers/gpu/drm/drm_exec.o
CC [M] drivers/gpu/drm/xe/xe_range_fence.o
AR drivers/acpi/built-in.a
CC drivers/gpu/drm/i915/gt/intel_gt_requests.o
CC [M] drivers/gpu/drm/drm_gpuvm.o
CC drivers/gpu/drm/i915/gt/intel_gt_sysfs.o
CC [M] drivers/gpu/drm/xe/xe_reg_sr.o
CC drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.o
CC [M] drivers/gpu/drm/drm_suballoc.o
CC drivers/gpu/drm/i915/gt/intel_gtt.o
CC [M] drivers/gpu/drm/xe/xe_reg_whitelist.o
CC [M] drivers/gpu/drm/xe/xe_rtp.o
CC [M] drivers/gpu/drm/drm_gem_ttm_helper.o
AR drivers/hid/built-in.a
CC [M] drivers/gpu/drm/xe/xe_ring_ops.o
CC drivers/gpu/drm/i915/gt/intel_llc.o
CC drivers/gpu/drm/i915/gt/intel_lrc.o
CC drivers/gpu/drm/i915/gt/intel_migrate.o
CC [M] drivers/gpu/drm/xe/xe_sa.o
CC [M] drivers/gpu/drm/xe/xe_sched_job.o
CC [M] drivers/gpu/drm/xe/xe_shrinker.o
CC [M] drivers/gpu/drm/xe/xe_step.o
CC [M] drivers/gpu/drm/xe/xe_sync.o
CC [M] drivers/gpu/drm/xe/xe_tile.o
CC [M] drivers/gpu/drm/xe/xe_tile_sysfs.o
CC drivers/gpu/drm/i915/gt/intel_mocs.o
CC [M] drivers/gpu/drm/xe/xe_trace.o
CC [M] drivers/gpu/drm/xe/xe_ttm_sys_mgr.o
CC [M] drivers/gpu/drm/xe/xe_ttm_stolen_mgr.o
CC [M] drivers/gpu/drm/xe/xe_ttm_vram_mgr.o
CC [M] drivers/gpu/drm/xe/xe_tuning.o
CC [M] drivers/gpu/drm/xe/xe_uc.o
CC [M] drivers/gpu/drm/xe/xe_uc_debugfs.o
CC drivers/gpu/drm/i915/gt/intel_ppgtt.o
CC drivers/gpu/drm/i915/gt/intel_rc6.o
CC drivers/gpu/drm/i915/gt/intel_region_lmem.o
CC drivers/gpu/drm/i915/gt/intel_renderstate.o
CC drivers/gpu/drm/i915/gt/intel_reset.o
LD [M] drivers/gpu/drm/drm_suballoc_helper.o
CC drivers/gpu/drm/i915/gt/intel_ring.o
CC drivers/gpu/drm/i915/gt/intel_ring_submission.o
CC [M] drivers/gpu/drm/xe/xe_uc_fw.o
CC drivers/gpu/drm/i915/gt/intel_rps.o
CC drivers/gpu/drm/i915/gt/intel_sa_media.o
CC [M] drivers/gpu/drm/xe/xe_vm.o
CC [M] drivers/gpu/drm/xe/xe_vram_freq.o
CC [M] drivers/gpu/drm/xe/xe_wait_user_fence.o
LD [M] drivers/gpu/drm/drm_ttm_helper.o
CC [M] drivers/gpu/drm/xe/xe_wa.o
CC [M] drivers/gpu/drm/xe/xe_wopcm.o
CC drivers/gpu/drm/i915/gt/intel_sseu.o
CC drivers/gpu/drm/i915/gt/intel_sseu_debugfs.o
CC [M] drivers/gpu/drm/xe/xe_hmm.o
CC drivers/gpu/drm/i915/gt/intel_timeline.o
CC [M] drivers/gpu/drm/xe/xe_hwmon.o
CC drivers/gpu/drm/i915/gt/intel_tlb.o
CC drivers/gpu/drm/i915/gt/intel_wopcm.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_vf.o
CC [M] drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.o
CC drivers/gpu/drm/i915/gt/intel_workarounds.o
CC [M] drivers/gpu/drm/xe/xe_guc_relay.o
CC [M] drivers/gpu/drm/xe/xe_memirq.o
CC [M] drivers/gpu/drm/xe/xe_sriov.o
CC drivers/gpu/drm/i915/gt/shmem_utils.o
CC drivers/gpu/drm/i915/gt/sysfs_engines.o
CC [M] drivers/gpu/drm/xe/display/ext/i915_irq.o
CC [M] drivers/gpu/drm/xe/display/ext/i915_utils.o
CC [M] drivers/gpu/drm/xe/display/intel_fb_bo.o
CC [M] drivers/gpu/drm/xe/display/intel_fbdev_fb.o
CC [M] drivers/gpu/drm/xe/display/xe_display.o
CC drivers/gpu/drm/i915/gt/intel_ggtt_gmch.o
CC [M] drivers/gpu/drm/xe/display/xe_display_misc.o
CC [M] drivers/gpu/drm/xe/display/xe_display_rps.o
CC [M] drivers/gpu/drm/xe/display/xe_dsb_buffer.o
CC [M] drivers/gpu/drm/xe/display/xe_fb_pin.o
CC drivers/gpu/drm/i915/gt/gen6_renderstate.o
CC [M] drivers/gpu/drm/xe/display/xe_hdcp_gsc.o
CC drivers/gpu/drm/i915/gt/gen7_renderstate.o
CC [M] drivers/gpu/drm/xe/display/xe_plane_initial.o
CC [M] drivers/gpu/drm/xe/display/xe_tdf.o
CC drivers/gpu/drm/i915/gt/gen8_renderstate.o
CC [M] drivers/gpu/drm/xe/i915-soc/intel_dram.o
CC [M] drivers/gpu/drm/xe/i915-soc/intel_pch.o
CC [M] drivers/gpu/drm/xe/i915-display/icl_dsi.o
CC drivers/gpu/drm/i915/gt/gen9_renderstate.o
CC drivers/gpu/drm/i915/gem/i915_gem_busy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_atomic.o
CC drivers/gpu/drm/i915/gem/i915_gem_clflush.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_atomic_plane.o
CC drivers/gpu/drm/i915/gem/i915_gem_context.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_audio.o
CC drivers/gpu/drm/i915/gem/i915_gem_create.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_backlight.o
CC drivers/gpu/drm/i915/gem/i915_gem_dmabuf.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_bios.o
CC drivers/gpu/drm/i915/gem/i915_gem_domain.o
CC drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o
CC drivers/gpu/drm/i915/gem/i915_gem_internal.o
CC drivers/gpu/drm/i915/gem/i915_gem_lmem.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_bw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cdclk.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_color.o
CC drivers/gpu/drm/i915/gem/i915_gem_mman.o
CC drivers/gpu/drm/i915/gem/i915_gem_object.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_combo_phy.o
CC drivers/gpu/drm/i915/gem/i915_gem_pages.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_connector.o
CC drivers/gpu/drm/i915/gem/i915_gem_phys.o
CC drivers/gpu/drm/i915/gem/i915_gem_pm.o
CC drivers/gpu/drm/i915/gem/i915_gem_region.o
CC drivers/gpu/drm/i915/gem/i915_gem_shmem.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_crtc.o
CC drivers/gpu/drm/i915/gem/i915_gem_shrinker.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_crtc_state_dump.o
CC drivers/gpu/drm/i915/gem/i915_gem_stolen.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cursor.o
CC drivers/gpu/drm/i915/gem/i915_gem_throttle.o
CC drivers/gpu/drm/i915/gem/i915_gem_tiling.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_cx0_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_ddi.o
CC drivers/gpu/drm/i915/gem/i915_gem_ttm.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_ddi_buf_trans.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_device.o
CC drivers/gpu/drm/i915/gem/i915_gem_ttm_move.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_driver.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_irq.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_params.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power.o
CC drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.o
CC drivers/gpu/drm/i915/gem/i915_gem_userptr.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power_map.o
CC drivers/gpu/drm/i915/gem/i915_gem_wait.o
CC drivers/gpu/drm/i915/gem/i915_gemfs.o
CC drivers/gpu/drm/i915/i915_active.o
CC drivers/gpu/drm/i915/i915_cmd_parser.o
CC drivers/gpu/drm/i915/i915_deps.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_power_well.o
CC drivers/gpu/drm/i915/i915_gem.o
CC drivers/gpu/drm/i915/i915_gem_evict.o
CC drivers/gpu/drm/i915/i915_gem_gtt.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_trace.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_wa.o
CC drivers/gpu/drm/i915/i915_gem_ww.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dkl_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dmc.o
CC drivers/gpu/drm/i915/i915_query.o
CC drivers/gpu/drm/i915/i915_request.o
CC drivers/gpu/drm/i915/i915_scheduler.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_aux.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_aux_backlight.o
CC drivers/gpu/drm/i915/i915_trace_points.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_hdcp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_link_training.o
CC drivers/gpu/drm/i915/i915_ttm_buddy_manager.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dp_mst.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpll.o
CC drivers/gpu/drm/i915/i915_vma.o
CC drivers/gpu/drm/i915/i915_vma_resource.o
CC drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.o
CC drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpll_mgr.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dpt_common.o
CC drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_drrs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsb.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi.o
CC drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi_dcs_backlight.o
CC drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dsi_vbt.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fb.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_ads.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fbc.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_capture.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fdi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_fifo_underrun.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_frontbuffer.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_ct.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_fw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_global_state.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_log.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_rc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_gmbus.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.o
CC drivers/gpu/drm/i915/gt/uc/intel_guc_submission.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdcp.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdcp_gsc_message.o
CC drivers/gpu/drm/i915/gt/uc/intel_huc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hdmi.o
CC drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hotplug.o
CC drivers/gpu/drm/i915/gt/uc/intel_huc_fw.o
CC drivers/gpu/drm/i915/gt/uc/intel_uc.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hotplug_irq.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_hti.o
CC drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_link_bw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_lspcon.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_lock.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_setup.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_modeset_verify.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_panel.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pmdemand.o
CC drivers/gpu/drm/i915/gt/uc/intel_uc_fw.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pps.o
CC drivers/gpu/drm/i915/gt/intel_gsc.o
CC drivers/gpu/drm/i915/i915_hwmon.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_psr.o
CC drivers/gpu/drm/i915/display/hsw_ips.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_qp_tables.o
CC drivers/gpu/drm/i915/display/i9xx_plane.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_quirks.o
CC drivers/gpu/drm/i915/display/i9xx_wm.o
CC drivers/gpu/drm/i915/display/intel_atomic.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_snps_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_tc.o
CC drivers/gpu/drm/i915/display/intel_atomic_plane.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vblank.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vdsc.o
CC drivers/gpu/drm/i915/display/intel_audio.o
CC drivers/gpu/drm/i915/display/intel_bios.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vga.o
CC drivers/gpu/drm/i915/display/intel_bw.o
CC drivers/gpu/drm/i915/display/intel_cdclk.o
CC drivers/gpu/drm/i915/display/intel_color.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_vrr.o
CC drivers/gpu/drm/i915/display/intel_combo_phy.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_dmc_wl.o
CC drivers/gpu/drm/i915/display/intel_connector.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_wm.o
CC drivers/gpu/drm/i915/display/intel_crtc.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_scaler.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_universal_plane.o
CC drivers/gpu/drm/i915/display/intel_crtc_state_dump.o
CC [M] drivers/gpu/drm/xe/i915-display/skl_watermark.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_acpi.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_opregion.o
CC drivers/gpu/drm/i915/display/intel_cursor.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_debugfs.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_display_debugfs_params.o
CC [M] drivers/gpu/drm/xe/i915-display/intel_pipe_crc.o
CC [M] drivers/gpu/drm/xe/xe_gsc.o
CC drivers/gpu/drm/i915/display/intel_display.o
CC [M] drivers/gpu/drm/xe/xe_guc.o
CC drivers/gpu/drm/i915/display/intel_display_driver.o
CC [M] drivers/gpu/drm/xe/xe_guc_ads.o
CC drivers/gpu/drm/i915/display/intel_display_irq.o
CC drivers/gpu/drm/i915/display/intel_display_params.o
CC drivers/gpu/drm/i915/display/intel_display_power.o
CC drivers/gpu/drm/i915/display/intel_display_power_map.o
CC drivers/gpu/drm/i915/display/intel_display_power_well.o
CC drivers/gpu/drm/i915/display/intel_display_reset.o
CC drivers/gpu/drm/i915/display/intel_display_rps.o
CC drivers/gpu/drm/i915/display/intel_display_wa.o
CC drivers/gpu/drm/i915/display/intel_dmc.o
CC drivers/gpu/drm/i915/display/intel_dmc_wl.o
CC drivers/gpu/drm/i915/display/intel_dpio_phy.o
CC drivers/gpu/drm/i915/display/intel_dpll.o
CC drivers/gpu/drm/i915/display/intel_dpll_mgr.o
CC drivers/gpu/drm/i915/display/intel_dpt.o
CC drivers/gpu/drm/i915/display/intel_dpt_common.o
CC drivers/gpu/drm/i915/display/intel_drrs.o
CC drivers/gpu/drm/i915/display/intel_dsb.o
CC drivers/gpu/drm/i915/display/intel_dsb_buffer.o
CC drivers/gpu/drm/i915/display/intel_fb.o
CC drivers/gpu/drm/i915/display/intel_fb_bo.o
CC drivers/gpu/drm/i915/display/intel_fb_pin.o
CC drivers/gpu/drm/i915/display/intel_fbc.o
CC drivers/gpu/drm/i915/display/intel_fdi.o
CC drivers/gpu/drm/i915/display/intel_fifo_underrun.o
CC drivers/gpu/drm/i915/display/intel_frontbuffer.o
CC drivers/gpu/drm/i915/display/intel_global_state.o
CC drivers/gpu/drm/i915/display/intel_hdcp.o
CC drivers/gpu/drm/i915/display/intel_hdcp_gsc.o
CC drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.o
CC drivers/gpu/drm/i915/display/intel_hotplug.o
CC drivers/gpu/drm/i915/display/intel_hotplug_irq.o
CC drivers/gpu/drm/i915/display/intel_hti.o
CC drivers/gpu/drm/i915/display/intel_link_bw.o
CC drivers/gpu/drm/i915/display/intel_load_detect.o
CC drivers/gpu/drm/i915/display/intel_lpe_audio.o
CC drivers/gpu/drm/i915/display/intel_modeset_lock.o
CC drivers/gpu/drm/i915/display/intel_modeset_setup.o
CC drivers/gpu/drm/i915/display/intel_modeset_verify.o
CC drivers/gpu/drm/i915/display/intel_overlay.o
CC drivers/gpu/drm/i915/display/intel_pch_display.o
CC drivers/gpu/drm/i915/display/intel_pch_refclk.o
CC drivers/gpu/drm/i915/display/intel_plane_initial.o
CC drivers/gpu/drm/i915/display/intel_pmdemand.o
CC drivers/gpu/drm/i915/display/intel_psr.o
CC drivers/gpu/drm/i915/display/intel_quirks.o
CC drivers/gpu/drm/i915/display/intel_sprite.o
CC drivers/gpu/drm/i915/display/intel_sprite_uapi.o
CC drivers/gpu/drm/i915/display/intel_tc.o
CC drivers/gpu/drm/i915/display/intel_vblank.o
CC drivers/gpu/drm/i915/display/intel_vga.o
CC drivers/gpu/drm/i915/display/intel_wm.o
CC drivers/gpu/drm/i915/display/skl_scaler.o
CC drivers/gpu/drm/i915/display/skl_universal_plane.o
CC drivers/gpu/drm/i915/display/skl_watermark.o
CC drivers/gpu/drm/i915/display/intel_acpi.o
CC drivers/gpu/drm/i915/display/intel_opregion.o
CC drivers/gpu/drm/i915/display/intel_display_debugfs.o
CC drivers/gpu/drm/i915/display/intel_display_debugfs_params.o
CC drivers/gpu/drm/i915/display/intel_pipe_crc.o
CC drivers/gpu/drm/i915/display/dvo_ch7017.o
CC drivers/gpu/drm/i915/display/dvo_ch7xxx.o
CC drivers/gpu/drm/i915/display/dvo_ivch.o
CC drivers/gpu/drm/i915/display/dvo_ns2501.o
CC drivers/gpu/drm/i915/display/dvo_sil164.o
CC drivers/gpu/drm/i915/display/dvo_tfp410.o
CC drivers/gpu/drm/i915/display/g4x_dp.o
CC drivers/gpu/drm/i915/display/g4x_hdmi.o
CC drivers/gpu/drm/i915/display/icl_dsi.o
CC drivers/gpu/drm/i915/display/intel_backlight.o
CC drivers/gpu/drm/i915/display/intel_crt.o
CC drivers/gpu/drm/i915/display/intel_cx0_phy.o
CC drivers/gpu/drm/i915/display/intel_ddi.o
LD [M] drivers/gpu/drm/xe/xe.o
CC drivers/gpu/drm/i915/display/intel_ddi_buf_trans.o
CC drivers/gpu/drm/i915/display/intel_display_device.o
CC drivers/gpu/drm/i915/display/intel_display_trace.o
CC drivers/gpu/drm/i915/display/intel_dkl_phy.o
CC drivers/gpu/drm/i915/display/intel_dp.o
CC drivers/gpu/drm/i915/display/intel_dp_aux.o
CC drivers/gpu/drm/i915/display/intel_dp_aux_backlight.o
CC drivers/gpu/drm/i915/display/intel_dp_hdcp.o
CC drivers/gpu/drm/i915/display/intel_dp_link_training.o
CC drivers/gpu/drm/i915/display/intel_dp_mst.o
CC drivers/gpu/drm/i915/display/intel_dsi.o
CC drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.o
CC drivers/gpu/drm/i915/display/intel_dsi_vbt.o
CC drivers/gpu/drm/i915/display/intel_dvo.o
CC drivers/gpu/drm/i915/display/intel_gmbus.o
CC drivers/gpu/drm/i915/display/intel_hdmi.o
CC drivers/gpu/drm/i915/display/intel_lspcon.o
CC drivers/gpu/drm/i915/display/intel_lvds.o
CC drivers/gpu/drm/i915/display/intel_panel.o
CC drivers/gpu/drm/i915/display/intel_pps.o
CC drivers/gpu/drm/i915/display/intel_qp_tables.o
CC drivers/gpu/drm/i915/display/intel_sdvo.o
CC drivers/gpu/drm/i915/display/intel_snps_phy.o
CC drivers/gpu/drm/i915/display/intel_tv.o
CC drivers/gpu/drm/i915/display/intel_vdsc.o
CC drivers/gpu/drm/i915/display/intel_vrr.o
CC drivers/gpu/drm/i915/display/vlv_dsi.o
CC drivers/gpu/drm/i915/display/vlv_dsi_pll.o
CC drivers/gpu/drm/i915/i915_perf.o
CC drivers/gpu/drm/i915/pxp/intel_pxp.o
CC drivers/gpu/drm/i915/pxp/intel_pxp_huc.o
CC drivers/gpu/drm/i915/pxp/intel_pxp_tee.o
CC drivers/gpu/drm/i915/i915_gpu_error.o
CC drivers/gpu/drm/i915/i915_vgpu.o
AR drivers/gpu/drm/i915/built-in.a
AR drivers/gpu/drm/built-in.a
AR drivers/gpu/built-in.a
AR drivers/built-in.a
AR built-in.a
AR vmlinux.a
LD vmlinux.o
OBJCOPY modules.builtin.modinfo
GEN modules.builtin
MODPOST Module.symvers
CC .vmlinux.export.o
CC [M] fs/efivarfs/efivarfs.mod.o
CC [M] drivers/gpu/drm/drm_exec.mod.o
CC [M] drivers/gpu/drm/drm_gpuvm.mod.o
CC [M] drivers/gpu/drm/drm_suballoc_helper.mod.o
CC [M] drivers/gpu/drm/drm_ttm_helper.mod.o
CC [M] drivers/gpu/drm/scheduler/gpu-sched.mod.o
CC [M] drivers/gpu/drm/xe/xe.mod.o
CC [M] drivers/thermal/intel/x86_pkg_temp_thermal.mod.o
CC [M] sound/core/snd-hwdep.mod.o
CC [M] sound/core/snd-pcm.mod.o
CC [M] sound/pci/hda/snd-hda-codec.mod.o
CC [M] sound/pci/hda/snd-hda-codec-hdmi.mod.o
CC [M] sound/pci/hda/snd-hda-intel.mod.o
CC [M] sound/hda/snd-hda-core.mod.o
CC [M] sound/hda/snd-intel-dspcfg.mod.o
CC [M] sound/hda/snd-intel-sdw-acpi.mod.o
CC [M] net/netfilter/nf_log_syslog.mod.o
CC [M] net/netfilter/xt_mark.mod.o
CC [M] net/netfilter/xt_nat.mod.o
CC [M] net/netfilter/xt_LOG.mod.o
CC [M] net/netfilter/xt_MASQUERADE.mod.o
CC [M] net/netfilter/xt_addrtype.mod.o
CC [M] net/ipv4/netfilter/iptable_nat.mod.o
LD [M] fs/efivarfs/efivarfs.ko
LD [M] sound/hda/snd-intel-sdw-acpi.ko
LD [M] drivers/gpu/drm/drm_gpuvm.ko
LD [M] sound/pci/hda/snd-hda-intel.ko
LD [M] drivers/gpu/drm/drm_ttm_helper.ko
LD [M] sound/core/snd-pcm.ko
LD [M] net/netfilter/xt_nat.ko
LD [M] net/netfilter/nf_log_syslog.ko
LD [M] net/netfilter/xt_addrtype.ko
LD [M] drivers/gpu/drm/scheduler/gpu-sched.ko
LD [M] drivers/thermal/intel/x86_pkg_temp_thermal.ko
LD [M] net/ipv4/netfilter/iptable_nat.ko
LD [M] sound/hda/snd-intel-dspcfg.ko
LD [M] net/netfilter/xt_mark.ko
LD [M] net/netfilter/xt_MASQUERADE.ko
LD [M] drivers/gpu/drm/drm_suballoc_helper.ko
LD [M] sound/core/snd-hwdep.ko
LD [M] drivers/gpu/drm/drm_exec.ko
LD [M] sound/hda/snd-hda-core.ko
LD [M] net/netfilter/xt_LOG.ko
LD [M] drivers/gpu/drm/xe/xe.ko
LD [M] sound/pci/hda/snd-hda-codec-hdmi.ko
LD [M] sound/pci/hda/snd-hda-codec.ko
UPD include/generated/utsversion.h
CC init/version-timestamp.o
LD .tmp_vmlinux.kallsyms1
ld: drivers/gpu/drm/ttm/ttm_bo.o: in function `ttm_bo_validate':
ttm_bo.c:(.text+0x10f3): undefined reference to `drm_exec_snapshot'
ld: ttm_bo.c:(.text+0x11b3): undefined reference to `drm_exec_restore'
ld: ttm_bo.c:(.text+0x1240): undefined reference to `drm_exec_restore'
ld: ttm_bo.c:(.text+0x128c): undefined reference to `drm_exec_restore'
ld: drivers/gpu/drm/ttm/ttm_bo.o: in function `ttm_bo_init_reserved':
ttm_bo.c:(.text+0x1349): undefined reference to `drm_exec_trylock_obj'
ld: ttm_bo.c:(.text+0x1377): undefined reference to `drm_exec_unlock_obj'
ld: drivers/gpu/drm/ttm/ttm_bo_util.o: in function `ttm_lru_walk_for_evict':
ttm_bo_util.c:(.text+0xb14): undefined reference to `drm_exec_trylock_obj'
ld: ttm_bo_util.c:(.text+0xcc9): undefined reference to `drm_exec_lock_obj'
ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `ttm_bo_vm_reserve':
ttm_bo_vm.c:(.text+0x38e): undefined reference to `drm_exec_trylock_obj'
ld: ttm_bo_vm.c:(.text+0x443): undefined reference to `drm_exec_lock_obj'
ld: ttm_bo_vm.c:(.text+0x469): undefined reference to `drm_exec_unlock_obj'
ld: ttm_bo_vm.c:(.text+0x4ed): undefined reference to `drm_exec_unlock_obj'
ld: ttm_bo_vm.c:(.text+0x52e): undefined reference to `drm_exec_lock_obj'
ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `ttm_bo_vm_fault_reserved':
ttm_bo_vm.c:(.text+0x90d): undefined reference to `drm_exec_unlock_obj'
ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `ttm_bo_vm_fault':
ttm_bo_vm.c:(.text+0x9ee): undefined reference to `drm_exec_init'
ld: ttm_bo_vm.c:(.text+0xa04): undefined reference to `drm_exec_cleanup'
ld: ttm_bo_vm.c:(.text+0xa6d): undefined reference to `drm_exec_handle_contended'
ld: ttm_bo_vm.c:(.text+0xa7f): undefined reference to `drm_exec_cleanup'
ld: ttm_bo_vm.c:(.text+0xa94): undefined reference to `drm_exec_fini'
ld: ttm_bo_vm.c:(.text+0xac6): undefined reference to `drm_exec_handle_contended'
make[2]: *** [/workspace/kernel/scripts/Makefile.vmlinux:37: vmlinux] Error 1
make[1]: *** [/workspace/kernel/Makefile:1160: vmlinux] Error 2
make: *** [/workspace/kernel/Makefile:240: __sub-make] Error 2
run-parts: /workspace/ci/hooks/11-build-32b exited with return code 2
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✗ CI.checksparse: warning for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (26 preceding siblings ...)
2024-05-21 7:39 ` ✗ CI.Hooks: failure " Patchwork
@ 2024-05-21 7:41 ` Patchwork
2024-05-21 8:03 ` ✓ CI.BAT: success " Patchwork
2024-05-21 9:09 ` ✗ CI.FULL: failure " Patchwork
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 7:41 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : warning
== Summary ==
+ trap cleanup EXIT
+ KERNEL=/kernel
+ MT=/root/linux/maintainer-tools
+ git clone https://gitlab.freedesktop.org/drm/maintainer-tools /root/linux/maintainer-tools
Cloning into '/root/linux/maintainer-tools'...
warning: redirecting to https://gitlab.freedesktop.org/drm/maintainer-tools.git/
+ make -C /root/linux/maintainer-tools
make: Entering directory '/root/linux/maintainer-tools'
cc -O2 -g -Wextra -o remap-log remap-log.c
make: Leaving directory '/root/linux/maintainer-tools'
+ cd /kernel
+ git config --global --add safe.directory /kernel
+ /root/linux/maintainer-tools/dim sparse --fast 3addfb8584a4fcbff8123461682e5bdfd8785bde
Sparse version: 0.6.1 (Ubuntu: 0.6.1-2build1)
Fast mode used, each commit won't be checked separately.
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✓ CI.BAT: success for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (27 preceding siblings ...)
2024-05-21 7:41 ` ✗ CI.checksparse: warning " Patchwork
@ 2024-05-21 8:03 ` Patchwork
2024-05-21 9:09 ` ✗ CI.FULL: failure " Patchwork
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 8:03 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : success
== Summary ==
CI Bug Log - changes from xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde_BAT -> xe-pw-131815v3_BAT
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (5 -> 5)
------------------------------
No changes in participating hosts
New tests
---------
New tests have been introduced between xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde_BAT and xe-pw-131815v3_BAT:
### New IGT tests (1) ###
* igt@xe_live_ktest@xe_bo@xe_bo_shrink_kunit:
- Statuses : 5 pass(s)
- Exec time: [7.06, 50.39] s
Changes
-------
No changes found
Build changes
-------------
* Linux: xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde -> xe-pw-131815v3
IGT_7864: 8eff53c9664fa0abaa55b403c9f10f96260e44b7 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde: 3addfb8584a4fcbff8123461682e5bdfd8785bde
xe-pw-131815v3: 131815v3
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/index.html
[-- Attachment #2: Type: text/html, Size: 1827 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* ✗ CI.FULL: failure for TTM shrinker helpers and xe buffer object shrinker (rev3)
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
` (28 preceding siblings ...)
2024-05-21 8:03 ` ✓ CI.BAT: success " Patchwork
@ 2024-05-21 9:09 ` Patchwork
29 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2024-05-21 9:09 UTC (permalink / raw)
To: Thomas Hellström; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 73227 bytes --]
== Series Details ==
Series: TTM shrinker helpers and xe buffer object shrinker (rev3)
URL : https://patchwork.freedesktop.org/series/131815/
State : failure
== Summary ==
CI Bug Log - changes from xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde_full -> xe-pw-131815v3_full
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with xe-pw-131815v3_full absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in xe-pw-131815v3_full, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
to document this new failure mode, which will reduce false positives in CI.
Participating hosts (3 -> 3)
------------------------------
No changes in participating hosts
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in xe-pw-131815v3_full:
### IGT changes ###
#### Possible regressions ####
* igt@xe_live_ktest@xe_bo@xe_bo_shrink_kunit (NEW):
- {shard-lnl}: NOTRUN -> [INCOMPLETE][1] +1 other test incomplete
[1]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-3/igt@xe_live_ktest@xe_bo@xe_bo_shrink_kunit.html
* igt@xe_pm@s3-vm-bind-unbind-all:
- shard-adlp: [PASS][2] -> [FAIL][3]
[2]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-2/igt@xe_pm@s3-vm-bind-unbind-all.html
[3]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-6/igt@xe_pm@s3-vm-bind-unbind-all.html
#### Warnings ####
* igt@xe_exec_reset@cm-cat-error:
- shard-adlp: [DMESG-FAIL][4] ([Intel XE#1330] / [Intel XE#358]) -> [DMESG-FAIL][5]
[4]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@xe_exec_reset@cm-cat-error.html
[5]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_exec_reset@cm-cat-error.html
#### Suppressed ####
The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.
* igt@kms_psr@fbc-psr-primary-blt:
- {shard-lnl}: NOTRUN -> [INCOMPLETE][6] +1 other test incomplete
[6]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-4/igt@kms_psr@fbc-psr-primary-blt.html
* igt@kms_psr@psr2-cursor-plane-move:
- {shard-lnl}: NOTRUN -> [FAIL][7] +1 other test fail
[7]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-8/igt@kms_psr@psr2-cursor-plane-move.html
* igt@xe_exec_compute_mode@once-userptr-invalidate:
- {shard-lnl}: [PASS][8] -> [INCOMPLETE][9] +1 other test incomplete
[8]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-lnl-3/igt@xe_exec_compute_mode@once-userptr-invalidate.html
[9]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-3/igt@xe_exec_compute_mode@once-userptr-invalidate.html
* igt@xe_module_load@reload-no-display:
- {shard-lnl}: NOTRUN -> [ABORT][10]
[10]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-7/igt@xe_module_load@reload-no-display.html
New tests
---------
New tests have been introduced between xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde_full and xe-pw-131815v3_full:
### New IGT tests (2) ###
* igt@kms_rmfb:
- Statuses : 1 incomplete(s)
- Exec time: [0.0] s
* igt@xe_live_ktest@xe_bo@xe_bo_shrink_kunit:
- Statuses : 1 incomplete(s) 2 pass(s)
- Exec time: [0.00, 12.97] s
Known issues
------------
Here are the changes found in xe-pw-131815v3_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@kms_atomic_transition@plane-toggle-modeset-transition@pipe-a-hdmi-a-6:
- shard-dg2-set2: [PASS][11] -> [FAIL][12] ([Intel XE#1388]) +1 other test fail
[11]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_atomic_transition@plane-toggle-modeset-transition@pipe-a-hdmi-a-6.html
[12]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_atomic_transition@plane-toggle-modeset-transition@pipe-a-hdmi-a-6.html
* igt@kms_big_fb@linear-64bpp-rotate-270:
- shard-adlp: NOTRUN -> [SKIP][13] ([Intel XE#1201] / [Intel XE#316])
[13]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_big_fb@linear-64bpp-rotate-270.html
* igt@kms_big_fb@yf-tiled-64bpp-rotate-270:
- shard-adlp: NOTRUN -> [SKIP][14] ([Intel XE#1124] / [Intel XE#1201]) +5 other tests skip
[14]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_big_fb@yf-tiled-64bpp-rotate-270.html
* igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip:
- shard-dg2-set2: NOTRUN -> [SKIP][15] ([Intel XE#1124] / [Intel XE#1201])
[15]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip.html
* igt@kms_bw@linear-tiling-2-displays-2560x1440p:
- shard-adlp: NOTRUN -> [SKIP][16] ([Intel XE#1201] / [Intel XE#367]) +1 other test skip
[16]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_bw@linear-tiling-2-displays-2560x1440p.html
* igt@kms_ccs@bad-aux-stride-4-tiled-mtl-rc-ccs-cc:
- shard-adlp: NOTRUN -> [SKIP][17] ([Intel XE#1201] / [Intel XE#455] / [Intel XE#787]) +7 other tests skip
[17]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_ccs@bad-aux-stride-4-tiled-mtl-rc-ccs-cc.html
* igt@kms_ccs@bad-rotation-90-4-tiled-dg2-mc-ccs:
- shard-dg2-set2: [PASS][18] -> [INCOMPLETE][19] ([Intel XE#1195]) +1 other test incomplete
[18]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-466/igt@kms_ccs@bad-rotation-90-4-tiled-dg2-mc-ccs.html
[19]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-466/igt@kms_ccs@bad-rotation-90-4-tiled-dg2-mc-ccs.html
* igt@kms_ccs@crc-primary-basic-y-tiled-gen12-rc-ccs-cc@pipe-a-hdmi-a-1:
- shard-adlp: NOTRUN -> [SKIP][20] ([Intel XE#1201] / [Intel XE#787]) +11 other tests skip
[20]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_ccs@crc-primary-basic-y-tiled-gen12-rc-ccs-cc@pipe-a-hdmi-a-1.html
* igt@kms_ccs@random-ccs-data-4-tiled-xe2-ccs:
- shard-adlp: NOTRUN -> [SKIP][21] ([Intel XE#1201] / [Intel XE#1252])
[21]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_ccs@random-ccs-data-4-tiled-xe2-ccs.html
* igt@kms_chamelium_color@degamma:
- shard-adlp: NOTRUN -> [SKIP][22] ([Intel XE#1201] / [Intel XE#306])
[22]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_chamelium_color@degamma.html
* igt@kms_chamelium_frames@dp-frame-dump:
- shard-adlp: NOTRUN -> [SKIP][23] ([Intel XE#1201] / [Intel XE#373]) +1 other test skip
[23]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_chamelium_frames@dp-frame-dump.html
* igt@kms_cursor_crc@cursor-onscreen-512x512:
- shard-dg2-set2: NOTRUN -> [SKIP][24] ([Intel XE#1201] / [Intel XE#308])
[24]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@kms_cursor_crc@cursor-onscreen-512x512.html
* igt@kms_cursor_legacy@2x-cursor-vs-flip-legacy:
- shard-dg2-set2: [PASS][25] -> [DMESG-WARN][26] ([Intel XE#1214] / [Intel XE#282] / [Intel XE#910])
[25]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-435/igt@kms_cursor_legacy@2x-cursor-vs-flip-legacy.html
[26]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-463/igt@kms_cursor_legacy@2x-cursor-vs-flip-legacy.html
* igt@kms_cursor_legacy@cursora-vs-flipa-atomic-transitions:
- shard-dg2-set2: [PASS][27] -> [DMESG-WARN][28] ([Intel XE#1214] / [Intel XE#282]) +2 other tests dmesg-warn
[27]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-433/igt@kms_cursor_legacy@cursora-vs-flipa-atomic-transitions.html
[28]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-466/igt@kms_cursor_legacy@cursora-vs-flipa-atomic-transitions.html
* igt@kms_cursor_legacy@cursorb-vs-flipb-legacy:
- shard-adlp: NOTRUN -> [SKIP][29] ([Intel XE#1201] / [Intel XE#309]) +5 other tests skip
[29]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_cursor_legacy@cursorb-vs-flipb-legacy.html
* igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size:
- shard-adlp: NOTRUN -> [SKIP][30] ([Intel XE#1201] / [Intel XE#323])
[30]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size.html
* igt@kms_feature_discovery@psr1:
- shard-adlp: NOTRUN -> [SKIP][31] ([Intel XE#1135] / [Intel XE#1201])
[31]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_feature_discovery@psr1.html
* igt@kms_flip@2x-nonexisting-fb-interruptible:
- shard-adlp: NOTRUN -> [SKIP][32] ([Intel XE#1201] / [Intel XE#310]) +5 other tests skip
[32]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_flip@2x-nonexisting-fb-interruptible.html
* igt@kms_flip@flip-vs-suspend-interruptible@b-hdmi-a1:
- shard-adlp: NOTRUN -> [DMESG-WARN][33] ([Intel XE#1214] / [Intel XE#1608]) +2 other tests dmesg-warn
[33]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-8/igt@kms_flip@flip-vs-suspend-interruptible@b-hdmi-a1.html
* igt@kms_flip@flip-vs-suspend@b-hdmi-a1:
- shard-adlp: NOTRUN -> [DMESG-WARN][34] ([Intel XE#1191] / [Intel XE#1214] / [Intel XE#1608]) +6 other tests dmesg-warn
[34]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_flip@flip-vs-suspend@b-hdmi-a1.html
* igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-downscaling@pipe-a-valid-mode:
- shard-adlp: NOTRUN -> [SKIP][35] ([Intel XE#1201] / [Intel XE#455]) +6 other tests skip
[35]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-downscaling@pipe-a-valid-mode.html
* igt@kms_flip_tiling@flip-change-tiling@pipe-b-hdmi-a-1-y-to-x:
- shard-adlp: [PASS][36] -> [FAIL][37] ([Intel XE#1874]) +1 other test fail
[36]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@kms_flip_tiling@flip-change-tiling@pipe-b-hdmi-a-1-y-to-x.html
[37]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_flip_tiling@flip-change-tiling@pipe-b-hdmi-a-1-y-to-x.html
* igt@kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-mmap-wc:
- shard-adlp: NOTRUN -> [SKIP][38] ([Intel XE#1201] / [Intel XE#656]) +13 other tests skip
[38]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-mmap-wc.html
* igt@kms_frontbuffer_tracking@fbcdrrs-shrfb-scaledprimary:
- shard-adlp: NOTRUN -> [SKIP][39] ([Intel XE#1201] / [Intel XE#651]) +3 other tests skip
[39]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_frontbuffer_tracking@fbcdrrs-shrfb-scaledprimary.html
* igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-render:
- shard-adlp: NOTRUN -> [SKIP][40] ([Intel XE#1201] / [Intel XE#653]) +5 other tests skip
[40]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-render.html
* igt@kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt:
- shard-dg2-set2: NOTRUN -> [SKIP][41] ([Intel XE#1201] / [Intel XE#653])
[41]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt.html
* igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-hdmi-a-1:
- shard-adlp: [PASS][42] -> [DMESG-WARN][43] ([Intel XE#1191] / [Intel XE#1214]) +1 other test dmesg-warn
[42]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-hdmi-a-1.html
[43]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-hdmi-a-1.html
* igt@kms_plane_lowres@tiling-x:
- shard-adlp: NOTRUN -> [FAIL][44] ([Intel XE#1874]) +3 other tests fail
[44]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_plane_lowres@tiling-x.html
* igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-6:
- shard-dg2-set2: [PASS][45] -> [FAIL][46] ([Intel XE#361])
[45]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-6.html
[46]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-463/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-6.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-a-hdmi-a-1:
- shard-adlp: NOTRUN -> [SKIP][47] ([Intel XE#1201] / [Intel XE#305]) +5 other tests skip
[47]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-a-hdmi-a-1.html
* igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25:
- shard-adlp: NOTRUN -> [SKIP][48] ([Intel XE#1201] / [Intel XE#305] / [Intel XE#455]) +3 other tests skip
[48]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25.html
* igt@kms_pm_rpm@dpms-mode-unset-lpsp:
- shard-adlp: NOTRUN -> [SKIP][49] ([Intel XE#1201] / [Intel XE#1211])
[49]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_pm_rpm@dpms-mode-unset-lpsp.html
* igt@kms_psr2_sf@fbc-overlay-plane-update-sf-dmg-area:
- shard-adlp: NOTRUN -> [SKIP][50] ([Intel XE#1201]) +2 other tests skip
[50]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-8/igt@kms_psr2_sf@fbc-overlay-plane-update-sf-dmg-area.html
* igt@kms_psr@fbc-psr-primary-render:
- shard-adlp: NOTRUN -> [SKIP][51] ([Intel XE#1201] / [Intel XE#929]) +4 other tests skip
[51]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_psr@fbc-psr-primary-render.html
* igt@kms_psr@psr-primary-page-flip:
- shard-dg2-set2: NOTRUN -> [SKIP][52] ([Intel XE#1201] / [Intel XE#929]) +1 other test skip
[52]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@kms_psr@psr-primary-page-flip.html
* igt@kms_rotation_crc@sprite-rotation-90:
- shard-adlp: NOTRUN -> [SKIP][53] ([Intel XE#1201] / [Intel XE#327])
[53]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_rotation_crc@sprite-rotation-90.html
* igt@xe_ccs@block-copy-compressed-inc-dimension:
- shard-adlp: NOTRUN -> [SKIP][54] ([Intel XE#1201] / [Intel XE#455] / [Intel XE#488])
[54]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@xe_ccs@block-copy-compressed-inc-dimension.html
* igt@xe_evict@evict-beng-small:
- shard-adlp: NOTRUN -> [SKIP][55] ([Intel XE#1201] / [Intel XE#261] / [Intel XE#688])
[55]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_evict@evict-beng-small.html
* igt@xe_exec_basic@multigpu-no-exec-userptr-rebind:
- shard-adlp: NOTRUN -> [SKIP][56] ([Intel XE#1201] / [Intel XE#1392]) +3 other tests skip
[56]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@xe_exec_basic@multigpu-no-exec-userptr-rebind.html
* igt@xe_exec_fault_mode@many-execqueues-bindexecqueue-userptr-prefetch:
- shard-dg2-set2: NOTRUN -> [SKIP][57] ([Intel XE#1201] / [Intel XE#288])
[57]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@xe_exec_fault_mode@many-execqueues-bindexecqueue-userptr-prefetch.html
* igt@xe_exec_fault_mode@twice-bindexecqueue-userptr-prefetch:
- shard-adlp: NOTRUN -> [SKIP][58] ([Intel XE#1201] / [Intel XE#288]) +6 other tests skip
[58]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@xe_exec_fault_mode@twice-bindexecqueue-userptr-prefetch.html
* igt@xe_module_load@load:
- shard-adlp: NOTRUN -> [SKIP][59] ([Intel XE#1201] / [Intel XE#378])
[59]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_module_load@load.html
* igt@xe_pm@s3-d3cold-basic-exec:
- shard-adlp: NOTRUN -> [SKIP][60] ([Intel XE#1201] / [Intel XE#366])
[60]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_pm@s3-d3cold-basic-exec.html
* igt@xe_pm@s4-basic:
- shard-adlp: [PASS][61] -> [ABORT][62] ([Intel XE#1358])
[61]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-2/igt@xe_pm@s4-basic.html
[62]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-9/igt@xe_pm@s4-basic.html
* igt@xe_pm@s4-multiple-execs:
- shard-adlp: [PASS][63] -> [DMESG-WARN][64] ([Intel XE#1214])
[63]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@xe_pm@s4-multiple-execs.html
[64]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-6/igt@xe_pm@s4-multiple-execs.html
* igt@xe_query@multigpu-query-engines:
- shard-adlp: NOTRUN -> [SKIP][65] ([Intel XE#1201] / [Intel XE#944])
[65]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@xe_query@multigpu-query-engines.html
* igt@xe_query@multigpu-query-uc-fw-version-guc:
- shard-dg2-set2: NOTRUN -> [SKIP][66] ([Intel XE#1201] / [Intel XE#944])
[66]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@xe_query@multigpu-query-uc-fw-version-guc.html
#### Possible fixes ####
* igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-1-y:
- shard-adlp: [DMESG-WARN][67] ([Intel XE#1214] / [Intel XE#324]) -> [PASS][68] +2 other tests pass
[67]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-2/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-1-y.html
[68]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-9/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-1-y.html
* igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-async-flip:
- {shard-lnl}: [INCOMPLETE][69] -> [PASS][70] +1 other test pass
[69]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-lnl-7/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-async-flip.html
[70]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-4/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-async-flip.html
* igt@kms_cursor_legacy@forked-move@pipe-b:
- shard-dg2-set2: [DMESG-WARN][71] ([Intel XE#1214] / [Intel XE#282]) -> [PASS][72] +6 other tests pass
[71]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-436/igt@kms_cursor_legacy@forked-move@pipe-b.html
[72]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-466/igt@kms_cursor_legacy@forked-move@pipe-b.html
* igt@kms_cursor_legacy@torture-move@pipe-a:
- shard-dg2-set2: [DMESG-WARN][73] ([Intel XE#877]) -> [PASS][74] +1 other test pass
[73]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_cursor_legacy@torture-move@pipe-a.html
[74]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_cursor_legacy@torture-move@pipe-a.html
* igt@kms_fbcon_fbt@fbc-suspend:
- shard-dg2-set2: [FAIL][75] ([Intel XE#1609]) -> [PASS][76]
[75]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_fbcon_fbt@fbc-suspend.html
[76]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_fbcon_fbt@fbc-suspend.html
* igt@kms_flip_tiling@flip-change-tiling@pipe-c-hdmi-a-1-y-to-x:
- shard-adlp: [FAIL][77] ([Intel XE#1874]) -> [PASS][78]
[77]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@kms_flip_tiling@flip-change-tiling@pipe-c-hdmi-a-1-y-to-x.html
[78]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_flip_tiling@flip-change-tiling@pipe-c-hdmi-a-1-y-to-x.html
* igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1:
- shard-adlp: [DMESG-WARN][79] ([Intel XE#1191] / [Intel XE#1214]) -> [PASS][80]
[79]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1.html
[80]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1.html
* igt@xe_evict@evict-beng-large-multi-vm-cm:
- shard-dg2-set2: [FAIL][81] ([Intel XE#1600]) -> [PASS][82] +1 other test pass
[81]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-433/igt@xe_evict@evict-beng-large-multi-vm-cm.html
[82]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-464/igt@xe_evict@evict-beng-large-multi-vm-cm.html
* igt@xe_evict@evict-mixed-threads-large:
- shard-dg2-set2: [INCOMPLETE][83] ([Intel XE#1195] / [Intel XE#1473] / [Intel XE#392]) -> [PASS][84]
[83]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_evict@evict-mixed-threads-large.html
[84]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_evict@evict-mixed-threads-large.html
* igt@xe_evict@evict-threads-large:
- shard-dg2-set2: [TIMEOUT][85] ([Intel XE#1473] / [Intel XE#392]) -> [PASS][86]
[85]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-436/igt@xe_evict@evict-threads-large.html
[86]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-464/igt@xe_evict@evict-threads-large.html
* igt@xe_exec_reset@cat-error:
- shard-adlp: [DMESG-WARN][87] ([Intel XE#1214] / [Intel XE#1330]) -> [PASS][88]
[87]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-8/igt@xe_exec_reset@cat-error.html
[88]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-9/igt@xe_exec_reset@cat-error.html
* igt@xe_exec_threads@threads-hang-fd-userptr-invalidate:
- shard-dg2-set2: [FAIL][89] ([Intel XE#1081]) -> [PASS][90]
[89]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-435/igt@xe_exec_threads@threads-hang-fd-userptr-invalidate.html
[90]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-434/igt@xe_exec_threads@threads-hang-fd-userptr-invalidate.html
* igt@xe_exec_threads@threads-hang-fd-userptr-invalidate-race:
- {shard-lnl}: [FAIL][91] ([Intel XE#1081]) -> [PASS][92]
[91]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-lnl-7/igt@xe_exec_threads@threads-hang-fd-userptr-invalidate-race.html
[92]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-7/igt@xe_exec_threads@threads-hang-fd-userptr-invalidate-race.html
* igt@xe_pm@s4-basic:
- {shard-lnl}: [ABORT][93] ([Intel XE#1358] / [Intel XE#1607]) -> [PASS][94]
[93]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-lnl-2/igt@xe_pm@s4-basic.html
[94]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-6/igt@xe_pm@s4-basic.html
* igt@xe_pm@s4-basic-exec:
- shard-dg2-set2: [INCOMPLETE][95] ([Intel XE#1195] / [Intel XE#1358]) -> [PASS][96]
[95]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-463/igt@xe_pm@s4-basic-exec.html
[96]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-433/igt@xe_pm@s4-basic-exec.html
- shard-adlp: [DMESG-WARN][97] ([Intel XE#1214]) -> [PASS][98]
[97]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@xe_pm@s4-basic-exec.html
[98]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-8/igt@xe_pm@s4-basic-exec.html
* igt@xe_pm@s4-d3hot-basic-exec:
- shard-adlp: [ABORT][99] ([Intel XE#1358]) -> [PASS][100]
[99]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@xe_pm@s4-d3hot-basic-exec.html
[100]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_pm@s4-d3hot-basic-exec.html
* igt@xe_query@query-uc-fw-version-guc:
- {shard-lnl}: [DMESG-WARN][101] ([Intel XE#1638]) -> [PASS][102]
[101]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-lnl-1/igt@xe_query@query-uc-fw-version-guc.html
[102]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-lnl-1/igt@xe_query@query-uc-fw-version-guc.html
#### Warnings ####
* igt@core_hotunplug@hotreplug:
- shard-adlp: [INCOMPLETE][103] ([Intel XE#1195] / [Intel XE#1451]) -> [ABORT][104] ([Intel XE#1538] / [Intel XE#1548] / [Intel XE#1717] / [Intel XE#1760])
[103]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@core_hotunplug@hotreplug.html
[104]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@core_hotunplug@hotreplug.html
* igt@core_hotunplug@hotreplug-lateclose:
- shard-adlp: [INCOMPLETE][105] ([Intel XE#1195] / [Intel XE#1365]) -> [ABORT][106] ([Intel XE#1538] / [Intel XE#1548] / [Intel XE#1717] / [Intel XE#1760])
[105]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@core_hotunplug@hotreplug-lateclose.html
[106]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@core_hotunplug@hotreplug-lateclose.html
* igt@core_hotunplug@hotunplug-rescan:
- shard-adlp: [INCOMPLETE][107] ([Intel XE#1195] / [Intel XE#1365] / [Intel XE#1451]) -> [ABORT][108] ([Intel XE#1548] / [Intel XE#1717] / [Intel XE#1760])
[107]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@core_hotunplug@hotunplug-rescan.html
[108]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@core_hotunplug@hotunplug-rescan.html
* igt@core_setmaster@master-drop-set-user:
- shard-dg2-set2: [DMESG-WARN][109] ([Intel XE#1162]) -> [DMESG-WARN][110] ([Intel XE#1162] / [Intel XE#1214])
[109]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@core_setmaster@master-drop-set-user.html
[110]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@core_setmaster@master-drop-set-user.html
* igt@kms_addfb_basic@addfb25-y-tiled-small-legacy:
- shard-dg2-set2: [SKIP][111] ([Intel XE#623]) -> [SKIP][112] ([Intel XE#1201] / [Intel XE#623])
[111]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_addfb_basic@addfb25-y-tiled-small-legacy.html
[112]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_addfb_basic@addfb25-y-tiled-small-legacy.html
* igt@kms_async_flips@async-flip-with-page-flip-events:
- shard-adlp: [DMESG-WARN][113] ([Intel XE#1033] / [Intel XE#1214] / [Intel XE#324]) -> [DMESG-WARN][114] ([Intel XE#1033] / [Intel XE#1214])
[113]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-2/igt@kms_async_flips@async-flip-with-page-flip-events.html
[114]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-9/igt@kms_async_flips@async-flip-with-page-flip-events.html
* igt@kms_big_fb@linear-8bpp-rotate-270:
- shard-dg2-set2: [SKIP][115] ([Intel XE#316]) -> [SKIP][116] ([Intel XE#1201] / [Intel XE#316]) +1 other test skip
[115]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_big_fb@linear-8bpp-rotate-270.html
[116]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_big_fb@linear-8bpp-rotate-270.html
* igt@kms_big_fb@y-tiled-8bpp-rotate-180:
- shard-dg2-set2: [SKIP][117] ([Intel XE#1124] / [Intel XE#1201]) -> [SKIP][118] ([Intel XE#1124]) +4 other tests skip
[117]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html
[118]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html
* igt@kms_big_fb@y-tiled-addfb-size-overflow:
- shard-dg2-set2: [SKIP][119] ([Intel XE#1201] / [Intel XE#610]) -> [SKIP][120] ([Intel XE#610])
[119]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_big_fb@y-tiled-addfb-size-overflow.html
[120]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_big_fb@y-tiled-addfb-size-overflow.html
* igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-async-flip:
- shard-adlp: [DMESG-FAIL][121] ([Intel XE#324]) -> [FAIL][122] ([Intel XE#1231]) +2 other tests fail
[121]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html
[122]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html
* igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip:
- shard-adlp: [FAIL][123] ([Intel XE#1231]) -> [FAIL][124] ([Intel XE#1242])
[123]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip.html
[124]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip.html
* igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip:
- shard-dg2-set2: [SKIP][125] ([Intel XE#1124]) -> [SKIP][126] ([Intel XE#1124] / [Intel XE#1201]) +3 other tests skip
[125]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip.html
[126]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip.html
* igt@kms_big_joiner@invalid-modeset:
- shard-dg2-set2: [SKIP][127] ([Intel XE#346]) -> [SKIP][128] ([Intel XE#1201] / [Intel XE#346])
[127]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_big_joiner@invalid-modeset.html
[128]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_big_joiner@invalid-modeset.html
* igt@kms_bw@linear-tiling-2-displays-2160x1440p:
- shard-dg2-set2: [SKIP][129] ([Intel XE#367]) -> [SKIP][130] ([Intel XE#1201] / [Intel XE#367]) +1 other test skip
[129]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_bw@linear-tiling-2-displays-2160x1440p.html
[130]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_bw@linear-tiling-2-displays-2160x1440p.html
* igt@kms_bw@linear-tiling-2-displays-2560x1440p:
- shard-dg2-set2: [SKIP][131] ([Intel XE#1201] / [Intel XE#367]) -> [SKIP][132] ([Intel XE#367])
[131]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_bw@linear-tiling-2-displays-2560x1440p.html
[132]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_bw@linear-tiling-2-displays-2560x1440p.html
* igt@kms_ccs@bad-pixel-format-y-tiled-gen12-rc-ccs-cc@pipe-b-dp-4:
- shard-dg2-set2: [SKIP][133] ([Intel XE#787]) -> [SKIP][134] ([Intel XE#1201] / [Intel XE#787]) +34 other tests skip
[133]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_ccs@bad-pixel-format-y-tiled-gen12-rc-ccs-cc@pipe-b-dp-4.html
[134]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_ccs@bad-pixel-format-y-tiled-gen12-rc-ccs-cc@pipe-b-dp-4.html
* igt@kms_ccs@bad-pixel-format-yf-tiled-ccs:
- shard-dg2-set2: [SKIP][135] ([Intel XE#1201] / [Intel XE#455] / [Intel XE#787]) -> [SKIP][136] ([Intel XE#455] / [Intel XE#787]) +13 other tests skip
[135]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_ccs@bad-pixel-format-yf-tiled-ccs.html
[136]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_ccs@bad-pixel-format-yf-tiled-ccs.html
* igt@kms_ccs@ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc@pipe-d-dp-4:
- shard-dg2-set2: [SKIP][137] ([Intel XE#455] / [Intel XE#787]) -> [SKIP][138] ([Intel XE#1201] / [Intel XE#455] / [Intel XE#787]) +9 other tests skip
[137]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_ccs@ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc@pipe-d-dp-4.html
[138]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_ccs@ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc@pipe-d-dp-4.html
* igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs:
- shard-dg2-set2: [TIMEOUT][139] ([Intel XE#1850]) -> [INCOMPLETE][140] ([Intel XE#1195])
[139]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-435/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs.html
[140]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs.html
* igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs@pipe-a-hdmi-a-6:
- shard-dg2-set2: [TIMEOUT][141] ([Intel XE#1713]) -> [INCOMPLETE][142] ([Intel XE#1195])
[141]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-435/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs@pipe-a-hdmi-a-6.html
[142]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-dg2-mc-ccs@pipe-a-hdmi-a-6.html
* igt@kms_ccs@crc-sprite-planes-basic-y-tiled-gen12-mc-ccs@pipe-b-hdmi-a-6:
- shard-dg2-set2: [SKIP][143] ([Intel XE#1201] / [Intel XE#787]) -> [SKIP][144] ([Intel XE#787]) +48 other tests skip
[143]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_ccs@crc-sprite-planes-basic-y-tiled-gen12-mc-ccs@pipe-b-hdmi-a-6.html
[144]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_ccs@crc-sprite-planes-basic-y-tiled-gen12-mc-ccs@pipe-b-hdmi-a-6.html
* igt@kms_ccs@random-ccs-data-4-tiled-xe2-ccs:
- shard-dg2-set2: [SKIP][145] ([Intel XE#1201] / [Intel XE#1252]) -> [SKIP][146] ([Intel XE#1252])
[145]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_ccs@random-ccs-data-4-tiled-xe2-ccs.html
[146]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_ccs@random-ccs-data-4-tiled-xe2-ccs.html
* igt@kms_chamelium_color@gamma:
- shard-dg2-set2: [SKIP][147] ([Intel XE#1201] / [Intel XE#306]) -> [SKIP][148] ([Intel XE#306])
[147]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_chamelium_color@gamma.html
[148]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_chamelium_color@gamma.html
* igt@kms_chamelium_edid@hdmi-mode-timings:
- shard-dg2-set2: [SKIP][149] ([Intel XE#1201] / [Intel XE#373]) -> [SKIP][150] ([Intel XE#373]) +2 other tests skip
[149]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_chamelium_edid@hdmi-mode-timings.html
[150]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_chamelium_edid@hdmi-mode-timings.html
* igt@kms_chamelium_hpd@hdmi-hpd:
- shard-dg2-set2: [SKIP][151] ([Intel XE#373]) -> [SKIP][152] ([Intel XE#1201] / [Intel XE#373]) +5 other tests skip
[151]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_chamelium_hpd@hdmi-hpd.html
[152]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_chamelium_hpd@hdmi-hpd.html
* igt@kms_content_protection@dp-mst-type-0:
- shard-dg2-set2: [SKIP][153] ([Intel XE#307]) -> [SKIP][154] ([Intel XE#1201] / [Intel XE#307]) +1 other test skip
[153]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_content_protection@dp-mst-type-0.html
[154]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_content_protection@dp-mst-type-0.html
* igt@kms_cursor_crc@cursor-rapid-movement-512x170:
- shard-dg2-set2: [SKIP][155] ([Intel XE#1201] / [Intel XE#308]) -> [SKIP][156] ([Intel XE#308])
[155]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_cursor_crc@cursor-rapid-movement-512x170.html
[156]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_cursor_crc@cursor-rapid-movement-512x170.html
* igt@kms_cursor_crc@cursor-sliding-512x512:
- shard-dg2-set2: [SKIP][157] ([Intel XE#308]) -> [SKIP][158] ([Intel XE#1201] / [Intel XE#308])
[157]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_cursor_crc@cursor-sliding-512x512.html
[158]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_cursor_crc@cursor-sliding-512x512.html
* igt@kms_cursor_crc@cursor-suspend:
- shard-adlp: [INCOMPLETE][159] ([Intel XE#1195] / [Intel XE#927]) -> [DMESG-WARN][160] ([Intel XE#1191] / [Intel XE#1214] / [Intel XE#1608])
[159]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@kms_cursor_crc@cursor-suspend.html
[160]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@kms_cursor_crc@cursor-suspend.html
* igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
- shard-dg2-set2: [DMESG-WARN][161] ([Intel XE#1214] / [Intel XE#282]) -> [DMESG-WARN][162] ([Intel XE#1214] / [Intel XE#282] / [Intel XE#910])
[161]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-436/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
[162]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-464/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
* igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
- shard-dg2-set2: [SKIP][163] ([Intel XE#1201] / [Intel XE#323]) -> [SKIP][164] ([Intel XE#323]) +1 other test skip
[163]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
[164]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
* igt@kms_cursor_legacy@cursorb-vs-flipa-legacy:
- shard-dg2-set2: [DMESG-WARN][165] ([Intel XE#282]) -> [DMESG-WARN][166] ([Intel XE#1214] / [Intel XE#282])
[165]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_cursor_legacy@cursorb-vs-flipa-legacy.html
[166]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_cursor_legacy@cursorb-vs-flipa-legacy.html
* igt@kms_dirtyfb@fbc-dirtyfb-ioctl:
- shard-dg2-set2: [SKIP][167] ([Intel XE#455]) -> [SKIP][168] ([Intel XE#1201] / [Intel XE#455]) +9 other tests skip
[167]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_dirtyfb@fbc-dirtyfb-ioctl.html
[168]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_dirtyfb@fbc-dirtyfb-ioctl.html
* igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-dp-4:
- shard-dg2-set2: [SKIP][169] ([Intel XE#455] / [Intel XE#929]) -> [SKIP][170] ([Intel XE#1201] / [Intel XE#455] / [Intel XE#929])
[169]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-dp-4.html
[170]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-dp-4.html
* igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-6:
- shard-dg2-set2: [SKIP][171] -> [SKIP][172] ([Intel XE#1201]) +1 other test skip
[171]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-6.html
[172]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-6.html
* igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-6:
- shard-dg2-set2: [SKIP][173] ([i915#3804]) -> [SKIP][174] ([Intel XE#1201] / [i915#3804])
[173]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-6.html
[174]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-6.html
* igt@kms_feature_discovery@display-3x:
- shard-dg2-set2: [SKIP][175] ([Intel XE#1201] / [Intel XE#703]) -> [SKIP][176] ([Intel XE#703])
[175]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_feature_discovery@display-3x.html
[176]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_feature_discovery@display-3x.html
* igt@kms_feature_discovery@psr1:
- shard-dg2-set2: [SKIP][177] ([Intel XE#1135] / [Intel XE#1201]) -> [SKIP][178] ([Intel XE#1135])
[177]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_feature_discovery@psr1.html
[178]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_feature_discovery@psr1.html
* igt@kms_flip@flip-vs-suspend-interruptible@a-hdmi-a1:
- shard-adlp: [INCOMPLETE][179] ([Intel XE#1195]) -> [DMESG-WARN][180] ([Intel XE#1191] / [Intel XE#1214] / [Intel XE#1608]) +2 other tests dmesg-warn
[179]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@kms_flip@flip-vs-suspend-interruptible@a-hdmi-a1.html
[180]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-8/igt@kms_flip@flip-vs-suspend-interruptible@a-hdmi-a1.html
* igt@kms_flip@flip-vs-suspend@a-hdmi-a6:
- shard-dg2-set2: [DMESG-WARN][181] ([Intel XE#1162] / [Intel XE#1214]) -> [DMESG-WARN][182] ([Intel XE#1162]) +3 other tests dmesg-warn
[181]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_flip@flip-vs-suspend@a-hdmi-a6.html
[182]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_flip@flip-vs-suspend@a-hdmi-a6.html
* igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling:
- shard-dg2-set2: [SKIP][183] ([Intel XE#1201] / [Intel XE#455]) -> [SKIP][184] ([Intel XE#455]) +4 other tests skip
[183]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling.html
[184]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling.html
* igt@kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-fullscreen:
- shard-dg2-set2: [SKIP][185] ([Intel XE#651]) -> [SKIP][186] ([Intel XE#1201] / [Intel XE#651]) +14 other tests skip
[185]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-fullscreen.html
[186]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-fullscreen.html
* igt@kms_frontbuffer_tracking@fbcdrrs-1p-rte:
- shard-dg2-set2: [SKIP][187] ([Intel XE#1201] / [Intel XE#651]) -> [SKIP][188] ([Intel XE#651]) +14 other tests skip
[187]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_frontbuffer_tracking@fbcdrrs-1p-rte.html
[188]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_frontbuffer_tracking@fbcdrrs-1p-rte.html
* igt@kms_frontbuffer_tracking@fbcdrrs-tiling-y:
- shard-dg2-set2: [SKIP][189] ([Intel XE#658]) -> [SKIP][190] ([Intel XE#1201] / [Intel XE#658])
[189]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_frontbuffer_tracking@fbcdrrs-tiling-y.html
[190]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_frontbuffer_tracking@fbcdrrs-tiling-y.html
* igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt:
- shard-dg2-set2: [SKIP][191] ([Intel XE#653]) -> [SKIP][192] ([Intel XE#1201] / [Intel XE#653]) +15 other tests skip
[191]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt.html
[192]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt.html
* igt@kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-plflip-blt:
- shard-dg2-set2: [SKIP][193] ([Intel XE#1201] / [Intel XE#653]) -> [SKIP][194] ([Intel XE#653]) +13 other tests skip
[193]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-plflip-blt.html
[194]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-plflip-blt.html
* igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
- shard-dg2-set2: [SKIP][195] ([Intel XE#1201] / [Intel XE#356]) -> [SKIP][196] ([Intel XE#356])
[195]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
[196]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
* igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats:
- shard-dg2-set2: [INCOMPLETE][197] ([Intel XE#1195] / [Intel XE#909]) -> [INCOMPLETE][198] ([Intel XE#909])
[197]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats.html
[198]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats.html
* igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-a-hdmi-a-6:
- shard-dg2-set2: [INCOMPLETE][199] ([Intel XE#1195] / [Intel XE#904] / [Intel XE#909]) -> [INCOMPLETE][200] ([Intel XE#904] / [Intel XE#909])
[199]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-a-hdmi-a-6.html
[200]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-a-hdmi-a-6.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling:
- shard-dg2-set2: [SKIP][201] ([Intel XE#305] / [Intel XE#455]) -> [SKIP][202] ([Intel XE#1201] / [Intel XE#305] / [Intel XE#455]) +1 other test skip
[201]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling.html
[202]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling@pipe-a-hdmi-a-6:
- shard-dg2-set2: [SKIP][203] ([Intel XE#305]) -> [SKIP][204] ([Intel XE#1201] / [Intel XE#305]) +2 other tests skip
[203]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling@pipe-a-hdmi-a-6.html
[204]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling@pipe-a-hdmi-a-6.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-b-hdmi-a-6:
- shard-dg2-set2: [SKIP][205] ([Intel XE#1201] / [Intel XE#305]) -> [SKIP][206] ([Intel XE#305]) +2 other tests skip
[205]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-b-hdmi-a-6.html
[206]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-b-hdmi-a-6.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-d-hdmi-a-6:
- shard-dg2-set2: [SKIP][207] ([Intel XE#1201] / [Intel XE#305] / [Intel XE#455]) -> [SKIP][208] ([Intel XE#305] / [Intel XE#455]) +1 other test skip
[207]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-d-hdmi-a-6.html
[208]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-d-hdmi-a-6.html
* igt@kms_pm_dc@dc5-psr:
- shard-dg2-set2: [SKIP][209] ([Intel XE#1129]) -> [SKIP][210] ([Intel XE#1129] / [Intel XE#1201])
[209]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_pm_dc@dc5-psr.html
[210]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_pm_dc@dc5-psr.html
* igt@kms_pm_rpm@system-suspend-modeset:
- shard-dg2-set2: [DMESG-WARN][211] -> [DMESG-WARN][212] ([Intel XE#1214]) +1 other test dmesg-warn
[211]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_pm_rpm@system-suspend-modeset.html
[212]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@kms_pm_rpm@system-suspend-modeset.html
* igt@kms_psr2_su@page_flip-p010:
- shard-dg2-set2: [SKIP][213] ([Intel XE#1122] / [Intel XE#1201]) -> [SKIP][214] ([Intel XE#1122])
[213]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_psr2_su@page_flip-p010.html
[214]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_psr2_su@page_flip-p010.html
* igt@kms_psr@fbc-pr-no-drrs:
- shard-dg2-set2: [SKIP][215] ([Intel XE#1201] / [Intel XE#929]) -> [SKIP][216] ([Intel XE#929]) +7 other tests skip
[215]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_psr@fbc-pr-no-drrs.html
[216]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_psr@fbc-pr-no-drrs.html
* igt@kms_psr@fbc-psr2-sprite-plane-move:
- shard-dg2-set2: [SKIP][217] ([Intel XE#929]) -> [SKIP][218] ([Intel XE#1201] / [Intel XE#929]) +9 other tests skip
[217]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_psr@fbc-psr2-sprite-plane-move.html
[218]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_psr@fbc-psr2-sprite-plane-move.html
* igt@kms_rotation_crc@primary-yf-tiled-reflect-x-270:
- shard-dg2-set2: [SKIP][219] ([Intel XE#1201] / [Intel XE#327]) -> [SKIP][220] ([Intel XE#327])
[219]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-270.html
[220]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-270.html
* igt@kms_rotation_crc@sprite-rotation-90-pos-100-0:
- shard-dg2-set2: [SKIP][221] ([Intel XE#327]) -> [SKIP][222] ([Intel XE#1201] / [Intel XE#327])
[221]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.html
[222]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.html
* igt@kms_scaling_modes@scaling-mode-none:
- shard-dg2-set2: [SKIP][223] ([Intel XE#1201] / [Intel XE#455]) -> [INCOMPLETE][224] ([Intel XE#1195])
[223]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-434/igt@kms_scaling_modes@scaling-mode-none.html
[224]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-434/igt@kms_scaling_modes@scaling-mode-none.html
* igt@kms_vblank@ts-continuation-dpms-suspend:
- shard-adlp: [DMESG-WARN][225] ([Intel XE#1191] / [Intel XE#1214]) -> [DMESG-WARN][226] ([Intel XE#1191] / [Intel XE#1214] / [Intel XE#1608])
[225]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_vblank@ts-continuation-dpms-suspend.html
[226]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-6/igt@kms_vblank@ts-continuation-dpms-suspend.html
* igt@kms_vblank@ts-continuation-dpms-suspend@pipe-d-hdmi-a-1:
- shard-adlp: [DMESG-WARN][227] ([Intel XE#1191] / [Intel XE#1214]) -> [DMESG-WARN][228] ([Intel XE#1214] / [Intel XE#1608])
[227]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_vblank@ts-continuation-dpms-suspend@pipe-d-hdmi-a-1.html
[228]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-6/igt@kms_vblank@ts-continuation-dpms-suspend@pipe-d-hdmi-a-1.html
* igt@kms_vblank@ts-continuation-suspend:
- shard-adlp: [DMESG-WARN][229] ([Intel XE#1191] / [Intel XE#1214]) -> [INCOMPLETE][230] ([Intel XE#1034] / [Intel XE#1195] / [Intel XE#927])
[229]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_vblank@ts-continuation-suspend.html
[230]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-1/igt@kms_vblank@ts-continuation-suspend.html
* igt@kms_vblank@ts-continuation-suspend@pipe-a-hdmi-a-1:
- shard-adlp: [DMESG-WARN][231] ([Intel XE#1191] / [Intel XE#1214]) -> [INCOMPLETE][232] ([Intel XE#1034] / [Intel XE#1195])
[231]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@kms_vblank@ts-continuation-suspend@pipe-a-hdmi-a-1.html
[232]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-1/igt@kms_vblank@ts-continuation-suspend@pipe-a-hdmi-a-1.html
* igt@kms_writeback@writeback-fb-id:
- shard-dg2-set2: [SKIP][233] ([Intel XE#756]) -> [SKIP][234] ([Intel XE#1201] / [Intel XE#756])
[233]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@kms_writeback@writeback-fb-id.html
[234]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@kms_writeback@writeback-fb-id.html
* igt@sriov_basic@enable-vfs-bind-unbind-each:
- shard-dg2-set2: [SKIP][235] ([Intel XE#1091] / [Intel XE#1201]) -> [SKIP][236] ([Intel XE#1091])
[235]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@sriov_basic@enable-vfs-bind-unbind-each.html
[236]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@sriov_basic@enable-vfs-bind-unbind-each.html
* igt@xe_copy_basic@mem-copy-linear-0xfffe:
- shard-dg2-set2: [SKIP][237] ([Intel XE#1123]) -> [SKIP][238] ([Intel XE#1123] / [Intel XE#1201])
[237]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@xe_copy_basic@mem-copy-linear-0xfffe.html
[238]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@xe_copy_basic@mem-copy-linear-0xfffe.html
* igt@xe_evict@evict-beng-mixed-threads-large:
- shard-dg2-set2: [TIMEOUT][239] ([Intel XE#1473] / [Intel XE#392]) -> [ABORT][240] ([Intel XE#1205])
[239]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-436/igt@xe_evict@evict-beng-mixed-threads-large.html
[240]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-464/igt@xe_evict@evict-beng-mixed-threads-large.html
* igt@xe_exec_fault_mode@many-execqueues-bindexecqueue-userptr-invalidate-prefetch:
- shard-dg2-set2: [SKIP][241] ([Intel XE#1201] / [Intel XE#288]) -> [SKIP][242] ([Intel XE#288]) +9 other tests skip
[241]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_exec_fault_mode@many-execqueues-bindexecqueue-userptr-invalidate-prefetch.html
[242]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_exec_fault_mode@many-execqueues-bindexecqueue-userptr-invalidate-prefetch.html
* igt@xe_exec_fault_mode@many-userptr-rebind-prefetch:
- shard-dg2-set2: [SKIP][243] ([Intel XE#288]) -> [SKIP][244] ([Intel XE#1201] / [Intel XE#288]) +12 other tests skip
[243]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@xe_exec_fault_mode@many-userptr-rebind-prefetch.html
[244]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-436/igt@xe_exec_fault_mode@many-userptr-rebind-prefetch.html
* igt@xe_media_fill@media-fill:
- shard-dg2-set2: [SKIP][245] ([Intel XE#1201] / [Intel XE#560]) -> [SKIP][246] ([Intel XE#560])
[245]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_media_fill@media-fill.html
[246]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_media_fill@media-fill.html
* igt@xe_pat@pat-index-xe2:
- shard-dg2-set2: [SKIP][247] ([Intel XE#1201] / [Intel XE#977]) -> [SKIP][248] ([Intel XE#977])
[247]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_pat@pat-index-xe2.html
[248]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_pat@pat-index-xe2.html
* igt@xe_pm@s2idle-multiple-execs:
- shard-dg2-set2: [INCOMPLETE][249] ([Intel XE#1195] / [Intel XE#1358]) -> [INCOMPLETE][250] ([Intel XE#1358])
[249]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_pm@s2idle-multiple-execs.html
[250]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_pm@s2idle-multiple-execs.html
* igt@xe_pm@s2idle-vm-bind-prefetch:
- shard-adlp: [INCOMPLETE][251] ([Intel XE#1195] / [Intel XE#1694]) -> [DMESG-WARN][252] ([Intel XE#1214] / [Intel XE#1608])
[251]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-9/igt@xe_pm@s2idle-vm-bind-prefetch.html
[252]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-2/igt@xe_pm@s2idle-vm-bind-prefetch.html
* igt@xe_pm@s2idle-vm-bind-userptr:
- shard-adlp: [INCOMPLETE][253] ([Intel XE#1195]) -> [DMESG-WARN][254] ([Intel XE#1214] / [Intel XE#1608])
[253]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-1/igt@xe_pm@s2idle-vm-bind-userptr.html
[254]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-4/igt@xe_pm@s2idle-vm-bind-userptr.html
* igt@xe_pm@s3-vm-bind-userptr:
- shard-adlp: [DMESG-WARN][255] ([Intel XE#1214]) -> [INCOMPLETE][256] ([Intel XE#1195])
[255]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-adlp-4/igt@xe_pm@s3-vm-bind-userptr.html
[256]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-adlp-1/igt@xe_pm@s3-vm-bind-userptr.html
* igt@xe_pm@s4-d3cold-basic-exec:
- shard-dg2-set2: [SKIP][257] ([Intel XE#1201] / [Intel XE#366]) -> [SKIP][258] ([Intel XE#366])
[257]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_pm@s4-d3cold-basic-exec.html
[258]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_pm@s4-d3cold-basic-exec.html
* igt@xe_query@multigpu-query-config:
- shard-dg2-set2: [SKIP][259] ([Intel XE#944]) -> [SKIP][260] ([Intel XE#1201] / [Intel XE#944])
[259]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-432/igt@xe_query@multigpu-query-config.html
[260]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-435/igt@xe_query@multigpu-query-config.html
* igt@xe_query@multigpu-query-engines:
- shard-dg2-set2: [SKIP][261] ([Intel XE#1201] / [Intel XE#944]) -> [SKIP][262] ([Intel XE#944]) +1 other test skip
[261]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde/shard-dg2-464/igt@xe_query@multigpu-query-engines.html
[262]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/shard-dg2-432/igt@xe_query@multigpu-query-engines.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[Intel XE#1033]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1033
[Intel XE#1034]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1034
[Intel XE#1081]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1081
[Intel XE#1091]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1091
[Intel XE#1122]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1122
[Intel XE#1123]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1123
[Intel XE#1124]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1124
[Intel XE#1125]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1125
[Intel XE#1128]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1128
[Intel XE#1129]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1129
[Intel XE#1135]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1135
[Intel XE#1162]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1162
[Intel XE#1191]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1191
[Intel XE#1195]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1195
[Intel XE#1201]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1201
[Intel XE#1205]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1205
[Intel XE#1211]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1211
[Intel XE#1214]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1214
[Intel XE#1231]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1231
[Intel XE#1242]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1242
[Intel XE#1252]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1252
[Intel XE#1330]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1330
[Intel XE#1339]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1339
[Intel XE#1358]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1358
[Intel XE#1365]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1365
[Intel XE#1388]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1388
[Intel XE#1392]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1392
[Intel XE#1397]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1397
[Intel XE#1399]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1399
[Intel XE#1401]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1401
[Intel XE#1406]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1406
[Intel XE#1407]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1407
[Intel XE#1413]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1413
[Intel XE#1420]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1420
[Intel XE#1421]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1421
[Intel XE#1424]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1424
[Intel XE#1435]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1435
[Intel XE#1446]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1446
[Intel XE#1451]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1451
[Intel XE#1465]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1465
[Intel XE#1467]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1467
[Intel XE#1473]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1473
[Intel XE#1538]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1538
[Intel XE#1548]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1548
[Intel XE#1595]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1595
[Intel XE#1600]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1600
[Intel XE#1602]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1602
[Intel XE#1607]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1607
[Intel XE#1608]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1608
[Intel XE#1609]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1609
[Intel XE#1638]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1638
[Intel XE#1667]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1667
[Intel XE#1694]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1694
[Intel XE#1713]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1713
[Intel XE#1717]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1717
[Intel XE#1725]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1725
[Intel XE#1745]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1745
[Intel XE#1760]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1760
[Intel XE#1761]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1761
[Intel XE#1829]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1829
[Intel XE#1850]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1850
[Intel XE#1874]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1874
[Intel XE#261]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/261
[Intel XE#282]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/282
[Intel XE#288]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/288
[Intel XE#305]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/305
[Intel XE#306]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/306
[Intel XE#307]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/307
[Intel XE#308]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/308
[Intel XE#309]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/309
[Intel XE#310]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/310
[Intel XE#316]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/316
[Intel XE#323]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/323
[Intel XE#324]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/324
[Intel XE#327]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/327
[Intel XE#346]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/346
[Intel XE#352]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/352
[Intel XE#356]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/356
[Intel XE#358]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/358
[Intel XE#361]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/361
[Intel XE#366]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/366
[Intel XE#367]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/367
[Intel XE#373]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/373
[Intel XE#378]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/378
[Intel XE#392]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/392
[Intel XE#455]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/455
[Intel XE#488]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/488
[Intel XE#498]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/498
[Intel XE#560]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/560
[Intel XE#584]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/584
[Intel XE#599]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/599
[Intel XE#610]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/610
[Intel XE#623]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/623
[Intel XE#651]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/651
[Intel XE#653]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/653
[Intel XE#656]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/656
[Intel XE#658]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/658
[Intel XE#688]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/688
[Intel XE#703]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/703
[Intel XE#756]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/756
[Intel XE#787]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/787
[Intel XE#877]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/877
[Intel XE#904]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/904
[Intel XE#909]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/909
[Intel XE#910]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/910
[Intel XE#927]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/927
[Intel XE#929]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/929
[Intel XE#944]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/944
[Intel XE#977]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/977
[i915#3804]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3804
Build changes
-------------
* Linux: xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde -> xe-pw-131815v3
IGT_7864: 8eff53c9664fa0abaa55b403c9f10f96260e44b7 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
xe-1311-3addfb8584a4fcbff8123461682e5bdfd8785bde: 3addfb8584a4fcbff8123461682e5bdfd8785bde
xe-pw-131815v3: 131815v3
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-131815v3/index.html
[-- Attachment #2: Type: text/html, Size: 96085 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
@ 2024-05-21 13:12 ` Matthew Brost
2024-05-28 9:16 ` Christian König
1 sibling, 0 replies; 50+ messages in thread
From: Matthew Brost @ 2024-05-21 13:12 UTC (permalink / raw)
To: Thomas Hellström
Cc: intel-xe, Christian König, Somalapuram Amaranath, dri-devel
On Tue, May 21, 2024 at 09:16:19AM +0200, Thomas Hellström wrote:
> To be able to handle list unlocking while traversing the LRU
> list, we want the iterators not only to point to the next
> position of the list traversal, but to insert themselves as
> list nodes at that point to work around the fact that the
> next node might otherwise disappear from the list while
> the iterator is pointing to it.
>
> These list nodes need to be easily distinguishable from other
> list nodes so that others traversing the list can skip
> over them.
>
> So declare a struct ttm_lru_item, with a struct list_head member
> and a type enum. This will slightly increase the size of a
> struct ttm_resource.
>
> Changes in previous series:
> - Update enum ttm_lru_item_type documentation.
> v3:
> - Introduce ttm_lru_first_res_or_null()
> (Christian König, Thomas Hellström)
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> drivers/gpu/drm/ttm/ttm_device.c | 4 +-
> drivers/gpu/drm/ttm/ttm_resource.c | 89 +++++++++++++++++++++++-------
> include/drm/ttm/ttm_resource.h | 54 +++++++++++++++++-
> 3 files changed, 125 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
> index 434cf0258000..09411978a13a 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -274,14 +274,14 @@ static void ttm_device_clear_lru_dma_mappings(struct ttm_device *bdev,
> struct ttm_resource *res;
>
> spin_lock(&bdev->lru_lock);
> - while ((res = list_first_entry_or_null(list, typeof(*res), lru))) {
> + while ((res = ttm_lru_first_res_or_null(list))) {
> struct ttm_buffer_object *bo = res->bo;
>
> /* Take ref against racing releases once lru_lock is unlocked */
> if (!ttm_bo_get_unless_zero(bo))
> continue;
>
> - list_del_init(&res->lru);
> + list_del_init(&bo->resource->lru.link);
> spin_unlock(&bdev->lru_lock);
>
> if (bo->ttm)
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index 4a66b851b67d..db9a7a3717c4 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -70,8 +70,8 @@ void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk)
> dma_resv_assert_held(pos->last->bo->base.resv);
>
> man = ttm_manager_type(pos->first->bo->bdev, i);
> - list_bulk_move_tail(&man->lru[j], &pos->first->lru,
> - &pos->last->lru);
> + list_bulk_move_tail(&man->lru[j], &pos->first->lru.link,
> + &pos->last->lru.link);
> }
> }
> }
> @@ -84,14 +84,38 @@ ttm_lru_bulk_move_pos(struct ttm_lru_bulk_move *bulk, struct ttm_resource *res)
> return &bulk->pos[res->mem_type][res->bo->priority];
> }
>
> +/* Return the previous resource on the list (skip over non-resource list items) */
> +static struct ttm_resource *ttm_lru_prev_res(struct ttm_resource *cur)
> +{
> + struct ttm_lru_item *lru = &cur->lru;
> +
> + do {
> + lru = list_prev_entry(lru, link);
> + } while (!ttm_lru_item_is_res(lru));
> +
> + return ttm_lru_item_to_res(lru);
> +}
> +
> +/* Return the next resource on the list (skip over non-resource list items) */
> +static struct ttm_resource *ttm_lru_next_res(struct ttm_resource *cur)
> +{
> + struct ttm_lru_item *lru = &cur->lru;
> +
> + do {
> + lru = list_next_entry(lru, link);
> + } while (!ttm_lru_item_is_res(lru));
> +
> + return ttm_lru_item_to_res(lru);
> +}
> +
> /* Move the resource to the tail of the bulk move range */
> static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
> struct ttm_resource *res)
> {
> if (pos->last != res) {
> if (pos->first == res)
> - pos->first = list_next_entry(res, lru);
> - list_move(&res->lru, &pos->last->lru);
> + pos->first = ttm_lru_next_res(res);
> + list_move(&res->lru.link, &pos->last->lru.link);
> pos->last = res;
> }
> }
> @@ -122,11 +146,11 @@ static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
> pos->first = NULL;
> pos->last = NULL;
> } else if (pos->first == res) {
> - pos->first = list_next_entry(res, lru);
> + pos->first = ttm_lru_next_res(res);
> } else if (pos->last == res) {
> - pos->last = list_prev_entry(res, lru);
> + pos->last = ttm_lru_prev_res(res);
> } else {
> - list_move(&res->lru, &pos->last->lru);
> + list_move(&res->lru.link, &pos->last->lru.link);
> }
> }
>
> @@ -155,7 +179,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
> lockdep_assert_held(&bo->bdev->lru_lock);
>
> if (bo->pin_count) {
> - list_move_tail(&res->lru, &bdev->pinned);
> + list_move_tail(&res->lru.link, &bdev->pinned);
>
> } else if (bo->bulk_move) {
> struct ttm_lru_bulk_move_pos *pos =
> @@ -166,7 +190,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
> struct ttm_resource_manager *man;
>
> man = ttm_manager_type(bdev, res->mem_type);
> - list_move_tail(&res->lru, &man->lru[bo->priority]);
> + list_move_tail(&res->lru.link, &man->lru[bo->priority]);
> }
> }
>
> @@ -197,9 +221,9 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
> man = ttm_manager_type(bo->bdev, place->mem_type);
> spin_lock(&bo->bdev->lru_lock);
> if (bo->pin_count)
> - list_add_tail(&res->lru, &bo->bdev->pinned);
> + list_add_tail(&res->lru.link, &bo->bdev->pinned);
> else
> - list_add_tail(&res->lru, &man->lru[bo->priority]);
> + list_add_tail(&res->lru.link, &man->lru[bo->priority]);
> man->usage += res->size;
> spin_unlock(&bo->bdev->lru_lock);
> }
> @@ -221,7 +245,7 @@ void ttm_resource_fini(struct ttm_resource_manager *man,
> struct ttm_device *bdev = man->bdev;
>
> spin_lock(&bdev->lru_lock);
> - list_del_init(&res->lru);
> + list_del_init(&res->lru.link);
> man->usage -= res->size;
> spin_unlock(&bdev->lru_lock);
> }
> @@ -472,14 +496,16 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor)
> {
> - struct ttm_resource *res;
> + struct ttm_lru_item *lru;
>
> lockdep_assert_held(&man->bdev->lru_lock);
>
> for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
> ++cursor->priority)
> - list_for_each_entry(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> return NULL;
> }
> @@ -498,15 +524,40 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor,
> struct ttm_resource *res)
> {
> + struct ttm_lru_item *lru = &res->lru;
> +
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - list_for_each_entry_continue(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
> ++cursor->priority)
> - list_for_each_entry(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + ttm_lru_item_to_res(lru);
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + * ttm_lru_first_res_or_null() - Return the first resource on an lru list
> + * @head: The list head of the lru list.
> + *
> + * Return: Pointer to the first resource on the lru list or NULL if
> + * there is none.
> + */
> +struct ttm_resource *ttm_lru_first_res_or_null(struct list_head *head)
> +{
> + struct ttm_lru_item *lru;
> +
> + list_for_each_entry(lru, head, link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> return NULL;
> }
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index 69769355139f..1511d91e290d 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -49,6 +49,43 @@ struct io_mapping;
> struct sg_table;
> struct scatterlist;
>
> +/**
> + * enum ttm_lru_item_type - enumerate ttm_lru_item subclasses
> + */
> +enum ttm_lru_item_type {
> + /** @TTM_LRU_RESOURCE: The resource subclass */
> + TTM_LRU_RESOURCE,
> + /** @TTM_LRU_HITCH: The iterator hitch subclass */
> + TTM_LRU_HITCH
> +};
> +
> +/**
> + * struct ttm_lru_item - The TTM lru list node base class
> + * @link: The list link
> + * @type: The subclass type
> + */
> +struct ttm_lru_item {
> + struct list_head link;
> + enum ttm_lru_item_type type;
> +};
> +
> +/**
> + * ttm_lru_item_init() - initialize a struct ttm_lru_item
> + * @item: The item to initialize
> + * @type: The subclass type
> + */
> +static inline void ttm_lru_item_init(struct ttm_lru_item *item,
> + enum ttm_lru_item_type type)
> +{
> + item->type = type;
> + INIT_LIST_HEAD(&item->link);
> +}
> +
> +static inline bool ttm_lru_item_is_res(const struct ttm_lru_item *item)
> +{
> + return item->type == TTM_LRU_RESOURCE;
> +}
> +
> struct ttm_resource_manager_func {
> /**
> * struct ttm_resource_manager_func member alloc
> @@ -217,9 +254,21 @@ struct ttm_resource {
> /**
> * @lru: Least recently used list, see &ttm_resource_manager.lru
> */
> - struct list_head lru;
> + struct ttm_lru_item lru;
> };
>
> +/**
> + * ttm_lru_item_to_res() - Downcast a struct ttm_lru_item to a struct ttm_resource
> + * @item: The struct ttm_lru_item to downcast
> + *
> + * Return: Pointer to the embedding struct ttm_resource
> + */
> +static inline struct ttm_resource *
> +ttm_lru_item_to_res(struct ttm_lru_item *item)
> +{
> + return container_of(item, struct ttm_resource, lru);
> +}
> +
> /**
> * struct ttm_resource_cursor
> *
> @@ -393,6 +442,9 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor,
> struct ttm_resource *res);
>
> +struct ttm_resource *
> +ttm_lru_first_res_or_null(struct list_head *head);
> +
> /**
> * ttm_resource_manager_for_each_res - iterate over all resources
> * @man: the resource manager
> --
> 2.44.0
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration
2024-05-21 7:16 ` [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration Thomas Hellström
@ 2024-05-21 15:39 ` Matthew Brost
2024-05-28 9:19 ` Christian König
1 sibling, 0 replies; 50+ messages in thread
From: Matthew Brost @ 2024-05-21 15:39 UTC (permalink / raw)
To: Thomas Hellström
Cc: intel-xe, Christian König, Somalapuram Amaranath, dri-devel
On Tue, May 21, 2024 at 09:16:20AM +0200, Thomas Hellström wrote:
> To make the transition to using lru hitches easier,
> simplify the ttm_resource_manager_next() interface to only take
> the cursor and reuse ttm_resource_manager_next() functionality
> from ttm_resource_manager_first().
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> drivers/gpu/drm/ttm/ttm_resource.c | 48 +++++++++++++-----------------
> include/drm/ttm/ttm_resource.h | 10 ++++---
> 2 files changed, 27 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index db9a7a3717c4..8bfbddddc0e8 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -496,50 +496,44 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor)
> {
> - struct ttm_lru_item *lru;
> -
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
> - ++cursor->priority)
> - list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - return ttm_lru_item_to_res(lru);
> - }
> -
> - return NULL;
> + cursor->priority = 0;
> + cursor->man = man;
> + cursor->cur = &man->lru[cursor->priority];
> + return ttm_resource_manager_next(cursor);
> }
>
> /**
> * ttm_resource_manager_next
> *
> - * @man: resource manager to iterate over
> * @cursor: cursor to record the position
> - * @res: the current resource pointer
> *
> - * Returns the next resource from the resource manager.
> + * Return: the next resource from the resource manager.
> */
> struct ttm_resource *
> -ttm_resource_manager_next(struct ttm_resource_manager *man,
> - struct ttm_resource_cursor *cursor,
> - struct ttm_resource *res)
> +ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
> {
> - struct ttm_lru_item *lru = &res->lru;
> + struct ttm_resource_manager *man = cursor->man;
> + struct ttm_lru_item *lru;
>
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - return ttm_lru_item_to_res(lru);
> - }
> -
> - for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
> - ++cursor->priority)
> - list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - ttm_lru_item_to_res(lru);
> + for (;;) {
> + lru = list_entry(cursor->cur, typeof(*lru), link);
> + list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru)) {
> + cursor->cur = &lru->link;
> + return ttm_lru_item_to_res(lru);
> + }
> }
>
> + if (++cursor->priority >= TTM_MAX_BO_PRIORITY)
> + break;
> +
> + cursor->cur = &man->lru[cursor->priority];
> + }
> +
> return NULL;
> }
>
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index 1511d91e290d..7d81fd5b5b83 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -272,11 +272,15 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
> /**
> * struct ttm_resource_cursor
> *
> + * @man: The resource manager currently being iterated over.
> + * @cur: The list head the cursor currently points to.
> * @priority: the current priority
> *
> * Cursor to iterate over the resources in a manager.
> */
> struct ttm_resource_cursor {
> + struct ttm_resource_manager *man;
> + struct list_head *cur;
> unsigned int priority;
> };
>
> @@ -438,9 +442,7 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor);
> struct ttm_resource *
> -ttm_resource_manager_next(struct ttm_resource_manager *man,
> - struct ttm_resource_cursor *cursor,
> - struct ttm_resource *res);
> +ttm_resource_manager_next(struct ttm_resource_cursor *cursor);
>
> struct ttm_resource *
> ttm_lru_first_res_or_null(struct list_head *head);
> @@ -455,7 +457,7 @@ ttm_lru_first_res_or_null(struct list_head *head);
> */
> #define ttm_resource_manager_for_each_res(man, cursor, res) \
> for (res = ttm_resource_manager_first(man, cursor); res; \
> - res = ttm_resource_manager_next(man, cursor, res))
> + res = ttm_resource_manager_next(cursor))
>
> struct ttm_kmap_iter *
> ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
> --
> 2.44.0
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3 03/21] drm/ttm: Use LRU hitches
2024-05-21 7:16 ` [PATCH v3 03/21] drm/ttm: Use LRU hitches Thomas Hellström
@ 2024-05-21 16:09 ` Matthew Brost
0 siblings, 0 replies; 50+ messages in thread
From: Matthew Brost @ 2024-05-21 16:09 UTC (permalink / raw)
To: Thomas Hellström
Cc: intel-xe, Christian König, Somalapuram Amaranath, dri-devel
On Tue, May 21, 2024 at 09:16:21AM +0200, Thomas Hellström wrote:
> Have iterators insert themselves into the list they are iterating
> over using hitch list nodes. Since only the iterator owner
> can remove these list nodes from the list, it's safe to unlock
> the list and when continuing, use them as a starting point. Due to
> the way LRU bumping works in TTM, newly added items will not be
> missed, and bumped items will be iterated over a second time before
> reaching the end of the list.
>
> The exception is list with bulk move sublists. When bumping a
> sublist, a hitch that is part of that sublist will also be moved
> and we might miss items if restarting from it. This will be
> addressed in a later patch.
>
> Changes in previous series:
> - Updated ttm_resource_cursor_fini() documentation.
> v2:
> - Don't reorder ttm_resource_manager_first() and _next().
> (Christian König).
> - Use list_add instead of list_move
> (Christian König)
> v3:
> - Split into two patches, one cleanup, one new functionality
> (Christian König)
> - use ttm_resource_cursor_fini_locked() instead of open-coding
> (Matthew Brost)
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> drivers/gpu/drm/ttm/ttm_bo.c | 1 +
> drivers/gpu/drm/ttm/ttm_device.c | 9 +++--
> drivers/gpu/drm/ttm/ttm_resource.c | 56 +++++++++++++++++++++++++-----
> include/drm/ttm/ttm_resource.h | 9 +++--
> 4 files changed, 62 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 6396dece0db1..43eda720657f 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -621,6 +621,7 @@ int ttm_mem_evict_first(struct ttm_device *bdev,
> if (locked)
> dma_resv_unlock(res->bo->base.resv);
> }
> + ttm_resource_cursor_fini_locked(&cursor);
>
> if (!bo) {
> if (busy_bo && !ttm_bo_get_unless_zero(busy_bo))
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
> index 09411978a13a..f9e9b1ec8c8a 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -170,12 +170,17 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
> num_pages = PFN_UP(bo->base.size);
> ret = ttm_bo_swapout(bo, ctx, gfp_flags);
> /* ttm_bo_swapout has dropped the lru_lock */
> - if (!ret)
> + if (!ret) {
> + ttm_resource_cursor_fini(&cursor);
> return num_pages;
> - if (ret != -EBUSY)
> + }
> + if (ret != -EBUSY) {
> + ttm_resource_cursor_fini(&cursor);
> return ret;
> + }
> }
> }
> + ttm_resource_cursor_fini_locked(&cursor);
> spin_unlock(&bdev->lru_lock);
> return 0;
> }
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index 8bfbddddc0e8..9c8b6499edfb 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -33,6 +33,37 @@
>
> #include <drm/drm_util.h>
>
> +/**
> + * ttm_resource_cursor_fini_locked() - Finalize the LRU list cursor usage
> + * @cursor: The struct ttm_resource_cursor to finalize.
> + *
> + * The function pulls the LRU list cursor off any lists it was previusly
> + * attached to. Needs to be called with the LRU lock held. The function
> + * can be called multiple times after eachother.
> + */
> +void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor)
> +{
> + lockdep_assert_held(&cursor->man->bdev->lru_lock);
> + list_del_init(&cursor->hitch.link);
> +}
> +
> +/**
> + * ttm_resource_cursor_fini() - Finalize the LRU list cursor usage
> + * @cursor: The struct ttm_resource_cursor to finalize.
> + *
> + * The function pulls the LRU list cursor off any lists it was previusly
> + * attached to. Needs to be called without the LRU list lock held. The
> + * function can be called multiple times after eachother.
> + */
> +void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor)
> +{
> + spinlock_t *lru_lock = &cursor->man->bdev->lru_lock;
> +
> + spin_lock(lru_lock);
> + ttm_resource_cursor_fini_locked(cursor);
> + spin_unlock(lru_lock);
> +}
> +
> /**
> * ttm_lru_bulk_move_init - initialize a bulk move structure
> * @bulk: the structure to init
> @@ -485,12 +516,15 @@ void ttm_resource_manager_debug(struct ttm_resource_manager *man,
> EXPORT_SYMBOL(ttm_resource_manager_debug);
>
> /**
> - * ttm_resource_manager_first
> - *
> + * ttm_resource_manager_first() - Start iterating over the resources
> + * of a resource manager
> * @man: resource manager to iterate over
> * @cursor: cursor to record the position
> *
> - * Returns the first resource from the resource manager.
> + * Initializes the cursor and starts iterating. When done iterating,
> + * the caller must explicitly call ttm_resource_cursor_fini().
> + *
> + * Return: The first resource from the resource manager.
> */
> struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> @@ -500,13 +534,15 @@ ttm_resource_manager_first(struct ttm_resource_manager *man,
>
> cursor->priority = 0;
> cursor->man = man;
> - cursor->cur = &man->lru[cursor->priority];
> + ttm_lru_item_init(&cursor->hitch, TTM_LRU_HITCH);
> + list_add(&cursor->hitch.link, &man->lru[cursor->priority]);
> +
> return ttm_resource_manager_next(cursor);
> }
>
> /**
> - * ttm_resource_manager_next
> - *
> + * ttm_resource_manager_next() - Continue iterating over the resource manager
> + * resources
> * @cursor: cursor to record the position
> *
> * Return: the next resource from the resource manager.
> @@ -520,10 +556,10 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
> lockdep_assert_held(&man->bdev->lru_lock);
>
> for (;;) {
> - lru = list_entry(cursor->cur, typeof(*lru), link);
> + lru = &cursor->hitch;
> list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> if (ttm_lru_item_is_res(lru)) {
> - cursor->cur = &lru->link;
> + list_move(&cursor->hitch.link, &lru->link);
> return ttm_lru_item_to_res(lru);
> }
> }
> @@ -531,9 +567,11 @@ ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
> if (++cursor->priority >= TTM_MAX_BO_PRIORITY)
> break;
>
> - cursor->cur = &man->lru[cursor->priority];
> + list_move(&cursor->hitch.link, &man->lru[cursor->priority]);
> }
>
> + ttm_resource_cursor_fini_locked(cursor);
> +
> return NULL;
> }
>
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index 7d81fd5b5b83..8fac781f641e 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -273,17 +273,22 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
> * struct ttm_resource_cursor
> *
> * @man: The resource manager currently being iterated over.
> - * @cur: The list head the cursor currently points to.
> + * @hitch: A hitch list node inserted before the next resource
> + * to iterate over.
> * @priority: the current priority
> *
> * Cursor to iterate over the resources in a manager.
> */
> struct ttm_resource_cursor {
> struct ttm_resource_manager *man;
> - struct list_head *cur;
> + struct ttm_lru_item hitch;
> unsigned int priority;
> };
>
> +void ttm_resource_cursor_fini_locked(struct ttm_resource_cursor *cursor);
> +
> +void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor);
> +
> /**
> * struct ttm_lru_bulk_move_pos
> *
> --
> 2.44.0
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-21 7:16 ` [RFC PATCH v3 13/21] drm/exec: Rework contended locking Thomas Hellström
@ 2024-05-22 5:52 ` Christian König
2024-05-22 14:32 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-22 5:52 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> If contention and backoff occurs during a drm_exec ww transaction,
> the contended lock is not locked again until the next orinary
> attempt to lock a dma_resv lock. However, with the introduction of
> drm_exec_trylock(), that doesn't work, since the locking of the
> contended lock needs to be a sleeping lock. Neither can we ignore
> locking the contended lock during a trylock since that would violate
> at least the ww_mutex annotations.
>
> So resolve this by actually locking the contended lock during
> drm_exec_retry_on_contention(). However, this introduces a new point
> of failure since locking the contended lock may return -EINTR.
>
> Hence drm_exec_retry_on_contention() must take an error parameter and
> also return a value indicating success.
After thinking more about that I have to pretty clearly NAK this.
It's an intentional design decision to guarantee that at the start of
the loop no object is locked.
This is because Sima and I wanted to integrate userptr handling into
drm_exec as well in the long term.
I think we should just document that drm_exec_trylock() can't be used to
lock the first BO in the loop and explicitly WARN if that's the case.
Regards,
Christian.
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++-----
> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
> drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
> drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
> drivers/gpu/drm/drm_exec.c | 35 ++++++++++++++-----
> drivers/gpu/drm/drm_gpuvm.c | 8 ++---
> drivers/gpu/drm/imagination/pvr_job.c | 2 +-
> drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
> drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
> drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
> drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
> drivers/gpu/drm/xe/xe_vm.c | 10 +++---
> include/drm/drm_exec.h | 23 +++++++++---
> 17 files changed, 92 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index e4d4e55c08ad..4a08a692aa1f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
> drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> drm_exec_until_all_locked(&ctx->exec) {
> ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> - drm_exec_retry_on_contention(&ctx->exec);
> + ret = drm_exec_retry_on_contention(&ctx->exec, ret);
> if (unlikely(ret))
> goto error;
>
> ret = drm_exec_prepare_obj(&ctx->exec, &bo->tbo.base, 1);
> - drm_exec_retry_on_contention(&ctx->exec);
> + ret = drm_exec_retry_on_contention(&ctx->exec, ret);
> if (unlikely(ret))
> goto error;
> }
> @@ -1199,14 +1199,14 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
>
> ret = amdgpu_vm_lock_pd(entry->bo_va->base.vm,
> &ctx->exec, 2);
> - drm_exec_retry_on_contention(&ctx->exec);
> + ret = drm_exec_retry_on_contention(&ctx->exec, ret);
> if (unlikely(ret))
> goto error;
> ++ctx->n_vms;
> }
>
> ret = drm_exec_prepare_obj(&ctx->exec, &bo->tbo.base, 1);
> - drm_exec_retry_on_contention(&ctx->exec);
> + ret = drm_exec_retry_on_contention(&ctx->exec, ret);
> if (unlikely(ret))
> goto error;
> }
> @@ -2619,7 +2619,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
> list_for_each_entry(peer_vm, &process_info->vm_list_head,
> vm_list_node) {
> ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (unlikely(ret))
> goto unreserve_out;
> }
> @@ -2631,7 +2631,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
>
> gobj = &mem->bo->tbo.base;
> ret = drm_exec_prepare_obj(&exec, gobj, 1);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (unlikely(ret))
> goto unreserve_out;
> }
> @@ -2875,7 +2875,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
> list_for_each_entry(peer_vm, &process_info->vm_list_head,
> vm_list_node) {
> ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (unlikely(ret)) {
> pr_err("Locking VM PD failed, ret: %d\n", ret);
> goto ttm_reserve_fail;
> @@ -2891,7 +2891,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
>
> gobj = &mem->bo->tbo.base;
> ret = drm_exec_prepare_obj(&exec, gobj, 1);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (unlikely(ret)) {
> pr_err("drm_exec_prepare_obj failed, ret: %d\n", ret);
> goto ttm_reserve_fail;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index ec888fc6ead8..299e46a6d934 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
>
> drm_exec_until_all_locked(&p->exec) {
> r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec, 1 + p->gang_size);
> - drm_exec_retry_on_contention(&p->exec);
> + r = drm_exec_retry_on_contention(&p->exec, r);
> if (unlikely(r))
> goto out_free_user_pages;
>
> @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
> /* One fence for TTM and one for each CS job */
> r = drm_exec_prepare_obj(&p->exec, &e->bo->tbo.base,
> 1 + p->gang_size);
> - drm_exec_retry_on_contention(&p->exec);
> + r = drm_exec_retry_on_contention(&p->exec, r);
> if (unlikely(r))
> goto out_free_user_pages;
>
> @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
> if (p->uf_bo) {
> r = drm_exec_prepare_obj(&p->exec, &p->uf_bo->tbo.base,
> 1 + p->gang_size);
> - drm_exec_retry_on_contention(&p->exec);
> + r = drm_exec_retry_on_contention(&p->exec, r);
> if (unlikely(r))
> goto out_free_user_pages;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> index cfdf558b48b6..8b2b86c7a6c5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> if (likely(!r))
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r)) {
> DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
> goto error;
> @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> if (likely(!r))
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r)) {
> DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
> goto error;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index 67c234bcf89f..17e16c971e21 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -239,12 +239,12 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> drm_exec_until_all_locked(&exec) {
> r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
>
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
> }
> @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
> drm_exec_until_all_locked(&exec) {
> if (gobj) {
> r = drm_exec_lock_obj(&exec, gobj);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error;
> }
>
> r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> index 5ca5c47ab54e..1b1a5147606e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> @@ -1221,12 +1221,12 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,
> drm_exec_until_all_locked(&exec) {
> r = drm_exec_lock_obj(&exec,
> &ctx_data->meta_data_obj->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error_fini_exec;
>
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error_fini_exec;
> }
> @@ -1292,12 +1292,12 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
> drm_exec_until_all_locked(&exec) {
> r = drm_exec_lock_obj(&exec,
> &ctx_data->meta_data_obj->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
>
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> index e22cb2b5cd92..72b8213e352c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> if (likely(!r))
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error;
> }
> @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> if (likely(!r))
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> index e01c1c8e64c4..63392ce43945 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> @@ -89,12 +89,12 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> drm_exec_init(&exec, 0, 0);
> drm_exec_until_all_locked(&exec) {
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error_fini_exec;
>
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto error_fini_exec;
> }
> @@ -152,12 +152,12 @@ static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> drm_exec_init(&exec, 0, 0);
> drm_exec_until_all_locked(&exec) {
> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
>
> r = amdgpu_vm_lock_pd(vm, &exec, 0);
> - drm_exec_retry_on_contention(&exec);
> + r = drm_exec_retry_on_contention(&exec, r);
> if (unlikely(r))
> goto out_unlock;
> }
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> index 386875e6eb96..a3aa7fd22f6a 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr)
> vm = drm_priv_to_vm(pdd->drm_priv);
>
> r = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> - drm_exec_retry_on_contention(&ctx->exec);
> + r = drm_exec_retry_on_contention(&ctx->exec, r);
> if (unlikely(r)) {
> pr_debug("failed %d to reserve bo\n", r);
> goto unreserve_out;
> diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
> index 2da094bdf8a4..3770a5d30213 100644
> --- a/drivers/gpu/drm/drm_exec.c
> +++ b/drivers/gpu/drm/drm_exec.c
> @@ -28,12 +28,12 @@
> * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
> * drm_exec_until_all_locked(&exec) {
> * ret = drm_exec_prepare_obj(&exec, boA, 1);
> - * drm_exec_retry_on_contention(&exec);
> + * ret = drm_exec_retry_on_contention(&exec, ret);
> * if (ret)
> * goto error;
> *
> * ret = drm_exec_prepare_obj(&exec, boB, 1);
> - * drm_exec_retry_on_contention(&exec);
> + * ret = drm_exec_retry_on_contention(&exec, ret);
> * if (ret)
> * goto error;
> * }
> @@ -48,7 +48,8 @@
> */
>
> /* Dummy value used to initially enter the retry loop */
> -#define DRM_EXEC_DUMMY ((void *)~0)
> +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
>
> /* Unlock all objects and drop references */
> static void drm_exec_unlock_all(struct drm_exec *exec)
> @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec *exec)
> return true;
> }
>
> - drm_exec_unlock_all(exec);
> - exec->num_objects = 0;
> + exec->contended = NULL;
> return true;
> }
> EXPORT_SYMBOL(drm_exec_cleanup);
> @@ -194,6 +194,27 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
> return ret;
> }
>
> +/**
> + * drm_exec_handle_contended() - Perform cleanup before a ww transaction restart
> + * @exec: Pointer to the drm_exec object.
> + *
> + * Unlocks all held resvs and re-locks the contended object.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int drm_exec_handle_contended(struct drm_exec *exec)
> +{
> + int ret;
> +
> + drm_exec_unlock_all(exec);
> + exec->num_objects = 0;
> + ret = drm_exec_lock_contended(exec);
> + exec->contended = DRM_EXEC_CONTENDED;
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(drm_exec_handle_contended);
> +
> /**
> * drm_exec_lock_obj - lock a GEM object for use
> * @exec: the drm_exec object with the state
> @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
> {
> int ret;
>
> - ret = drm_exec_lock_contended(exec);
> - if (unlikely(ret))
> - return ret;
> -
> if (exec->prelocked == obj) {
> drm_gem_object_put(exec->prelocked);
> exec->prelocked = NULL;
> diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
> index f9eb56f24bef..0923d6ae18e2 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
>
> drm_exec_until_all_locked(exec) {
> ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
> - drm_exec_retry_on_contention(exec);
> + ret = drm_exec_retry_on_contention(exec, ret);
> if (ret)
> goto err;
>
> ret = drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
> - drm_exec_retry_on_contention(exec);
> + ret = drm_exec_retry_on_contention(exec, ret);
> if (ret)
> goto err;
>
> if (vm_exec->extra.fn) {
> ret = vm_exec->extra.fn(vm_exec);
> - drm_exec_retry_on_contention(exec);
> + ret = drm_exec_retry_on_contention(exec, ret);
> if (ret)
> goto err;
> }
> @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
> drm_exec_until_all_locked(exec) {
> ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
> vm_exec->num_fences);
> - drm_exec_retry_on_contention(exec);
> + ret = drm_exec_retry_on_contention(exec, ret);
> if (ret)
> goto err;
> }
> diff --git a/drivers/gpu/drm/imagination/pvr_job.c b/drivers/gpu/drm/imagination/pvr_job.c
> index 78c2f3c6dce0..6e0ce6c4576c 100644
> --- a/drivers/gpu/drm/imagination/pvr_job.c
> +++ b/drivers/gpu/drm/imagination/pvr_job.c
> @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct drm_exec *exec, struct pvr_job_data *job_data,
> drm_exec_until_all_locked(exec) {
> int err = jobs_lock_all_objs(exec, job_data, job_count);
>
> - drm_exec_retry_on_contention(exec);
> + err = drm_exec_retry_on_contention(exec, err);
> if (err)
> return err;
> }
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
> index fba78193127d..01992b43ea4b 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -259,7 +259,7 @@ static int submit_lock_objects(struct msm_gem_submit *submit)
> for (unsigned i = 0; i < submit->nr_bos; i++) {
> struct drm_gem_object *obj = submit->bos[i].obj;
> ret = drm_exec_prepare_obj(&submit->exec, obj, 1);
> - drm_exec_retry_on_contention(&submit->exec);
> + ret = drm_exec_retry_on_contention(&submit->exec, ret);
> if (ret)
> goto error;
> }
> diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> index ee02cd833c5e..0c871634fdfb 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job,
> drm_exec_init(exec, vme->flags, 0);
> drm_exec_until_all_locked(exec) {
> ret = bind_lock_validate(job, exec, vme->num_fences);
> - drm_exec_retry_on_contention(exec);
> + ret = drm_exec_retry_on_contention(exec, ret);
> if (ret) {
> op = list_last_op(&bind_job->ops);
> goto unwind;
> diff --git a/drivers/gpu/drm/tests/drm_exec_test.c b/drivers/gpu/drm/tests/drm_exec_test.c
> index 81f928a429ba..28558fdb08df 100644
> --- a/drivers/gpu/drm/tests/drm_exec_test.c
> +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> drm_exec_until_all_locked(&exec) {
> ret = drm_exec_lock_obj(&exec, &gobj);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
> @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit *test)
> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> drm_exec_until_all_locked(&exec) {
> ret = drm_exec_lock_obj(&exec, &gobj);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
>
> drm_exec_unlock_obj(&exec, &gobj);
> ret = drm_exec_lock_obj(&exec, &gobj);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
> @@ -110,13 +110,13 @@ static void test_duplicates(struct kunit *test)
> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> drm_exec_until_all_locked(&exec) {
> ret = drm_exec_lock_obj(&exec, &gobj);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
>
> ret = drm_exec_lock_obj(&exec, &gobj);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
> @@ -137,7 +137,7 @@ static void test_prepare(struct kunit *test)
> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> drm_exec_until_all_locked(&exec) {
> ret = drm_exec_prepare_obj(&exec, &gobj, 1);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> KUNIT_EXPECT_EQ(test, ret, 0);
> if (ret)
> break;
> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> index 040dd142c49c..20ec1ab1b52d 100644
> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
> drm_exec_init(&exec, 0, 0);
> drm_exec_until_all_locked(&exec) {
> ret = xe_pf_begin(&exec, vma, atomic, tile->id);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (ret)
> goto unlock_dma_resv;
>
> @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc)
> drm_exec_init(&exec, 0, 0);
> drm_exec_until_all_locked(&exec) {
> ret = xe_pf_begin(&exec, vma, true, tile->id);
> - drm_exec_retry_on_contention(&exec);
> + ret = drm_exec_retry_on_contention(&exec, ret);
> if (ret)
> break;
> }
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index e2ec148c9c33..335524e803e7 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -501,7 +501,7 @@ static void preempt_rebind_work_func(struct work_struct *w)
> bool done = false;
>
> err = xe_preempt_work_begin(&exec, vm, &done);
> - drm_exec_retry_on_contention(&exec);
> + err = drm_exec_retry_on_contention(&exec, err);
> if (err || done) {
> drm_exec_fini(&exec);
> if (err && xe_vm_validate_should_retry(&exec, err, &end))
> @@ -1052,7 +1052,7 @@ static void xe_vma_destroy_unlocked(struct xe_vma *vma)
> drm_exec_init(&exec, 0, 0);
> drm_exec_until_all_locked(&exec) {
> err = xe_vm_lock_vma(&exec, vma);
> - drm_exec_retry_on_contention(&exec);
> + err = drm_exec_retry_on_contention(&exec, err);
> if (XE_WARN_ON(err))
> break;
> }
> @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
> err = 0;
> if (!bo->vm) {
> err = drm_exec_lock_obj(&exec, xe_vm_obj(vm));
> - drm_exec_retry_on_contention(&exec);
> + err = drm_exec_retry_on_contention(&exec, err);
> }
> if (!err) {
> err = drm_exec_lock_obj(&exec, &bo->ttm.base);
> - drm_exec_retry_on_contention(&exec);
> + err = drm_exec_retry_on_contention(&exec, err);
> }
> if (err) {
> drm_exec_fini(&exec);
> @@ -2884,7 +2884,7 @@ static int vm_bind_ioctl_ops_execute(struct xe_vm *vm,
> DRM_EXEC_IGNORE_DUPLICATES, 0);
> drm_exec_until_all_locked(&exec) {
> err = vm_bind_ioctl_ops_lock_and_prep(&exec, vm, vops);
> - drm_exec_retry_on_contention(&exec);
> + err = drm_exec_retry_on_contention(&exec, err);
> if (err)
> goto unlock;
>
> diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> index aa786b828a0a..fafb40d96e38 100644
> --- a/include/drm/drm_exec.h
> +++ b/include/drm/drm_exec.h
> @@ -51,6 +51,8 @@ struct drm_exec {
> struct drm_gem_object *prelocked;
> };
>
> +int drm_exec_handle_contended(struct drm_exec *exec);
> +
> /**
> * drm_exec_obj() - Return the object for a give drm_exec index
> * @exec: Pointer to the drm_exec context
> @@ -113,15 +115,26 @@ __PASTE(__drm_exec_, __LINE__): \
> /**
> * drm_exec_retry_on_contention - restart the loop to grap all locks
> * @exec: drm_exec object
> + * @_ret: The current error status
> *
> * Control flow helper to continue when a contention was detected and we need to
> * clean up and re-start the loop to prepare all GEM objects.
> + *
> + * Return: If no loop restart occurred: The error status.
> */
> -#define drm_exec_retry_on_contention(exec) \
> - do { \
> - if (unlikely(drm_exec_is_contended(exec))) \
> - goto *__drm_exec_retry_ptr; \
> - } while (0)
> +#define drm_exec_retry_on_contention(exec, _ret) \
> + ({ \
> + struct drm_exec *__exec = (exec); \
> + int __ret = (_ret); \
> + \
> + if (unlikely(drm_exec_is_contended(__exec))) { \
> + WARN_ON(__ret != -EDEADLK); \
> + __ret = drm_exec_handle_contended(__exec); \
> + if (!__ret) \
> + goto *__drm_exec_retry_ptr; \
> + } \
> + __ret; \
> + })
>
> /**
> * drm_exec_is_contended - check for contention
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability
2024-05-21 7:16 ` [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability Thomas Hellström
@ 2024-05-22 11:27 ` Christian König
2024-05-22 13:54 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-22 11:27 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel, Daniel Vetter
Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> When validating a buffer object for submission, we might need to lock
> a number of object for eviction to make room for the validation.
>
> This makes it pretty likely that validation will eventually succeed,
> since eventually the validating process will hold most dma_resv locks
> of the buffer objects residing in the memory type being validated for.
>
> However, once validation of a single object has succeeded it might not
> be beneficial to hold on to those locks anymore, and the validator
> would want to drop the locks of all objects taken during validation.
Exactly avoiding that was one of the goals of developing the drm_exec
object.
When objects are unlocked after evicting them it just gives concurrent
operations an opportunity to lock them and re-validate them into the
contended domain.
So why should that approach here be beneficial at all?
Regards,
Christian.
>
> Introduce a drm_exec snapshot functionality that can be used to
> record the locks held at a certain time, and a restore functionality
> that restores the drm_exec state to the snapshot by dropping all
> locks.
>
> Snapshots can be nested if needed.
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> drivers/gpu/drm/drm_exec.c | 55 +++++++++++++++++++++++++++++++++++++-
> include/drm/drm_exec.h | 23 +++++++++++++++-
> 2 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
> index 1383680ffa4a..9eea5d0d3a98 100644
> --- a/drivers/gpu/drm/drm_exec.c
> +++ b/drivers/gpu/drm/drm_exec.c
> @@ -57,6 +57,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
> struct drm_gem_object *obj;
> unsigned long index;
>
> + WARN_ON(exec->snap);
> drm_exec_for_each_locked_object_reverse(exec, index, obj) {
> dma_resv_unlock(obj->resv);
> drm_gem_object_put(obj);
> @@ -90,6 +91,7 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
> exec->num_objects = 0;
> exec->contended = DRM_EXEC_DUMMY;
> exec->prelocked = NULL;
> + exec->snap = NULL;
> }
> EXPORT_SYMBOL(drm_exec_init);
>
> @@ -301,7 +303,6 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
> goto error_unlock;
>
> return 0;
> -
> error_unlock:
> dma_resv_unlock(obj->resv);
> return ret;
> @@ -395,5 +396,57 @@ int drm_exec_prepare_array(struct drm_exec *exec,
> }
> EXPORT_SYMBOL(drm_exec_prepare_array);
>
> +/**
> + * drm_exec_restore() - Restore the drm_exec state to the point of a snapshot.
> + * @exec: The drm_exec object with the state.
> + * @snap: The snapshot state.
> + *
> + * Restores the drm_exec object by means of unlocking and dropping references
> + * to objects locked after the snapshot.
> + */
> +void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap)
> +{
> + struct drm_gem_object *obj;
> + unsigned int index;
> +
> + exec->snap = snap->saved_snap;
> +
> + drm_exec_for_each_locked_object_reverse(exec, index, obj) {
> + if (index + 1 == snap->num_locked)
> + break;
> +
> + dma_resv_unlock(obj->resv);
> + drm_gem_object_put(obj);
> + exec->objects[index] = NULL;
> + }
> +
> + exec->num_objects = snap->num_locked;
> +
> + if (!exec->prelocked)
> + exec->prelocked = snap->prelocked;
> + else
> + drm_gem_object_put(snap->prelocked);
> +}
> +EXPORT_SYMBOL(drm_exec_restore);
> +
> +/**
> + * drm_exec_snapshot() - Take a snapshot of the drm_exec state
> + * @exec: The drm_exec object with the state.
> + * @snap: The snapshot state.
> + *
> + * Records the @exec state in @snap. The @snap object is typically allocated
> + * in the stack of the caller.
> + */
> +void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap)
> +{
> + snap->num_locked = exec->num_objects;
> + snap->prelocked = exec->prelocked;
> + if (snap->prelocked)
> + drm_gem_object_get(snap->prelocked);
> + snap->saved_snap = exec->snap;
> + exec->snap = snap;
> +}
> +EXPORT_SYMBOL(drm_exec_snapshot);
> +
> MODULE_DESCRIPTION("DRM execution context");
> MODULE_LICENSE("Dual MIT/GPL");
> diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> index ea0f2117ee0c..0ce4d749511b 100644
> --- a/include/drm/drm_exec.h
> +++ b/include/drm/drm_exec.h
> @@ -19,7 +19,6 @@ struct drm_exec {
> * @flags: Flags to control locking behavior
> */
> u32 flags;
> -
> /**
> * @ticket: WW ticket used for acquiring locks
> */
> @@ -49,6 +48,25 @@ struct drm_exec {
> * @prelocked: already locked GEM object due to contention
> */
> struct drm_gem_object *prelocked;
> +
> + /**
> + * @snap: Pointer to the last snapshot taken or NULL if none.
> + */
> + struct drm_exec_snapshot *snap;
> +};
> +
> +/**
> + * struct drm_exec_snapshot - drm_exec snapshot information
> + */
> +struct drm_exec_snapshot {
> + /** @saved_snap: Pointer to the previous snapshot or NULL. */
> + struct drm_exec_snapshot *saved_snap;
> +
> + /** @prelocked: Refcounted pointer to the prelocked object at snapshot time. */
> + struct drm_gem_object *prelocked;
> +
> + /** @num_locked: Number of locked objects at snapshot time. */
> + unsigned long num_locked;
> };
>
> int drm_exec_handle_contended(struct drm_exec *exec);
> @@ -160,5 +178,8 @@ int drm_exec_prepare_array(struct drm_exec *exec,
> struct drm_gem_object **objects,
> unsigned int num_objects,
> unsigned int num_fences);
> +void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap);
> +void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap);
> +
>
> #endif
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode
2024-05-21 7:16 ` [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode Thomas Hellström
@ 2024-05-22 13:28 ` Christian König
2024-05-22 13:44 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-22 13:28 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> Locking for eviction is in some way different from locking for
> submission:
>
> 1) We can't lock objects that are already locked for submission,
> hence DRM_EXEC_IGNORE_DUPLICATES must be unset.
> 2) We must be able to re-lock objects locked for eviction,
> either for submission or for yet another eviction, in
> particular objects sharing a single resv must be considered.
Yeah, I was already thinking about that as well.
My idea so far was to have a separate function for locking eviction BOs.
This function would then use trylock or blocking depending on some setting.
> 3) There is no point to keep a contending object after the
> transaction restart. We don't know whether we actually want to use
> it again.
Well that isn't true as far as I know.
If we don't use trylock we still need to lock the object after rollback
to make sure that we waited for it to become available.
Regards,
Christian.
> So introduce a drm_exec evict mode, and for now instead of
> explicitly setting it using a function call or implement separate
> locking functions that use evict mode, assume evict mode if
> there is a snapshot registered. This can easily be changed later.
>
> To keep track of resvs locked for eviction, use a pointer set
> implemented by an xarray. This is probably not the most efficient
> data structure but used as an easy-to-implement first approach.
> If the set is empty (evict mode never used), the performance-
> and memory usage impact will be very small.
>
> TODO: Probably want to implement the set using an open addressing
> hash table.
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
> drivers/gpu/drm/drm_exec.c | 77 ++++++++++++++++++++++++++++++++++----
> include/drm/drm_exec.h | 15 ++++++++
> 2 files changed, 85 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
> index 9eea5d0d3a98..ea79d96f5439 100644
> --- a/drivers/gpu/drm/drm_exec.c
> +++ b/drivers/gpu/drm/drm_exec.c
> @@ -65,6 +65,10 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
>
> drm_gem_object_put(exec->prelocked);
> exec->prelocked = NULL;
> +
> + /* garbage collect */
> + xa_destroy(&exec->resv_set);
> + xa_init(&exec->resv_set);
> }
>
> /**
> @@ -92,6 +96,8 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
> exec->contended = DRM_EXEC_DUMMY;
> exec->prelocked = NULL;
> exec->snap = NULL;
> + exec->drop_contended = false;
> + xa_init(&exec->resv_set);
> }
> EXPORT_SYMBOL(drm_exec_init);
>
> @@ -110,6 +116,7 @@ void drm_exec_fini(struct drm_exec *exec)
> drm_gem_object_put(exec->contended);
> ww_acquire_fini(&exec->ticket);
> }
> + xa_destroy(&exec->resv_set);
> }
> EXPORT_SYMBOL(drm_exec_fini);
>
> @@ -139,6 +146,30 @@ bool drm_exec_cleanup(struct drm_exec *exec)
> }
> EXPORT_SYMBOL(drm_exec_cleanup);
>
> +static unsigned long drm_exec_resv_to_key(const struct dma_resv *resv)
> +{
> + return (unsigned long)resv / __alignof__(typeof(*resv));
> +}
> +
> +static void
> +drm_exec_resv_set_erase(struct drm_exec *exec, unsigned long key)
> +{
> + if (xa_load(&exec->resv_set, key))
> + xa_erase(&exec->resv_set, key);
> +}
> +
> +static bool drm_exec_in_evict_mode(struct drm_exec *exec)
> +{
> + return !!exec->snap;
> +}
> +
> +static void drm_exec_set_evict_mode(struct drm_exec *exec,
> + struct drm_exec_snapshot *snap)
> +{
> + exec->snap = snap;
> + exec->flags &= ~DRM_EXEC_IGNORE_DUPLICATES;
> +}
> +
> /* Track the locked object in the array */
> static int drm_exec_obj_locked(struct drm_exec *exec,
> struct drm_gem_object *obj,
> @@ -161,6 +192,14 @@ static int drm_exec_obj_locked(struct drm_exec *exec,
> drm_gem_object_get(obj);
> exec->objects[exec->num_objects++] = obj;
>
> + /*
> + * Errors here are not fatal, It means the object we locked
> + * for eviction can't be locked again. If that is problematic
> + * we may need to reconsider this.
> + */
> + if (drm_exec_in_evict_mode(exec))
> + (void)xa_store(&exec->resv_set, drm_exec_resv_to_key(obj->resv),
> + obj->resv, gfp | __GFP_NOWARN);
> return 0;
> }
>
> @@ -184,6 +223,9 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
> dma_resv_lock_slow(obj->resv, &exec->ticket);
> }
>
> + if (exec->drop_contended)
> + goto error_unlock;
> +
> ret = drm_exec_obj_locked(exec, obj, GFP_KERNEL);
> if (unlikely(ret))
> goto error_unlock;
> @@ -245,10 +287,19 @@ int drm_exec_trylock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
> }
>
> if (!dma_resv_trylock_ctx(obj->resv, &exec->ticket)) {
> - if (dma_resv_locking_ctx(obj->resv) == &exec->ticket)
> - return (exec->flags & DRM_EXEC_IGNORE_DUPLICATES) ? 0 : -EALREADY;
> - else
> + if (dma_resv_locking_ctx(obj->resv) == &exec->ticket) {
> + unsigned long key = drm_exec_resv_to_key(obj->resv);
> +
> + if (exec->flags & DRM_EXEC_IGNORE_DUPLICATES ||
> + xa_load(&exec->resv_set, key)) {
> + if (!drm_exec_in_evict_mode(exec))
> + drm_exec_resv_set_erase(exec, key);
> + return 0;
> + }
> + return -EALREADY;
> + } else {
> return -EBUSY;
> + }
> }
>
> ret = drm_exec_obj_locked(exec, obj, GFP_ATOMIC | __GFP_NOWARN);
> @@ -288,12 +339,20 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
> if (unlikely(ret == -EDEADLK)) {
> drm_gem_object_get(obj);
> exec->contended = obj;
> + exec->drop_contended = drm_exec_in_evict_mode(exec);
> return -EDEADLK;
> }
>
> - if (unlikely(ret == -EALREADY) &&
> - exec->flags & DRM_EXEC_IGNORE_DUPLICATES)
> - return 0;
> + if (unlikely(ret == -EALREADY)) {
> + unsigned long key = drm_exec_resv_to_key(obj->resv);
> +
> + if (exec->flags & DRM_EXEC_IGNORE_DUPLICATES ||
> + xa_load(&exec->resv_set, key)) {
> + if (!drm_exec_in_evict_mode(exec))
> + drm_exec_resv_set_erase(exec, key);
> + return 0;
> + }
> + }
>
> if (unlikely(ret))
> return ret;
> @@ -324,6 +383,7 @@ void drm_exec_unlock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
>
> for (i = exec->num_objects; i--;) {
> if (exec->objects[i] == obj) {
> + drm_exec_resv_set_erase(exec, drm_exec_resv_to_key(obj->resv));
> dma_resv_unlock(obj->resv);
> for (++i; i < exec->num_objects; ++i)
> exec->objects[i - 1] = exec->objects[i];
> @@ -415,12 +475,14 @@ void drm_exec_restore(struct drm_exec *exec, struct drm_exec_snapshot *snap)
> if (index + 1 == snap->num_locked)
> break;
>
> + xa_erase(&exec->resv_set, drm_exec_resv_to_key(obj->resv));
> dma_resv_unlock(obj->resv);
> drm_gem_object_put(obj);
> exec->objects[index] = NULL;
> }
>
> exec->num_objects = snap->num_locked;
> + exec->flags = snap->flags;
>
> if (!exec->prelocked)
> exec->prelocked = snap->prelocked;
> @@ -443,8 +505,9 @@ void drm_exec_snapshot(struct drm_exec *exec, struct drm_exec_snapshot *snap)
> snap->prelocked = exec->prelocked;
> if (snap->prelocked)
> drm_gem_object_get(snap->prelocked);
> + snap->flags = exec->flags;
> snap->saved_snap = exec->snap;
> - exec->snap = snap;
> + drm_exec_set_evict_mode(exec, snap);
> }
> EXPORT_SYMBOL(drm_exec_snapshot);
>
> diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> index 0ce4d749511b..0b6d5ac0c092 100644
> --- a/include/drm/drm_exec.h
> +++ b/include/drm/drm_exec.h
> @@ -5,6 +5,7 @@
>
> #include <linux/compiler.h>
> #include <linux/ww_mutex.h>
> +#include <linux/xarray.h>
>
> #define DRM_EXEC_INTERRUPTIBLE_WAIT BIT(0)
> #define DRM_EXEC_IGNORE_DUPLICATES BIT(1)
> @@ -53,6 +54,17 @@ struct drm_exec {
> * @snap: Pointer to the last snapshot taken or NULL if none.
> */
> struct drm_exec_snapshot *snap;
> +
> + /**
> + * @resv_set: Set of pointers to locked objects in evict mode.
> + */
> + struct xarray resv_set;
> +
> + /**
> + * @drop_contended: Drop the contended object after WW transaction
> + * relaxation.
> + */
> + bool drop_contended;
> };
>
> /**
> @@ -67,6 +79,9 @@ struct drm_exec_snapshot {
>
> /** @num_locked: Number of locked objects at snapshot time. */
> unsigned long num_locked;
> +
> + /** @flags: The drm_exec flags at snapshot time. */
> + u32 flags;
> };
>
> int drm_exec_handle_contended(struct drm_exec *exec);
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode
2024-05-22 13:28 ` Christian König
@ 2024-05-22 13:44 ` Thomas Hellström
0 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-22 13:44 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
On Wed, 2024-05-22 at 15:28 +0200, Christian König wrote:
> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > Locking for eviction is in some way different from locking for
> > submission:
> >
> > 1) We can't lock objects that are already locked for submission,
> > hence DRM_EXEC_IGNORE_DUPLICATES must be unset.
> > 2) We must be able to re-lock objects locked for eviction,
> > either for submission or for yet another eviction, in
> > particular objects sharing a single resv must be considered.
>
> Yeah, I was already thinking about that as well.
>
> My idea so far was to have a separate function for locking eviction
> BOs.
> This function would then use trylock or blocking depending on some
> setting.
Downstream i915 also has a separate locking function for this. I'm fine
with that as well. Probably the most sane choice.
>
> > 3) There is no point to keep a contending object after the
> > transaction restart. We don't know whether we actually want to use
> > it again.
>
> Well that isn't true as far as I know.
>
> If we don't use trylock we still need to lock the object after
> rollback
> to make sure that we waited for it to become available.
Yes, the transaction restart mentioned above is *after* the relaxation,
so the rollback becomes:
unlock_all
lock_contending_lock.
unlock_contending_lock.
drop_contending lock.
/Thomas
>
> Regards,
> Christian.
>
> > So introduce a drm_exec evict mode, and for now instead of
> > explicitly setting it using a function call or implement separate
> > locking functions that use evict mode, assume evict mode if
> > there is a snapshot registered. This can easily be changed later.
> >
> > To keep track of resvs locked for eviction, use a pointer set
> > implemented by an xarray. This is probably not the most efficient
> > data structure but used as an easy-to-implement first approach.
> > If the set is empty (evict mode never used), the performance-
> > and memory usage impact will be very small.
> >
> > TODO: Probably want to implement the set using an open addressing
> > hash table.
> >
> > Cc: Christian König <christian.koenig@amd.com>
> > Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > Cc: <dri-devel@lists.freedesktop.org>
> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> > ---
> > drivers/gpu/drm/drm_exec.c | 77
> > ++++++++++++++++++++++++++++++++++----
> > include/drm/drm_exec.h | 15 ++++++++
> > 2 files changed, 85 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_exec.c
> > b/drivers/gpu/drm/drm_exec.c
> > index 9eea5d0d3a98..ea79d96f5439 100644
> > --- a/drivers/gpu/drm/drm_exec.c
> > +++ b/drivers/gpu/drm/drm_exec.c
> > @@ -65,6 +65,10 @@ static void drm_exec_unlock_all(struct drm_exec
> > *exec)
> >
> > drm_gem_object_put(exec->prelocked);
> > exec->prelocked = NULL;
> > +
> > + /* garbage collect */
> > + xa_destroy(&exec->resv_set);
> > + xa_init(&exec->resv_set);
> > }
> >
> > /**
> > @@ -92,6 +96,8 @@ void drm_exec_init(struct drm_exec *exec, u32
> > flags, unsigned nr)
> > exec->contended = DRM_EXEC_DUMMY;
> > exec->prelocked = NULL;
> > exec->snap = NULL;
> > + exec->drop_contended = false;
> > + xa_init(&exec->resv_set);
> > }
> > EXPORT_SYMBOL(drm_exec_init);
> >
> > @@ -110,6 +116,7 @@ void drm_exec_fini(struct drm_exec *exec)
> > drm_gem_object_put(exec->contended);
> > ww_acquire_fini(&exec->ticket);
> > }
> > + xa_destroy(&exec->resv_set);
> > }
> > EXPORT_SYMBOL(drm_exec_fini);
> >
> > @@ -139,6 +146,30 @@ bool drm_exec_cleanup(struct drm_exec *exec)
> > }
> > EXPORT_SYMBOL(drm_exec_cleanup);
> >
> > +static unsigned long drm_exec_resv_to_key(const struct dma_resv
> > *resv)
> > +{
> > + return (unsigned long)resv / __alignof__(typeof(*resv));
> > +}
> > +
> > +static void
> > +drm_exec_resv_set_erase(struct drm_exec *exec, unsigned long key)
> > +{
> > + if (xa_load(&exec->resv_set, key))
> > + xa_erase(&exec->resv_set, key);
> > +}
> > +
> > +static bool drm_exec_in_evict_mode(struct drm_exec *exec)
> > +{
> > + return !!exec->snap;
> > +}
> > +
> > +static void drm_exec_set_evict_mode(struct drm_exec *exec,
> > + struct drm_exec_snapshot
> > *snap)
> > +{
> > + exec->snap = snap;
> > + exec->flags &= ~DRM_EXEC_IGNORE_DUPLICATES;
> > +}
> > +
> > /* Track the locked object in the array */
> > static int drm_exec_obj_locked(struct drm_exec *exec,
> > struct drm_gem_object *obj,
> > @@ -161,6 +192,14 @@ static int drm_exec_obj_locked(struct drm_exec
> > *exec,
> > drm_gem_object_get(obj);
> > exec->objects[exec->num_objects++] = obj;
> >
> > + /*
> > + * Errors here are not fatal, It means the object we
> > locked
> > + * for eviction can't be locked again. If that is
> > problematic
> > + * we may need to reconsider this.
> > + */
> > + if (drm_exec_in_evict_mode(exec))
> > + (void)xa_store(&exec->resv_set,
> > drm_exec_resv_to_key(obj->resv),
> > + obj->resv, gfp | __GFP_NOWARN);
> > return 0;
> > }
> >
> > @@ -184,6 +223,9 @@ static int drm_exec_lock_contended(struct
> > drm_exec *exec)
> > dma_resv_lock_slow(obj->resv, &exec->ticket);
> > }
> >
> > + if (exec->drop_contended)
> > + goto error_unlock;
> > +
> > ret = drm_exec_obj_locked(exec, obj, GFP_KERNEL);
> > if (unlikely(ret))
> > goto error_unlock;
> > @@ -245,10 +287,19 @@ int drm_exec_trylock_obj(struct drm_exec
> > *exec, struct drm_gem_object *obj)
> > }
> >
> > if (!dma_resv_trylock_ctx(obj->resv, &exec->ticket)) {
> > - if (dma_resv_locking_ctx(obj->resv) == &exec-
> > >ticket)
> > - return (exec->flags &
> > DRM_EXEC_IGNORE_DUPLICATES) ? 0 : -EALREADY;
> > - else
> > + if (dma_resv_locking_ctx(obj->resv) == &exec-
> > >ticket) {
> > + unsigned long key =
> > drm_exec_resv_to_key(obj->resv);
> > +
> > + if (exec->flags &
> > DRM_EXEC_IGNORE_DUPLICATES ||
> > + xa_load(&exec->resv_set, key)) {
> > + if (!drm_exec_in_evict_mode(exec))
> > + drm_exec_resv_set_erase(ex
> > ec, key);
> > + return 0;
> > + }
> > + return -EALREADY;
> > + } else {
> > return -EBUSY;
> > + }
> > }
> >
> > ret = drm_exec_obj_locked(exec, obj, GFP_ATOMIC |
> > __GFP_NOWARN);
> > @@ -288,12 +339,20 @@ int drm_exec_lock_obj(struct drm_exec *exec,
> > struct drm_gem_object *obj)
> > if (unlikely(ret == -EDEADLK)) {
> > drm_gem_object_get(obj);
> > exec->contended = obj;
> > + exec->drop_contended =
> > drm_exec_in_evict_mode(exec);
> > return -EDEADLK;
> > }
> >
> > - if (unlikely(ret == -EALREADY) &&
> > - exec->flags & DRM_EXEC_IGNORE_DUPLICATES)
> > - return 0;
> > + if (unlikely(ret == -EALREADY)) {
> > + unsigned long key = drm_exec_resv_to_key(obj-
> > >resv);
> > +
> > + if (exec->flags & DRM_EXEC_IGNORE_DUPLICATES ||
> > + xa_load(&exec->resv_set, key)) {
> > + if (!drm_exec_in_evict_mode(exec))
> > + drm_exec_resv_set_erase(exec,
> > key);
> > + return 0;
> > + }
> > + }
> >
> > if (unlikely(ret))
> > return ret;
> > @@ -324,6 +383,7 @@ void drm_exec_unlock_obj(struct drm_exec *exec,
> > struct drm_gem_object *obj)
> >
> > for (i = exec->num_objects; i--;) {
> > if (exec->objects[i] == obj) {
> > + drm_exec_resv_set_erase(exec,
> > drm_exec_resv_to_key(obj->resv));
> > dma_resv_unlock(obj->resv);
> > for (++i; i < exec->num_objects; ++i)
> > exec->objects[i - 1] = exec-
> > >objects[i];
> > @@ -415,12 +475,14 @@ void drm_exec_restore(struct drm_exec *exec,
> > struct drm_exec_snapshot *snap)
> > if (index + 1 == snap->num_locked)
> > break;
> >
> > + xa_erase(&exec->resv_set,
> > drm_exec_resv_to_key(obj->resv));
> > dma_resv_unlock(obj->resv);
> > drm_gem_object_put(obj);
> > exec->objects[index] = NULL;
> > }
> >
> > exec->num_objects = snap->num_locked;
> > + exec->flags = snap->flags;
> >
> > if (!exec->prelocked)
> > exec->prelocked = snap->prelocked;
> > @@ -443,8 +505,9 @@ void drm_exec_snapshot(struct drm_exec *exec,
> > struct drm_exec_snapshot *snap)
> > snap->prelocked = exec->prelocked;
> > if (snap->prelocked)
> > drm_gem_object_get(snap->prelocked);
> > + snap->flags = exec->flags;
> > snap->saved_snap = exec->snap;
> > - exec->snap = snap;
> > + drm_exec_set_evict_mode(exec, snap);
> > }
> > EXPORT_SYMBOL(drm_exec_snapshot);
> >
> > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > index 0ce4d749511b..0b6d5ac0c092 100644
> > --- a/include/drm/drm_exec.h
> > +++ b/include/drm/drm_exec.h
> > @@ -5,6 +5,7 @@
> >
> > #include <linux/compiler.h>
> > #include <linux/ww_mutex.h>
> > +#include <linux/xarray.h>
> >
> > #define DRM_EXEC_INTERRUPTIBLE_WAIT BIT(0)
> > #define DRM_EXEC_IGNORE_DUPLICATES BIT(1)
> > @@ -53,6 +54,17 @@ struct drm_exec {
> > * @snap: Pointer to the last snapshot taken or NULL if
> > none.
> > */
> > struct drm_exec_snapshot *snap;
> > +
> > + /**
> > + * @resv_set: Set of pointers to locked objects in evict
> > mode.
> > + */
> > + struct xarray resv_set;
> > +
> > + /**
> > + * @drop_contended: Drop the contended object after WW
> > transaction
> > + * relaxation.
> > + */
> > + bool drop_contended;
> > };
> >
> > /**
> > @@ -67,6 +79,9 @@ struct drm_exec_snapshot {
> >
> > /** @num_locked: Number of locked objects at snapshot
> > time. */
> > unsigned long num_locked;
> > +
> > + /** @flags: The drm_exec flags at snapshot time. */
> > + u32 flags;
> > };
> >
> > int drm_exec_handle_contended(struct drm_exec *exec);
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability
2024-05-22 11:27 ` Christian König
@ 2024-05-22 13:54 ` Thomas Hellström
2024-05-22 14:41 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-22 13:54 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel, Daniel Vetter
On Wed, 2024-05-22 at 13:27 +0200, Christian König wrote:
> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > When validating a buffer object for submission, we might need to
> > lock
> > a number of object for eviction to make room for the validation.
> >
> > This makes it pretty likely that validation will eventually
> > succeed,
> > since eventually the validating process will hold most dma_resv
> > locks
> > of the buffer objects residing in the memory type being validated
> > for.
> >
> > However, once validation of a single object has succeeded it might
> > not
> > be beneficial to hold on to those locks anymore, and the validator
> > would want to drop the locks of all objects taken during
> > validation.
>
> Exactly avoiding that was one of the goals of developing the drm_exec
> object.
>
> When objects are unlocked after evicting them it just gives
> concurrent
> operations an opportunity to lock them and re-validate them into the
> contended domain.
>
> So why should that approach here be beneficial at all?
It's a matter of being nice to the rest of the system while *still
guaranteeing progress*. For each object we're trying to validate, we
keep on evicting other objects until we make progress even if we lock
all the objects in the domain.
If we were unlocking after each eviction, we can't really guarantee
progress.
OTOH, a concurrent locker of the object may well be one with higher
priority (lower ticket number) just wanting to perform a pagefault
So it's a tradeoff between locking just locking other processes out to
allow us to make one step of progress and to in addition hit them with
the big sledgehammer.
/Thomas
>
> Regards,
> Christian.
>
> >
> > Introduce a drm_exec snapshot functionality that can be used to
> > record the locks held at a certain time, and a restore
> > functionality
> > that restores the drm_exec state to the snapshot by dropping all
> > locks.
> >
> > Snapshots can be nested if needed.
> >
> > Cc: Christian König <christian.koenig@amd.com>
> > Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > Cc: <dri-devel@lists.freedesktop.org>
> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> > ---
> > drivers/gpu/drm/drm_exec.c | 55
> > +++++++++++++++++++++++++++++++++++++-
> > include/drm/drm_exec.h | 23 +++++++++++++++-
> > 2 files changed, 76 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_exec.c
> > b/drivers/gpu/drm/drm_exec.c
> > index 1383680ffa4a..9eea5d0d3a98 100644
> > --- a/drivers/gpu/drm/drm_exec.c
> > +++ b/drivers/gpu/drm/drm_exec.c
> > @@ -57,6 +57,7 @@ static void drm_exec_unlock_all(struct drm_exec
> > *exec)
> > struct drm_gem_object *obj;
> > unsigned long index;
> >
> > + WARN_ON(exec->snap);
> > drm_exec_for_each_locked_object_reverse(exec, index, obj)
> > {
> > dma_resv_unlock(obj->resv);
> > drm_gem_object_put(obj);
> > @@ -90,6 +91,7 @@ void drm_exec_init(struct drm_exec *exec, u32
> > flags, unsigned nr)
> > exec->num_objects = 0;
> > exec->contended = DRM_EXEC_DUMMY;
> > exec->prelocked = NULL;
> > + exec->snap = NULL;
> > }
> > EXPORT_SYMBOL(drm_exec_init);
> >
> > @@ -301,7 +303,6 @@ int drm_exec_lock_obj(struct drm_exec *exec,
> > struct drm_gem_object *obj)
> > goto error_unlock;
> >
> > return 0;
> > -
> > error_unlock:
> > dma_resv_unlock(obj->resv);
> > return ret;
> > @@ -395,5 +396,57 @@ int drm_exec_prepare_array(struct drm_exec
> > *exec,
> > }
> > EXPORT_SYMBOL(drm_exec_prepare_array);
> >
> > +/**
> > + * drm_exec_restore() - Restore the drm_exec state to the point of
> > a snapshot.
> > + * @exec: The drm_exec object with the state.
> > + * @snap: The snapshot state.
> > + *
> > + * Restores the drm_exec object by means of unlocking and dropping
> > references
> > + * to objects locked after the snapshot.
> > + */
> > +void drm_exec_restore(struct drm_exec *exec, struct
> > drm_exec_snapshot *snap)
> > +{
> > + struct drm_gem_object *obj;
> > + unsigned int index;
> > +
> > + exec->snap = snap->saved_snap;
> > +
> > + drm_exec_for_each_locked_object_reverse(exec, index, obj)
> > {
> > + if (index + 1 == snap->num_locked)
> > + break;
> > +
> > + dma_resv_unlock(obj->resv);
> > + drm_gem_object_put(obj);
> > + exec->objects[index] = NULL;
> > + }
> > +
> > + exec->num_objects = snap->num_locked;
> > +
> > + if (!exec->prelocked)
> > + exec->prelocked = snap->prelocked;
> > + else
> > + drm_gem_object_put(snap->prelocked);
> > +}
> > +EXPORT_SYMBOL(drm_exec_restore);
> > +
> > +/**
> > + * drm_exec_snapshot() - Take a snapshot of the drm_exec state
> > + * @exec: The drm_exec object with the state.
> > + * @snap: The snapshot state.
> > + *
> > + * Records the @exec state in @snap. The @snap object is typically
> > allocated
> > + * in the stack of the caller.
> > + */
> > +void drm_exec_snapshot(struct drm_exec *exec, struct
> > drm_exec_snapshot *snap)
> > +{
> > + snap->num_locked = exec->num_objects;
> > + snap->prelocked = exec->prelocked;
> > + if (snap->prelocked)
> > + drm_gem_object_get(snap->prelocked);
> > + snap->saved_snap = exec->snap;
> > + exec->snap = snap;
> > +}
> > +EXPORT_SYMBOL(drm_exec_snapshot);
> > +
> > MODULE_DESCRIPTION("DRM execution context");
> > MODULE_LICENSE("Dual MIT/GPL");
> > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > index ea0f2117ee0c..0ce4d749511b 100644
> > --- a/include/drm/drm_exec.h
> > +++ b/include/drm/drm_exec.h
> > @@ -19,7 +19,6 @@ struct drm_exec {
> > * @flags: Flags to control locking behavior
> > */
> > u32 flags;
> > -
> > /**
> > * @ticket: WW ticket used for acquiring locks
> > */
> > @@ -49,6 +48,25 @@ struct drm_exec {
> > * @prelocked: already locked GEM object due to contention
> > */
> > struct drm_gem_object *prelocked;
> > +
> > + /**
> > + * @snap: Pointer to the last snapshot taken or NULL if
> > none.
> > + */
> > + struct drm_exec_snapshot *snap;
> > +};
> > +
> > +/**
> > + * struct drm_exec_snapshot - drm_exec snapshot information
> > + */
> > +struct drm_exec_snapshot {
> > + /** @saved_snap: Pointer to the previous snapshot or NULL.
> > */
> > + struct drm_exec_snapshot *saved_snap;
> > +
> > + /** @prelocked: Refcounted pointer to the prelocked object
> > at snapshot time. */
> > + struct drm_gem_object *prelocked;
> > +
> > + /** @num_locked: Number of locked objects at snapshot
> > time. */
> > + unsigned long num_locked;
> > };
> >
> > int drm_exec_handle_contended(struct drm_exec *exec);
> > @@ -160,5 +178,8 @@ int drm_exec_prepare_array(struct drm_exec
> > *exec,
> > struct drm_gem_object **objects,
> > unsigned int num_objects,
> > unsigned int num_fences);
> > +void drm_exec_snapshot(struct drm_exec *exec, struct
> > drm_exec_snapshot *snap);
> > +void drm_exec_restore(struct drm_exec *exec, struct
> > drm_exec_snapshot *snap);
> > +
> >
> > #endif
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-22 5:52 ` Christian König
@ 2024-05-22 14:32 ` Thomas Hellström
2024-05-22 16:52 ` Christian König
0 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-22 14:32 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > If contention and backoff occurs during a drm_exec ww transaction,
> > the contended lock is not locked again until the next orinary
> > attempt to lock a dma_resv lock. However, with the introduction of
> > drm_exec_trylock(), that doesn't work, since the locking of the
> > contended lock needs to be a sleeping lock. Neither can we ignore
> > locking the contended lock during a trylock since that would
> > violate
> > at least the ww_mutex annotations.
> >
> > So resolve this by actually locking the contended lock during
> > drm_exec_retry_on_contention(). However, this introduces a new
> > point
> > of failure since locking the contended lock may return -EINTR.
> >
> > Hence drm_exec_retry_on_contention() must take an error parameter
> > and
> > also return a value indicating success.
>
> After thinking more about that I have to pretty clearly NAK this.
>
I thought we were beyond upfront NAKing in the first reply :/
> It's an intentional design decision to guarantee that at the start of
> the loop no object is locked.
>
> This is because Sima and I wanted to integrate userptr handling into
> drm_exec as well in the long term.
First I agree the interface looks worse with this patch.
But I thought generic userptr handling were going to end up as a gpuvm
helper (without using GEM objects) as we've discussed previously.
Anyway if still there would be helpers in drm_exec for some other
generic userptr solution, those need to be done before the
ww_acquire_ctx_init(). The contended locking here is done after, so I
can't really see how these would clash.
Still, If we need to come up with another solution, I think it's fair
we clearly sort out why.
> I think we should just document that drm_exec_trylock() can't be used
> to
> lock the first BO in the loop and explicitly WARN if that's the case.
Unfortunately that's not sufficient for the general use-case. If we
want to keep the ttm_bo_vm approach of dropping the mmap lock when
there is contention on the bo resv, we need to be able to trylock on
first lock. Also bo creation is using trylock but might be able to use
a sleeping lock there. But if that sleeping lock triggers an -EDEADLK
(DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of referencing an
object that never was fully created as a contending object.
So the only really working alternative solution I can see is that
drm_exec_trylock simply fails if there is a contended lock and we'd
need to live with the weird bo creation situation described above.
/Thomas
>
> Regards,
> Christian.
>
> >
> > Cc: Christian König <christian.koenig@amd.com>
> > Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > Cc: <dri-devel@lists.freedesktop.org>
> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> > ---
> > .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++-----
> > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
> > drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
> > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
> > drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
> > drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
> > drivers/gpu/drm/drm_exec.c | 35
> > ++++++++++++++-----
> > drivers/gpu/drm/drm_gpuvm.c | 8 ++---
> > drivers/gpu/drm/imagination/pvr_job.c | 2 +-
> > drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
> > drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
> > drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
> > drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
> > drivers/gpu/drm/xe/xe_vm.c | 10 +++---
> > include/drm/drm_exec.h | 23 +++++++++---
> > 17 files changed, 92 insertions(+), 62 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > index e4d4e55c08ad..4a08a692aa1f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct kgd_mem
> > *mem,
> > drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > drm_exec_until_all_locked(&ctx->exec) {
> > ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> > - drm_exec_retry_on_contention(&ctx->exec);
> > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > ret);
> > if (unlikely(ret))
> > goto error;
> >
> > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > >tbo.base, 1);
> > - drm_exec_retry_on_contention(&ctx->exec);
> > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > ret);
> > if (unlikely(ret))
> > goto error;
> > }
> > @@ -1199,14 +1199,14 @@ static int reserve_bo_and_cond_vms(struct
> > kgd_mem *mem,
> >
> > ret = amdgpu_vm_lock_pd(entry->bo_va-
> > >base.vm,
> > &ctx->exec, 2);
> > - drm_exec_retry_on_contention(&ctx->exec);
> > + ret = drm_exec_retry_on_contention(&ctx-
> > >exec, ret);
> > if (unlikely(ret))
> > goto error;
> > ++ctx->n_vms;
> > }
> >
> > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > >tbo.base, 1);
> > - drm_exec_retry_on_contention(&ctx->exec);
> > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > ret);
> > if (unlikely(ret))
> > goto error;
> > }
> > @@ -2619,7 +2619,7 @@ static int validate_invalid_user_pages(struct
> > amdkfd_process_info *process_info)
> > list_for_each_entry(peer_vm, &process_info-
> > >vm_list_head,
> > vm_list_node) {
> > ret = amdgpu_vm_lock_pd(peer_vm, &exec,
> > 2);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec,
> > ret);
> > if (unlikely(ret))
> > goto unreserve_out;
> > }
> > @@ -2631,7 +2631,7 @@ static int validate_invalid_user_pages(struct
> > amdkfd_process_info *process_info)
> >
> > gobj = &mem->bo->tbo.base;
> > ret = drm_exec_prepare_obj(&exec, gobj,
> > 1);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec,
> > ret);
> > if (unlikely(ret))
> > goto unreserve_out;
> > }
> > @@ -2875,7 +2875,7 @@ int
> > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > dma_fence __rcu *
> > list_for_each_entry(peer_vm, &process_info-
> > >vm_list_head,
> > vm_list_node) {
> > ret = amdgpu_vm_lock_pd(peer_vm, &exec,
> > 2);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec,
> > ret);
> > if (unlikely(ret)) {
> > pr_err("Locking VM PD failed, ret:
> > %d\n", ret);
> > goto ttm_reserve_fail;
> > @@ -2891,7 +2891,7 @@ int
> > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > dma_fence __rcu *
> >
> > gobj = &mem->bo->tbo.base;
> > ret = drm_exec_prepare_obj(&exec, gobj,
> > 1);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec,
> > ret);
> > if (unlikely(ret)) {
> > pr_err("drm_exec_prepare_obj
> > failed, ret: %d\n", ret);
> > goto ttm_reserve_fail;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > index ec888fc6ead8..299e46a6d934 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct
> > amdgpu_cs_parser *p,
> >
> > drm_exec_until_all_locked(&p->exec) {
> > r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec, 1 + p-
> > >gang_size);
> > - drm_exec_retry_on_contention(&p->exec);
> > + r = drm_exec_retry_on_contention(&p->exec, r);
> > if (unlikely(r))
> > goto out_free_user_pages;
> >
> > @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct
> > amdgpu_cs_parser *p,
> > /* One fence for TTM and one for each CS
> > job */
> > r = drm_exec_prepare_obj(&p->exec, &e->bo-
> > >tbo.base,
> > 1 + p-
> > >gang_size);
> > - drm_exec_retry_on_contention(&p->exec);
> > + r = drm_exec_retry_on_contention(&p->exec,
> > r);
> > if (unlikely(r))
> > goto out_free_user_pages;
> >
> > @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct
> > amdgpu_cs_parser *p,
> > if (p->uf_bo) {
> > r = drm_exec_prepare_obj(&p->exec, &p-
> > >uf_bo->tbo.base,
> > 1 + p-
> > >gang_size);
> > - drm_exec_retry_on_contention(&p->exec);
> > + r = drm_exec_retry_on_contention(&p->exec,
> > r);
> > if (unlikely(r))
> > goto out_free_user_pages;
> > }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > index cfdf558b48b6..8b2b86c7a6c5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct amdgpu_device
> > *adev, struct amdgpu_vm *vm,
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > if (likely(!r))
> > r = drm_exec_lock_obj(&exec, &bo-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r)) {
> > DRM_ERROR("failed to reserve CSA,PD BOs:
> > err=%d\n", r);
> > goto error;
> > @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
> > amdgpu_device *adev, struct amdgpu_vm *vm,
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > if (likely(!r))
> > r = drm_exec_lock_obj(&exec, &bo-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r)) {
> > DRM_ERROR("failed to reserve CSA,PD BOs:
> > err=%d\n", r);
> > goto error;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > index 67c234bcf89f..17e16c971e21 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > @@ -239,12 +239,12 @@ static void amdgpu_gem_object_close(struct
> > drm_gem_object *obj,
> > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > drm_exec_until_all_locked(&exec) {
> > r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> >
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> > }
> > @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct drm_device
> > *dev, void *data,
> > drm_exec_until_all_locked(&exec) {
> > if (gobj) {
> > r = drm_exec_lock_obj(&exec, gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec,
> > r);
> > if (unlikely(r))
> > goto error;
> > }
> >
> > r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error;
> > }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > index 5ca5c47ab54e..1b1a5147606e 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > @@ -1221,12 +1221,12 @@ int amdgpu_mes_ctx_map_meta_data(struct
> > amdgpu_device *adev,
> > drm_exec_until_all_locked(&exec) {
> > r = drm_exec_lock_obj(&exec,
> > &ctx_data->meta_data_obj-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error_fini_exec;
> >
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error_fini_exec;
> > }
> > @@ -1292,12 +1292,12 @@ int amdgpu_mes_ctx_unmap_meta_data(struct
> > amdgpu_device *adev,
> > drm_exec_until_all_locked(&exec) {
> > r = drm_exec_lock_obj(&exec,
> > &ctx_data->meta_data_obj-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> >
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> > }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > index e22cb2b5cd92..72b8213e352c 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev,
> > struct amdgpu_vm *vm,
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > if (likely(!r))
> > r = drm_exec_lock_obj(&exec, &bo-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error;
> > }
> > @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device
> > *adev, struct amdgpu_fpriv *fpriv)
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > if (likely(!r))
> > r = drm_exec_lock_obj(&exec, &bo-
> > >tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error;
> > }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > index e01c1c8e64c4..63392ce43945 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > @@ -89,12 +89,12 @@ static int map_ring_data(struct amdgpu_device
> > *adev, struct amdgpu_vm *vm,
> > drm_exec_init(&exec, 0, 0);
> > drm_exec_until_all_locked(&exec) {
> > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error_fini_exec;
> >
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto error_fini_exec;
> > }
> > @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
> > amdgpu_device *adev, struct amdgpu_vm *vm,
> > drm_exec_init(&exec, 0, 0);
> > drm_exec_until_all_locked(&exec) {
> > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> >
> > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > - drm_exec_retry_on_contention(&exec);
> > + r = drm_exec_retry_on_contention(&exec, r);
> > if (unlikely(r))
> > goto out_unlock;
> > }
> > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > index 386875e6eb96..a3aa7fd22f6a 100644
> > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct
> > svm_validate_context *ctx, bool intr)
> > vm = drm_priv_to_vm(pdd->drm_priv);
> >
> > r = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> > - drm_exec_retry_on_contention(&ctx->exec);
> > + r = drm_exec_retry_on_contention(&ctx-
> > >exec, r);
> > if (unlikely(r)) {
> > pr_debug("failed %d to reserve
> > bo\n", r);
> > goto unreserve_out;
> > diff --git a/drivers/gpu/drm/drm_exec.c
> > b/drivers/gpu/drm/drm_exec.c
> > index 2da094bdf8a4..3770a5d30213 100644
> > --- a/drivers/gpu/drm/drm_exec.c
> > +++ b/drivers/gpu/drm/drm_exec.c
> > @@ -28,12 +28,12 @@
> > * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
> > * drm_exec_until_all_locked(&exec) {
> > * ret = drm_exec_prepare_obj(&exec, boA, 1);
> > - * drm_exec_retry_on_contention(&exec);
> > + * ret = drm_exec_retry_on_contention(&exec, ret);
> > * if (ret)
> > * goto error;
> > *
> > * ret = drm_exec_prepare_obj(&exec, boB, 1);
> > - * drm_exec_retry_on_contention(&exec);
> > + * ret = drm_exec_retry_on_contention(&exec, ret);
> > * if (ret)
> > * goto error;
> > * }
> > @@ -48,7 +48,8 @@
> > */
> >
> > /* Dummy value used to initially enter the retry loop */
> > -#define DRM_EXEC_DUMMY ((void *)~0)
> > +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> > +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
> >
> > /* Unlock all objects and drop references */
> > static void drm_exec_unlock_all(struct drm_exec *exec)
> > @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec *exec)
> > return true;
> > }
> >
> > - drm_exec_unlock_all(exec);
> > - exec->num_objects = 0;
> > + exec->contended = NULL;
> > return true;
> > }
> > EXPORT_SYMBOL(drm_exec_cleanup);
> > @@ -194,6 +194,27 @@ static int drm_exec_lock_contended(struct
> > drm_exec *exec)
> > return ret;
> > }
> >
> > +/**
> > + * drm_exec_handle_contended() - Perform cleanup before a ww
> > transaction restart
> > + * @exec: Pointer to the drm_exec object.
> > + *
> > + * Unlocks all held resvs and re-locks the contended object.
> > + *
> > + * Return: 0 on success, negative error code on failure.
> > + */
> > +int drm_exec_handle_contended(struct drm_exec *exec)
> > +{
> > + int ret;
> > +
> > + drm_exec_unlock_all(exec);
> > + exec->num_objects = 0;
> > + ret = drm_exec_lock_contended(exec);
> > + exec->contended = DRM_EXEC_CONTENDED;
> > +
> > + return ret;
> > +}
> > +EXPORT_SYMBOL(drm_exec_handle_contended);
> > +
> > /**
> > * drm_exec_lock_obj - lock a GEM object for use
> > * @exec: the drm_exec object with the state
> > @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec *exec,
> > struct drm_gem_object *obj)
> > {
> > int ret;
> >
> > - ret = drm_exec_lock_contended(exec);
> > - if (unlikely(ret))
> > - return ret;
> > -
> > if (exec->prelocked == obj) {
> > drm_gem_object_put(exec->prelocked);
> > exec->prelocked = NULL;
> > diff --git a/drivers/gpu/drm/drm_gpuvm.c
> > b/drivers/gpu/drm/drm_gpuvm.c
> > index f9eb56f24bef..0923d6ae18e2 100644
> > --- a/drivers/gpu/drm/drm_gpuvm.c
> > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec
> > *vm_exec)
> >
> > drm_exec_until_all_locked(exec) {
> > ret = drm_gpuvm_prepare_vm(gpuvm, exec,
> > num_fences);
> > - drm_exec_retry_on_contention(exec);
> > + ret = drm_exec_retry_on_contention(exec, ret);
> > if (ret)
> > goto err;
> >
> > ret = drm_gpuvm_prepare_objects(gpuvm, exec,
> > num_fences);
> > - drm_exec_retry_on_contention(exec);
> > + ret = drm_exec_retry_on_contention(exec, ret);
> > if (ret)
> > goto err;
> >
> > if (vm_exec->extra.fn) {
> > ret = vm_exec->extra.fn(vm_exec);
> > - drm_exec_retry_on_contention(exec);
> > + ret = drm_exec_retry_on_contention(exec,
> > ret);
> > if (ret)
> > goto err;
> > }
> > @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
> > drm_gpuvm_exec *vm_exec,
> > drm_exec_until_all_locked(exec) {
> > ret = drm_gpuvm_prepare_range(gpuvm, exec, addr,
> > range,
> > vm_exec-
> > >num_fences);
> > - drm_exec_retry_on_contention(exec);
> > + ret = drm_exec_retry_on_contention(exec, ret);
> > if (ret)
> > goto err;
> > }
> > diff --git a/drivers/gpu/drm/imagination/pvr_job.c
> > b/drivers/gpu/drm/imagination/pvr_job.c
> > index 78c2f3c6dce0..6e0ce6c4576c 100644
> > --- a/drivers/gpu/drm/imagination/pvr_job.c
> > +++ b/drivers/gpu/drm/imagination/pvr_job.c
> > @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct drm_exec
> > *exec, struct pvr_job_data *job_data,
> > drm_exec_until_all_locked(exec) {
> > int err = jobs_lock_all_objs(exec, job_data,
> > job_count);
> >
> > - drm_exec_retry_on_contention(exec);
> > + err = drm_exec_retry_on_contention(exec, err);
> > if (err)
> > return err;
> > }
> > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > index fba78193127d..01992b43ea4b 100644
> > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
> > msm_gem_submit *submit)
> > for (unsigned i = 0; i < submit->nr_bos; i++) {
> > struct drm_gem_object *obj = submit-
> > >bos[i].obj;
> > ret = drm_exec_prepare_obj(&submit->exec,
> > obj, 1);
> > - drm_exec_retry_on_contention(&submit-
> > >exec);
> > + ret =
> > drm_exec_retry_on_contention(&submit->exec, ret);
> > if (ret)
> > goto error;
> > }
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > index ee02cd833c5e..0c871634fdfb 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
> > nouveau_job *job,
> > drm_exec_init(exec, vme->flags, 0);
> > drm_exec_until_all_locked(exec) {
> > ret = bind_lock_validate(job, exec, vme-
> > >num_fences);
> > - drm_exec_retry_on_contention(exec);
> > + ret = drm_exec_retry_on_contention(exec, ret);
> > if (ret) {
> > op = list_last_op(&bind_job->ops);
> > goto unwind;
> > diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
> > b/drivers/gpu/drm/tests/drm_exec_test.c
> > index 81f928a429ba..28558fdb08df 100644
> > --- a/drivers/gpu/drm/tests/drm_exec_test.c
> > +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> > @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
> > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = drm_exec_lock_obj(&exec, &gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> > @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit
> > *test)
> > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = drm_exec_lock_obj(&exec, &gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> >
> > drm_exec_unlock_obj(&exec, &gobj);
> > ret = drm_exec_lock_obj(&exec, &gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> > @@ -110,13 +110,13 @@ static void test_duplicates(struct kunit
> > *test)
> > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = drm_exec_lock_obj(&exec, &gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> >
> > ret = drm_exec_lock_obj(&exec, &gobj);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> > @@ -137,7 +137,7 @@ static void test_prepare(struct kunit *test)
> > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = drm_exec_prepare_obj(&exec, &gobj, 1);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > KUNIT_EXPECT_EQ(test, ret, 0);
> > if (ret)
> > break;
> > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > index 040dd142c49c..20ec1ab1b52d 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt *gt,
> > struct pagefault *pf)
> > drm_exec_init(&exec, 0, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = xe_pf_begin(&exec, vma, atomic, tile->id);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > if (ret)
> > goto unlock_dma_resv;
> >
> > @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt, struct
> > acc *acc)
> > drm_exec_init(&exec, 0, 0);
> > drm_exec_until_all_locked(&exec) {
> > ret = xe_pf_begin(&exec, vma, true, tile->id);
> > - drm_exec_retry_on_contention(&exec);
> > + ret = drm_exec_retry_on_contention(&exec, ret);
> > if (ret)
> > break;
> > }
> > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > b/drivers/gpu/drm/xe/xe_vm.c
> > index e2ec148c9c33..335524e803e7 100644
> > --- a/drivers/gpu/drm/xe/xe_vm.c
> > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > @@ -501,7 +501,7 @@ static void preempt_rebind_work_func(struct
> > work_struct *w)
> > bool done = false;
> >
> > err = xe_preempt_work_begin(&exec, vm, &done);
> > - drm_exec_retry_on_contention(&exec);
> > + err = drm_exec_retry_on_contention(&exec, err);
> > if (err || done) {
> > drm_exec_fini(&exec);
> > if (err &&
> > xe_vm_validate_should_retry(&exec, err, &end))
> > @@ -1052,7 +1052,7 @@ static void xe_vma_destroy_unlocked(struct
> > xe_vma *vma)
> > drm_exec_init(&exec, 0, 0);
> > drm_exec_until_all_locked(&exec) {
> > err = xe_vm_lock_vma(&exec, vma);
> > - drm_exec_retry_on_contention(&exec);
> > + err = drm_exec_retry_on_contention(&exec, err);
> > if (XE_WARN_ON(err))
> > break;
> > }
> > @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct xe_vm
> > *vm, struct drm_gpuva_op_map *op,
> > err = 0;
> > if (!bo->vm) {
> > err = drm_exec_lock_obj(&exec,
> > xe_vm_obj(vm));
> > -
> > drm_exec_retry_on_contention(&exec);
> > + err =
> > drm_exec_retry_on_contention(&exec, err);
> > }
> > if (!err) {
> > err = drm_exec_lock_obj(&exec,
> > &bo->ttm.base);
> > -
> > drm_exec_retry_on_contention(&exec);
> > + err =
> > drm_exec_retry_on_contention(&exec, err);
> > }
> > if (err) {
> > drm_exec_fini(&exec);
> > @@ -2884,7 +2884,7 @@ static int vm_bind_ioctl_ops_execute(struct
> > xe_vm *vm,
> > DRM_EXEC_IGNORE_DUPLICATES, 0);
> > drm_exec_until_all_locked(&exec) {
> > err = vm_bind_ioctl_ops_lock_and_prep(&exec, vm,
> > vops);
> > - drm_exec_retry_on_contention(&exec);
> > + err = drm_exec_retry_on_contention(&exec, err);
> > if (err)
> > goto unlock;
> >
> > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > index aa786b828a0a..fafb40d96e38 100644
> > --- a/include/drm/drm_exec.h
> > +++ b/include/drm/drm_exec.h
> > @@ -51,6 +51,8 @@ struct drm_exec {
> > struct drm_gem_object *prelocked;
> > };
> >
> > +int drm_exec_handle_contended(struct drm_exec *exec);
> > +
> > /**
> > * drm_exec_obj() - Return the object for a give drm_exec index
> > * @exec: Pointer to the drm_exec context
> > @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
> > __LINE__): \
> > /**
> > * drm_exec_retry_on_contention - restart the loop to grap all
> > locks
> > * @exec: drm_exec object
> > + * @_ret: The current error status
> > *
> > * Control flow helper to continue when a contention was detected
> > and we need to
> > * clean up and re-start the loop to prepare all GEM objects.
> > + *
> > + * Return: If no loop restart occurred: The error status.
> > */
> > -#define drm_exec_retry_on_contention(exec) \
> > - do { \
> > - if (unlikely(drm_exec_is_contended(exec))) \
> > - goto *__drm_exec_retry_ptr; \
> > - } while (0)
> > +#define drm_exec_retry_on_contention(exec,
> > _ret) \
> > + ({
> > \
> > + struct drm_exec *__exec =
> > (exec); \
> > + int __ret =
> > (_ret); \
> > +
> > \
> > + if (unlikely(drm_exec_is_contended(__exec)))
> > { \
> > + WARN_ON(__ret != -
> > EDEADLK); \
> > + __ret =
> > drm_exec_handle_contended(__exec); \
> > + if
> > (!__ret) \
> > + goto
> > *__drm_exec_retry_ptr; \
> > + }
> > \
> > + __ret;
> > \
> > + })
> >
> > /**
> > * drm_exec_is_contended - check for contention
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability
2024-05-22 13:54 ` Thomas Hellström
@ 2024-05-22 14:41 ` Thomas Hellström
0 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-22 14:41 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel, Daniel Vetter
On Wed, 2024-05-22 at 15:54 +0200, Thomas Hellström wrote:
> On Wed, 2024-05-22 at 13:27 +0200, Christian König wrote:
> > Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > > When validating a buffer object for submission, we might need to
> > > lock
> > > a number of object for eviction to make room for the validation.
> > >
> > > This makes it pretty likely that validation will eventually
> > > succeed,
> > > since eventually the validating process will hold most dma_resv
> > > locks
> > > of the buffer objects residing in the memory type being validated
> > > for.
> > >
> > > However, once validation of a single object has succeeded it
> > > might
> > > not
> > > be beneficial to hold on to those locks anymore, and the
> > > validator
> > > would want to drop the locks of all objects taken during
> > > validation.
> >
> > Exactly avoiding that was one of the goals of developing the
> > drm_exec
> > object.
> >
> > When objects are unlocked after evicting them it just gives
> > concurrent
> > operations an opportunity to lock them and re-validate them into
> > the
> > contended domain.
> >
> > So why should that approach here be beneficial at all?
>
> It's a matter of being nice to the rest of the system while *still
> guaranteeing progress*. For each object we're trying to validate, we
> keep on evicting other objects until we make progress even if we lock
> all the objects in the domain.
>
> If we were unlocking after each eviction, we can't really guarantee
> progress.
>
> OTOH, a concurrent locker of the object may well be one with higher
> priority (lower ticket number) just wanting to perform a pagefault
>
> So it's a tradeoff between locking just locking other processes out
> to
> allow us to make one step of progress and to in addition hit them
> with
> the big sledgehammer.
I thought I'd also mention that the ideal solution here I think would
be to have an rw_mutex per manager. Ordinary allocations take it in
read mode, evictions take it in write mode. Now the bad thing is it
sits in between ww_mutexes so it would have to be a ww_rw_mutex which
would probably be too nasty to implement.
/Thomas
>
> /Thomas
>
> >
> > Regards,
> > Christian.
> >
> > >
> > > Introduce a drm_exec snapshot functionality that can be used to
> > > record the locks held at a certain time, and a restore
> > > functionality
> > > that restores the drm_exec state to the snapshot by dropping all
> > > locks.
> > >
> > > Snapshots can be nested if needed.
> > >
> > > Cc: Christian König <christian.koenig@amd.com>
> > > Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> > > Cc: Matthew Brost <matthew.brost@intel.com>
> > > Cc: <dri-devel@lists.freedesktop.org>
> > > Signed-off-by: Thomas Hellström
> > > <thomas.hellstrom@linux.intel.com>
> > > ---
> > > drivers/gpu/drm/drm_exec.c | 55
> > > +++++++++++++++++++++++++++++++++++++-
> > > include/drm/drm_exec.h | 23 +++++++++++++++-
> > > 2 files changed, 76 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_exec.c
> > > b/drivers/gpu/drm/drm_exec.c
> > > index 1383680ffa4a..9eea5d0d3a98 100644
> > > --- a/drivers/gpu/drm/drm_exec.c
> > > +++ b/drivers/gpu/drm/drm_exec.c
> > > @@ -57,6 +57,7 @@ static void drm_exec_unlock_all(struct drm_exec
> > > *exec)
> > > struct drm_gem_object *obj;
> > > unsigned long index;
> > >
> > > + WARN_ON(exec->snap);
> > > drm_exec_for_each_locked_object_reverse(exec, index,
> > > obj)
> > > {
> > > dma_resv_unlock(obj->resv);
> > > drm_gem_object_put(obj);
> > > @@ -90,6 +91,7 @@ void drm_exec_init(struct drm_exec *exec, u32
> > > flags, unsigned nr)
> > > exec->num_objects = 0;
> > > exec->contended = DRM_EXEC_DUMMY;
> > > exec->prelocked = NULL;
> > > + exec->snap = NULL;
> > > }
> > > EXPORT_SYMBOL(drm_exec_init);
> > >
> > > @@ -301,7 +303,6 @@ int drm_exec_lock_obj(struct drm_exec *exec,
> > > struct drm_gem_object *obj)
> > > goto error_unlock;
> > >
> > > return 0;
> > > -
> > > error_unlock:
> > > dma_resv_unlock(obj->resv);
> > > return ret;
> > > @@ -395,5 +396,57 @@ int drm_exec_prepare_array(struct drm_exec
> > > *exec,
> > > }
> > > EXPORT_SYMBOL(drm_exec_prepare_array);
> > >
> > > +/**
> > > + * drm_exec_restore() - Restore the drm_exec state to the point
> > > of
> > > a snapshot.
> > > + * @exec: The drm_exec object with the state.
> > > + * @snap: The snapshot state.
> > > + *
> > > + * Restores the drm_exec object by means of unlocking and
> > > dropping
> > > references
> > > + * to objects locked after the snapshot.
> > > + */
> > > +void drm_exec_restore(struct drm_exec *exec, struct
> > > drm_exec_snapshot *snap)
> > > +{
> > > + struct drm_gem_object *obj;
> > > + unsigned int index;
> > > +
> > > + exec->snap = snap->saved_snap;
> > > +
> > > + drm_exec_for_each_locked_object_reverse(exec, index,
> > > obj)
> > > {
> > > + if (index + 1 == snap->num_locked)
> > > + break;
> > > +
> > > + dma_resv_unlock(obj->resv);
> > > + drm_gem_object_put(obj);
> > > + exec->objects[index] = NULL;
> > > + }
> > > +
> > > + exec->num_objects = snap->num_locked;
> > > +
> > > + if (!exec->prelocked)
> > > + exec->prelocked = snap->prelocked;
> > > + else
> > > + drm_gem_object_put(snap->prelocked);
> > > +}
> > > +EXPORT_SYMBOL(drm_exec_restore);
> > > +
> > > +/**
> > > + * drm_exec_snapshot() - Take a snapshot of the drm_exec state
> > > + * @exec: The drm_exec object with the state.
> > > + * @snap: The snapshot state.
> > > + *
> > > + * Records the @exec state in @snap. The @snap object is
> > > typically
> > > allocated
> > > + * in the stack of the caller.
> > > + */
> > > +void drm_exec_snapshot(struct drm_exec *exec, struct
> > > drm_exec_snapshot *snap)
> > > +{
> > > + snap->num_locked = exec->num_objects;
> > > + snap->prelocked = exec->prelocked;
> > > + if (snap->prelocked)
> > > + drm_gem_object_get(snap->prelocked);
> > > + snap->saved_snap = exec->snap;
> > > + exec->snap = snap;
> > > +}
> > > +EXPORT_SYMBOL(drm_exec_snapshot);
> > > +
> > > MODULE_DESCRIPTION("DRM execution context");
> > > MODULE_LICENSE("Dual MIT/GPL");
> > > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > > index ea0f2117ee0c..0ce4d749511b 100644
> > > --- a/include/drm/drm_exec.h
> > > +++ b/include/drm/drm_exec.h
> > > @@ -19,7 +19,6 @@ struct drm_exec {
> > > * @flags: Flags to control locking behavior
> > > */
> > > u32 flags;
> > > -
> > > /**
> > > * @ticket: WW ticket used for acquiring locks
> > > */
> > > @@ -49,6 +48,25 @@ struct drm_exec {
> > > * @prelocked: already locked GEM object due to
> > > contention
> > > */
> > > struct drm_gem_object *prelocked;
> > > +
> > > + /**
> > > + * @snap: Pointer to the last snapshot taken or NULL if
> > > none.
> > > + */
> > > + struct drm_exec_snapshot *snap;
> > > +};
> > > +
> > > +/**
> > > + * struct drm_exec_snapshot - drm_exec snapshot information
> > > + */
> > > +struct drm_exec_snapshot {
> > > + /** @saved_snap: Pointer to the previous snapshot or
> > > NULL.
> > > */
> > > + struct drm_exec_snapshot *saved_snap;
> > > +
> > > + /** @prelocked: Refcounted pointer to the prelocked
> > > object
> > > at snapshot time. */
> > > + struct drm_gem_object *prelocked;
> > > +
> > > + /** @num_locked: Number of locked objects at snapshot
> > > time. */
> > > + unsigned long num_locked;
> > > };
> > >
> > > int drm_exec_handle_contended(struct drm_exec *exec);
> > > @@ -160,5 +178,8 @@ int drm_exec_prepare_array(struct drm_exec
> > > *exec,
> > > struct drm_gem_object **objects,
> > > unsigned int num_objects,
> > > unsigned int num_fences);
> > > +void drm_exec_snapshot(struct drm_exec *exec, struct
> > > drm_exec_snapshot *snap);
> > > +void drm_exec_restore(struct drm_exec *exec, struct
> > > drm_exec_snapshot *snap);
> > > +
> > >
> > > #endif
> >
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-22 14:32 ` Thomas Hellström
@ 2024-05-22 16:52 ` Christian König
2024-05-22 17:42 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-22 16:52 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
[-- Attachment #1: Type: text/plain, Size: 31665 bytes --]
Am 22.05.24 um 16:32 schrieb Thomas Hellström:
> On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
>> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
>>> If contention and backoff occurs during a drm_exec ww transaction,
>>> the contended lock is not locked again until the next orinary
>>> attempt to lock a dma_resv lock. However, with the introduction of
>>> drm_exec_trylock(), that doesn't work, since the locking of the
>>> contended lock needs to be a sleeping lock. Neither can we ignore
>>> locking the contended lock during a trylock since that would
>>> violate
>>> at least the ww_mutex annotations.
>>>
>>> So resolve this by actually locking the contended lock during
>>> drm_exec_retry_on_contention(). However, this introduces a new
>>> point
>>> of failure since locking the contended lock may return -EINTR.
>>>
>>> Hence drm_exec_retry_on_contention() must take an error parameter
>>> and
>>> also return a value indicating success.
>> After thinking more about that I have to pretty clearly NAK this.
>>
> I thought we were beyond upfront NAKing in the first reply :/
Well my memory could fail me, but I mentioned concerns on this approach
before.
I was a bit annoyed seeing that again. But could as well be that my
response never got out or that I'm mixing things up.
>> It's an intentional design decision to guarantee that at the start of
>> the loop no object is locked.
>>
>> This is because Sima and I wanted to integrate userptr handling into
>> drm_exec as well in the long term.
> First I agree the interface looks worse with this patch.
> But I thought generic userptr handling were going to end up as a gpuvm
> helper (without using GEM objects) as we've discussed previously.
We might be talking past each other. That sounds like SVM, e.g. on
demand paging.
What I mean is pre-faulting during command submission like radeon,
amdgpu and i915 do for the userptr handling.
For that you need to re-start the whole handling similar to how you need
to re-start for the mutex locking when you detect that the page array is
stale, the difference is that you are not allowed to hold any resv locks
while pre-faulting.
That's why it is a requirement that the drm_exec loop starts without any
locks held.
> Anyway if still there would be helpers in drm_exec for some other
> generic userptr solution, those need to be done before the
> ww_acquire_ctx_init(). The contended locking here is done after, so I
> can't really see how these would clash.
Yes, that indeed was a problem. The ww_acquire_ctx_init() was
intentionally moved into drm_exec_cleanup() to partially prevent that issue.
I haven't fully figured out how to do handle everything exactly, but at
least in principle it can be made work. With this change here it becomes
impossible.
> Still, If we need to come up with another solution, I think it's fair
> we clearly sort out why.
>
>> I think we should just document that drm_exec_trylock() can't be used
>> to
>> lock the first BO in the loop and explicitly WARN if that's the case.
> Unfortunately that's not sufficient for the general use-case. If we
> want to keep the ttm_bo_vm approach of dropping the mmap lock when
> there is contention on the bo resv, we need to be able to trylock on
> first lock.
Mhm, why exactly do we still have that dance in the first place?
I mean we have sorted out the mmap() and dma_resv() locking order long
ago. See dma_resv_lockdep() which is enforcing that.
> Also bo creation is using trylock but might be able to use
> a sleeping lock there. But if that sleeping lock triggers an -EDEADLK
> (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of referencing an
> object that never was fully created as a contending object.
I wanted to eliminate that as well by not validating the BO during
initialization any more.
So bo creation would then be:
ttm_bo_init(bo)
drm_exec_while_not_all_locked() {
drm_exec_prepare_object(bo, 1);
ttm_bo_validate(bo);
}
if (r)
ttm_bo_put(bo);
return r;
I have that on a branch here somewhere prepared, but never got the time
to clean it up.
Regards,
Christian.
>
> So the only really working alternative solution I can see is that
> drm_exec_trylock simply fails if there is a contended lock and we'd
> need to live with the weird bo creation situation described above.
>
> /Thomas
>
>> Regards,
>> Christian.
>>
>>> Cc: Christian König<christian.koenig@amd.com>
>>> Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
>>> Cc: Matthew Brost<matthew.brost@intel.com>
>>> Cc:<dri-devel@lists.freedesktop.org>
>>> Signed-off-by: Thomas Hellström<thomas.hellstrom@linux.intel.com>
>>> ---
>>> .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++-----
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
>>> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
>>> drivers/gpu/drm/drm_exec.c | 35
>>> ++++++++++++++-----
>>> drivers/gpu/drm/drm_gpuvm.c | 8 ++---
>>> drivers/gpu/drm/imagination/pvr_job.c | 2 +-
>>> drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
>>> drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
>>> drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
>>> drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
>>> drivers/gpu/drm/xe/xe_vm.c | 10 +++---
>>> include/drm/drm_exec.h | 23 +++++++++---
>>> 17 files changed, 92 insertions(+), 62 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>> index e4d4e55c08ad..4a08a692aa1f 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>> @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct kgd_mem
>>> *mem,
>>> drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
>>> drm_exec_until_all_locked(&ctx->exec) {
>>> ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
>>> - drm_exec_retry_on_contention(&ctx->exec);
>>> + ret = drm_exec_retry_on_contention(&ctx->exec,
>>> ret);
>>> if (unlikely(ret))
>>> goto error;
>>>
>>> ret = drm_exec_prepare_obj(&ctx->exec, &bo-
>>>> tbo.base, 1);
>>> - drm_exec_retry_on_contention(&ctx->exec);
>>> + ret = drm_exec_retry_on_contention(&ctx->exec,
>>> ret);
>>> if (unlikely(ret))
>>> goto error;
>>> }
>>> @@ -1199,14 +1199,14 @@ static int reserve_bo_and_cond_vms(struct
>>> kgd_mem *mem,
>>>
>>> ret = amdgpu_vm_lock_pd(entry->bo_va-
>>>> base.vm,
>>> &ctx->exec, 2);
>>> - drm_exec_retry_on_contention(&ctx->exec);
>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>> exec, ret);
>>> if (unlikely(ret))
>>> goto error;
>>> ++ctx->n_vms;
>>> }
>>>
>>> ret = drm_exec_prepare_obj(&ctx->exec, &bo-
>>>> tbo.base, 1);
>>> - drm_exec_retry_on_contention(&ctx->exec);
>>> + ret = drm_exec_retry_on_contention(&ctx->exec,
>>> ret);
>>> if (unlikely(ret))
>>> goto error;
>>> }
>>> @@ -2619,7 +2619,7 @@ static int validate_invalid_user_pages(struct
>>> amdkfd_process_info *process_info)
>>> list_for_each_entry(peer_vm, &process_info-
>>>> vm_list_head,
>>> vm_list_node) {
>>> ret = amdgpu_vm_lock_pd(peer_vm, &exec,
>>> 2);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec,
>>> ret);
>>> if (unlikely(ret))
>>> goto unreserve_out;
>>> }
>>> @@ -2631,7 +2631,7 @@ static int validate_invalid_user_pages(struct
>>> amdkfd_process_info *process_info)
>>>
>>> gobj = &mem->bo->tbo.base;
>>> ret = drm_exec_prepare_obj(&exec, gobj,
>>> 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec,
>>> ret);
>>> if (unlikely(ret))
>>> goto unreserve_out;
>>> }
>>> @@ -2875,7 +2875,7 @@ int
>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
>>> dma_fence __rcu *
>>> list_for_each_entry(peer_vm, &process_info-
>>>> vm_list_head,
>>> vm_list_node) {
>>> ret = amdgpu_vm_lock_pd(peer_vm, &exec,
>>> 2);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec,
>>> ret);
>>> if (unlikely(ret)) {
>>> pr_err("Locking VM PD failed, ret:
>>> %d\n", ret);
>>> goto ttm_reserve_fail;
>>> @@ -2891,7 +2891,7 @@ int
>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
>>> dma_fence __rcu *
>>>
>>> gobj = &mem->bo->tbo.base;
>>> ret = drm_exec_prepare_obj(&exec, gobj,
>>> 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec,
>>> ret);
>>> if (unlikely(ret)) {
>>> pr_err("drm_exec_prepare_obj
>>> failed, ret: %d\n", ret);
>>> goto ttm_reserve_fail;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> index ec888fc6ead8..299e46a6d934 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct
>>> amdgpu_cs_parser *p,
>>>
>>> drm_exec_until_all_locked(&p->exec) {
>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec, 1 + p-
>>>> gang_size);
>>> - drm_exec_retry_on_contention(&p->exec);
>>> + r = drm_exec_retry_on_contention(&p->exec, r);
>>> if (unlikely(r))
>>> goto out_free_user_pages;
>>>
>>> @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct
>>> amdgpu_cs_parser *p,
>>> /* One fence for TTM and one for each CS
>>> job */
>>> r = drm_exec_prepare_obj(&p->exec, &e->bo-
>>>> tbo.base,
>>> 1 + p-
>>>> gang_size);
>>> - drm_exec_retry_on_contention(&p->exec);
>>> + r = drm_exec_retry_on_contention(&p->exec,
>>> r);
>>> if (unlikely(r))
>>> goto out_free_user_pages;
>>>
>>> @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct
>>> amdgpu_cs_parser *p,
>>> if (p->uf_bo) {
>>> r = drm_exec_prepare_obj(&p->exec, &p-
>>>> uf_bo->tbo.base,
>>> 1 + p-
>>>> gang_size);
>>> - drm_exec_retry_on_contention(&p->exec);
>>> + r = drm_exec_retry_on_contention(&p->exec,
>>> r);
>>> if (unlikely(r))
>>> goto out_free_user_pages;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>> index cfdf558b48b6..8b2b86c7a6c5 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>> @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct amdgpu_device
>>> *adev, struct amdgpu_vm *vm,
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> if (likely(!r))
>>> r = drm_exec_lock_obj(&exec, &bo-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r)) {
>>> DRM_ERROR("failed to reserve CSA,PD BOs:
>>> err=%d\n", r);
>>> goto error;
>>> @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> if (likely(!r))
>>> r = drm_exec_lock_obj(&exec, &bo-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r)) {
>>> DRM_ERROR("failed to reserve CSA,PD BOs:
>>> err=%d\n", r);
>>> goto error;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> index 67c234bcf89f..17e16c971e21 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> @@ -239,12 +239,12 @@ static void amdgpu_gem_object_close(struct
>>> drm_gem_object *obj,
>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>>
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>> }
>>> @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct drm_device
>>> *dev, void *data,
>>> drm_exec_until_all_locked(&exec) {
>>> if (gobj) {
>>> r = drm_exec_lock_obj(&exec, gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec,
>>> r);
>>> if (unlikely(r))
>>> goto error;
>>> }
>>>
>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>> index 5ca5c47ab54e..1b1a5147606e 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>> @@ -1221,12 +1221,12 @@ int amdgpu_mes_ctx_map_meta_data(struct
>>> amdgpu_device *adev,
>>> drm_exec_until_all_locked(&exec) {
>>> r = drm_exec_lock_obj(&exec,
>>> &ctx_data->meta_data_obj-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error_fini_exec;
>>>
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error_fini_exec;
>>> }
>>> @@ -1292,12 +1292,12 @@ int amdgpu_mes_ctx_unmap_meta_data(struct
>>> amdgpu_device *adev,
>>> drm_exec_until_all_locked(&exec) {
>>> r = drm_exec_lock_obj(&exec,
>>> &ctx_data->meta_data_obj-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>>
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>> index e22cb2b5cd92..72b8213e352c 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>> @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev,
>>> struct amdgpu_vm *vm,
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> if (likely(!r))
>>> r = drm_exec_lock_obj(&exec, &bo-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error;
>>> }
>>> @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device
>>> *adev, struct amdgpu_fpriv *fpriv)
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> if (likely(!r))
>>> r = drm_exec_lock_obj(&exec, &bo-
>>>> tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>> index e01c1c8e64c4..63392ce43945 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>> @@ -89,12 +89,12 @@ static int map_ring_data(struct amdgpu_device
>>> *adev, struct amdgpu_vm *vm,
>>> drm_exec_init(&exec, 0, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error_fini_exec;
>>>
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto error_fini_exec;
>>> }
>>> @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>> drm_exec_init(&exec, 0, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>>
>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>> - drm_exec_retry_on_contention(&exec);
>>> + r = drm_exec_retry_on_contention(&exec, r);
>>> if (unlikely(r))
>>> goto out_unlock;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> index 386875e6eb96..a3aa7fd22f6a 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct
>>> svm_validate_context *ctx, bool intr)
>>> vm = drm_priv_to_vm(pdd->drm_priv);
>>>
>>> r = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
>>> - drm_exec_retry_on_contention(&ctx->exec);
>>> + r = drm_exec_retry_on_contention(&ctx-
>>>> exec, r);
>>> if (unlikely(r)) {
>>> pr_debug("failed %d to reserve
>>> bo\n", r);
>>> goto unreserve_out;
>>> diff --git a/drivers/gpu/drm/drm_exec.c
>>> b/drivers/gpu/drm/drm_exec.c
>>> index 2da094bdf8a4..3770a5d30213 100644
>>> --- a/drivers/gpu/drm/drm_exec.c
>>> +++ b/drivers/gpu/drm/drm_exec.c
>>> @@ -28,12 +28,12 @@
>>> * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
>>> * drm_exec_until_all_locked(&exec) {
>>> * ret = drm_exec_prepare_obj(&exec, boA, 1);
>>> - * drm_exec_retry_on_contention(&exec);
>>> + * ret = drm_exec_retry_on_contention(&exec, ret);
>>> * if (ret)
>>> * goto error;
>>> *
>>> * ret = drm_exec_prepare_obj(&exec, boB, 1);
>>> - * drm_exec_retry_on_contention(&exec);
>>> + * ret = drm_exec_retry_on_contention(&exec, ret);
>>> * if (ret)
>>> * goto error;
>>> * }
>>> @@ -48,7 +48,8 @@
>>> */
>>>
>>> /* Dummy value used to initially enter the retry loop */
>>> -#define DRM_EXEC_DUMMY ((void *)~0)
>>> +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
>>> +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
>>>
>>> /* Unlock all objects and drop references */
>>> static void drm_exec_unlock_all(struct drm_exec *exec)
>>> @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec *exec)
>>> return true;
>>> }
>>>
>>> - drm_exec_unlock_all(exec);
>>> - exec->num_objects = 0;
>>> + exec->contended = NULL;
>>> return true;
>>> }
>>> EXPORT_SYMBOL(drm_exec_cleanup);
>>> @@ -194,6 +194,27 @@ static int drm_exec_lock_contended(struct
>>> drm_exec *exec)
>>> return ret;
>>> }
>>>
>>> +/**
>>> + * drm_exec_handle_contended() - Perform cleanup before a ww
>>> transaction restart
>>> + * @exec: Pointer to the drm_exec object.
>>> + *
>>> + * Unlocks all held resvs and re-locks the contended object.
>>> + *
>>> + * Return: 0 on success, negative error code on failure.
>>> + */
>>> +int drm_exec_handle_contended(struct drm_exec *exec)
>>> +{
>>> + int ret;
>>> +
>>> + drm_exec_unlock_all(exec);
>>> + exec->num_objects = 0;
>>> + ret = drm_exec_lock_contended(exec);
>>> + exec->contended = DRM_EXEC_CONTENDED;
>>> +
>>> + return ret;
>>> +}
>>> +EXPORT_SYMBOL(drm_exec_handle_contended);
>>> +
>>> /**
>>> * drm_exec_lock_obj - lock a GEM object for use
>>> * @exec: the drm_exec object with the state
>>> @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec *exec,
>>> struct drm_gem_object *obj)
>>> {
>>> int ret;
>>>
>>> - ret = drm_exec_lock_contended(exec);
>>> - if (unlikely(ret))
>>> - return ret;
>>> -
>>> if (exec->prelocked == obj) {
>>> drm_gem_object_put(exec->prelocked);
>>> exec->prelocked = NULL;
>>> diff --git a/drivers/gpu/drm/drm_gpuvm.c
>>> b/drivers/gpu/drm/drm_gpuvm.c
>>> index f9eb56f24bef..0923d6ae18e2 100644
>>> --- a/drivers/gpu/drm/drm_gpuvm.c
>>> +++ b/drivers/gpu/drm/drm_gpuvm.c
>>> @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec
>>> *vm_exec)
>>>
>>> drm_exec_until_all_locked(exec) {
>>> ret = drm_gpuvm_prepare_vm(gpuvm, exec,
>>> num_fences);
>>> - drm_exec_retry_on_contention(exec);
>>> + ret = drm_exec_retry_on_contention(exec, ret);
>>> if (ret)
>>> goto err;
>>>
>>> ret = drm_gpuvm_prepare_objects(gpuvm, exec,
>>> num_fences);
>>> - drm_exec_retry_on_contention(exec);
>>> + ret = drm_exec_retry_on_contention(exec, ret);
>>> if (ret)
>>> goto err;
>>>
>>> if (vm_exec->extra.fn) {
>>> ret = vm_exec->extra.fn(vm_exec);
>>> - drm_exec_retry_on_contention(exec);
>>> + ret = drm_exec_retry_on_contention(exec,
>>> ret);
>>> if (ret)
>>> goto err;
>>> }
>>> @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
>>> drm_gpuvm_exec *vm_exec,
>>> drm_exec_until_all_locked(exec) {
>>> ret = drm_gpuvm_prepare_range(gpuvm, exec, addr,
>>> range,
>>> vm_exec-
>>>> num_fences);
>>> - drm_exec_retry_on_contention(exec);
>>> + ret = drm_exec_retry_on_contention(exec, ret);
>>> if (ret)
>>> goto err;
>>> }
>>> diff --git a/drivers/gpu/drm/imagination/pvr_job.c
>>> b/drivers/gpu/drm/imagination/pvr_job.c
>>> index 78c2f3c6dce0..6e0ce6c4576c 100644
>>> --- a/drivers/gpu/drm/imagination/pvr_job.c
>>> +++ b/drivers/gpu/drm/imagination/pvr_job.c
>>> @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct drm_exec
>>> *exec, struct pvr_job_data *job_data,
>>> drm_exec_until_all_locked(exec) {
>>> int err = jobs_lock_all_objs(exec, job_data,
>>> job_count);
>>>
>>> - drm_exec_retry_on_contention(exec);
>>> + err = drm_exec_retry_on_contention(exec, err);
>>> if (err)
>>> return err;
>>> }
>>> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
>>> b/drivers/gpu/drm/msm/msm_gem_submit.c
>>> index fba78193127d..01992b43ea4b 100644
>>> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
>>> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
>>> @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
>>> msm_gem_submit *submit)
>>> for (unsigned i = 0; i < submit->nr_bos; i++) {
>>> struct drm_gem_object *obj = submit-
>>>> bos[i].obj;
>>> ret = drm_exec_prepare_obj(&submit->exec,
>>> obj, 1);
>>> - drm_exec_retry_on_contention(&submit-
>>>> exec);
>>> + ret =
>>> drm_exec_retry_on_contention(&submit->exec, ret);
>>> if (ret)
>>> goto error;
>>> }
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>> b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>> index ee02cd833c5e..0c871634fdfb 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>> @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
>>> nouveau_job *job,
>>> drm_exec_init(exec, vme->flags, 0);
>>> drm_exec_until_all_locked(exec) {
>>> ret = bind_lock_validate(job, exec, vme-
>>>> num_fences);
>>> - drm_exec_retry_on_contention(exec);
>>> + ret = drm_exec_retry_on_contention(exec, ret);
>>> if (ret) {
>>> op = list_last_op(&bind_job->ops);
>>> goto unwind;
>>> diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
>>> b/drivers/gpu/drm/tests/drm_exec_test.c
>>> index 81f928a429ba..28558fdb08df 100644
>>> --- a/drivers/gpu/drm/tests/drm_exec_test.c
>>> +++ b/drivers/gpu/drm/tests/drm_exec_test.c
>>> @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>> @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit
>>> *test)
>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>>
>>> drm_exec_unlock_obj(&exec, &gobj);
>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>> @@ -110,13 +110,13 @@ static void test_duplicates(struct kunit
>>> *test)
>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>>
>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>> @@ -137,7 +137,7 @@ static void test_prepare(struct kunit *test)
>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = drm_exec_prepare_obj(&exec, &gobj, 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>> if (ret)
>>> break;
>>> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>> b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>> index 040dd142c49c..20ec1ab1b52d 100644
>>> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>> @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt *gt,
>>> struct pagefault *pf)
>>> drm_exec_init(&exec, 0, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = xe_pf_begin(&exec, vma, atomic, tile->id);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> if (ret)
>>> goto unlock_dma_resv;
>>>
>>> @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt, struct
>>> acc *acc)
>>> drm_exec_init(&exec, 0, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> ret = xe_pf_begin(&exec, vma, true, tile->id);
>>> - drm_exec_retry_on_contention(&exec);
>>> + ret = drm_exec_retry_on_contention(&exec, ret);
>>> if (ret)
>>> break;
>>> }
>>> diff --git a/drivers/gpu/drm/xe/xe_vm.c
>>> b/drivers/gpu/drm/xe/xe_vm.c
>>> index e2ec148c9c33..335524e803e7 100644
>>> --- a/drivers/gpu/drm/xe/xe_vm.c
>>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>>> @@ -501,7 +501,7 @@ static void preempt_rebind_work_func(struct
>>> work_struct *w)
>>> bool done = false;
>>>
>>> err = xe_preempt_work_begin(&exec, vm, &done);
>>> - drm_exec_retry_on_contention(&exec);
>>> + err = drm_exec_retry_on_contention(&exec, err);
>>> if (err || done) {
>>> drm_exec_fini(&exec);
>>> if (err &&
>>> xe_vm_validate_should_retry(&exec, err, &end))
>>> @@ -1052,7 +1052,7 @@ static void xe_vma_destroy_unlocked(struct
>>> xe_vma *vma)
>>> drm_exec_init(&exec, 0, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> err = xe_vm_lock_vma(&exec, vma);
>>> - drm_exec_retry_on_contention(&exec);
>>> + err = drm_exec_retry_on_contention(&exec, err);
>>> if (XE_WARN_ON(err))
>>> break;
>>> }
>>> @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct xe_vm
>>> *vm, struct drm_gpuva_op_map *op,
>>> err = 0;
>>> if (!bo->vm) {
>>> err = drm_exec_lock_obj(&exec,
>>> xe_vm_obj(vm));
>>> -
>>> drm_exec_retry_on_contention(&exec);
>>> + err =
>>> drm_exec_retry_on_contention(&exec, err);
>>> }
>>> if (!err) {
>>> err = drm_exec_lock_obj(&exec,
>>> &bo->ttm.base);
>>> -
>>> drm_exec_retry_on_contention(&exec);
>>> + err =
>>> drm_exec_retry_on_contention(&exec, err);
>>> }
>>> if (err) {
>>> drm_exec_fini(&exec);
>>> @@ -2884,7 +2884,7 @@ static int vm_bind_ioctl_ops_execute(struct
>>> xe_vm *vm,
>>> DRM_EXEC_IGNORE_DUPLICATES, 0);
>>> drm_exec_until_all_locked(&exec) {
>>> err = vm_bind_ioctl_ops_lock_and_prep(&exec, vm,
>>> vops);
>>> - drm_exec_retry_on_contention(&exec);
>>> + err = drm_exec_retry_on_contention(&exec, err);
>>> if (err)
>>> goto unlock;
>>>
>>> diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
>>> index aa786b828a0a..fafb40d96e38 100644
>>> --- a/include/drm/drm_exec.h
>>> +++ b/include/drm/drm_exec.h
>>> @@ -51,6 +51,8 @@ struct drm_exec {
>>> struct drm_gem_object *prelocked;
>>> };
>>>
>>> +int drm_exec_handle_contended(struct drm_exec *exec);
>>> +
>>> /**
>>> * drm_exec_obj() - Return the object for a give drm_exec index
>>> * @exec: Pointer to the drm_exec context
>>> @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
>>> __LINE__): \
>>> /**
>>> * drm_exec_retry_on_contention - restart the loop to grap all
>>> locks
>>> * @exec: drm_exec object
>>> + * @_ret: The current error status
>>> *
>>> * Control flow helper to continue when a contention was detected
>>> and we need to
>>> * clean up and re-start the loop to prepare all GEM objects.
>>> + *
>>> + * Return: If no loop restart occurred: The error status.
>>> */
>>> -#define drm_exec_retry_on_contention(exec) \
>>> - do { \
>>> - if (unlikely(drm_exec_is_contended(exec))) \
>>> - goto *__drm_exec_retry_ptr; \
>>> - } while (0)
>>> +#define drm_exec_retry_on_contention(exec,
>>> _ret) \
>>> + ({
>>> \
>>> + struct drm_exec *__exec =
>>> (exec); \
>>> + int __ret =
>>> (_ret); \
>>> +
>>> \
>>> + if (unlikely(drm_exec_is_contended(__exec)))
>>> { \
>>> + WARN_ON(__ret != -
>>> EDEADLK); \
>>> + __ret =
>>> drm_exec_handle_contended(__exec); \
>>> + if
>>> (!__ret) \
>>> + goto
>>> *__drm_exec_retry_ptr; \
>>> + }
>>> \
>>> + __ret;
>>> \
>>> + })
>>>
>>> /**
>>> * drm_exec_is_contended - check for contention
[-- Attachment #2: Type: text/html, Size: 39117 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-22 16:52 ` Christian König
@ 2024-05-22 17:42 ` Thomas Hellström
2024-05-28 6:36 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-22 17:42 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
> Am 22.05.24 um 16:32 schrieb Thomas Hellström:
> > On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
> > > Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > > > If contention and backoff occurs during a drm_exec ww
> > > > transaction,
> > > > the contended lock is not locked again until the next orinary
> > > > attempt to lock a dma_resv lock. However, with the introduction
> > > > of
> > > > drm_exec_trylock(), that doesn't work, since the locking of the
> > > > contended lock needs to be a sleeping lock. Neither can we
> > > > ignore
> > > > locking the contended lock during a trylock since that would
> > > > violate
> > > > at least the ww_mutex annotations.
> > > >
> > > > So resolve this by actually locking the contended lock during
> > > > drm_exec_retry_on_contention(). However, this introduces a new
> > > > point
> > > > of failure since locking the contended lock may return -EINTR.
> > > >
> > > > Hence drm_exec_retry_on_contention() must take an error
> > > > parameter
> > > > and
> > > > also return a value indicating success.
> > > After thinking more about that I have to pretty clearly NAK this.
> > >
> > I thought we were beyond upfront NAKing in the first reply :/
>
> Well my memory could fail me, but I mentioned concerns on this
> approach
> before.
>
> I was a bit annoyed seeing that again. But could as well be that my
> response never got out or that I'm mixing things up.
I haven't seen it at least. Last discussion on this I saw was
here. I didn't see a follow-up on that.
https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>
> > > It's an intentional design decision to guarantee that at the
> > > start of
> > > the loop no object is locked.
> > >
> > > This is because Sima and I wanted to integrate userptr handling
> > > into
> > > drm_exec as well in the long term.
> > First I agree the interface looks worse with this patch.
> > But I thought generic userptr handling were going to end up as a
> > gpuvm
> > helper (without using GEM objects) as we've discussed previously.
>
> We might be talking past each other. That sounds like SVM, e.g. on
> demand paging.
>
> What I mean is pre-faulting during command submission like radeon,
> amdgpu and i915 do for the userptr handling.
Yes, then we're talking about the same thing.
We discussed in this thread here, started by Dave.
https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
I still think the right place is in drm_gpuvm for this sort of stuff.
And I think that's the concluding argument by Sima as well.
In any case, If the planned drm_exec development is to be a full
execbuf helper, I think we need a capable sub-helper for ONLY the ww
transaction locking as well, with support for the various locking
primitives. In particular if we're going to be able to port i915 ww
transaction locking over. There are more uses of the ww locking
transacions than execbuf.
>
> For that you need to re-start the whole handling similar to how you
> need
> to re-start for the mutex locking when you detect that the page array
> is
> stale, the difference is that you are not allowed to hold any resv
> locks
> while pre-faulting.
>
> That's why it is a requirement that the drm_exec loop starts without
> any
> locks held.
But wouldn't you need an outer (userptr) loop and an inner
(ww_transaction) loop for this? Why would we want to re-validate
userptrs on -EDEADLKS?
>
> > Anyway if still there would be helpers in drm_exec for some other
> > generic userptr solution, those need to be done before the
> > ww_acquire_ctx_init(). The contended locking here is done after, so
> > I
> > can't really see how these would clash.
>
> Yes, that indeed was a problem. The ww_acquire_ctx_init() was
> intentionally moved into drm_exec_cleanup() to partially prevent that
> issue.
>
> I haven't fully figured out how to do handle everything exactly, but
> at
> least in principle it can be made work. With this change here it
> becomes
> impossible.
>
> > Still, If we need to come up with another solution, I think it's
> > fair
> > we clearly sort out why.
> >
> > > I think we should just document that drm_exec_trylock() can't be
> > > used
> > > to
> > > lock the first BO in the loop and explicitly WARN if that's the
> > > case.
> > Unfortunately that's not sufficient for the general use-case. If we
> > want to keep the ttm_bo_vm approach of dropping the mmap lock when
> > there is contention on the bo resv, we need to be able to trylock
> > on
> > first lock.
>
> Mhm, why exactly do we still have that dance in the first place?
>
> I mean we have sorted out the mmap() and dma_resv() locking order
> long
> ago. See dma_resv_lockdep() which is enforcing that.
I explained that in my reply here:
https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
We shouldn't be holding the mmap lock when waiting for stuff. In
particular not while waiting for mutexes that may be blocked by gpu
activity.
>
> > Also bo creation is using trylock but might be able to use
> > a sleeping lock there. But if that sleeping lock triggers an -
> > EDEADLK
> > (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
> > referencing an
> > object that never was fully created as a contending object.
>
> I wanted to eliminate that as well by not validating the BO during
> initialization any more.
>
> So bo creation would then be:
>
> ttm_bo_init(bo)
>
> drm_exec_while_not_all_locked() {
> drm_exec_prepare_object(bo, 1);
>
> ttm_bo_validate(bo);
> }
>
> if (r)
> ttm_bo_put(bo);
>
> return r;
>
> I have that on a branch here somewhere prepared, but never got the
> time
> to clean it up.
Still, bo creation and validation may be part of a ww transaction as
well, like page-table bos (Although those are pre-locked so perhaps not
a good example). But in the general case, I'm not sure this is
sufficient for all use-cases.
/Thomas
>
> Regards,
> Christian.
>
> >
> > So the only really working alternative solution I can see is that
> > drm_exec_trylock simply fails if there is a contended lock and we'd
> > need to live with the weird bo creation situation described above.
> >
> > /Thomas
> >
> > > Regards,
> > > Christian.
> > >
> > > > Cc: Christian König<christian.koenig@amd.com>
> > > > Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
> > > > Cc: Matthew Brost<matthew.brost@intel.com>
> > > > Cc:<dri-devel@lists.freedesktop.org>
> > > > Signed-off-by: Thomas
> > > > Hellström<thomas.hellstrom@linux.intel.com>
> > > > ---
> > > > .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++-----
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
> > > > drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
> > > > drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
> > > > drivers/gpu/drm/drm_exec.c | 35
> > > > ++++++++++++++-----
> > > > drivers/gpu/drm/drm_gpuvm.c | 8 ++---
> > > > drivers/gpu/drm/imagination/pvr_job.c | 2 +-
> > > > drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
> > > > drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
> > > > drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
> > > > drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
> > > > drivers/gpu/drm/xe/xe_vm.c | 10 +++---
> > > > include/drm/drm_exec.h | 23
> > > > +++++++++---
> > > > 17 files changed, 92 insertions(+), 62 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > index e4d4e55c08ad..4a08a692aa1f 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct
> > > > kgd_mem
> > > > *mem,
> > > > drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > 0);
> > > > drm_exec_until_all_locked(&ctx->exec) {
> > > > ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > > > ret);
> > > > if (unlikely(ret))
> > > > goto error;
> > > >
> > > > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > > > > tbo.base, 1);
> > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > > > ret);
> > > > if (unlikely(ret))
> > > > goto error;
> > > > }
> > > > @@ -1199,14 +1199,14 @@ static int
> > > > reserve_bo_and_cond_vms(struct
> > > > kgd_mem *mem,
> > > >
> > > > ret = amdgpu_vm_lock_pd(entry->bo_va-
> > > > > base.vm,
> > > > &ctx->exec,
> > > > 2);
> > > > - drm_exec_retry_on_contention(&ctx-
> > > > >exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&ctx-
> > > > > exec, ret);
> > > > if (unlikely(ret))
> > > > goto error;
> > > > ++ctx->n_vms;
> > > > }
> > > >
> > > > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > > > > tbo.base, 1);
> > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > + ret = drm_exec_retry_on_contention(&ctx->exec,
> > > > ret);
> > > > if (unlikely(ret))
> > > > goto error;
> > > > }
> > > > @@ -2619,7 +2619,7 @@ static int
> > > > validate_invalid_user_pages(struct
> > > > amdkfd_process_info *process_info)
> > > > list_for_each_entry(peer_vm, &process_info-
> > > > > vm_list_head,
> > > > vm_list_node) {
> > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > &exec,
> > > > 2);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (unlikely(ret))
> > > > goto unreserve_out;
> > > > }
> > > > @@ -2631,7 +2631,7 @@ static int
> > > > validate_invalid_user_pages(struct
> > > > amdkfd_process_info *process_info)
> > > >
> > > > gobj = &mem->bo->tbo.base;
> > > > ret = drm_exec_prepare_obj(&exec,
> > > > gobj,
> > > > 1);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (unlikely(ret))
> > > > goto unreserve_out;
> > > > }
> > > > @@ -2875,7 +2875,7 @@ int
> > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > > > dma_fence __rcu *
> > > > list_for_each_entry(peer_vm, &process_info-
> > > > > vm_list_head,
> > > > vm_list_node) {
> > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > &exec,
> > > > 2);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (unlikely(ret)) {
> > > > pr_err("Locking VM PD failed,
> > > > ret:
> > > > %d\n", ret);
> > > > goto ttm_reserve_fail;
> > > > @@ -2891,7 +2891,7 @@ int
> > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > > > dma_fence __rcu *
> > > >
> > > > gobj = &mem->bo->tbo.base;
> > > > ret = drm_exec_prepare_obj(&exec,
> > > > gobj,
> > > > 1);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (unlikely(ret)) {
> > > > pr_err("drm_exec_prepare_obj
> > > > failed, ret: %d\n", ret);
> > > > goto ttm_reserve_fail;
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > index ec888fc6ead8..299e46a6d934 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > amdgpu_cs_parser *p,
> > > >
> > > > drm_exec_until_all_locked(&p->exec) {
> > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec, 1
> > > > + p-
> > > > > gang_size);
> > > > - drm_exec_retry_on_contention(&p->exec);
> > > > + r = drm_exec_retry_on_contention(&p->exec, r);
> > > > if (unlikely(r))
> > > > goto out_free_user_pages;
> > > >
> > > > @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > amdgpu_cs_parser *p,
> > > > /* One fence for TTM and one for each
> > > > CS
> > > > job */
> > > > r = drm_exec_prepare_obj(&p->exec, &e-
> > > > >bo-
> > > > > tbo.base,
> > > > 1 + p-
> > > > > gang_size);
> > > > - drm_exec_retry_on_contention(&p-
> > > > >exec);
> > > > + r = drm_exec_retry_on_contention(&p-
> > > > >exec,
> > > > r);
> > > > if (unlikely(r))
> > > > goto out_free_user_pages;
> > > >
> > > > @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > amdgpu_cs_parser *p,
> > > > if (p->uf_bo) {
> > > > r = drm_exec_prepare_obj(&p->exec, &p-
> > > > > uf_bo->tbo.base,
> > > > 1 + p-
> > > > > gang_size);
> > > > - drm_exec_retry_on_contention(&p-
> > > > >exec);
> > > > + r = drm_exec_retry_on_contention(&p-
> > > > >exec,
> > > > r);
> > > > if (unlikely(r))
> > > > goto out_free_user_pages;
> > > > }
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > index cfdf558b48b6..8b2b86c7a6c5 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
> > > > amdgpu_device
> > > > *adev, struct amdgpu_vm *vm,
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > if (likely(!r))
> > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r)) {
> > > > DRM_ERROR("failed to reserve CSA,PD
> > > > BOs:
> > > > err=%d\n", r);
> > > > goto error;
> > > > @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
> > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > if (likely(!r))
> > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r)) {
> > > > DRM_ERROR("failed to reserve CSA,PD
> > > > BOs:
> > > > err=%d\n", r);
> > > > goto error;
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > index 67c234bcf89f..17e16c971e21 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > @@ -239,12 +239,12 @@ static void
> > > > amdgpu_gem_object_close(struct
> > > > drm_gem_object *obj,
> > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > r = drm_exec_prepare_obj(&exec, &bo->tbo.base,
> > > > 1);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > > }
> > > > @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct drm_device
> > > > *dev, void *data,
> > > > drm_exec_until_all_locked(&exec) {
> > > > if (gobj) {
> > > > r = drm_exec_lock_obj(&exec, gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r =
> > > > drm_exec_retry_on_contention(&exec,
> > > > r);
> > > > if (unlikely(r))
> > > > goto error;
> > > > }
> > > >
> > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error;
> > > > }
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > index 5ca5c47ab54e..1b1a5147606e 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > @@ -1221,12 +1221,12 @@ int amdgpu_mes_ctx_map_meta_data(struct
> > > > amdgpu_device *adev,
> > > > drm_exec_until_all_locked(&exec) {
> > > > r = drm_exec_lock_obj(&exec,
> > > > &ctx_data-
> > > > >meta_data_obj-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error_fini_exec;
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error_fini_exec;
> > > > }
> > > > @@ -1292,12 +1292,12 @@ int
> > > > amdgpu_mes_ctx_unmap_meta_data(struct
> > > > amdgpu_device *adev,
> > > > drm_exec_until_all_locked(&exec) {
> > > > r = drm_exec_lock_obj(&exec,
> > > > &ctx_data-
> > > > >meta_data_obj-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > > }
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > index e22cb2b5cd92..72b8213e352c 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device
> > > > *adev,
> > > > struct amdgpu_vm *vm,
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > if (likely(!r))
> > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error;
> > > > }
> > > > @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
> > > > amdgpu_device
> > > > *adev, struct amdgpu_fpriv *fpriv)
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > if (likely(!r))
> > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error;
> > > > }
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > index e01c1c8e64c4..63392ce43945 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > @@ -89,12 +89,12 @@ static int map_ring_data(struct
> > > > amdgpu_device
> > > > *adev, struct amdgpu_vm *vm,
> > > > drm_exec_init(&exec, 0, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error_fini_exec;
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto error_fini_exec;
> > > > }
> > > > @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
> > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > drm_exec_init(&exec, 0, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > if (unlikely(r))
> > > > goto out_unlock;
> > > > }
> > > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > index 386875e6eb96..a3aa7fd22f6a 100644
> > > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct
> > > > svm_validate_context *ctx, bool intr)
> > > > vm = drm_priv_to_vm(pdd->drm_priv);
> > > >
> > > > r = amdgpu_vm_lock_pd(vm, &ctx->exec,
> > > > 2);
> > > > - drm_exec_retry_on_contention(&ctx-
> > > > >exec);
> > > > + r = drm_exec_retry_on_contention(&ctx-
> > > > > exec, r);
> > > > if (unlikely(r)) {
> > > > pr_debug("failed %d to reserve
> > > > bo\n", r);
> > > > goto unreserve_out;
> > > > diff --git a/drivers/gpu/drm/drm_exec.c
> > > > b/drivers/gpu/drm/drm_exec.c
> > > > index 2da094bdf8a4..3770a5d30213 100644
> > > > --- a/drivers/gpu/drm/drm_exec.c
> > > > +++ b/drivers/gpu/drm/drm_exec.c
> > > > @@ -28,12 +28,12 @@
> > > > * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
> > > > * drm_exec_until_all_locked(&exec) {
> > > > * ret = drm_exec_prepare_obj(&exec, boA, 1);
> > > > - * drm_exec_retry_on_contention(&exec);
> > > > + * ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > * if (ret)
> > > > * goto error;
> > > > *
> > > > * ret = drm_exec_prepare_obj(&exec, boB, 1);
> > > > - * drm_exec_retry_on_contention(&exec);
> > > > + * ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > * if (ret)
> > > > * goto error;
> > > > * }
> > > > @@ -48,7 +48,8 @@
> > > > */
> > > >
> > > > /* Dummy value used to initially enter the retry loop */
> > > > -#define DRM_EXEC_DUMMY ((void *)~0)
> > > > +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> > > > +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
> > > >
> > > > /* Unlock all objects and drop references */
> > > > static void drm_exec_unlock_all(struct drm_exec *exec)
> > > > @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec
> > > > *exec)
> > > > return true;
> > > > }
> > > >
> > > > - drm_exec_unlock_all(exec);
> > > > - exec->num_objects = 0;
> > > > + exec->contended = NULL;
> > > > return true;
> > > > }
> > > > EXPORT_SYMBOL(drm_exec_cleanup);
> > > > @@ -194,6 +194,27 @@ static int drm_exec_lock_contended(struct
> > > > drm_exec *exec)
> > > > return ret;
> > > > }
> > > >
> > > > +/**
> > > > + * drm_exec_handle_contended() - Perform cleanup before a ww
> > > > transaction restart
> > > > + * @exec: Pointer to the drm_exec object.
> > > > + *
> > > > + * Unlocks all held resvs and re-locks the contended object.
> > > > + *
> > > > + * Return: 0 on success, negative error code on failure.
> > > > + */
> > > > +int drm_exec_handle_contended(struct drm_exec *exec)
> > > > +{
> > > > + int ret;
> > > > +
> > > > + drm_exec_unlock_all(exec);
> > > > + exec->num_objects = 0;
> > > > + ret = drm_exec_lock_contended(exec);
> > > > + exec->contended = DRM_EXEC_CONTENDED;
> > > > +
> > > > + return ret;
> > > > +}
> > > > +EXPORT_SYMBOL(drm_exec_handle_contended);
> > > > +
> > > > /**
> > > > * drm_exec_lock_obj - lock a GEM object for use
> > > > * @exec: the drm_exec object with the state
> > > > @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec
> > > > *exec,
> > > > struct drm_gem_object *obj)
> > > > {
> > > > int ret;
> > > >
> > > > - ret = drm_exec_lock_contended(exec);
> > > > - if (unlikely(ret))
> > > > - return ret;
> > > > -
> > > > if (exec->prelocked == obj) {
> > > > drm_gem_object_put(exec->prelocked);
> > > > exec->prelocked = NULL;
> > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c
> > > > b/drivers/gpu/drm/drm_gpuvm.c
> > > > index f9eb56f24bef..0923d6ae18e2 100644
> > > > --- a/drivers/gpu/drm/drm_gpuvm.c
> > > > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > > > @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
> > > > drm_gpuvm_exec
> > > > *vm_exec)
> > > >
> > > > drm_exec_until_all_locked(exec) {
> > > > ret = drm_gpuvm_prepare_vm(gpuvm, exec,
> > > > num_fences);
> > > > - drm_exec_retry_on_contention(exec);
> > > > + ret = drm_exec_retry_on_contention(exec, ret);
> > > > if (ret)
> > > > goto err;
> > > >
> > > > ret = drm_gpuvm_prepare_objects(gpuvm, exec,
> > > > num_fences);
> > > > - drm_exec_retry_on_contention(exec);
> > > > + ret = drm_exec_retry_on_contention(exec, ret);
> > > > if (ret)
> > > > goto err;
> > > >
> > > > if (vm_exec->extra.fn) {
> > > > ret = vm_exec->extra.fn(vm_exec);
> > > > - drm_exec_retry_on_contention(exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(exec,
> > > > ret);
> > > > if (ret)
> > > > goto err;
> > > > }
> > > > @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
> > > > drm_gpuvm_exec *vm_exec,
> > > > drm_exec_until_all_locked(exec) {
> > > > ret = drm_gpuvm_prepare_range(gpuvm, exec,
> > > > addr,
> > > > range,
> > > > vm_exec-
> > > > > num_fences);
> > > > - drm_exec_retry_on_contention(exec);
> > > > + ret = drm_exec_retry_on_contention(exec, ret);
> > > > if (ret)
> > > > goto err;
> > > > }
> > > > diff --git a/drivers/gpu/drm/imagination/pvr_job.c
> > > > b/drivers/gpu/drm/imagination/pvr_job.c
> > > > index 78c2f3c6dce0..6e0ce6c4576c 100644
> > > > --- a/drivers/gpu/drm/imagination/pvr_job.c
> > > > +++ b/drivers/gpu/drm/imagination/pvr_job.c
> > > > @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct drm_exec
> > > > *exec, struct pvr_job_data *job_data,
> > > > drm_exec_until_all_locked(exec) {
> > > > int err = jobs_lock_all_objs(exec, job_data,
> > > > job_count);
> > > >
> > > > - drm_exec_retry_on_contention(exec);
> > > > + err = drm_exec_retry_on_contention(exec, err);
> > > > if (err)
> > > > return err;
> > > > }
> > > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > index fba78193127d..01992b43ea4b 100644
> > > > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
> > > > msm_gem_submit *submit)
> > > > for (unsigned i = 0; i < submit->nr_bos; i++)
> > > > {
> > > > struct drm_gem_object *obj = submit-
> > > > > bos[i].obj;
> > > > ret = drm_exec_prepare_obj(&submit-
> > > > >exec,
> > > > obj, 1);
> > > > - drm_exec_retry_on_contention(&submit-
> > > > > exec);
> > > > + ret =
> > > > drm_exec_retry_on_contention(&submit->exec, ret);
> > > > if (ret)
> > > > goto error;
> > > > }
> > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > index ee02cd833c5e..0c871634fdfb 100644
> > > > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
> > > > nouveau_job *job,
> > > > drm_exec_init(exec, vme->flags, 0);
> > > > drm_exec_until_all_locked(exec) {
> > > > ret = bind_lock_validate(job, exec, vme-
> > > > > num_fences);
> > > > - drm_exec_retry_on_contention(exec);
> > > > + ret = drm_exec_retry_on_contention(exec, ret);
> > > > if (ret) {
> > > > op = list_last_op(&bind_job->ops);
> > > > goto unwind;
> > > > diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > index 81f928a429ba..28558fdb08df 100644
> > > > --- a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
> > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > > @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit
> > > > *test)
> > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > >
> > > > drm_exec_unlock_obj(&exec, &gobj);
> > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > > @@ -110,13 +110,13 @@ static void test_duplicates(struct kunit
> > > > *test)
> > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > >
> > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > > @@ -137,7 +137,7 @@ static void test_prepare(struct kunit
> > > > *test)
> > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = drm_exec_prepare_obj(&exec, &gobj, 1);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > if (ret)
> > > > break;
> > > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > index 040dd142c49c..20ec1ab1b52d 100644
> > > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt
> > > > *gt,
> > > > struct pagefault *pf)
> > > > drm_exec_init(&exec, 0, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = xe_pf_begin(&exec, vma, atomic, tile-
> > > > >id);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (ret)
> > > > goto unlock_dma_resv;
> > > >
> > > > @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt,
> > > > struct
> > > > acc *acc)
> > > > drm_exec_init(&exec, 0, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > ret = xe_pf_begin(&exec, vma, true, tile->id);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > ret);
> > > > if (ret)
> > > > break;
> > > > }
> > > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > > b/drivers/gpu/drm/xe/xe_vm.c
> > > > index e2ec148c9c33..335524e803e7 100644
> > > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > > @@ -501,7 +501,7 @@ static void preempt_rebind_work_func(struct
> > > > work_struct *w)
> > > > bool done = false;
> > > >
> > > > err = xe_preempt_work_begin(&exec, vm, &done);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + err = drm_exec_retry_on_contention(&exec,
> > > > err);
> > > > if (err || done) {
> > > > drm_exec_fini(&exec);
> > > > if (err &&
> > > > xe_vm_validate_should_retry(&exec, err, &end))
> > > > @@ -1052,7 +1052,7 @@ static void
> > > > xe_vma_destroy_unlocked(struct
> > > > xe_vma *vma)
> > > > drm_exec_init(&exec, 0, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > err = xe_vm_lock_vma(&exec, vma);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + err = drm_exec_retry_on_contention(&exec,
> > > > err);
> > > > if (XE_WARN_ON(err))
> > > > break;
> > > > }
> > > > @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct
> > > > xe_vm
> > > > *vm, struct drm_gpuva_op_map *op,
> > > > err = 0;
> > > > if (!bo->vm) {
> > > > err = drm_exec_lock_obj(&exec,
> > > > xe_vm_obj(vm));
> > > > -
> > > > drm_exec_retry_on_contention(&
> > > > exec);
> > > > + err =
> > > > drm_exec_retry_on_contention(&exec, err);
> > > > }
> > > > if (!err) {
> > > > err = drm_exec_lock_obj(&exec,
> > > > &bo->ttm.base);
> > > > -
> > > > drm_exec_retry_on_contention(&
> > > > exec);
> > > > + err =
> > > > drm_exec_retry_on_contention(&exec, err);
> > > > }
> > > > if (err) {
> > > > drm_exec_fini(&exec);
> > > > @@ -2884,7 +2884,7 @@ static int
> > > > vm_bind_ioctl_ops_execute(struct
> > > > xe_vm *vm,
> > > > DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > drm_exec_until_all_locked(&exec) {
> > > > err = vm_bind_ioctl_ops_lock_and_prep(&exec,
> > > > vm,
> > > > vops);
> > > > - drm_exec_retry_on_contention(&exec);
> > > > + err = drm_exec_retry_on_contention(&exec,
> > > > err);
> > > > if (err)
> > > > goto unlock;
> > > >
> > > > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > > > index aa786b828a0a..fafb40d96e38 100644
> > > > --- a/include/drm/drm_exec.h
> > > > +++ b/include/drm/drm_exec.h
> > > > @@ -51,6 +51,8 @@ struct drm_exec {
> > > > struct drm_gem_object *prelocked;
> > > > };
> > > >
> > > > +int drm_exec_handle_contended(struct drm_exec *exec);
> > > > +
> > > > /**
> > > > * drm_exec_obj() - Return the object for a give drm_exec
> > > > index
> > > > * @exec: Pointer to the drm_exec context
> > > > @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
> > > > __LINE__): \
> > > > /**
> > > > * drm_exec_retry_on_contention - restart the loop to grap
> > > > all
> > > > locks
> > > > * @exec: drm_exec object
> > > > + * @_ret: The current error status
> > > > *
> > > > * Control flow helper to continue when a contention was
> > > > detected
> > > > and we need to
> > > > * clean up and re-start the loop to prepare all GEM
> > > > objects.
> > > > + *
> > > > + * Return: If no loop restart occurred: The error status.
> > > > */
> > > > -#define
> > > > drm_exec_retry_on_contention(exec) \
> > > > - do
> > > > { \
> > > > - if
> > > > (unlikely(drm_exec_is_contended(exec))) \
> > > > - goto
> > > > *__drm_exec_retry_ptr; \
> > > > - } while (0)
> > > > +#define drm_exec_retry_on_contention(exec,
> > > > _ret) \
> > > > + ({
> > > >
> > > > \
> > > > + struct drm_exec *__exec =
> > > > (exec); \
> > > > + int __ret =
> > > > (_ret); \
> > > > +
> > > >
> > > > \
> > > > + if (unlikely(drm_exec_is_contended(__exec)))
> > > > { \
> > > > + WARN_ON(__ret != -
> > > > EDEADLK); \
> > > > + __ret =
> > > > drm_exec_handle_contended(__exec); \
> > > > + if
> > > > (!__ret) \
> > > > + goto
> > > > *__drm_exec_retry_ptr; \
> > > > + }
> > > >
> > > > \
> > > > + __ret;
> > > >
> > > > \
> > > > + })
> > > >
> > > > /**
> > > > * drm_exec_is_contended - check for contention
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-22 17:42 ` Thomas Hellström
@ 2024-05-28 6:36 ` Thomas Hellström
2024-05-28 6:51 ` Christian König
0 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-28 6:36 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Hi, Christian.
I'd appreciate if you could respond to the below, since it is a bit
hard to try to design around a problem I don't believe exists, and come
up with a good solution for that.
In short.
1) To prefault userptr we have to exit the ww transaction anyway.
2) Any contended lock held at loop start is completely encapsulated in
the ww transaction and can and will be unlocked when exiting it, so
this patch doesn't introduce any additional problems for userptr
handling AFAICT.
3) The need for a fully capable ww transaction helper moving forward.
If we need a tool that also does userptr locking, then I think we need
to separate that from the ww transaction tool and only pass the latter
around to TTM.
Thanks,
Thomas
On Wed, 2024-05-22 at 19:42 +0200, Thomas Hellström wrote:
> On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
> > Am 22.05.24 um 16:32 schrieb Thomas Hellström:
> > > On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
> > > > Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > > > > If contention and backoff occurs during a drm_exec ww
> > > > > transaction,
> > > > > the contended lock is not locked again until the next orinary
> > > > > attempt to lock a dma_resv lock. However, with the
> > > > > introduction
> > > > > of
> > > > > drm_exec_trylock(), that doesn't work, since the locking of
> > > > > the
> > > > > contended lock needs to be a sleeping lock. Neither can we
> > > > > ignore
> > > > > locking the contended lock during a trylock since that would
> > > > > violate
> > > > > at least the ww_mutex annotations.
> > > > >
> > > > > So resolve this by actually locking the contended lock during
> > > > > drm_exec_retry_on_contention(). However, this introduces a
> > > > > new
> > > > > point
> > > > > of failure since locking the contended lock may return -
> > > > > EINTR.
> > > > >
> > > > > Hence drm_exec_retry_on_contention() must take an error
> > > > > parameter
> > > > > and
> > > > > also return a value indicating success.
> > > > After thinking more about that I have to pretty clearly NAK
> > > > this.
> > > >
> > > I thought we were beyond upfront NAKing in the first reply :/
> >
> > Well my memory could fail me, but I mentioned concerns on this
> > approach
> > before.
> >
> > I was a bit annoyed seeing that again. But could as well be that my
> > response never got out or that I'm mixing things up.
>
> I haven't seen it at least. Last discussion on this I saw was
> here. I didn't see a follow-up on that.
>
> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>
>
> >
> > > > It's an intentional design decision to guarantee that at the
> > > > start of
> > > > the loop no object is locked.
> > > >
> > > > This is because Sima and I wanted to integrate userptr handling
> > > > into
> > > > drm_exec as well in the long term.
> > > First I agree the interface looks worse with this patch.
> > > But I thought generic userptr handling were going to end up as a
> > > gpuvm
> > > helper (without using GEM objects) as we've discussed previously.
> >
> > We might be talking past each other. That sounds like SVM, e.g. on
> > demand paging.
> >
> > What I mean is pre-faulting during command submission like radeon,
> > amdgpu and i915 do for the userptr handling.
>
> Yes, then we're talking about the same thing.
>
> We discussed in this thread here, started by Dave.
>
> https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
>
> I still think the right place is in drm_gpuvm for this sort of stuff.
> And I think that's the concluding argument by Sima as well.
>
> In any case, If the planned drm_exec development is to be a full
> execbuf helper, I think we need a capable sub-helper for ONLY the ww
> transaction locking as well, with support for the various locking
> primitives. In particular if we're going to be able to port i915 ww
> transaction locking over. There are more uses of the ww locking
> transacions than execbuf.
>
> >
> > For that you need to re-start the whole handling similar to how you
> > need
> > to re-start for the mutex locking when you detect that the page
> > array
> > is
> > stale, the difference is that you are not allowed to hold any resv
> > locks
> > while pre-faulting.
> >
> > That's why it is a requirement that the drm_exec loop starts
> > without
> > any
> > locks held.
>
> But wouldn't you need an outer (userptr) loop and an inner
> (ww_transaction) loop for this? Why would we want to re-validate
> userptrs on -EDEADLKS?
>
> >
> > > Anyway if still there would be helpers in drm_exec for some other
> > > generic userptr solution, those need to be done before the
> > > ww_acquire_ctx_init(). The contended locking here is done after,
> > > so
> > > I
> > > can't really see how these would clash.
> >
> > Yes, that indeed was a problem. The ww_acquire_ctx_init() was
> > intentionally moved into drm_exec_cleanup() to partially prevent
> > that
> > issue.
> >
> > I haven't fully figured out how to do handle everything exactly,
> > but
> > at
> > least in principle it can be made work. With this change here it
> > becomes
> > impossible.
> >
> > > Still, If we need to come up with another solution, I think it's
> > > fair
> > > we clearly sort out why.
> > >
> > > > I think we should just document that drm_exec_trylock() can't
> > > > be
> > > > used
> > > > to
> > > > lock the first BO in the loop and explicitly WARN if that's the
> > > > case.
> > > Unfortunately that's not sufficient for the general use-case. If
> > > we
> > > want to keep the ttm_bo_vm approach of dropping the mmap lock
> > > when
> > > there is contention on the bo resv, we need to be able to trylock
> > > on
> > > first lock.
> >
> > Mhm, why exactly do we still have that dance in the first place?
> >
> > I mean we have sorted out the mmap() and dma_resv() locking order
> > long
> > ago. See dma_resv_lockdep() which is enforcing that.
>
> I explained that in my reply here:
>
> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>
> We shouldn't be holding the mmap lock when waiting for stuff. In
> particular not while waiting for mutexes that may be blocked by gpu
> activity.
>
> >
> > > Also bo creation is using trylock but might be able to use
> > > a sleeping lock there. But if that sleeping lock triggers an -
> > > EDEADLK
> > > (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
> > > referencing an
> > > object that never was fully created as a contending object.
> >
> > I wanted to eliminate that as well by not validating the BO during
> > initialization any more.
>
> >
> > So bo creation would then be:
> >
> > ttm_bo_init(bo)
> >
> > drm_exec_while_not_all_locked() {
> > drm_exec_prepare_object(bo, 1);
> >
> > ttm_bo_validate(bo);
> > }
> >
> > if (r)
> > ttm_bo_put(bo);
> >
> > return r;
> >
> > I have that on a branch here somewhere prepared, but never got the
> > time
> > to clean it up.
>
> Still, bo creation and validation may be part of a ww transaction as
> well, like page-table bos (Although those are pre-locked so perhaps
> not
> a good example). But in the general case, I'm not sure this is
> sufficient for all use-cases.
>
> /Thomas
>
>
>
> >
> > Regards,
> > Christian.
> >
> > >
> > > So the only really working alternative solution I can see is that
> > > drm_exec_trylock simply fails if there is a contended lock and
> > > we'd
> > > need to live with the weird bo creation situation described
> > > above.
> > >
> > > /Thomas
> > >
> > > > Regards,
> > > > Christian.
> > > >
> > > > > Cc: Christian König<christian.koenig@amd.com>
> > > > > Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
> > > > > Cc: Matthew Brost<matthew.brost@intel.com>
> > > > > Cc:<dri-devel@lists.freedesktop.org>
> > > > > Signed-off-by: Thomas
> > > > > Hellström<thomas.hellstrom@linux.intel.com>
> > > > > ---
> > > > > .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++---
> > > > > --
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
> > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
> > > > > drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
> > > > > drivers/gpu/drm/drm_exec.c | 35
> > > > > ++++++++++++++-----
> > > > > drivers/gpu/drm/drm_gpuvm.c | 8 ++---
> > > > > drivers/gpu/drm/imagination/pvr_job.c | 2 +-
> > > > > drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
> > > > > drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
> > > > > drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
> > > > > drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
> > > > > drivers/gpu/drm/xe/xe_vm.c | 10 +++---
> > > > > include/drm/drm_exec.h | 23
> > > > > +++++++++---
> > > > > 17 files changed, 92 insertions(+), 62 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > index e4d4e55c08ad..4a08a692aa1f 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct
> > > > > kgd_mem
> > > > > *mem,
> > > > > drm_exec_init(&ctx->exec,
> > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > 0);
> > > > > drm_exec_until_all_locked(&ctx->exec) {
> > > > > ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
> > > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > >exec,
> > > > > ret);
> > > > > if (unlikely(ret))
> > > > > goto error;
> > > > >
> > > > > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > > > > > tbo.base, 1);
> > > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > >exec,
> > > > > ret);
> > > > > if (unlikely(ret))
> > > > > goto error;
> > > > > }
> > > > > @@ -1199,14 +1199,14 @@ static int
> > > > > reserve_bo_and_cond_vms(struct
> > > > > kgd_mem *mem,
> > > > >
> > > > > ret = amdgpu_vm_lock_pd(entry-
> > > > > >bo_va-
> > > > > > base.vm,
> > > > > &ctx->exec,
> > > > > 2);
> > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > exec, ret);
> > > > > if (unlikely(ret))
> > > > > goto error;
> > > > > ++ctx->n_vms;
> > > > > }
> > > > >
> > > > > ret = drm_exec_prepare_obj(&ctx->exec, &bo-
> > > > > > tbo.base, 1);
> > > > > - drm_exec_retry_on_contention(&ctx->exec);
> > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > >exec,
> > > > > ret);
> > > > > if (unlikely(ret))
> > > > > goto error;
> > > > > }
> > > > > @@ -2619,7 +2619,7 @@ static int
> > > > > validate_invalid_user_pages(struct
> > > > > amdkfd_process_info *process_info)
> > > > > list_for_each_entry(peer_vm, &process_info-
> > > > > > vm_list_head,
> > > > > vm_list_node) {
> > > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > > &exec,
> > > > > 2);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (unlikely(ret))
> > > > > goto unreserve_out;
> > > > > }
> > > > > @@ -2631,7 +2631,7 @@ static int
> > > > > validate_invalid_user_pages(struct
> > > > > amdkfd_process_info *process_info)
> > > > >
> > > > > gobj = &mem->bo->tbo.base;
> > > > > ret = drm_exec_prepare_obj(&exec,
> > > > > gobj,
> > > > > 1);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (unlikely(ret))
> > > > > goto unreserve_out;
> > > > > }
> > > > > @@ -2875,7 +2875,7 @@ int
> > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > > > > dma_fence __rcu *
> > > > > list_for_each_entry(peer_vm, &process_info-
> > > > > > vm_list_head,
> > > > > vm_list_node) {
> > > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > > &exec,
> > > > > 2);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (unlikely(ret)) {
> > > > > pr_err("Locking VM PD
> > > > > failed,
> > > > > ret:
> > > > > %d\n", ret);
> > > > > goto ttm_reserve_fail;
> > > > > @@ -2891,7 +2891,7 @@ int
> > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
> > > > > dma_fence __rcu *
> > > > >
> > > > > gobj = &mem->bo->tbo.base;
> > > > > ret = drm_exec_prepare_obj(&exec,
> > > > > gobj,
> > > > > 1);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (unlikely(ret)) {
> > > > > pr_err("drm_exec_prepare_obj
> > > > > failed, ret: %d\n", ret);
> > > > > goto ttm_reserve_fail;
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > index ec888fc6ead8..299e46a6d934 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > > amdgpu_cs_parser *p,
> > > > >
> > > > > drm_exec_until_all_locked(&p->exec) {
> > > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec,
> > > > > 1
> > > > > + p-
> > > > > > gang_size);
> > > > > - drm_exec_retry_on_contention(&p->exec);
> > > > > + r = drm_exec_retry_on_contention(&p->exec,
> > > > > r);
> > > > > if (unlikely(r))
> > > > > goto out_free_user_pages;
> > > > >
> > > > > @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > > amdgpu_cs_parser *p,
> > > > > /* One fence for TTM and one for
> > > > > each
> > > > > CS
> > > > > job */
> > > > > r = drm_exec_prepare_obj(&p->exec,
> > > > > &e-
> > > > > > bo-
> > > > > > tbo.base,
> > > > > 1 + p-
> > > > > > gang_size);
> > > > > - drm_exec_retry_on_contention(&p-
> > > > > > exec);
> > > > > + r = drm_exec_retry_on_contention(&p-
> > > > > > exec,
> > > > > r);
> > > > > if (unlikely(r))
> > > > > goto out_free_user_pages;
> > > > >
> > > > > @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct
> > > > > amdgpu_cs_parser *p,
> > > > > if (p->uf_bo) {
> > > > > r = drm_exec_prepare_obj(&p->exec,
> > > > > &p-
> > > > > > uf_bo->tbo.base,
> > > > > 1 + p-
> > > > > > gang_size);
> > > > > - drm_exec_retry_on_contention(&p-
> > > > > > exec);
> > > > > + r = drm_exec_retry_on_contention(&p-
> > > > > > exec,
> > > > > r);
> > > > > if (unlikely(r))
> > > > > goto out_free_user_pages;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > index cfdf558b48b6..8b2b86c7a6c5 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
> > > > > amdgpu_device
> > > > > *adev, struct amdgpu_vm *vm,
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > if (likely(!r))
> > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r)) {
> > > > > DRM_ERROR("failed to reserve CSA,PD
> > > > > BOs:
> > > > > err=%d\n", r);
> > > > > goto error;
> > > > > @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
> > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > if (likely(!r))
> > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r)) {
> > > > > DRM_ERROR("failed to reserve CSA,PD
> > > > > BOs:
> > > > > err=%d\n", r);
> > > > > goto error;
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > index 67c234bcf89f..17e16c971e21 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > @@ -239,12 +239,12 @@ static void
> > > > > amdgpu_gem_object_close(struct
> > > > > drm_gem_object *obj,
> > > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > r = drm_exec_prepare_obj(&exec, &bo-
> > > > > >tbo.base,
> > > > > 1);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > > }
> > > > > @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct
> > > > > drm_device
> > > > > *dev, void *data,
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > if (gobj) {
> > > > > r = drm_exec_lock_obj(&exec, gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r =
> > > > > drm_exec_retry_on_contention(&exec,
> > > > > r);
> > > > > if (unlikely(r))
> > > > > goto error;
> > > > > }
> > > > >
> > > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > index 5ca5c47ab54e..1b1a5147606e 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > @@ -1221,12 +1221,12 @@ int
> > > > > amdgpu_mes_ctx_map_meta_data(struct
> > > > > amdgpu_device *adev,
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > r = drm_exec_lock_obj(&exec,
> > > > > &ctx_data-
> > > > > > meta_data_obj-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error_fini_exec;
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error_fini_exec;
> > > > > }
> > > > > @@ -1292,12 +1292,12 @@ int
> > > > > amdgpu_mes_ctx_unmap_meta_data(struct
> > > > > amdgpu_device *adev,
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > r = drm_exec_lock_obj(&exec,
> > > > > &ctx_data-
> > > > > > meta_data_obj-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > index e22cb2b5cd92..72b8213e352c 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device
> > > > > *adev,
> > > > > struct amdgpu_vm *vm,
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > if (likely(!r))
> > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error;
> > > > > }
> > > > > @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
> > > > > amdgpu_device
> > > > > *adev, struct amdgpu_fpriv *fpriv)
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > if (likely(!r))
> > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > index e01c1c8e64c4..63392ce43945 100644
> > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > @@ -89,12 +89,12 @@ static int map_ring_data(struct
> > > > > amdgpu_device
> > > > > *adev, struct amdgpu_vm *vm,
> > > > > drm_exec_init(&exec, 0, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error_fini_exec;
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto error_fini_exec;
> > > > > }
> > > > > @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
> > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > drm_exec_init(&exec, 0, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > r = drm_exec_lock_obj(&exec, &bo->tbo.base);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + r = drm_exec_retry_on_contention(&exec, r);
> > > > > if (unlikely(r))
> > > > > goto out_unlock;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > index 386875e6eb96..a3aa7fd22f6a 100644
> > > > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct
> > > > > svm_validate_context *ctx, bool intr)
> > > > > vm = drm_priv_to_vm(pdd->drm_priv);
> > > > >
> > > > > r = amdgpu_vm_lock_pd(vm, &ctx-
> > > > > >exec,
> > > > > 2);
> > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > exec);
> > > > > + r =
> > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > exec, r);
> > > > > if (unlikely(r)) {
> > > > > pr_debug("failed %d to
> > > > > reserve
> > > > > bo\n", r);
> > > > > goto unreserve_out;
> > > > > diff --git a/drivers/gpu/drm/drm_exec.c
> > > > > b/drivers/gpu/drm/drm_exec.c
> > > > > index 2da094bdf8a4..3770a5d30213 100644
> > > > > --- a/drivers/gpu/drm/drm_exec.c
> > > > > +++ b/drivers/gpu/drm/drm_exec.c
> > > > > @@ -28,12 +28,12 @@
> > > > > * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
> > > > > * drm_exec_until_all_locked(&exec) {
> > > > > * ret = drm_exec_prepare_obj(&exec, boA, 1);
> > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > + * ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > * if (ret)
> > > > > * goto error;
> > > > > *
> > > > > * ret = drm_exec_prepare_obj(&exec, boB, 1);
> > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > + * ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > * if (ret)
> > > > > * goto error;
> > > > > * }
> > > > > @@ -48,7 +48,8 @@
> > > > > */
> > > > >
> > > > > /* Dummy value used to initially enter the retry loop */
> > > > > -#define DRM_EXEC_DUMMY ((void *)~0)
> > > > > +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> > > > > +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
> > > > >
> > > > > /* Unlock all objects and drop references */
> > > > > static void drm_exec_unlock_all(struct drm_exec *exec)
> > > > > @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec
> > > > > *exec)
> > > > > return true;
> > > > > }
> > > > >
> > > > > - drm_exec_unlock_all(exec);
> > > > > - exec->num_objects = 0;
> > > > > + exec->contended = NULL;
> > > > > return true;
> > > > > }
> > > > > EXPORT_SYMBOL(drm_exec_cleanup);
> > > > > @@ -194,6 +194,27 @@ static int
> > > > > drm_exec_lock_contended(struct
> > > > > drm_exec *exec)
> > > > > return ret;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * drm_exec_handle_contended() - Perform cleanup before a ww
> > > > > transaction restart
> > > > > + * @exec: Pointer to the drm_exec object.
> > > > > + *
> > > > > + * Unlocks all held resvs and re-locks the contended object.
> > > > > + *
> > > > > + * Return: 0 on success, negative error code on failure.
> > > > > + */
> > > > > +int drm_exec_handle_contended(struct drm_exec *exec)
> > > > > +{
> > > > > + int ret;
> > > > > +
> > > > > + drm_exec_unlock_all(exec);
> > > > > + exec->num_objects = 0;
> > > > > + ret = drm_exec_lock_contended(exec);
> > > > > + exec->contended = DRM_EXEC_CONTENDED;
> > > > > +
> > > > > + return ret;
> > > > > +}
> > > > > +EXPORT_SYMBOL(drm_exec_handle_contended);
> > > > > +
> > > > > /**
> > > > > * drm_exec_lock_obj - lock a GEM object for use
> > > > > * @exec: the drm_exec object with the state
> > > > > @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec
> > > > > *exec,
> > > > > struct drm_gem_object *obj)
> > > > > {
> > > > > int ret;
> > > > >
> > > > > - ret = drm_exec_lock_contended(exec);
> > > > > - if (unlikely(ret))
> > > > > - return ret;
> > > > > -
> > > > > if (exec->prelocked == obj) {
> > > > > drm_gem_object_put(exec->prelocked);
> > > > > exec->prelocked = NULL;
> > > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c
> > > > > b/drivers/gpu/drm/drm_gpuvm.c
> > > > > index f9eb56f24bef..0923d6ae18e2 100644
> > > > > --- a/drivers/gpu/drm/drm_gpuvm.c
> > > > > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > > > > @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
> > > > > drm_gpuvm_exec
> > > > > *vm_exec)
> > > > >
> > > > > drm_exec_until_all_locked(exec) {
> > > > > ret = drm_gpuvm_prepare_vm(gpuvm, exec,
> > > > > num_fences);
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > ret);
> > > > > if (ret)
> > > > > goto err;
> > > > >
> > > > > ret = drm_gpuvm_prepare_objects(gpuvm, exec,
> > > > > num_fences);
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > ret);
> > > > > if (ret)
> > > > > goto err;
> > > > >
> > > > > if (vm_exec->extra.fn) {
> > > > > ret = vm_exec->extra.fn(vm_exec);
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(exec,
> > > > > ret);
> > > > > if (ret)
> > > > > goto err;
> > > > > }
> > > > > @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
> > > > > drm_gpuvm_exec *vm_exec,
> > > > > drm_exec_until_all_locked(exec) {
> > > > > ret = drm_gpuvm_prepare_range(gpuvm, exec,
> > > > > addr,
> > > > > range,
> > > > > vm_exec-
> > > > > > num_fences);
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > ret);
> > > > > if (ret)
> > > > > goto err;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > index 78c2f3c6dce0..6e0ce6c4576c 100644
> > > > > --- a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > +++ b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct
> > > > > drm_exec
> > > > > *exec, struct pvr_job_data *job_data,
> > > > > drm_exec_until_all_locked(exec) {
> > > > > int err = jobs_lock_all_objs(exec, job_data,
> > > > > job_count);
> > > > >
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + err = drm_exec_retry_on_contention(exec,
> > > > > err);
> > > > > if (err)
> > > > > return err;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > index fba78193127d..01992b43ea4b 100644
> > > > > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
> > > > > msm_gem_submit *submit)
> > > > > for (unsigned i = 0; i < submit->nr_bos;
> > > > > i++)
> > > > > {
> > > > > struct drm_gem_object *obj = submit-
> > > > > > bos[i].obj;
> > > > > ret = drm_exec_prepare_obj(&submit-
> > > > > > exec,
> > > > > obj, 1);
> > > > > -
> > > > > drm_exec_retry_on_contention(&submit-
> > > > > > exec);
> > > > > + ret =
> > > > > drm_exec_retry_on_contention(&submit->exec, ret);
> > > > > if (ret)
> > > > > goto error;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > index ee02cd833c5e..0c871634fdfb 100644
> > > > > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
> > > > > nouveau_job *job,
> > > > > drm_exec_init(exec, vme->flags, 0);
> > > > > drm_exec_until_all_locked(exec) {
> > > > > ret = bind_lock_validate(job, exec, vme-
> > > > > > num_fences);
> > > > > - drm_exec_retry_on_contention(exec);
> > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > ret);
> > > > > if (ret) {
> > > > > op = list_last_op(&bind_job->ops);
> > > > > goto unwind;
> > > > > diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > index 81f928a429ba..28558fdb08df 100644
> > > > > --- a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
> > > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > > @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit
> > > > > *test)
> > > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > >
> > > > > drm_exec_unlock_obj(&exec, &gobj);
> > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > > @@ -110,13 +110,13 @@ static void test_duplicates(struct
> > > > > kunit
> > > > > *test)
> > > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > >
> > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > > @@ -137,7 +137,7 @@ static void test_prepare(struct kunit
> > > > > *test)
> > > > > drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = drm_exec_prepare_obj(&exec, &gobj, 1);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > if (ret)
> > > > > break;
> > > > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > index 040dd142c49c..20ec1ab1b52d 100644
> > > > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt
> > > > > *gt,
> > > > > struct pagefault *pf)
> > > > > drm_exec_init(&exec, 0, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = xe_pf_begin(&exec, vma, atomic, tile-
> > > > > > id);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (ret)
> > > > > goto unlock_dma_resv;
> > > > >
> > > > > @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt,
> > > > > struct
> > > > > acc *acc)
> > > > > drm_exec_init(&exec, 0, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > ret = xe_pf_begin(&exec, vma, true, tile-
> > > > > >id);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + ret = drm_exec_retry_on_contention(&exec,
> > > > > ret);
> > > > > if (ret)
> > > > > break;
> > > > > }
> > > > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > > > b/drivers/gpu/drm/xe/xe_vm.c
> > > > > index e2ec148c9c33..335524e803e7 100644
> > > > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > > > @@ -501,7 +501,7 @@ static void
> > > > > preempt_rebind_work_func(struct
> > > > > work_struct *w)
> > > > > bool done = false;
> > > > >
> > > > > err = xe_preempt_work_begin(&exec, vm,
> > > > > &done);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + err = drm_exec_retry_on_contention(&exec,
> > > > > err);
> > > > > if (err || done) {
> > > > > drm_exec_fini(&exec);
> > > > > if (err &&
> > > > > xe_vm_validate_should_retry(&exec, err, &end))
> > > > > @@ -1052,7 +1052,7 @@ static void
> > > > > xe_vma_destroy_unlocked(struct
> > > > > xe_vma *vma)
> > > > > drm_exec_init(&exec, 0, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > err = xe_vm_lock_vma(&exec, vma);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + err = drm_exec_retry_on_contention(&exec,
> > > > > err);
> > > > > if (XE_WARN_ON(err))
> > > > > break;
> > > > > }
> > > > > @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct
> > > > > xe_vm
> > > > > *vm, struct drm_gpuva_op_map *op,
> > > > > err = 0;
> > > > > if (!bo->vm) {
> > > > > err =
> > > > > drm_exec_lock_obj(&exec,
> > > > > xe_vm_obj(vm));
> > > > > -
> > > > > drm_exec_retry_on_contention
> > > > > (&
> > > > > exec);
> > > > > + err =
> > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > }
> > > > > if (!err) {
> > > > > err =
> > > > > drm_exec_lock_obj(&exec,
> > > > > &bo->ttm.base);
> > > > > -
> > > > > drm_exec_retry_on_contention
> > > > > (&
> > > > > exec);
> > > > > + err =
> > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > }
> > > > > if (err) {
> > > > > drm_exec_fini(&exec);
> > > > > @@ -2884,7 +2884,7 @@ static int
> > > > > vm_bind_ioctl_ops_execute(struct
> > > > > xe_vm *vm,
> > > > > DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > > drm_exec_until_all_locked(&exec) {
> > > > > err = vm_bind_ioctl_ops_lock_and_prep(&exec,
> > > > > vm,
> > > > > vops);
> > > > > - drm_exec_retry_on_contention(&exec);
> > > > > + err = drm_exec_retry_on_contention(&exec,
> > > > > err);
> > > > > if (err)
> > > > > goto unlock;
> > > > >
> > > > > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
> > > > > index aa786b828a0a..fafb40d96e38 100644
> > > > > --- a/include/drm/drm_exec.h
> > > > > +++ b/include/drm/drm_exec.h
> > > > > @@ -51,6 +51,8 @@ struct drm_exec {
> > > > > struct drm_gem_object *prelocked;
> > > > > };
> > > > >
> > > > > +int drm_exec_handle_contended(struct drm_exec *exec);
> > > > > +
> > > > > /**
> > > > > * drm_exec_obj() - Return the object for a give drm_exec
> > > > > index
> > > > > * @exec: Pointer to the drm_exec context
> > > > > @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
> > > > > __LINE__): \
> > > > > /**
> > > > > * drm_exec_retry_on_contention - restart the loop to grap
> > > > > all
> > > > > locks
> > > > > * @exec: drm_exec object
> > > > > + * @_ret: The current error status
> > > > > *
> > > > > * Control flow helper to continue when a contention was
> > > > > detected
> > > > > and we need to
> > > > > * clean up and re-start the loop to prepare all GEM
> > > > > objects.
> > > > > + *
> > > > > + * Return: If no loop restart occurred: The error status.
> > > > > */
> > > > > -#define
> > > > > drm_exec_retry_on_contention(exec) \
> > > > > - do
> > > > > { \
> > > > > - if
> > > > > (unlikely(drm_exec_is_contended(exec))) \
> > > > > - goto
> > > > > *__drm_exec_retry_ptr; \
> > > > > - } while (0)
> > > > > +#define drm_exec_retry_on_contention(exec,
> > > > > _ret) \
> > > > > + ({
> > > > >
> > > > > \
> > > > > + struct drm_exec *__exec =
> > > > > (exec); \
> > > > > + int __ret =
> > > > > (_ret); \
> > > > > +
> > > > >
> > > > > \
> > > > > + if (unlikely(drm_exec_is_contended(__exec)))
> > > > > { \
> > > > > + WARN_ON(__ret != -
> > > > > EDEADLK); \
> > > > > + __ret =
> > > > > drm_exec_handle_contended(__exec); \
> > > > > + if
> > > > > (!__ret) \
> > > > > + goto
> > > > > *__drm_exec_retry_ptr; \
> > > > > + }
> > > > >
> > > > > \
> > > > > + __ret;
> > > > >
> > > > > \
> > > > > + })
> > > > >
> > > > > /**
> > > > > * drm_exec_is_contended - check for contention
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-28 6:36 ` Thomas Hellström
@ 2024-05-28 6:51 ` Christian König
2024-05-28 8:07 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-28 6:51 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Hi Thomas,
Am 28.05.24 um 08:36 schrieb Thomas Hellström:
> Hi, Christian.
>
> I'd appreciate if you could respond to the below, since it is a bit
> hard to try to design around a problem I don't believe exists, and come
> up with a good solution for that.
>
> In short.
> 1) To prefault userptr we have to exit the ww transaction anyway.
Yeah and I would rather like to have that handling in drm_exec at some time.
Basically a GEM object with outdated struct pages backing it can be
handled in the same loop at the ww transaction.
> 2) Any contended lock held at loop start is completely encapsulated in
> the ww transaction and can and will be unlocked when exiting it, so
> this patch doesn't introduce any additional problems for userptr
> handling AFAICT.
The drm_exec object was intentionally design to not have anything locked
at the beginning of the loop. See the discussion I had with Sima around
that when pushing the drm_exec object upstream.
I would really like to stick with that design and honestly don't see the
reason to change that. Contenting on a trylock seem to be much more
questionable.
> 3) The need for a fully capable ww transaction helper moving forward.
> If we need a tool that also does userptr locking, then I think we need
> to separate that from the ww transaction tool and only pass the latter
> around to TTM.
drm_exec is *not* meant to be a ww_transaction helper.
The functionality here is to support drivers in their CS interface and
that includes userptr handling as well as a couple of other things.
Regards,
Christian.
>
> Thanks,
> Thomas
>
> On Wed, 2024-05-22 at 19:42 +0200, Thomas Hellström wrote:
>> On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
>>> Am 22.05.24 um 16:32 schrieb Thomas Hellström:
>>>> On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
>>>>> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
>>>>>> If contention and backoff occurs during a drm_exec ww
>>>>>> transaction,
>>>>>> the contended lock is not locked again until the next orinary
>>>>>> attempt to lock a dma_resv lock. However, with the
>>>>>> introduction
>>>>>> of
>>>>>> drm_exec_trylock(), that doesn't work, since the locking of
>>>>>> the
>>>>>> contended lock needs to be a sleeping lock. Neither can we
>>>>>> ignore
>>>>>> locking the contended lock during a trylock since that would
>>>>>> violate
>>>>>> at least the ww_mutex annotations.
>>>>>>
>>>>>> So resolve this by actually locking the contended lock during
>>>>>> drm_exec_retry_on_contention(). However, this introduces a
>>>>>> new
>>>>>> point
>>>>>> of failure since locking the contended lock may return -
>>>>>> EINTR.
>>>>>>
>>>>>> Hence drm_exec_retry_on_contention() must take an error
>>>>>> parameter
>>>>>> and
>>>>>> also return a value indicating success.
>>>>> After thinking more about that I have to pretty clearly NAK
>>>>> this.
>>>>>
>>>> I thought we were beyond upfront NAKing in the first reply :/
>>> Well my memory could fail me, but I mentioned concerns on this
>>> approach
>>> before.
>>>
>>> I was a bit annoyed seeing that again. But could as well be that my
>>> response never got out or that I'm mixing things up.
>> I haven't seen it at least. Last discussion on this I saw was
>> here. I didn't see a follow-up on that.
>>
>> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>>
>>
>>>>> It's an intentional design decision to guarantee that at the
>>>>> start of
>>>>> the loop no object is locked.
>>>>>
>>>>> This is because Sima and I wanted to integrate userptr handling
>>>>> into
>>>>> drm_exec as well in the long term.
>>>> First I agree the interface looks worse with this patch.
>>>> But I thought generic userptr handling were going to end up as a
>>>> gpuvm
>>>> helper (without using GEM objects) as we've discussed previously.
>>> We might be talking past each other. That sounds like SVM, e.g. on
>>> demand paging.
>>>
>>> What I mean is pre-faulting during command submission like radeon,
>>> amdgpu and i915 do for the userptr handling.
>> Yes, then we're talking about the same thing.
>>
>> We discussed in this thread here, started by Dave.
>>
>> https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
>>
>> I still think the right place is in drm_gpuvm for this sort of stuff.
>> And I think that's the concluding argument by Sima as well.
>>
>> In any case, If the planned drm_exec development is to be a full
>> execbuf helper, I think we need a capable sub-helper for ONLY the ww
>> transaction locking as well, with support for the various locking
>> primitives. In particular if we're going to be able to port i915 ww
>> transaction locking over. There are more uses of the ww locking
>> transacions than execbuf.
>>
>>> For that you need to re-start the whole handling similar to how you
>>> need
>>> to re-start for the mutex locking when you detect that the page
>>> array
>>> is
>>> stale, the difference is that you are not allowed to hold any resv
>>> locks
>>> while pre-faulting.
>>>
>>> That's why it is a requirement that the drm_exec loop starts
>>> without
>>> any
>>> locks held.
>> But wouldn't you need an outer (userptr) loop and an inner
>> (ww_transaction) loop for this? Why would we want to re-validate
>> userptrs on -EDEADLKS?
>>
>>>> Anyway if still there would be helpers in drm_exec for some other
>>>> generic userptr solution, those need to be done before the
>>>> ww_acquire_ctx_init(). The contended locking here is done after,
>>>> so
>>>> I
>>>> can't really see how these would clash.
>>> Yes, that indeed was a problem. The ww_acquire_ctx_init() was
>>> intentionally moved into drm_exec_cleanup() to partially prevent
>>> that
>>> issue.
>>>
>>> I haven't fully figured out how to do handle everything exactly,
>>> but
>>> at
>>> least in principle it can be made work. With this change here it
>>> becomes
>>> impossible.
>>>
>>>> Still, If we need to come up with another solution, I think it's
>>>> fair
>>>> we clearly sort out why.
>>>>
>>>>> I think we should just document that drm_exec_trylock() can't
>>>>> be
>>>>> used
>>>>> to
>>>>> lock the first BO in the loop and explicitly WARN if that's the
>>>>> case.
>>>> Unfortunately that's not sufficient for the general use-case. If
>>>> we
>>>> want to keep the ttm_bo_vm approach of dropping the mmap lock
>>>> when
>>>> there is contention on the bo resv, we need to be able to trylock
>>>> on
>>>> first lock.
>>> Mhm, why exactly do we still have that dance in the first place?
>>>
>>> I mean we have sorted out the mmap() and dma_resv() locking order
>>> long
>>> ago. See dma_resv_lockdep() which is enforcing that.
>> I explained that in my reply here:
>>
>> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>>
>> We shouldn't be holding the mmap lock when waiting for stuff. In
>> particular not while waiting for mutexes that may be blocked by gpu
>> activity.
>>
>>>> Also bo creation is using trylock but might be able to use
>>>> a sleeping lock there. But if that sleeping lock triggers an -
>>>> EDEADLK
>>>> (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
>>>> referencing an
>>>> object that never was fully created as a contending object.
>>> I wanted to eliminate that as well by not validating the BO during
>>> initialization any more.
>>> So bo creation would then be:
>>>
>>> ttm_bo_init(bo)
>>>
>>> drm_exec_while_not_all_locked() {
>>> drm_exec_prepare_object(bo, 1);
>>>
>>> ttm_bo_validate(bo);
>>> }
>>>
>>> if (r)
>>> ttm_bo_put(bo);
>>>
>>> return r;
>>>
>>> I have that on a branch here somewhere prepared, but never got the
>>> time
>>> to clean it up.
>> Still, bo creation and validation may be part of a ww transaction as
>> well, like page-table bos (Although those are pre-locked so perhaps
>> not
>> a good example). But in the general case, I'm not sure this is
>> sufficient for all use-cases.
>>
>> /Thomas
>>
>>
>>
>>> Regards,
>>> Christian.
>>>
>>>> So the only really working alternative solution I can see is that
>>>> drm_exec_trylock simply fails if there is a contended lock and
>>>> we'd
>>>> need to live with the weird bo creation situation described
>>>> above.
>>>>
>>>> /Thomas
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> Cc: Christian König<christian.koenig@amd.com>
>>>>>> Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
>>>>>> Cc: Matthew Brost<matthew.brost@intel.com>
>>>>>> Cc:<dri-devel@lists.freedesktop.org>
>>>>>> Signed-off-by: Thomas
>>>>>> Hellström<thomas.hellstrom@linux.intel.com>
>>>>>> ---
>>>>>> .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++---
>>>>>> --
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++--
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +--
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8 ++---
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8 ++---
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +--
>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8 ++---
>>>>>> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
>>>>>> drivers/gpu/drm/drm_exec.c | 35
>>>>>> ++++++++++++++-----
>>>>>> drivers/gpu/drm/drm_gpuvm.c | 8 ++---
>>>>>> drivers/gpu/drm/imagination/pvr_job.c | 2 +-
>>>>>> drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
>>>>>> drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
>>>>>> drivers/gpu/drm/tests/drm_exec_test.c | 12 +++----
>>>>>> drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +--
>>>>>> drivers/gpu/drm/xe/xe_vm.c | 10 +++---
>>>>>> include/drm/drm_exec.h | 23
>>>>>> +++++++++---
>>>>>> 17 files changed, 92 insertions(+), 62 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>> index e4d4e55c08ad..4a08a692aa1f 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>> @@ -1152,12 +1152,12 @@ static int reserve_bo_and_vm(struct
>>>>>> kgd_mem
>>>>>> *mem,
>>>>>> drm_exec_init(&ctx->exec,
>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>> 0);
>>>>>> drm_exec_until_all_locked(&ctx->exec) {
>>>>>> ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
>>>>>> - drm_exec_retry_on_contention(&ctx->exec);
>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>> exec,
>>>>>> ret);
>>>>>> if (unlikely(ret))
>>>>>> goto error;
>>>>>>
>>>>>> ret = drm_exec_prepare_obj(&ctx->exec, &bo-
>>>>>>> tbo.base, 1);
>>>>>> - drm_exec_retry_on_contention(&ctx->exec);
>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>> exec,
>>>>>> ret);
>>>>>> if (unlikely(ret))
>>>>>> goto error;
>>>>>> }
>>>>>> @@ -1199,14 +1199,14 @@ static int
>>>>>> reserve_bo_and_cond_vms(struct
>>>>>> kgd_mem *mem,
>>>>>>
>>>>>> ret = amdgpu_vm_lock_pd(entry-
>>>>>>> bo_va-
>>>>>>> base.vm,
>>>>>> &ctx->exec,
>>>>>> 2);
>>>>>> - drm_exec_retry_on_contention(&ctx-
>>>>>>> exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>> exec, ret);
>>>>>> if (unlikely(ret))
>>>>>> goto error;
>>>>>> ++ctx->n_vms;
>>>>>> }
>>>>>>
>>>>>> ret = drm_exec_prepare_obj(&ctx->exec, &bo-
>>>>>>> tbo.base, 1);
>>>>>> - drm_exec_retry_on_contention(&ctx->exec);
>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>> exec,
>>>>>> ret);
>>>>>> if (unlikely(ret))
>>>>>> goto error;
>>>>>> }
>>>>>> @@ -2619,7 +2619,7 @@ static int
>>>>>> validate_invalid_user_pages(struct
>>>>>> amdkfd_process_info *process_info)
>>>>>> list_for_each_entry(peer_vm, &process_info-
>>>>>>> vm_list_head,
>>>>>> vm_list_node) {
>>>>>> ret = amdgpu_vm_lock_pd(peer_vm,
>>>>>> &exec,
>>>>>> 2);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (unlikely(ret))
>>>>>> goto unreserve_out;
>>>>>> }
>>>>>> @@ -2631,7 +2631,7 @@ static int
>>>>>> validate_invalid_user_pages(struct
>>>>>> amdkfd_process_info *process_info)
>>>>>>
>>>>>> gobj = &mem->bo->tbo.base;
>>>>>> ret = drm_exec_prepare_obj(&exec,
>>>>>> gobj,
>>>>>> 1);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (unlikely(ret))
>>>>>> goto unreserve_out;
>>>>>> }
>>>>>> @@ -2875,7 +2875,7 @@ int
>>>>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
>>>>>> dma_fence __rcu *
>>>>>> list_for_each_entry(peer_vm, &process_info-
>>>>>>> vm_list_head,
>>>>>> vm_list_node) {
>>>>>> ret = amdgpu_vm_lock_pd(peer_vm,
>>>>>> &exec,
>>>>>> 2);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (unlikely(ret)) {
>>>>>> pr_err("Locking VM PD
>>>>>> failed,
>>>>>> ret:
>>>>>> %d\n", ret);
>>>>>> goto ttm_reserve_fail;
>>>>>> @@ -2891,7 +2891,7 @@ int
>>>>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct
>>>>>> dma_fence __rcu *
>>>>>>
>>>>>> gobj = &mem->bo->tbo.base;
>>>>>> ret = drm_exec_prepare_obj(&exec,
>>>>>> gobj,
>>>>>> 1);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (unlikely(ret)) {
>>>>>> pr_err("drm_exec_prepare_obj
>>>>>> failed, ret: %d\n", ret);
>>>>>> goto ttm_reserve_fail;
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>> index ec888fc6ead8..299e46a6d934 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>> @@ -897,7 +897,7 @@ static int amdgpu_cs_parser_bos(struct
>>>>>> amdgpu_cs_parser *p,
>>>>>>
>>>>>> drm_exec_until_all_locked(&p->exec) {
>>>>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &p->exec,
>>>>>> 1
>>>>>> + p-
>>>>>>> gang_size);
>>>>>> - drm_exec_retry_on_contention(&p->exec);
>>>>>> + r = drm_exec_retry_on_contention(&p->exec,
>>>>>> r);
>>>>>> if (unlikely(r))
>>>>>> goto out_free_user_pages;
>>>>>>
>>>>>> @@ -905,7 +905,7 @@ static int amdgpu_cs_parser_bos(struct
>>>>>> amdgpu_cs_parser *p,
>>>>>> /* One fence for TTM and one for
>>>>>> each
>>>>>> CS
>>>>>> job */
>>>>>> r = drm_exec_prepare_obj(&p->exec,
>>>>>> &e-
>>>>>>> bo-
>>>>>>> tbo.base,
>>>>>> 1 + p-
>>>>>>> gang_size);
>>>>>> - drm_exec_retry_on_contention(&p-
>>>>>>> exec);
>>>>>> + r = drm_exec_retry_on_contention(&p-
>>>>>>> exec,
>>>>>> r);
>>>>>> if (unlikely(r))
>>>>>> goto out_free_user_pages;
>>>>>>
>>>>>> @@ -915,7 +915,7 @@ static int amdgpu_cs_parser_bos(struct
>>>>>> amdgpu_cs_parser *p,
>>>>>> if (p->uf_bo) {
>>>>>> r = drm_exec_prepare_obj(&p->exec,
>>>>>> &p-
>>>>>>> uf_bo->tbo.base,
>>>>>> 1 + p-
>>>>>>> gang_size);
>>>>>> - drm_exec_retry_on_contention(&p-
>>>>>>> exec);
>>>>>> + r = drm_exec_retry_on_contention(&p-
>>>>>>> exec,
>>>>>> r);
>>>>>> if (unlikely(r))
>>>>>> goto out_free_user_pages;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>> index cfdf558b48b6..8b2b86c7a6c5 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>> @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
>>>>>> amdgpu_device
>>>>>> *adev, struct amdgpu_vm *vm,
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> if (likely(!r))
>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r)) {
>>>>>> DRM_ERROR("failed to reserve CSA,PD
>>>>>> BOs:
>>>>>> err=%d\n", r);
>>>>>> goto error;
>>>>>> @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
>>>>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> if (likely(!r))
>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r)) {
>>>>>> DRM_ERROR("failed to reserve CSA,PD
>>>>>> BOs:
>>>>>> err=%d\n", r);
>>>>>> goto error;
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>> index 67c234bcf89f..17e16c971e21 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>> @@ -239,12 +239,12 @@ static void
>>>>>> amdgpu_gem_object_close(struct
>>>>>> drm_gem_object *obj,
>>>>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> r = drm_exec_prepare_obj(&exec, &bo-
>>>>>>> tbo.base,
>>>>>> 1);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>> }
>>>>>> @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct
>>>>>> drm_device
>>>>>> *dev, void *data,
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> if (gobj) {
>>>>>> r = drm_exec_lock_obj(&exec, gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r =
>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>> r);
>>>>>> if (unlikely(r))
>>>>>> goto error;
>>>>>> }
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>> index 5ca5c47ab54e..1b1a5147606e 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>> @@ -1221,12 +1221,12 @@ int
>>>>>> amdgpu_mes_ctx_map_meta_data(struct
>>>>>> amdgpu_device *adev,
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>> &ctx_data-
>>>>>>> meta_data_obj-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error_fini_exec;
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error_fini_exec;
>>>>>> }
>>>>>> @@ -1292,12 +1292,12 @@ int
>>>>>> amdgpu_mes_ctx_unmap_meta_data(struct
>>>>>> amdgpu_device *adev,
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>> &ctx_data-
>>>>>>> meta_data_obj-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>> index e22cb2b5cd92..72b8213e352c 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>> @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct amdgpu_device
>>>>>> *adev,
>>>>>> struct amdgpu_vm *vm,
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> if (likely(!r))
>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error;
>>>>>> }
>>>>>> @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
>>>>>> amdgpu_device
>>>>>> *adev, struct amdgpu_fpriv *fpriv)
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> if (likely(!r))
>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>> tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>> index e01c1c8e64c4..63392ce43945 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>> @@ -89,12 +89,12 @@ static int map_ring_data(struct
>>>>>> amdgpu_device
>>>>>> *adev, struct amdgpu_vm *vm,
>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error_fini_exec;
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto error_fini_exec;
>>>>>> }
>>>>>> @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
>>>>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> r = drm_exec_lock_obj(&exec, &bo->tbo.base);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + r = drm_exec_retry_on_contention(&exec, r);
>>>>>> if (unlikely(r))
>>>>>> goto out_unlock;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>> b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>> index 386875e6eb96..a3aa7fd22f6a 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>> @@ -1499,7 +1499,7 @@ static int svm_range_reserve_bos(struct
>>>>>> svm_validate_context *ctx, bool intr)
>>>>>> vm = drm_priv_to_vm(pdd->drm_priv);
>>>>>>
>>>>>> r = amdgpu_vm_lock_pd(vm, &ctx-
>>>>>>> exec,
>>>>>> 2);
>>>>>> - drm_exec_retry_on_contention(&ctx-
>>>>>>> exec);
>>>>>> + r =
>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>> exec, r);
>>>>>> if (unlikely(r)) {
>>>>>> pr_debug("failed %d to
>>>>>> reserve
>>>>>> bo\n", r);
>>>>>> goto unreserve_out;
>>>>>> diff --git a/drivers/gpu/drm/drm_exec.c
>>>>>> b/drivers/gpu/drm/drm_exec.c
>>>>>> index 2da094bdf8a4..3770a5d30213 100644
>>>>>> --- a/drivers/gpu/drm/drm_exec.c
>>>>>> +++ b/drivers/gpu/drm/drm_exec.c
>>>>>> @@ -28,12 +28,12 @@
>>>>>> * drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
>>>>>> * drm_exec_until_all_locked(&exec) {
>>>>>> * ret = drm_exec_prepare_obj(&exec, boA, 1);
>>>>>> - * drm_exec_retry_on_contention(&exec);
>>>>>> + * ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> * if (ret)
>>>>>> * goto error;
>>>>>> *
>>>>>> * ret = drm_exec_prepare_obj(&exec, boB, 1);
>>>>>> - * drm_exec_retry_on_contention(&exec);
>>>>>> + * ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> * if (ret)
>>>>>> * goto error;
>>>>>> * }
>>>>>> @@ -48,7 +48,8 @@
>>>>>> */
>>>>>>
>>>>>> /* Dummy value used to initially enter the retry loop */
>>>>>> -#define DRM_EXEC_DUMMY ((void *)~0)
>>>>>> +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
>>>>>> +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
>>>>>>
>>>>>> /* Unlock all objects and drop references */
>>>>>> static void drm_exec_unlock_all(struct drm_exec *exec)
>>>>>> @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec
>>>>>> *exec)
>>>>>> return true;
>>>>>> }
>>>>>>
>>>>>> - drm_exec_unlock_all(exec);
>>>>>> - exec->num_objects = 0;
>>>>>> + exec->contended = NULL;
>>>>>> return true;
>>>>>> }
>>>>>> EXPORT_SYMBOL(drm_exec_cleanup);
>>>>>> @@ -194,6 +194,27 @@ static int
>>>>>> drm_exec_lock_contended(struct
>>>>>> drm_exec *exec)
>>>>>> return ret;
>>>>>> }
>>>>>>
>>>>>> +/**
>>>>>> + * drm_exec_handle_contended() - Perform cleanup before a ww
>>>>>> transaction restart
>>>>>> + * @exec: Pointer to the drm_exec object.
>>>>>> + *
>>>>>> + * Unlocks all held resvs and re-locks the contended object.
>>>>>> + *
>>>>>> + * Return: 0 on success, negative error code on failure.
>>>>>> + */
>>>>>> +int drm_exec_handle_contended(struct drm_exec *exec)
>>>>>> +{
>>>>>> + int ret;
>>>>>> +
>>>>>> + drm_exec_unlock_all(exec);
>>>>>> + exec->num_objects = 0;
>>>>>> + ret = drm_exec_lock_contended(exec);
>>>>>> + exec->contended = DRM_EXEC_CONTENDED;
>>>>>> +
>>>>>> + return ret;
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(drm_exec_handle_contended);
>>>>>> +
>>>>>> /**
>>>>>> * drm_exec_lock_obj - lock a GEM object for use
>>>>>> * @exec: the drm_exec object with the state
>>>>>> @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct drm_exec
>>>>>> *exec,
>>>>>> struct drm_gem_object *obj)
>>>>>> {
>>>>>> int ret;
>>>>>>
>>>>>> - ret = drm_exec_lock_contended(exec);
>>>>>> - if (unlikely(ret))
>>>>>> - return ret;
>>>>>> -
>>>>>> if (exec->prelocked == obj) {
>>>>>> drm_gem_object_put(exec->prelocked);
>>>>>> exec->prelocked = NULL;
>>>>>> diff --git a/drivers/gpu/drm/drm_gpuvm.c
>>>>>> b/drivers/gpu/drm/drm_gpuvm.c
>>>>>> index f9eb56f24bef..0923d6ae18e2 100644
>>>>>> --- a/drivers/gpu/drm/drm_gpuvm.c
>>>>>> +++ b/drivers/gpu/drm/drm_gpuvm.c
>>>>>> @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
>>>>>> drm_gpuvm_exec
>>>>>> *vm_exec)
>>>>>>
>>>>>> drm_exec_until_all_locked(exec) {
>>>>>> ret = drm_gpuvm_prepare_vm(gpuvm, exec,
>>>>>> num_fences);
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> goto err;
>>>>>>
>>>>>> ret = drm_gpuvm_prepare_objects(gpuvm, exec,
>>>>>> num_fences);
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> goto err;
>>>>>>
>>>>>> if (vm_exec->extra.fn) {
>>>>>> ret = vm_exec->extra.fn(vm_exec);
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> goto err;
>>>>>> }
>>>>>> @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
>>>>>> drm_gpuvm_exec *vm_exec,
>>>>>> drm_exec_until_all_locked(exec) {
>>>>>> ret = drm_gpuvm_prepare_range(gpuvm, exec,
>>>>>> addr,
>>>>>> range,
>>>>>> vm_exec-
>>>>>>> num_fences);
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> goto err;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/imagination/pvr_job.c
>>>>>> b/drivers/gpu/drm/imagination/pvr_job.c
>>>>>> index 78c2f3c6dce0..6e0ce6c4576c 100644
>>>>>> --- a/drivers/gpu/drm/imagination/pvr_job.c
>>>>>> +++ b/drivers/gpu/drm/imagination/pvr_job.c
>>>>>> @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct
>>>>>> drm_exec
>>>>>> *exec, struct pvr_job_data *job_data,
>>>>>> drm_exec_until_all_locked(exec) {
>>>>>> int err = jobs_lock_all_objs(exec, job_data,
>>>>>> job_count);
>>>>>>
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + err = drm_exec_retry_on_contention(exec,
>>>>>> err);
>>>>>> if (err)
>>>>>> return err;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>> b/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>> index fba78193127d..01992b43ea4b 100644
>>>>>> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>> @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
>>>>>> msm_gem_submit *submit)
>>>>>> for (unsigned i = 0; i < submit->nr_bos;
>>>>>> i++)
>>>>>> {
>>>>>> struct drm_gem_object *obj = submit-
>>>>>>> bos[i].obj;
>>>>>> ret = drm_exec_prepare_obj(&submit-
>>>>>>> exec,
>>>>>> obj, 1);
>>>>>> -
>>>>>> drm_exec_retry_on_contention(&submit-
>>>>>>> exec);
>>>>>> + ret =
>>>>>> drm_exec_retry_on_contention(&submit->exec, ret);
>>>>>> if (ret)
>>>>>> goto error;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>> b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>> index ee02cd833c5e..0c871634fdfb 100644
>>>>>> --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>> +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>> @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
>>>>>> nouveau_job *job,
>>>>>> drm_exec_init(exec, vme->flags, 0);
>>>>>> drm_exec_until_all_locked(exec) {
>>>>>> ret = bind_lock_validate(job, exec, vme-
>>>>>>> num_fences);
>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>> ret);
>>>>>> if (ret) {
>>>>>> op = list_last_op(&bind_job->ops);
>>>>>> goto unwind;
>>>>>> diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>> b/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>> index 81f928a429ba..28558fdb08df 100644
>>>>>> --- a/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>> +++ b/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>> @@ -63,7 +63,7 @@ static void test_lock(struct kunit *test)
>>>>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>> 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>> @@ -83,14 +83,14 @@ static void test_lock_unlock(struct kunit
>>>>>> *test)
>>>>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>> 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>>
>>>>>> drm_exec_unlock_obj(&exec, &gobj);
>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>> @@ -110,13 +110,13 @@ static void test_duplicates(struct
>>>>>> kunit
>>>>>> *test)
>>>>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>>
>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>> @@ -137,7 +137,7 @@ static void test_prepare(struct kunit
>>>>>> *test)
>>>>>> drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>> 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = drm_exec_prepare_obj(&exec, &gobj, 1);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>> if (ret)
>>>>>> break;
>>>>>> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>> b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>> index 040dd142c49c..20ec1ab1b52d 100644
>>>>>> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>> @@ -200,7 +200,7 @@ static int handle_pagefault(struct xe_gt
>>>>>> *gt,
>>>>>> struct pagefault *pf)
>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = xe_pf_begin(&exec, vma, atomic, tile-
>>>>>>> id);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> goto unlock_dma_resv;
>>>>>>
>>>>>> @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt *gt,
>>>>>> struct
>>>>>> acc *acc)
>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> ret = xe_pf_begin(&exec, vma, true, tile-
>>>>>>> id);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + ret = drm_exec_retry_on_contention(&exec,
>>>>>> ret);
>>>>>> if (ret)
>>>>>> break;
>>>>>> }
>>>>>> diff --git a/drivers/gpu/drm/xe/xe_vm.c
>>>>>> b/drivers/gpu/drm/xe/xe_vm.c
>>>>>> index e2ec148c9c33..335524e803e7 100644
>>>>>> --- a/drivers/gpu/drm/xe/xe_vm.c
>>>>>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>>>>>> @@ -501,7 +501,7 @@ static void
>>>>>> preempt_rebind_work_func(struct
>>>>>> work_struct *w)
>>>>>> bool done = false;
>>>>>>
>>>>>> err = xe_preempt_work_begin(&exec, vm,
>>>>>> &done);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + err = drm_exec_retry_on_contention(&exec,
>>>>>> err);
>>>>>> if (err || done) {
>>>>>> drm_exec_fini(&exec);
>>>>>> if (err &&
>>>>>> xe_vm_validate_should_retry(&exec, err, &end))
>>>>>> @@ -1052,7 +1052,7 @@ static void
>>>>>> xe_vma_destroy_unlocked(struct
>>>>>> xe_vma *vma)
>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> err = xe_vm_lock_vma(&exec, vma);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + err = drm_exec_retry_on_contention(&exec,
>>>>>> err);
>>>>>> if (XE_WARN_ON(err))
>>>>>> break;
>>>>>> }
>>>>>> @@ -2148,11 +2148,11 @@ static struct xe_vma *new_vma(struct
>>>>>> xe_vm
>>>>>> *vm, struct drm_gpuva_op_map *op,
>>>>>> err = 0;
>>>>>> if (!bo->vm) {
>>>>>> err =
>>>>>> drm_exec_lock_obj(&exec,
>>>>>> xe_vm_obj(vm));
>>>>>> -
>>>>>> drm_exec_retry_on_contention
>>>>>> (&
>>>>>> exec);
>>>>>> + err =
>>>>>> drm_exec_retry_on_contention(&exec, err);
>>>>>> }
>>>>>> if (!err) {
>>>>>> err =
>>>>>> drm_exec_lock_obj(&exec,
>>>>>> &bo->ttm.base);
>>>>>> -
>>>>>> drm_exec_retry_on_contention
>>>>>> (&
>>>>>> exec);
>>>>>> + err =
>>>>>> drm_exec_retry_on_contention(&exec, err);
>>>>>> }
>>>>>> if (err) {
>>>>>> drm_exec_fini(&exec);
>>>>>> @@ -2884,7 +2884,7 @@ static int
>>>>>> vm_bind_ioctl_ops_execute(struct
>>>>>> xe_vm *vm,
>>>>>> DRM_EXEC_IGNORE_DUPLICATES, 0);
>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>> err = vm_bind_ioctl_ops_lock_and_prep(&exec,
>>>>>> vm,
>>>>>> vops);
>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>> + err = drm_exec_retry_on_contention(&exec,
>>>>>> err);
>>>>>> if (err)
>>>>>> goto unlock;
>>>>>>
>>>>>> diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
>>>>>> index aa786b828a0a..fafb40d96e38 100644
>>>>>> --- a/include/drm/drm_exec.h
>>>>>> +++ b/include/drm/drm_exec.h
>>>>>> @@ -51,6 +51,8 @@ struct drm_exec {
>>>>>> struct drm_gem_object *prelocked;
>>>>>> };
>>>>>>
>>>>>> +int drm_exec_handle_contended(struct drm_exec *exec);
>>>>>> +
>>>>>> /**
>>>>>> * drm_exec_obj() - Return the object for a give drm_exec
>>>>>> index
>>>>>> * @exec: Pointer to the drm_exec context
>>>>>> @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
>>>>>> __LINE__): \
>>>>>> /**
>>>>>> * drm_exec_retry_on_contention - restart the loop to grap
>>>>>> all
>>>>>> locks
>>>>>> * @exec: drm_exec object
>>>>>> + * @_ret: The current error status
>>>>>> *
>>>>>> * Control flow helper to continue when a contention was
>>>>>> detected
>>>>>> and we need to
>>>>>> * clean up and re-start the loop to prepare all GEM
>>>>>> objects.
>>>>>> + *
>>>>>> + * Return: If no loop restart occurred: The error status.
>>>>>> */
>>>>>> -#define
>>>>>> drm_exec_retry_on_contention(exec) \
>>>>>> - do
>>>>>> { \
>>>>>> - if
>>>>>> (unlikely(drm_exec_is_contended(exec))) \
>>>>>> - goto
>>>>>> *__drm_exec_retry_ptr; \
>>>>>> - } while (0)
>>>>>> +#define drm_exec_retry_on_contention(exec,
>>>>>> _ret) \
>>>>>> + ({
>>>>>>
>>>>>> \
>>>>>> + struct drm_exec *__exec =
>>>>>> (exec); \
>>>>>> + int __ret =
>>>>>> (_ret); \
>>>>>> +
>>>>>>
>>>>>> \
>>>>>> + if (unlikely(drm_exec_is_contended(__exec)))
>>>>>> { \
>>>>>> + WARN_ON(__ret != -
>>>>>> EDEADLK); \
>>>>>> + __ret =
>>>>>> drm_exec_handle_contended(__exec); \
>>>>>> + if
>>>>>> (!__ret) \
>>>>>> + goto
>>>>>> *__drm_exec_retry_ptr; \
>>>>>> + }
>>>>>>
>>>>>> \
>>>>>> + __ret;
>>>>>>
>>>>>> \
>>>>>> + })
>>>>>>
>>>>>> /**
>>>>>> * drm_exec_is_contended - check for contention
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-28 6:51 ` Christian König
@ 2024-05-28 8:07 ` Thomas Hellström
2024-05-28 11:03 ` Christian König
0 siblings, 1 reply; 50+ messages in thread
From: Thomas Hellström @ 2024-05-28 8:07 UTC (permalink / raw)
To: Christian König, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
On Tue, 2024-05-28 at 08:51 +0200, Christian König wrote:
> Hi Thomas,
>
> Am 28.05.24 um 08:36 schrieb Thomas Hellström:
> > Hi, Christian.
> >
> > I'd appreciate if you could respond to the below, since it is a bit
> > hard to try to design around a problem I don't believe exists, and
> > come
> > up with a good solution for that.
> >
> > In short.
> > 1) To prefault userptr we have to exit the ww transaction anyway.
>
> Yeah and I would rather like to have that handling in drm_exec at
> some time.
>
> Basically a GEM object with outdated struct pages backing it can be
> handled in the same loop at the ww transaction.
OK.
>
> > 2) Any contended lock held at loop start is completely encapsulated
> > in
> > the ww transaction and can and will be unlocked when exiting it, so
> > this patch doesn't introduce any additional problems for userptr
> > handling AFAICT.
>
> The drm_exec object was intentionally design to not have anything
> locked
> at the beginning of the loop. See the discussion I had with Sima
> around
> that when pushing the drm_exec object upstream.
>
> I would really like to stick with that design and honestly don't see
> the
> reason to change that. Contenting on a trylock seem to be much more
> questionable.
The change here is to make sure we *don't* have contention in a
trylock, which is otherwise inherent in the current drm_exec design.
What I'm trying to say here is that we end up with the contended lock
grabbed at loop start you already conceptually have a conflicting lock
held (the we_class::acquire_key). Both these can be resolved.
>
> > 3) The need for a fully capable ww transaction helper moving
> > forward.
> > If we need a tool that also does userptr locking, then I think we
> > need
> > to separate that from the ww transaction tool and only pass the
> > latter
> > around to TTM.
>
> drm_exec is *not* meant to be a ww_transaction helper.
>
> The functionality here is to support drivers in their CS interface
> and
> that includes userptr handling as well as a couple of other things.
Then if so, I don't think drm_exec is the correct functionality to pass
to TTM to resolve the eviction issues, but rather a ww transaction
helper that can be used standalone *and* by drm_exec. Now the
functionality would be more or less what drm exec is today, but
slightly augmented.
But then IMHO instead of changing name and more or less replicating
what drm_exec is today wouldn't it be a better idea to subclass
drm_exec into a full-fledged CS helper at the time when that
functionality is indeed added?
/Thomas
>
> Regards,
> Christian.
>
> >
> > Thanks,
> > Thomas
> >
> > On Wed, 2024-05-22 at 19:42 +0200, Thomas Hellström wrote:
> > > On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
> > > > Am 22.05.24 um 16:32 schrieb Thomas Hellström:
> > > > > On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
> > > > > > Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > > > > > > If contention and backoff occurs during a drm_exec ww
> > > > > > > transaction,
> > > > > > > the contended lock is not locked again until the next
> > > > > > > orinary
> > > > > > > attempt to lock a dma_resv lock. However, with the
> > > > > > > introduction
> > > > > > > of
> > > > > > > drm_exec_trylock(), that doesn't work, since the locking
> > > > > > > of
> > > > > > > the
> > > > > > > contended lock needs to be a sleeping lock. Neither can
> > > > > > > we
> > > > > > > ignore
> > > > > > > locking the contended lock during a trylock since that
> > > > > > > would
> > > > > > > violate
> > > > > > > at least the ww_mutex annotations.
> > > > > > >
> > > > > > > So resolve this by actually locking the contended lock
> > > > > > > during
> > > > > > > drm_exec_retry_on_contention(). However, this introduces
> > > > > > > a
> > > > > > > new
> > > > > > > point
> > > > > > > of failure since locking the contended lock may return -
> > > > > > > EINTR.
> > > > > > >
> > > > > > > Hence drm_exec_retry_on_contention() must take an error
> > > > > > > parameter
> > > > > > > and
> > > > > > > also return a value indicating success.
> > > > > > After thinking more about that I have to pretty clearly NAK
> > > > > > this.
> > > > > >
> > > > > I thought we were beyond upfront NAKing in the first reply :/
> > > > Well my memory could fail me, but I mentioned concerns on this
> > > > approach
> > > > before.
> > > >
> > > > I was a bit annoyed seeing that again. But could as well be
> > > > that my
> > > > response never got out or that I'm mixing things up.
> > > I haven't seen it at least. Last discussion on this I saw was
> > > here. I didn't see a follow-up on that.
> > >
> > > https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
> > >
> > >
> > > > > > It's an intentional design decision to guarantee that at
> > > > > > the
> > > > > > start of
> > > > > > the loop no object is locked.
> > > > > >
> > > > > > This is because Sima and I wanted to integrate userptr
> > > > > > handling
> > > > > > into
> > > > > > drm_exec as well in the long term.
> > > > > First I agree the interface looks worse with this patch.
> > > > > But I thought generic userptr handling were going to end up
> > > > > as a
> > > > > gpuvm
> > > > > helper (without using GEM objects) as we've discussed
> > > > > previously.
> > > > We might be talking past each other. That sounds like SVM, e.g.
> > > > on
> > > > demand paging.
> > > >
> > > > What I mean is pre-faulting during command submission like
> > > > radeon,
> > > > amdgpu and i915 do for the userptr handling.
> > > Yes, then we're talking about the same thing.
> > >
> > > We discussed in this thread here, started by Dave.
> > >
> > > https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
> > >
> > > I still think the right place is in drm_gpuvm for this sort of
> > > stuff.
> > > And I think that's the concluding argument by Sima as well.
> > >
> > > In any case, If the planned drm_exec development is to be a full
> > > execbuf helper, I think we need a capable sub-helper for ONLY the
> > > ww
> > > transaction locking as well, with support for the various locking
> > > primitives. In particular if we're going to be able to port i915
> > > ww
> > > transaction locking over. There are more uses of the ww locking
> > > transacions than execbuf.
> > >
> > > > For that you need to re-start the whole handling similar to how
> > > > you
> > > > need
> > > > to re-start for the mutex locking when you detect that the page
> > > > array
> > > > is
> > > > stale, the difference is that you are not allowed to hold any
> > > > resv
> > > > locks
> > > > while pre-faulting.
> > > >
> > > > That's why it is a requirement that the drm_exec loop starts
> > > > without
> > > > any
> > > > locks held.
> > > But wouldn't you need an outer (userptr) loop and an inner
> > > (ww_transaction) loop for this? Why would we want to re-validate
> > > userptrs on -EDEADLKS?
> > >
> > > > > Anyway if still there would be helpers in drm_exec for some
> > > > > other
> > > > > generic userptr solution, those need to be done before the
> > > > > ww_acquire_ctx_init(). The contended locking here is done
> > > > > after,
> > > > > so
> > > > > I
> > > > > can't really see how these would clash.
> > > > Yes, that indeed was a problem. The ww_acquire_ctx_init() was
> > > > intentionally moved into drm_exec_cleanup() to partially
> > > > prevent
> > > > that
> > > > issue.
> > > >
> > > > I haven't fully figured out how to do handle everything
> > > > exactly,
> > > > but
> > > > at
> > > > least in principle it can be made work. With this change here
> > > > it
> > > > becomes
> > > > impossible.
> > > >
> > > > > Still, If we need to come up with another solution, I think
> > > > > it's
> > > > > fair
> > > > > we clearly sort out why.
> > > > >
> > > > > > I think we should just document that drm_exec_trylock()
> > > > > > can't
> > > > > > be
> > > > > > used
> > > > > > to
> > > > > > lock the first BO in the loop and explicitly WARN if that's
> > > > > > the
> > > > > > case.
> > > > > Unfortunately that's not sufficient for the general use-case.
> > > > > If
> > > > > we
> > > > > want to keep the ttm_bo_vm approach of dropping the mmap lock
> > > > > when
> > > > > there is contention on the bo resv, we need to be able to
> > > > > trylock
> > > > > on
> > > > > first lock.
> > > > Mhm, why exactly do we still have that dance in the first
> > > > place?
> > > >
> > > > I mean we have sorted out the mmap() and dma_resv() locking
> > > > order
> > > > long
> > > > ago. See dma_resv_lockdep() which is enforcing that.
> > > I explained that in my reply here:
> > >
> > > https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
> > >
> > > We shouldn't be holding the mmap lock when waiting for stuff. In
> > > particular not while waiting for mutexes that may be blocked by
> > > gpu
> > > activity.
> > >
> > > > > Also bo creation is using trylock but might be able to use
> > > > > a sleeping lock there. But if that sleeping lock triggers an
> > > > > -
> > > > > EDEADLK
> > > > > (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
> > > > > referencing an
> > > > > object that never was fully created as a contending object.
> > > > I wanted to eliminate that as well by not validating the BO
> > > > during
> > > > initialization any more.
> > > > So bo creation would then be:
> > > >
> > > > ttm_bo_init(bo)
> > > >
> > > > drm_exec_while_not_all_locked() {
> > > > drm_exec_prepare_object(bo, 1);
> > > >
> > > > ttm_bo_validate(bo);
> > > > }
> > > >
> > > > if (r)
> > > > ttm_bo_put(bo);
> > > >
> > > > return r;
> > > >
> > > > I have that on a branch here somewhere prepared, but never got
> > > > the
> > > > time
> > > > to clean it up.
> > > Still, bo creation and validation may be part of a ww transaction
> > > as
> > > well, like page-table bos (Although those are pre-locked so
> > > perhaps
> > > not
> > > a good example). But in the general case, I'm not sure this is
> > > sufficient for all use-cases.
> > >
> > > /Thomas
> > >
> > >
> > >
> > > > Regards,
> > > > Christian.
> > > >
> > > > > So the only really working alternative solution I can see is
> > > > > that
> > > > > drm_exec_trylock simply fails if there is a contended lock
> > > > > and
> > > > > we'd
> > > > > need to live with the weird bo creation situation described
> > > > > above.
> > > > >
> > > > > /Thomas
> > > > >
> > > > > > Regards,
> > > > > > Christian.
> > > > > >
> > > > > > > Cc: Christian König<christian.koenig@amd.com>
> > > > > > > Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
> > > > > > > Cc: Matthew Brost<matthew.brost@intel.com>
> > > > > > > Cc:<dri-devel@lists.freedesktop.org>
> > > > > > > Signed-off-by: Thomas
> > > > > > > Hellström<thomas.hellstrom@linux.intel.com>
> > > > > > > ---
> > > > > > > .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16
> > > > > > > ++++---
> > > > > > > --
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6
> > > > > > > ++--
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +-
> > > > > > > -
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8
> > > > > > > ++---
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8
> > > > > > > ++---
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +-
> > > > > > > -
> > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8
> > > > > > > ++---
> > > > > > > drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
> > > > > > > drivers/gpu/drm/drm_exec.c | 35
> > > > > > > ++++++++++++++-----
> > > > > > > drivers/gpu/drm/drm_gpuvm.c | 8
> > > > > > > ++---
> > > > > > > drivers/gpu/drm/imagination/pvr_job.c | 2 +-
> > > > > > > drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
> > > > > > > drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
> > > > > > > drivers/gpu/drm/tests/drm_exec_test.c | 12
> > > > > > > +++----
> > > > > > > drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +-
> > > > > > > -
> > > > > > > drivers/gpu/drm/xe/xe_vm.c | 10
> > > > > > > +++---
> > > > > > > include/drm/drm_exec.h | 23
> > > > > > > +++++++++---
> > > > > > > 17 files changed, 92 insertions(+), 62 deletions(-)
> > > > > > >
> > > > > > > diff --git
> > > > > > > a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > index e4d4e55c08ad..4a08a692aa1f 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > @@ -1152,12 +1152,12 @@ static int
> > > > > > > reserve_bo_and_vm(struct
> > > > > > > kgd_mem
> > > > > > > *mem,
> > > > > > > drm_exec_init(&ctx->exec,
> > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&ctx->exec) {
> > > > > > > ret = amdgpu_vm_lock_pd(vm, &ctx->exec,
> > > > > > > 2);
> > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > >exec);
> > > > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto error;
> > > > > > >
> > > > > > > ret = drm_exec_prepare_obj(&ctx->exec,
> > > > > > > &bo-
> > > > > > > > tbo.base, 1);
> > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > >exec);
> > > > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto error;
> > > > > > > }
> > > > > > > @@ -1199,14 +1199,14 @@ static int
> > > > > > > reserve_bo_and_cond_vms(struct
> > > > > > > kgd_mem *mem,
> > > > > > >
> > > > > > > ret = amdgpu_vm_lock_pd(entry-
> > > > > > > > bo_va-
> > > > > > > > base.vm,
> > > > > > > &ctx-
> > > > > > > >exec,
> > > > > > > 2);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec, ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto error;
> > > > > > > ++ctx->n_vms;
> > > > > > > }
> > > > > > >
> > > > > > > ret = drm_exec_prepare_obj(&ctx->exec,
> > > > > > > &bo-
> > > > > > > > tbo.base, 1);
> > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > >exec);
> > > > > > > + ret = drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto error;
> > > > > > > }
> > > > > > > @@ -2619,7 +2619,7 @@ static int
> > > > > > > validate_invalid_user_pages(struct
> > > > > > > amdkfd_process_info *process_info)
> > > > > > > list_for_each_entry(peer_vm,
> > > > > > > &process_info-
> > > > > > > > vm_list_head,
> > > > > > > vm_list_node) {
> > > > > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > > > > &exec,
> > > > > > > 2);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto unreserve_out;
> > > > > > > }
> > > > > > > @@ -2631,7 +2631,7 @@ static int
> > > > > > > validate_invalid_user_pages(struct
> > > > > > > amdkfd_process_info *process_info)
> > > > > > >
> > > > > > > gobj = &mem->bo->tbo.base;
> > > > > > > ret =
> > > > > > > drm_exec_prepare_obj(&exec,
> > > > > > > gobj,
> > > > > > > 1);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret))
> > > > > > > goto unreserve_out;
> > > > > > > }
> > > > > > > @@ -2875,7 +2875,7 @@ int
> > > > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
> > > > > > > struct
> > > > > > > dma_fence __rcu *
> > > > > > > list_for_each_entry(peer_vm,
> > > > > > > &process_info-
> > > > > > > > vm_list_head,
> > > > > > > vm_list_node) {
> > > > > > > ret = amdgpu_vm_lock_pd(peer_vm,
> > > > > > > &exec,
> > > > > > > 2);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret)) {
> > > > > > > pr_err("Locking VM PD
> > > > > > > failed,
> > > > > > > ret:
> > > > > > > %d\n", ret);
> > > > > > > goto ttm_reserve_fail;
> > > > > > > @@ -2891,7 +2891,7 @@ int
> > > > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
> > > > > > > struct
> > > > > > > dma_fence __rcu *
> > > > > > >
> > > > > > > gobj = &mem->bo->tbo.base;
> > > > > > > ret =
> > > > > > > drm_exec_prepare_obj(&exec,
> > > > > > > gobj,
> > > > > > > 1);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (unlikely(ret)) {
> > > > > > > pr_err("drm_exec_prepare
> > > > > > > _obj
> > > > > > > failed, ret: %d\n", ret);
> > > > > > > goto ttm_reserve_fail;
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > index ec888fc6ead8..299e46a6d934 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > @@ -897,7 +897,7 @@ static int
> > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > amdgpu_cs_parser *p,
> > > > > > >
> > > > > > > drm_exec_until_all_locked(&p->exec) {
> > > > > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &p-
> > > > > > > >exec,
> > > > > > > 1
> > > > > > > + p-
> > > > > > > > gang_size);
> > > > > > > - drm_exec_retry_on_contention(&p->exec);
> > > > > > > + r = drm_exec_retry_on_contention(&p-
> > > > > > > >exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_free_user_pages;
> > > > > > >
> > > > > > > @@ -905,7 +905,7 @@ static int
> > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > amdgpu_cs_parser *p,
> > > > > > > /* One fence for TTM and one for
> > > > > > > each
> > > > > > > CS
> > > > > > > job */
> > > > > > > r = drm_exec_prepare_obj(&p-
> > > > > > > >exec,
> > > > > > > &e-
> > > > > > > > bo-
> > > > > > > > tbo.base,
> > > > > > > 1 + p-
> > > > > > > > gang_size);
> > > > > > > - drm_exec_retry_on_contention(&p-
> > > > > > > > exec);
> > > > > > > + r =
> > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto
> > > > > > > out_free_user_pages;
> > > > > > >
> > > > > > > @@ -915,7 +915,7 @@ static int
> > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > amdgpu_cs_parser *p,
> > > > > > > if (p->uf_bo) {
> > > > > > > r = drm_exec_prepare_obj(&p-
> > > > > > > >exec,
> > > > > > > &p-
> > > > > > > > uf_bo->tbo.base,
> > > > > > > 1 + p-
> > > > > > > > gang_size);
> > > > > > > - drm_exec_retry_on_contention(&p-
> > > > > > > > exec);
> > > > > > > + r =
> > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto
> > > > > > > out_free_user_pages;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > index cfdf558b48b6..8b2b86c7a6c5 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
> > > > > > > amdgpu_device
> > > > > > > *adev, struct amdgpu_vm *vm,
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > if (likely(!r))
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &bo-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r)) {
> > > > > > > DRM_ERROR("failed to reserve
> > > > > > > CSA,PD
> > > > > > > BOs:
> > > > > > > err=%d\n", r);
> > > > > > > goto error;
> > > > > > > @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
> > > > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > if (likely(!r))
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &bo-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r)) {
> > > > > > > DRM_ERROR("failed to reserve
> > > > > > > CSA,PD
> > > > > > > BOs:
> > > > > > > err=%d\n", r);
> > > > > > > goto error;
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > index 67c234bcf89f..17e16c971e21 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > @@ -239,12 +239,12 @@ static void
> > > > > > > amdgpu_gem_object_close(struct
> > > > > > > drm_gem_object *obj,
> > > > > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > r = drm_exec_prepare_obj(&exec, &bo-
> > > > > > > > tbo.base,
> > > > > > > 1);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > > }
> > > > > > > @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct
> > > > > > > drm_device
> > > > > > > *dev, void *data,
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > if (gobj) {
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > gobj);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&exec);
> > > > > > > + r =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error;
> > > > > > > }
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(&fpriv->vm, &exec,
> > > > > > > 2);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > index 5ca5c47ab54e..1b1a5147606e 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > @@ -1221,12 +1221,12 @@ int
> > > > > > > amdgpu_mes_ctx_map_meta_data(struct
> > > > > > > amdgpu_device *adev,
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &ctx_data-
> > > > > > > > meta_data_obj-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error_fini_exec;
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error_fini_exec;
> > > > > > > }
> > > > > > > @@ -1292,12 +1292,12 @@ int
> > > > > > > amdgpu_mes_ctx_unmap_meta_data(struct
> > > > > > > amdgpu_device *adev,
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &ctx_data-
> > > > > > > > meta_data_obj-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > index e22cb2b5cd92..72b8213e352c 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct
> > > > > > > amdgpu_device
> > > > > > > *adev,
> > > > > > > struct amdgpu_vm *vm,
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > if (likely(!r))
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &bo-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error;
> > > > > > > }
> > > > > > > @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
> > > > > > > amdgpu_device
> > > > > > > *adev, struct amdgpu_fpriv *fpriv)
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > if (likely(!r))
> > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > &bo-
> > > > > > > > tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > index e01c1c8e64c4..63392ce43945 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > @@ -89,12 +89,12 @@ static int map_ring_data(struct
> > > > > > > amdgpu_device
> > > > > > > *adev, struct amdgpu_vm *vm,
> > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > > >tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error_fini_exec;
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto error_fini_exec;
> > > > > > > }
> > > > > > > @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
> > > > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > > >tbo.base);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + r = drm_exec_retry_on_contention(&exec,
> > > > > > > r);
> > > > > > > if (unlikely(r))
> > > > > > > goto out_unlock;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > index 386875e6eb96..a3aa7fd22f6a 100644
> > > > > > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > @@ -1499,7 +1499,7 @@ static int
> > > > > > > svm_range_reserve_bos(struct
> > > > > > > svm_validate_context *ctx, bool intr)
> > > > > > > vm = drm_priv_to_vm(pdd-
> > > > > > > >drm_priv);
> > > > > > >
> > > > > > > r = amdgpu_vm_lock_pd(vm, &ctx-
> > > > > > > > exec,
> > > > > > > 2);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec);
> > > > > > > + r =
> > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > exec, r);
> > > > > > > if (unlikely(r)) {
> > > > > > > pr_debug("failed %d to
> > > > > > > reserve
> > > > > > > bo\n", r);
> > > > > > > goto unreserve_out;
> > > > > > > diff --git a/drivers/gpu/drm/drm_exec.c
> > > > > > > b/drivers/gpu/drm/drm_exec.c
> > > > > > > index 2da094bdf8a4..3770a5d30213 100644
> > > > > > > --- a/drivers/gpu/drm/drm_exec.c
> > > > > > > +++ b/drivers/gpu/drm/drm_exec.c
> > > > > > > @@ -28,12 +28,12 @@
> > > > > > > * drm_exec_init(&exec,
> > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT);
> > > > > > > * drm_exec_until_all_locked(&exec) {
> > > > > > > * ret = drm_exec_prepare_obj(&exec, boA,
> > > > > > > 1);
> > > > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > > > + * ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > * if (ret)
> > > > > > > * goto error;
> > > > > > > *
> > > > > > > * ret = drm_exec_prepare_obj(&exec, boB,
> > > > > > > 1);
> > > > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > > > + * ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > * if (ret)
> > > > > > > * goto error;
> > > > > > > * }
> > > > > > > @@ -48,7 +48,8 @@
> > > > > > > */
> > > > > > >
> > > > > > > /* Dummy value used to initially enter the retry loop
> > > > > > > */
> > > > > > > -#define DRM_EXEC_DUMMY ((void *)~0)
> > > > > > > +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> > > > > > > +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
> > > > > > >
> > > > > > > /* Unlock all objects and drop references */
> > > > > > > static void drm_exec_unlock_all(struct drm_exec
> > > > > > > *exec)
> > > > > > > @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec
> > > > > > > *exec)
> > > > > > > return true;
> > > > > > > }
> > > > > > >
> > > > > > > - drm_exec_unlock_all(exec);
> > > > > > > - exec->num_objects = 0;
> > > > > > > + exec->contended = NULL;
> > > > > > > return true;
> > > > > > > }
> > > > > > > EXPORT_SYMBOL(drm_exec_cleanup);
> > > > > > > @@ -194,6 +194,27 @@ static int
> > > > > > > drm_exec_lock_contended(struct
> > > > > > > drm_exec *exec)
> > > > > > > return ret;
> > > > > > > }
> > > > > > >
> > > > > > > +/**
> > > > > > > + * drm_exec_handle_contended() - Perform cleanup before
> > > > > > > a ww
> > > > > > > transaction restart
> > > > > > > + * @exec: Pointer to the drm_exec object.
> > > > > > > + *
> > > > > > > + * Unlocks all held resvs and re-locks the contended
> > > > > > > object.
> > > > > > > + *
> > > > > > > + * Return: 0 on success, negative error code on failure.
> > > > > > > + */
> > > > > > > +int drm_exec_handle_contended(struct drm_exec *exec)
> > > > > > > +{
> > > > > > > + int ret;
> > > > > > > +
> > > > > > > + drm_exec_unlock_all(exec);
> > > > > > > + exec->num_objects = 0;
> > > > > > > + ret = drm_exec_lock_contended(exec);
> > > > > > > + exec->contended = DRM_EXEC_CONTENDED;
> > > > > > > +
> > > > > > > + return ret;
> > > > > > > +}
> > > > > > > +EXPORT_SYMBOL(drm_exec_handle_contended);
> > > > > > > +
> > > > > > > /**
> > > > > > > * drm_exec_lock_obj - lock a GEM object for use
> > > > > > > * @exec: the drm_exec object with the state
> > > > > > > @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct
> > > > > > > drm_exec
> > > > > > > *exec,
> > > > > > > struct drm_gem_object *obj)
> > > > > > > {
> > > > > > > int ret;
> > > > > > >
> > > > > > > - ret = drm_exec_lock_contended(exec);
> > > > > > > - if (unlikely(ret))
> > > > > > > - return ret;
> > > > > > > -
> > > > > > > if (exec->prelocked == obj) {
> > > > > > > drm_gem_object_put(exec->prelocked);
> > > > > > > exec->prelocked = NULL;
> > > > > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > b/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > index f9eb56f24bef..0923d6ae18e2 100644
> > > > > > > --- a/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
> > > > > > > drm_gpuvm_exec
> > > > > > > *vm_exec)
> > > > > > >
> > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > ret = drm_gpuvm_prepare_vm(gpuvm, exec,
> > > > > > > num_fences);
> > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > goto err;
> > > > > > >
> > > > > > > ret = drm_gpuvm_prepare_objects(gpuvm,
> > > > > > > exec,
> > > > > > > num_fences);
> > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > goto err;
> > > > > > >
> > > > > > > if (vm_exec->extra.fn) {
> > > > > > > ret = vm_exec-
> > > > > > > >extra.fn(vm_exec);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > goto err;
> > > > > > > }
> > > > > > > @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
> > > > > > > drm_gpuvm_exec *vm_exec,
> > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > ret = drm_gpuvm_prepare_range(gpuvm,
> > > > > > > exec,
> > > > > > > addr,
> > > > > > > range,
> > > > > > > vm_exec-
> > > > > > > > num_fences);
> > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > goto err;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > index 78c2f3c6dce0..6e0ce6c4576c 100644
> > > > > > > --- a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > +++ b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct
> > > > > > > drm_exec
> > > > > > > *exec, struct pvr_job_data *job_data,
> > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > int err = jobs_lock_all_objs(exec,
> > > > > > > job_data,
> > > > > > > job_count);
> > > > > > >
> > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > + err = drm_exec_retry_on_contention(exec,
> > > > > > > err);
> > > > > > > if (err)
> > > > > > > return err;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > index fba78193127d..01992b43ea4b 100644
> > > > > > > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
> > > > > > > msm_gem_submit *submit)
> > > > > > > for (unsigned i = 0; i < submit->nr_bos;
> > > > > > > i++)
> > > > > > > {
> > > > > > > struct drm_gem_object *obj =
> > > > > > > submit-
> > > > > > > > bos[i].obj;
> > > > > > > ret =
> > > > > > > drm_exec_prepare_obj(&submit-
> > > > > > > > exec,
> > > > > > > obj, 1);
> > > > > > > -
> > > > > > > drm_exec_retry_on_contention(&su
> > > > > > > bmit-
> > > > > > > > exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&submit->exec, ret);
> > > > > > > if (ret)
> > > > > > > goto error;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > index ee02cd833c5e..0c871634fdfb 100644
> > > > > > > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
> > > > > > > nouveau_job *job,
> > > > > > > drm_exec_init(exec, vme->flags, 0);
> > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > ret = bind_lock_validate(job, exec, vme-
> > > > > > > > num_fences);
> > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > + ret = drm_exec_retry_on_contention(exec,
> > > > > > > ret);
> > > > > > > if (ret) {
> > > > > > > op = list_last_op(&bind_job-
> > > > > > > >ops);
> > > > > > > goto unwind;
> > > > > > > diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > index 81f928a429ba..28558fdb08df 100644
> > > > > > > --- a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > @@ -63,7 +63,7 @@ static void test_lock(struct kunit
> > > > > > > *test)
> > > > > > > drm_exec_init(&exec,
> > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > > @@ -83,14 +83,14 @@ static void test_lock_unlock(struct
> > > > > > > kunit
> > > > > > > *test)
> > > > > > > drm_exec_init(&exec,
> > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > >
> > > > > > > drm_exec_unlock_obj(&exec, &gobj);
> > > > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > > @@ -110,13 +110,13 @@ static void test_duplicates(struct
> > > > > > > kunit
> > > > > > > *test)
> > > > > > > drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > >
> > > > > > > ret = drm_exec_lock_obj(&exec, &gobj);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > > @@ -137,7 +137,7 @@ static void test_prepare(struct kunit
> > > > > > > *test)
> > > > > > > drm_exec_init(&exec,
> > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = drm_exec_prepare_obj(&exec, &gobj,
> > > > > > > 1);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > index 040dd142c49c..20ec1ab1b52d 100644
> > > > > > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > @@ -200,7 +200,7 @@ static int handle_pagefault(struct
> > > > > > > xe_gt
> > > > > > > *gt,
> > > > > > > struct pagefault *pf)
> > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = xe_pf_begin(&exec, vma, atomic,
> > > > > > > tile-
> > > > > > > > id);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > goto unlock_dma_resv;
> > > > > > >
> > > > > > > @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt
> > > > > > > *gt,
> > > > > > > struct
> > > > > > > acc *acc)
> > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > ret = xe_pf_begin(&exec, vma, true,
> > > > > > > tile-
> > > > > > > > id);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + ret =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > ret);
> > > > > > > if (ret)
> > > > > > > break;
> > > > > > > }
> > > > > > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > b/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > index e2ec148c9c33..335524e803e7 100644
> > > > > > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > @@ -501,7 +501,7 @@ static void
> > > > > > > preempt_rebind_work_func(struct
> > > > > > > work_struct *w)
> > > > > > > bool done = false;
> > > > > > >
> > > > > > > err = xe_preempt_work_begin(&exec, vm,
> > > > > > > &done);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + err =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > err);
> > > > > > > if (err || done) {
> > > > > > > drm_exec_fini(&exec);
> > > > > > > if (err &&
> > > > > > > xe_vm_validate_should_retry(&exec, err, &end))
> > > > > > > @@ -1052,7 +1052,7 @@ static void
> > > > > > > xe_vma_destroy_unlocked(struct
> > > > > > > xe_vma *vma)
> > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > err = xe_vm_lock_vma(&exec, vma);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + err =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > err);
> > > > > > > if (XE_WARN_ON(err))
> > > > > > > break;
> > > > > > > }
> > > > > > > @@ -2148,11 +2148,11 @@ static struct xe_vma
> > > > > > > *new_vma(struct
> > > > > > > xe_vm
> > > > > > > *vm, struct drm_gpuva_op_map *op,
> > > > > > > err = 0;
> > > > > > > if (!bo->vm) {
> > > > > > > err =
> > > > > > > drm_exec_lock_obj(&exec,
> > > > > > > xe_vm_obj(vm));
> > > > > > > -
> > > > > > > drm_exec_retry_on_conten
> > > > > > > tion
> > > > > > > (&
> > > > > > > exec);
> > > > > > > + err =
> > > > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > > > }
> > > > > > > if (!err) {
> > > > > > > err =
> > > > > > > drm_exec_lock_obj(&exec,
> > > > > > > &bo->ttm.base);
> > > > > > > -
> > > > > > > drm_exec_retry_on_conten
> > > > > > > tion
> > > > > > > (&
> > > > > > > exec);
> > > > > > > + err =
> > > > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > > > }
> > > > > > > if (err) {
> > > > > > > drm_exec_fini(&exec);
> > > > > > > @@ -2884,7 +2884,7 @@ static int
> > > > > > > vm_bind_ioctl_ops_execute(struct
> > > > > > > xe_vm *vm,
> > > > > > > DRM_EXEC_IGNORE_DUPLICATES, 0);
> > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > err =
> > > > > > > vm_bind_ioctl_ops_lock_and_prep(&exec,
> > > > > > > vm,
> > > > > > > vops);
> > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > + err =
> > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > err);
> > > > > > > if (err)
> > > > > > > goto unlock;
> > > > > > >
> > > > > > > diff --git a/include/drm/drm_exec.h
> > > > > > > b/include/drm/drm_exec.h
> > > > > > > index aa786b828a0a..fafb40d96e38 100644
> > > > > > > --- a/include/drm/drm_exec.h
> > > > > > > +++ b/include/drm/drm_exec.h
> > > > > > > @@ -51,6 +51,8 @@ struct drm_exec {
> > > > > > > struct drm_gem_object *prelocked;
> > > > > > > };
> > > > > > >
> > > > > > > +int drm_exec_handle_contended(struct drm_exec *exec);
> > > > > > > +
> > > > > > > /**
> > > > > > > * drm_exec_obj() - Return the object for a give
> > > > > > > drm_exec
> > > > > > > index
> > > > > > > * @exec: Pointer to the drm_exec context
> > > > > > > @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
> > > > > > > __LINE__): \
> > > > > > > /**
> > > > > > > * drm_exec_retry_on_contention - restart the loop to
> > > > > > > grap
> > > > > > > all
> > > > > > > locks
> > > > > > > * @exec: drm_exec object
> > > > > > > + * @_ret: The current error status
> > > > > > > *
> > > > > > > * Control flow helper to continue when a contention
> > > > > > > was
> > > > > > > detected
> > > > > > > and we need to
> > > > > > > * clean up and re-start the loop to prepare all GEM
> > > > > > > objects.
> > > > > > > + *
> > > > > > > + * Return: If no loop restart occurred: The error
> > > > > > > status.
> > > > > > > */
> > > > > > > -#define
> > > > > > > drm_exec_retry_on_contention(exec) \
> > > > > > > - do
> > > > > > > { \
> > > > > > > - if
> > > > > > > (unlikely(drm_exec_is_contended(exec))) \
> > > > > > > - goto
> > > > > > > *__drm_exec_retry_ptr; \
> > > > > > > - } while (0)
> > > > > > > +#define drm_exec_retry_on_contention(exec,
> > > > > > > _ret) \
> > > > > > > + ({
> > > > > > >
> > > > > > > \
> > > > > > > + struct drm_exec *__exec =
> > > > > > > (exec); \
> > > > > > > + int __ret =
> > > > > > > (_ret); \
> > > > > > > +
> > > > > > >
> > > > > > > \
> > > > > > > + if
> > > > > > > (unlikely(drm_exec_is_contended(__exec)))
> > > > > > > { \
> > > > > > > + WARN_ON(__ret != -
> > > > > > > EDEADLK); \
> > > > > > > + __ret =
> > > > > > > drm_exec_handle_contended(__exec); \
> > > > > > > + if
> > > > > > > (!__ret) \
> > > > > > > + goto
> > > > > > > *__drm_exec_retry_ptr; \
> > > > > > > + }
> > > > > > >
> > > > > > > \
> > > > > > > + __ret;
> > > > > > >
> > > > > > > \
> > > > > > > + })
> > > > > > >
> > > > > > > /**
> > > > > > > * drm_exec_is_contended - check for contention
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
2024-05-21 13:12 ` Matthew Brost
@ 2024-05-28 9:16 ` Christian König
1 sibling, 0 replies; 50+ messages in thread
From: Christian König @ 2024-05-28 9:16 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> To be able to handle list unlocking while traversing the LRU
> list, we want the iterators not only to point to the next
> position of the list traversal, but to insert themselves as
> list nodes at that point to work around the fact that the
> next node might otherwise disappear from the list while
> the iterator is pointing to it.
>
> These list nodes need to be easily distinguishable from other
> list nodes so that others traversing the list can skip
> over them.
>
> So declare a struct ttm_lru_item, with a struct list_head member
> and a type enum. This will slightly increase the size of a
> struct ttm_resource.
>
> Changes in previous series:
> - Update enum ttm_lru_item_type documentation.
> v3:
> - Introduce ttm_lru_first_res_or_null()
> (Christian König, Thomas Hellström)
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/ttm/ttm_device.c | 4 +-
> drivers/gpu/drm/ttm/ttm_resource.c | 89 +++++++++++++++++++++++-------
> include/drm/ttm/ttm_resource.h | 54 +++++++++++++++++-
> 3 files changed, 125 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
> index 434cf0258000..09411978a13a 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -274,14 +274,14 @@ static void ttm_device_clear_lru_dma_mappings(struct ttm_device *bdev,
> struct ttm_resource *res;
>
> spin_lock(&bdev->lru_lock);
> - while ((res = list_first_entry_or_null(list, typeof(*res), lru))) {
> + while ((res = ttm_lru_first_res_or_null(list))) {
> struct ttm_buffer_object *bo = res->bo;
>
> /* Take ref against racing releases once lru_lock is unlocked */
> if (!ttm_bo_get_unless_zero(bo))
> continue;
>
> - list_del_init(&res->lru);
> + list_del_init(&bo->resource->lru.link);
> spin_unlock(&bdev->lru_lock);
>
> if (bo->ttm)
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index 4a66b851b67d..db9a7a3717c4 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -70,8 +70,8 @@ void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk)
> dma_resv_assert_held(pos->last->bo->base.resv);
>
> man = ttm_manager_type(pos->first->bo->bdev, i);
> - list_bulk_move_tail(&man->lru[j], &pos->first->lru,
> - &pos->last->lru);
> + list_bulk_move_tail(&man->lru[j], &pos->first->lru.link,
> + &pos->last->lru.link);
> }
> }
> }
> @@ -84,14 +84,38 @@ ttm_lru_bulk_move_pos(struct ttm_lru_bulk_move *bulk, struct ttm_resource *res)
> return &bulk->pos[res->mem_type][res->bo->priority];
> }
>
> +/* Return the previous resource on the list (skip over non-resource list items) */
> +static struct ttm_resource *ttm_lru_prev_res(struct ttm_resource *cur)
> +{
> + struct ttm_lru_item *lru = &cur->lru;
> +
> + do {
> + lru = list_prev_entry(lru, link);
> + } while (!ttm_lru_item_is_res(lru));
> +
> + return ttm_lru_item_to_res(lru);
> +}
> +
> +/* Return the next resource on the list (skip over non-resource list items) */
> +static struct ttm_resource *ttm_lru_next_res(struct ttm_resource *cur)
> +{
> + struct ttm_lru_item *lru = &cur->lru;
> +
> + do {
> + lru = list_next_entry(lru, link);
> + } while (!ttm_lru_item_is_res(lru));
> +
> + return ttm_lru_item_to_res(lru);
> +}
> +
> /* Move the resource to the tail of the bulk move range */
> static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
> struct ttm_resource *res)
> {
> if (pos->last != res) {
> if (pos->first == res)
> - pos->first = list_next_entry(res, lru);
> - list_move(&res->lru, &pos->last->lru);
> + pos->first = ttm_lru_next_res(res);
> + list_move(&res->lru.link, &pos->last->lru.link);
> pos->last = res;
> }
> }
> @@ -122,11 +146,11 @@ static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
> pos->first = NULL;
> pos->last = NULL;
> } else if (pos->first == res) {
> - pos->first = list_next_entry(res, lru);
> + pos->first = ttm_lru_next_res(res);
> } else if (pos->last == res) {
> - pos->last = list_prev_entry(res, lru);
> + pos->last = ttm_lru_prev_res(res);
> } else {
> - list_move(&res->lru, &pos->last->lru);
> + list_move(&res->lru.link, &pos->last->lru.link);
> }
> }
>
> @@ -155,7 +179,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
> lockdep_assert_held(&bo->bdev->lru_lock);
>
> if (bo->pin_count) {
> - list_move_tail(&res->lru, &bdev->pinned);
> + list_move_tail(&res->lru.link, &bdev->pinned);
>
> } else if (bo->bulk_move) {
> struct ttm_lru_bulk_move_pos *pos =
> @@ -166,7 +190,7 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
> struct ttm_resource_manager *man;
>
> man = ttm_manager_type(bdev, res->mem_type);
> - list_move_tail(&res->lru, &man->lru[bo->priority]);
> + list_move_tail(&res->lru.link, &man->lru[bo->priority]);
> }
> }
>
> @@ -197,9 +221,9 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
> man = ttm_manager_type(bo->bdev, place->mem_type);
> spin_lock(&bo->bdev->lru_lock);
> if (bo->pin_count)
> - list_add_tail(&res->lru, &bo->bdev->pinned);
> + list_add_tail(&res->lru.link, &bo->bdev->pinned);
> else
> - list_add_tail(&res->lru, &man->lru[bo->priority]);
> + list_add_tail(&res->lru.link, &man->lru[bo->priority]);
> man->usage += res->size;
> spin_unlock(&bo->bdev->lru_lock);
> }
> @@ -221,7 +245,7 @@ void ttm_resource_fini(struct ttm_resource_manager *man,
> struct ttm_device *bdev = man->bdev;
>
> spin_lock(&bdev->lru_lock);
> - list_del_init(&res->lru);
> + list_del_init(&res->lru.link);
> man->usage -= res->size;
> spin_unlock(&bdev->lru_lock);
> }
> @@ -472,14 +496,16 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor)
> {
> - struct ttm_resource *res;
> + struct ttm_lru_item *lru;
>
> lockdep_assert_held(&man->bdev->lru_lock);
>
> for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
> ++cursor->priority)
> - list_for_each_entry(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> return NULL;
> }
> @@ -498,15 +524,40 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor,
> struct ttm_resource *res)
> {
> + struct ttm_lru_item *lru = &res->lru;
> +
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - list_for_each_entry_continue(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
> ++cursor->priority)
> - list_for_each_entry(res, &man->lru[cursor->priority], lru)
> - return res;
> + list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru))
> + ttm_lru_item_to_res(lru);
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + * ttm_lru_first_res_or_null() - Return the first resource on an lru list
> + * @head: The list head of the lru list.
> + *
> + * Return: Pointer to the first resource on the lru list or NULL if
> + * there is none.
> + */
> +struct ttm_resource *ttm_lru_first_res_or_null(struct list_head *head)
> +{
> + struct ttm_lru_item *lru;
> +
> + list_for_each_entry(lru, head, link) {
> + if (ttm_lru_item_is_res(lru))
> + return ttm_lru_item_to_res(lru);
> + }
>
> return NULL;
> }
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index 69769355139f..1511d91e290d 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -49,6 +49,43 @@ struct io_mapping;
> struct sg_table;
> struct scatterlist;
>
> +/**
> + * enum ttm_lru_item_type - enumerate ttm_lru_item subclasses
> + */
> +enum ttm_lru_item_type {
> + /** @TTM_LRU_RESOURCE: The resource subclass */
> + TTM_LRU_RESOURCE,
> + /** @TTM_LRU_HITCH: The iterator hitch subclass */
> + TTM_LRU_HITCH
> +};
> +
> +/**
> + * struct ttm_lru_item - The TTM lru list node base class
> + * @link: The list link
> + * @type: The subclass type
> + */
> +struct ttm_lru_item {
> + struct list_head link;
> + enum ttm_lru_item_type type;
> +};
> +
> +/**
> + * ttm_lru_item_init() - initialize a struct ttm_lru_item
> + * @item: The item to initialize
> + * @type: The subclass type
> + */
> +static inline void ttm_lru_item_init(struct ttm_lru_item *item,
> + enum ttm_lru_item_type type)
> +{
> + item->type = type;
> + INIT_LIST_HEAD(&item->link);
> +}
> +
> +static inline bool ttm_lru_item_is_res(const struct ttm_lru_item *item)
> +{
> + return item->type == TTM_LRU_RESOURCE;
> +}
> +
> struct ttm_resource_manager_func {
> /**
> * struct ttm_resource_manager_func member alloc
> @@ -217,9 +254,21 @@ struct ttm_resource {
> /**
> * @lru: Least recently used list, see &ttm_resource_manager.lru
> */
> - struct list_head lru;
> + struct ttm_lru_item lru;
> };
>
> +/**
> + * ttm_lru_item_to_res() - Downcast a struct ttm_lru_item to a struct ttm_resource
> + * @item: The struct ttm_lru_item to downcast
> + *
> + * Return: Pointer to the embedding struct ttm_resource
> + */
> +static inline struct ttm_resource *
> +ttm_lru_item_to_res(struct ttm_lru_item *item)
> +{
> + return container_of(item, struct ttm_resource, lru);
> +}
> +
> /**
> * struct ttm_resource_cursor
> *
> @@ -393,6 +442,9 @@ ttm_resource_manager_next(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor,
> struct ttm_resource *res);
>
> +struct ttm_resource *
> +ttm_lru_first_res_or_null(struct list_head *head);
> +
> /**
> * ttm_resource_manager_for_each_res - iterate over all resources
> * @man: the resource manager
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration
2024-05-21 7:16 ` [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration Thomas Hellström
2024-05-21 15:39 ` Matthew Brost
@ 2024-05-28 9:19 ` Christian König
1 sibling, 0 replies; 50+ messages in thread
From: Christian König @ 2024-05-28 9:19 UTC (permalink / raw)
To: Thomas Hellström, intel-xe
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel
Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> To make the transition to using lru hitches easier,
> simplify the ttm_resource_manager_next() interface to only take
> the cursor and reuse ttm_resource_manager_next() functionality
> from ttm_resource_manager_first().
>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Somalapuram Amaranath <Amaranath.Somalapuram@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: <dri-devel@lists.freedesktop.org>
> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/ttm/ttm_resource.c | 48 +++++++++++++-----------------
> include/drm/ttm/ttm_resource.h | 10 ++++---
> 2 files changed, 27 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index db9a7a3717c4..8bfbddddc0e8 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -496,50 +496,44 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor)
> {
> - struct ttm_lru_item *lru;
> -
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
> - ++cursor->priority)
> - list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - return ttm_lru_item_to_res(lru);
> - }
> -
> - return NULL;
> + cursor->priority = 0;
> + cursor->man = man;
> + cursor->cur = &man->lru[cursor->priority];
> + return ttm_resource_manager_next(cursor);
> }
>
> /**
> * ttm_resource_manager_next
> *
> - * @man: resource manager to iterate over
> * @cursor: cursor to record the position
> - * @res: the current resource pointer
> *
> - * Returns the next resource from the resource manager.
> + * Return: the next resource from the resource manager.
> */
> struct ttm_resource *
> -ttm_resource_manager_next(struct ttm_resource_manager *man,
> - struct ttm_resource_cursor *cursor,
> - struct ttm_resource *res)
> +ttm_resource_manager_next(struct ttm_resource_cursor *cursor)
> {
> - struct ttm_lru_item *lru = &res->lru;
> + struct ttm_resource_manager *man = cursor->man;
> + struct ttm_lru_item *lru;
>
> lockdep_assert_held(&man->bdev->lru_lock);
>
> - list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - return ttm_lru_item_to_res(lru);
> - }
> -
> - for (++cursor->priority; cursor->priority < TTM_MAX_BO_PRIORITY;
> - ++cursor->priority)
> - list_for_each_entry(lru, &man->lru[cursor->priority], link) {
> - if (ttm_lru_item_is_res(lru))
> - ttm_lru_item_to_res(lru);
> + for (;;) {
> + lru = list_entry(cursor->cur, typeof(*lru), link);
> + list_for_each_entry_continue(lru, &man->lru[cursor->priority], link) {
> + if (ttm_lru_item_is_res(lru)) {
> + cursor->cur = &lru->link;
> + return ttm_lru_item_to_res(lru);
> + }
> }
>
> + if (++cursor->priority >= TTM_MAX_BO_PRIORITY)
> + break;
> +
> + cursor->cur = &man->lru[cursor->priority];
> + }
> +
> return NULL;
> }
>
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index 1511d91e290d..7d81fd5b5b83 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -272,11 +272,15 @@ ttm_lru_item_to_res(struct ttm_lru_item *item)
> /**
> * struct ttm_resource_cursor
> *
> + * @man: The resource manager currently being iterated over.
> + * @cur: The list head the cursor currently points to.
> * @priority: the current priority
> *
> * Cursor to iterate over the resources in a manager.
> */
> struct ttm_resource_cursor {
> + struct ttm_resource_manager *man;
> + struct list_head *cur;
> unsigned int priority;
> };
>
> @@ -438,9 +442,7 @@ struct ttm_resource *
> ttm_resource_manager_first(struct ttm_resource_manager *man,
> struct ttm_resource_cursor *cursor);
> struct ttm_resource *
> -ttm_resource_manager_next(struct ttm_resource_manager *man,
> - struct ttm_resource_cursor *cursor,
> - struct ttm_resource *res);
> +ttm_resource_manager_next(struct ttm_resource_cursor *cursor);
>
> struct ttm_resource *
> ttm_lru_first_res_or_null(struct list_head *head);
> @@ -455,7 +457,7 @@ ttm_lru_first_res_or_null(struct list_head *head);
> */
> #define ttm_resource_manager_for_each_res(man, cursor, res) \
> for (res = ttm_resource_manager_first(man, cursor); res; \
> - res = ttm_resource_manager_next(man, cursor, res))
> + res = ttm_resource_manager_next(cursor))
>
> struct ttm_kmap_iter *
> ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-28 8:07 ` Thomas Hellström
@ 2024-05-28 11:03 ` Christian König
2024-05-29 7:18 ` Thomas Hellström
0 siblings, 1 reply; 50+ messages in thread
From: Christian König @ 2024-05-28 11:03 UTC (permalink / raw)
To: Thomas Hellström
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel, intel-xe
[-- Attachment #1: Type: text/plain, Size: 45545 bytes --]
Am 28.05.24 um 10:07 schrieb Thomas Hellström:
> On Tue, 2024-05-28 at 08:51 +0200, Christian König wrote:
>>> 2) Any contended lock held at loop start is completely encapsulated
>>> in
>>> the ww transaction and can and will be unlocked when exiting it, so
>>> this patch doesn't introduce any additional problems for userptr
>>> handling AFAICT.
>> The drm_exec object was intentionally design to not have anything
>> locked
>> at the beginning of the loop. See the discussion I had with Sima
>> around
>> that when pushing the drm_exec object upstream.
>>
>> I would really like to stick with that design and honestly don't see
>> the
>> reason to change that. Contenting on a trylock seem to be much more
>> questionable.
> The change here is to make sure we *don't* have contention in a
> trylock, which is otherwise inherent in the current drm_exec design.
My sentence was probably a bit misleading. What I wanted to say is that
trylock as first thing in the loop sounds really odd to me.
See the intention of a trylock is to acquire something optional. What we
do for the freshly allocated BO and the 'don't try to block with the
mmap lock held' case is actually kind something different.
A clean approach would be to to have the BO initialization and backing
store allocation steps separated. In this case you don't even need to
use trylock here.
And for the VM fault locking case the clean approach would be to tell
the drm_exec object of the vm_fault parameters so that this helper can
do the drop all locks, drop the mmap lock, acquire the blocking lock and
return -EAGAIN.
This has the huge benefit that we not only stop blocking for the faulted
BO, but eventually all others which might need to move so that the
faulted BO is CPU accessible. I think that this is actually the more
problematic case.
> What I'm trying to say here is that we end up with the contended lock
> grabbed at loop start you already conceptually have a conflicting lock
> held (the we_class::acquire_key). Both these can be resolved.
Yeah, I'm perfectly aware of that. But this is just a shortcoming of
lockdep and not a real problem.
During the drm_exec code review we already moved the ww_acquire_init()
into the cleanup function so that it's only called at the start of the
loop. Background is that we ran into lockdep warnings with that otherwise.
But functionally it would still work if we do this in drm_exec_ini().
>>> 3) The need for a fully capable ww transaction helper moving
>>> forward.
>>> If we need a tool that also does userptr locking, then I think we
>>> need
>>> to separate that from the ww transaction tool and only pass the
>>> latter
>>> around to TTM.
>> drm_exec is *not* meant to be a ww_transaction helper.
>>
>> The functionality here is to support drivers in their CS interface
>> and
>> that includes userptr handling as well as a couple of other things.
> Then if so, I don't think drm_exec is the correct functionality to pass
> to TTM to resolve the eviction issues, but rather a ww transaction
> helper that can be used standalone *and* by drm_exec. Now the
> functionality would be more or less what drm exec is today, but
> slightly augmented.
>
> But then IMHO instead of changing name and more or less replicating
> what drm_exec is today wouldn't it be a better idea to subclass
> drm_exec into a full-fledged CS helper at the time when that
> functionality is indeed added?
Mhm, interesting idea. But it still means that the base object needs to
be designed in a way to not prevent the implementation of the subclass.
Christian.
>
> /Thomas
>
>> Regards,
>> Christian.
>>
>>> Thanks,
>>> Thomas
>>>
>>> On Wed, 2024-05-22 at 19:42 +0200, Thomas Hellström wrote:
>>>> On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
>>>>> Am 22.05.24 um 16:32 schrieb Thomas Hellström:
>>>>>> On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
>>>>>>> Am 21.05.24 um 09:16 schrieb Thomas Hellström:
>>>>>>>> If contention and backoff occurs during a drm_exec ww
>>>>>>>> transaction,
>>>>>>>> the contended lock is not locked again until the next
>>>>>>>> orinary
>>>>>>>> attempt to lock a dma_resv lock. However, with the
>>>>>>>> introduction
>>>>>>>> of
>>>>>>>> drm_exec_trylock(), that doesn't work, since the locking
>>>>>>>> of
>>>>>>>> the
>>>>>>>> contended lock needs to be a sleeping lock. Neither can
>>>>>>>> we
>>>>>>>> ignore
>>>>>>>> locking the contended lock during a trylock since that
>>>>>>>> would
>>>>>>>> violate
>>>>>>>> at least the ww_mutex annotations.
>>>>>>>>
>>>>>>>> So resolve this by actually locking the contended lock
>>>>>>>> during
>>>>>>>> drm_exec_retry_on_contention(). However, this introduces
>>>>>>>> a
>>>>>>>> new
>>>>>>>> point
>>>>>>>> of failure since locking the contended lock may return -
>>>>>>>> EINTR.
>>>>>>>>
>>>>>>>> Hence drm_exec_retry_on_contention() must take an error
>>>>>>>> parameter
>>>>>>>> and
>>>>>>>> also return a value indicating success.
>>>>>>> After thinking more about that I have to pretty clearly NAK
>>>>>>> this.
>>>>>>>
>>>>>> I thought we were beyond upfront NAKing in the first reply :/
>>>>> Well my memory could fail me, but I mentioned concerns on this
>>>>> approach
>>>>> before.
>>>>>
>>>>> I was a bit annoyed seeing that again. But could as well be
>>>>> that my
>>>>> response never got out or that I'm mixing things up.
>>>> I haven't seen it at least. Last discussion on this I saw was
>>>> here. I didn't see a follow-up on that.
>>>>
>>>> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>>>>
>>>>
>>>>>>> It's an intentional design decision to guarantee that at
>>>>>>> the
>>>>>>> start of
>>>>>>> the loop no object is locked.
>>>>>>>
>>>>>>> This is because Sima and I wanted to integrate userptr
>>>>>>> handling
>>>>>>> into
>>>>>>> drm_exec as well in the long term.
>>>>>> First I agree the interface looks worse with this patch.
>>>>>> But I thought generic userptr handling were going to end up
>>>>>> as a
>>>>>> gpuvm
>>>>>> helper (without using GEM objects) as we've discussed
>>>>>> previously.
>>>>> We might be talking past each other. That sounds like SVM, e.g.
>>>>> on
>>>>> demand paging.
>>>>>
>>>>> What I mean is pre-faulting during command submission like
>>>>> radeon,
>>>>> amdgpu and i915 do for the userptr handling.
>>>> Yes, then we're talking about the same thing.
>>>>
>>>> We discussed in this thread here, started by Dave.
>>>>
>>>> https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
>>>>
>>>> I still think the right place is in drm_gpuvm for this sort of
>>>> stuff.
>>>> And I think that's the concluding argument by Sima as well.
>>>>
>>>> In any case, If the planned drm_exec development is to be a full
>>>> execbuf helper, I think we need a capable sub-helper for ONLY the
>>>> ww
>>>> transaction locking as well, with support for the various locking
>>>> primitives. In particular if we're going to be able to port i915
>>>> ww
>>>> transaction locking over. There are more uses of the ww locking
>>>> transacions than execbuf.
>>>>
>>>>> For that you need to re-start the whole handling similar to how
>>>>> you
>>>>> need
>>>>> to re-start for the mutex locking when you detect that the page
>>>>> array
>>>>> is
>>>>> stale, the difference is that you are not allowed to hold any
>>>>> resv
>>>>> locks
>>>>> while pre-faulting.
>>>>>
>>>>> That's why it is a requirement that the drm_exec loop starts
>>>>> without
>>>>> any
>>>>> locks held.
>>>> But wouldn't you need an outer (userptr) loop and an inner
>>>> (ww_transaction) loop for this? Why would we want to re-validate
>>>> userptrs on -EDEADLKS?
>>>>
>>>>>> Anyway if still there would be helpers in drm_exec for some
>>>>>> other
>>>>>> generic userptr solution, those need to be done before the
>>>>>> ww_acquire_ctx_init(). The contended locking here is done
>>>>>> after,
>>>>>> so
>>>>>> I
>>>>>> can't really see how these would clash.
>>>>> Yes, that indeed was a problem. The ww_acquire_ctx_init() was
>>>>> intentionally moved into drm_exec_cleanup() to partially
>>>>> prevent
>>>>> that
>>>>> issue.
>>>>>
>>>>> I haven't fully figured out how to do handle everything
>>>>> exactly,
>>>>> but
>>>>> at
>>>>> least in principle it can be made work. With this change here
>>>>> it
>>>>> becomes
>>>>> impossible.
>>>>>
>>>>>> Still, If we need to come up with another solution, I think
>>>>>> it's
>>>>>> fair
>>>>>> we clearly sort out why.
>>>>>>
>>>>>>> I think we should just document that drm_exec_trylock()
>>>>>>> can't
>>>>>>> be
>>>>>>> used
>>>>>>> to
>>>>>>> lock the first BO in the loop and explicitly WARN if that's
>>>>>>> the
>>>>>>> case.
>>>>>> Unfortunately that's not sufficient for the general use-case.
>>>>>> If
>>>>>> we
>>>>>> want to keep the ttm_bo_vm approach of dropping the mmap lock
>>>>>> when
>>>>>> there is contention on the bo resv, we need to be able to
>>>>>> trylock
>>>>>> on
>>>>>> first lock.
>>>>> Mhm, why exactly do we still have that dance in the first
>>>>> place?
>>>>>
>>>>> I mean we have sorted out the mmap() and dma_resv() locking
>>>>> order
>>>>> long
>>>>> ago. See dma_resv_lockdep() which is enforcing that.
>>>> I explained that in my reply here:
>>>>
>>>> https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
>>>>
>>>> We shouldn't be holding the mmap lock when waiting for stuff. In
>>>> particular not while waiting for mutexes that may be blocked by
>>>> gpu
>>>> activity.
>>>>
>>>>>> Also bo creation is using trylock but might be able to use
>>>>>> a sleeping lock there. But if that sleeping lock triggers an
>>>>>> -
>>>>>> EDEADLK
>>>>>> (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
>>>>>> referencing an
>>>>>> object that never was fully created as a contending object.
>>>>> I wanted to eliminate that as well by not validating the BO
>>>>> during
>>>>> initialization any more.
>>>>> So bo creation would then be:
>>>>>
>>>>> ttm_bo_init(bo)
>>>>>
>>>>> drm_exec_while_not_all_locked() {
>>>>> drm_exec_prepare_object(bo, 1);
>>>>>
>>>>> ttm_bo_validate(bo);
>>>>> }
>>>>>
>>>>> if (r)
>>>>> ttm_bo_put(bo);
>>>>>
>>>>> return r;
>>>>>
>>>>> I have that on a branch here somewhere prepared, but never got
>>>>> the
>>>>> time
>>>>> to clean it up.
>>>> Still, bo creation and validation may be part of a ww transaction
>>>> as
>>>> well, like page-table bos (Although those are pre-locked so
>>>> perhaps
>>>> not
>>>> a good example). But in the general case, I'm not sure this is
>>>> sufficient for all use-cases.
>>>>
>>>> /Thomas
>>>>
>>>>
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> So the only really working alternative solution I can see is
>>>>>> that
>>>>>> drm_exec_trylock simply fails if there is a contended lock
>>>>>> and
>>>>>> we'd
>>>>>> need to live with the weird bo creation situation described
>>>>>> above.
>>>>>>
>>>>>> /Thomas
>>>>>>
>>>>>>> Regards,
>>>>>>> Christian.
>>>>>>>
>>>>>>>> Cc: Christian König<christian.koenig@amd.com>
>>>>>>>> Cc: Somalapuram Amaranath<Amaranath.Somalapuram@amd.com>
>>>>>>>> Cc: Matthew Brost<matthew.brost@intel.com>
>>>>>>>> Cc:<dri-devel@lists.freedesktop.org>
>>>>>>>> Signed-off-by: Thomas
>>>>>>>> Hellström<thomas.hellstrom@linux.intel.com>
>>>>>>>> ---
>>>>>>>> .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16
>>>>>>>> ++++---
>>>>>>>> --
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6
>>>>>>>> ++--
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 +-
>>>>>>>> -
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 8
>>>>>>>> ++---
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 8
>>>>>>>> ++---
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 4 +-
>>>>>>>> -
>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 8
>>>>>>>> ++---
>>>>>>>> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
>>>>>>>> drivers/gpu/drm/drm_exec.c | 35
>>>>>>>> ++++++++++++++-----
>>>>>>>> drivers/gpu/drm/drm_gpuvm.c | 8
>>>>>>>> ++---
>>>>>>>> drivers/gpu/drm/imagination/pvr_job.c | 2 +-
>>>>>>>> drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
>>>>>>>> drivers/gpu/drm/nouveau/nouveau_uvmm.c | 2 +-
>>>>>>>> drivers/gpu/drm/tests/drm_exec_test.c | 12
>>>>>>>> +++----
>>>>>>>> drivers/gpu/drm/xe/xe_gt_pagefault.c | 4 +-
>>>>>>>> -
>>>>>>>> drivers/gpu/drm/xe/xe_vm.c | 10
>>>>>>>> +++---
>>>>>>>> include/drm/drm_exec.h | 23
>>>>>>>> +++++++++---
>>>>>>>> 17 files changed, 92 insertions(+), 62 deletions(-)
>>>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>>>> index e4d4e55c08ad..4a08a692aa1f 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>>>>>>>> @@ -1152,12 +1152,12 @@ static int
>>>>>>>> reserve_bo_and_vm(struct
>>>>>>>> kgd_mem
>>>>>>>> *mem,
>>>>>>>> drm_exec_init(&ctx->exec,
>>>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&ctx->exec) {
>>>>>>>> ret = amdgpu_vm_lock_pd(vm, &ctx->exec,
>>>>>>>> 2);
>>>>>>>> - drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto error;
>>>>>>>>
>>>>>>>> ret = drm_exec_prepare_obj(&ctx->exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base, 1);
>>>>>>>> - drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> @@ -1199,14 +1199,14 @@ static int
>>>>>>>> reserve_bo_and_cond_vms(struct
>>>>>>>> kgd_mem *mem,
>>>>>>>>
>>>>>>>> ret = amdgpu_vm_lock_pd(entry-
>>>>>>>>> bo_va-
>>>>>>>>> base.vm,
>>>>>>>> &ctx-
>>>>>>>>> exec,
>>>>>>>> 2);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec, ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto error;
>>>>>>>> ++ctx->n_vms;
>>>>>>>> }
>>>>>>>>
>>>>>>>> ret = drm_exec_prepare_obj(&ctx->exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base, 1);
>>>>>>>> - drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> @@ -2619,7 +2619,7 @@ static int
>>>>>>>> validate_invalid_user_pages(struct
>>>>>>>> amdkfd_process_info *process_info)
>>>>>>>> list_for_each_entry(peer_vm,
>>>>>>>> &process_info-
>>>>>>>>> vm_list_head,
>>>>>>>> vm_list_node) {
>>>>>>>> ret = amdgpu_vm_lock_pd(peer_vm,
>>>>>>>> &exec,
>>>>>>>> 2);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto unreserve_out;
>>>>>>>> }
>>>>>>>> @@ -2631,7 +2631,7 @@ static int
>>>>>>>> validate_invalid_user_pages(struct
>>>>>>>> amdkfd_process_info *process_info)
>>>>>>>>
>>>>>>>> gobj = &mem->bo->tbo.base;
>>>>>>>> ret =
>>>>>>>> drm_exec_prepare_obj(&exec,
>>>>>>>> gobj,
>>>>>>>> 1);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret))
>>>>>>>> goto unreserve_out;
>>>>>>>> }
>>>>>>>> @@ -2875,7 +2875,7 @@ int
>>>>>>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
>>>>>>>> struct
>>>>>>>> dma_fence __rcu *
>>>>>>>> list_for_each_entry(peer_vm,
>>>>>>>> &process_info-
>>>>>>>>> vm_list_head,
>>>>>>>> vm_list_node) {
>>>>>>>> ret = amdgpu_vm_lock_pd(peer_vm,
>>>>>>>> &exec,
>>>>>>>> 2);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret)) {
>>>>>>>> pr_err("Locking VM PD
>>>>>>>> failed,
>>>>>>>> ret:
>>>>>>>> %d\n", ret);
>>>>>>>> goto ttm_reserve_fail;
>>>>>>>> @@ -2891,7 +2891,7 @@ int
>>>>>>>> amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
>>>>>>>> struct
>>>>>>>> dma_fence __rcu *
>>>>>>>>
>>>>>>>> gobj = &mem->bo->tbo.base;
>>>>>>>> ret =
>>>>>>>> drm_exec_prepare_obj(&exec,
>>>>>>>> gobj,
>>>>>>>> 1);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (unlikely(ret)) {
>>>>>>>> pr_err("drm_exec_prepare
>>>>>>>> _obj
>>>>>>>> failed, ret: %d\n", ret);
>>>>>>>> goto ttm_reserve_fail;
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>>>> index ec888fc6ead8..299e46a6d934 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>>>>>>> @@ -897,7 +897,7 @@ static int
>>>>>>>> amdgpu_cs_parser_bos(struct
>>>>>>>> amdgpu_cs_parser *p,
>>>>>>>>
>>>>>>>> drm_exec_until_all_locked(&p->exec) {
>>>>>>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &p-
>>>>>>>>> exec,
>>>>>>>> 1
>>>>>>>> + p-
>>>>>>>>> gang_size);
>>>>>>>> - drm_exec_retry_on_contention(&p->exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&p-
>>>>>>>>> exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_free_user_pages;
>>>>>>>>
>>>>>>>> @@ -905,7 +905,7 @@ static int
>>>>>>>> amdgpu_cs_parser_bos(struct
>>>>>>>> amdgpu_cs_parser *p,
>>>>>>>> /* One fence for TTM and one for
>>>>>>>> each
>>>>>>>> CS
>>>>>>>> job */
>>>>>>>> r = drm_exec_prepare_obj(&p-
>>>>>>>>> exec,
>>>>>>>> &e-
>>>>>>>>> bo-
>>>>>>>>> tbo.base,
>>>>>>>> 1 + p-
>>>>>>>>> gang_size);
>>>>>>>> - drm_exec_retry_on_contention(&p-
>>>>>>>>> exec);
>>>>>>>> + r =
>>>>>>>> drm_exec_retry_on_contention(&p-
>>>>>>>>> exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto
>>>>>>>> out_free_user_pages;
>>>>>>>>
>>>>>>>> @@ -915,7 +915,7 @@ static int
>>>>>>>> amdgpu_cs_parser_bos(struct
>>>>>>>> amdgpu_cs_parser *p,
>>>>>>>> if (p->uf_bo) {
>>>>>>>> r = drm_exec_prepare_obj(&p-
>>>>>>>>> exec,
>>>>>>>> &p-
>>>>>>>>> uf_bo->tbo.base,
>>>>>>>> 1 + p-
>>>>>>>>> gang_size);
>>>>>>>> - drm_exec_retry_on_contention(&p-
>>>>>>>>> exec);
>>>>>>>> + r =
>>>>>>>> drm_exec_retry_on_contention(&p-
>>>>>>>>> exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto
>>>>>>>> out_free_user_pages;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>>>> index cfdf558b48b6..8b2b86c7a6c5 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
>>>>>>>> @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
>>>>>>>> amdgpu_device
>>>>>>>> *adev, struct amdgpu_vm *vm,
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> if (likely(!r))
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r)) {
>>>>>>>> DRM_ERROR("failed to reserve
>>>>>>>> CSA,PD
>>>>>>>> BOs:
>>>>>>>> err=%d\n", r);
>>>>>>>> goto error;
>>>>>>>> @@ -114,7 +114,7 @@ int amdgpu_unmap_static_csa(struct
>>>>>>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> if (likely(!r))
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r)) {
>>>>>>>> DRM_ERROR("failed to reserve
>>>>>>>> CSA,PD
>>>>>>>> BOs:
>>>>>>>> err=%d\n", r);
>>>>>>>> goto error;
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>>>> index 67c234bcf89f..17e16c971e21 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>>>>>> @@ -239,12 +239,12 @@ static void
>>>>>>>> amdgpu_gem_object_close(struct
>>>>>>>> drm_gem_object *obj,
>>>>>>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> r = drm_exec_prepare_obj(&exec, &bo-
>>>>>>>>> tbo.base,
>>>>>>>> 1);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>> }
>>>>>>>> @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct
>>>>>>>> drm_device
>>>>>>>> *dev, void *data,
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> if (gobj) {
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> gobj);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&exec);
>>>>>>>> + r =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(&fpriv->vm, &exec,
>>>>>>>> 2);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>>>> index 5ca5c47ab54e..1b1a5147606e 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>>>>>>>> @@ -1221,12 +1221,12 @@ int
>>>>>>>> amdgpu_mes_ctx_map_meta_data(struct
>>>>>>>> amdgpu_device *adev,
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &ctx_data-
>>>>>>>>> meta_data_obj-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error_fini_exec;
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error_fini_exec;
>>>>>>>> }
>>>>>>>> @@ -1292,12 +1292,12 @@ int
>>>>>>>> amdgpu_mes_ctx_unmap_meta_data(struct
>>>>>>>> amdgpu_device *adev,
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &ctx_data-
>>>>>>>>> meta_data_obj-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>>>> index e22cb2b5cd92..72b8213e352c 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
>>>>>>>> @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct
>>>>>>>> amdgpu_device
>>>>>>>> *adev,
>>>>>>>> struct amdgpu_vm *vm,
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> if (likely(!r))
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
>>>>>>>> amdgpu_device
>>>>>>>> *adev, struct amdgpu_fpriv *fpriv)
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> if (likely(!r))
>>>>>>>> r = drm_exec_lock_obj(&exec,
>>>>>>>> &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>>>> index e01c1c8e64c4..63392ce43945 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
>>>>>>>> @@ -89,12 +89,12 @@ static int map_ring_data(struct
>>>>>>>> amdgpu_device
>>>>>>>> *adev, struct amdgpu_vm *vm,
>>>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error_fini_exec;
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto error_fini_exec;
>>>>>>>> }
>>>>>>>> @@ -152,12 +152,12 @@ static int unmap_ring_data(struct
>>>>>>>> amdgpu_device *adev, struct amdgpu_vm *vm,
>>>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> r = drm_exec_lock_obj(&exec, &bo-
>>>>>>>>> tbo.base);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &exec, 0);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + r = drm_exec_retry_on_contention(&exec,
>>>>>>>> r);
>>>>>>>> if (unlikely(r))
>>>>>>>> goto out_unlock;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>>>> b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>>>> index 386875e6eb96..a3aa7fd22f6a 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>>>>>>> @@ -1499,7 +1499,7 @@ static int
>>>>>>>> svm_range_reserve_bos(struct
>>>>>>>> svm_validate_context *ctx, bool intr)
>>>>>>>> vm = drm_priv_to_vm(pdd-
>>>>>>>>> drm_priv);
>>>>>>>>
>>>>>>>> r = amdgpu_vm_lock_pd(vm, &ctx-
>>>>>>>>> exec,
>>>>>>>> 2);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec);
>>>>>>>> + r =
>>>>>>>> drm_exec_retry_on_contention(&ctx-
>>>>>>>>> exec, r);
>>>>>>>> if (unlikely(r)) {
>>>>>>>> pr_debug("failed %d to
>>>>>>>> reserve
>>>>>>>> bo\n", r);
>>>>>>>> goto unreserve_out;
>>>>>>>> diff --git a/drivers/gpu/drm/drm_exec.c
>>>>>>>> b/drivers/gpu/drm/drm_exec.c
>>>>>>>> index 2da094bdf8a4..3770a5d30213 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_exec.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_exec.c
>>>>>>>> @@ -28,12 +28,12 @@
>>>>>>>> * drm_exec_init(&exec,
>>>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT);
>>>>>>>> * drm_exec_until_all_locked(&exec) {
>>>>>>>> * ret = drm_exec_prepare_obj(&exec, boA,
>>>>>>>> 1);
>>>>>>>> - * drm_exec_retry_on_contention(&exec);
>>>>>>>> + * ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> * if (ret)
>>>>>>>> * goto error;
>>>>>>>> *
>>>>>>>> * ret = drm_exec_prepare_obj(&exec, boB,
>>>>>>>> 1);
>>>>>>>> - * drm_exec_retry_on_contention(&exec);
>>>>>>>> + * ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> * if (ret)
>>>>>>>> * goto error;
>>>>>>>> * }
>>>>>>>> @@ -48,7 +48,8 @@
>>>>>>>> */
>>>>>>>>
>>>>>>>> /* Dummy value used to initially enter the retry loop
>>>>>>>> */
>>>>>>>> -#define DRM_EXEC_DUMMY ((void *)~0)
>>>>>>>> +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
>>>>>>>> +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
>>>>>>>>
>>>>>>>> /* Unlock all objects and drop references */
>>>>>>>> static void drm_exec_unlock_all(struct drm_exec
>>>>>>>> *exec)
>>>>>>>> @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct drm_exec
>>>>>>>> *exec)
>>>>>>>> return true;
>>>>>>>> }
>>>>>>>>
>>>>>>>> - drm_exec_unlock_all(exec);
>>>>>>>> - exec->num_objects = 0;
>>>>>>>> + exec->contended = NULL;
>>>>>>>> return true;
>>>>>>>> }
>>>>>>>> EXPORT_SYMBOL(drm_exec_cleanup);
>>>>>>>> @@ -194,6 +194,27 @@ static int
>>>>>>>> drm_exec_lock_contended(struct
>>>>>>>> drm_exec *exec)
>>>>>>>> return ret;
>>>>>>>> }
>>>>>>>>
>>>>>>>> +/**
>>>>>>>> + * drm_exec_handle_contended() - Perform cleanup before
>>>>>>>> a ww
>>>>>>>> transaction restart
>>>>>>>> + * @exec: Pointer to the drm_exec object.
>>>>>>>> + *
>>>>>>>> + * Unlocks all held resvs and re-locks the contended
>>>>>>>> object.
>>>>>>>> + *
>>>>>>>> + * Return: 0 on success, negative error code on failure.
>>>>>>>> + */
>>>>>>>> +int drm_exec_handle_contended(struct drm_exec *exec)
>>>>>>>> +{
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + drm_exec_unlock_all(exec);
>>>>>>>> + exec->num_objects = 0;
>>>>>>>> + ret = drm_exec_lock_contended(exec);
>>>>>>>> + exec->contended = DRM_EXEC_CONTENDED;
>>>>>>>> +
>>>>>>>> + return ret;
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL(drm_exec_handle_contended);
>>>>>>>> +
>>>>>>>> /**
>>>>>>>> * drm_exec_lock_obj - lock a GEM object for use
>>>>>>>> * @exec: the drm_exec object with the state
>>>>>>>> @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct
>>>>>>>> drm_exec
>>>>>>>> *exec,
>>>>>>>> struct drm_gem_object *obj)
>>>>>>>> {
>>>>>>>> int ret;
>>>>>>>>
>>>>>>>> - ret = drm_exec_lock_contended(exec);
>>>>>>>> - if (unlikely(ret))
>>>>>>>> - return ret;
>>>>>>>> -
>>>>>>>> if (exec->prelocked == obj) {
>>>>>>>> drm_gem_object_put(exec->prelocked);
>>>>>>>> exec->prelocked = NULL;
>>>>>>>> diff --git a/drivers/gpu/drm/drm_gpuvm.c
>>>>>>>> b/drivers/gpu/drm/drm_gpuvm.c
>>>>>>>> index f9eb56f24bef..0923d6ae18e2 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_gpuvm.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_gpuvm.c
>>>>>>>> @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
>>>>>>>> drm_gpuvm_exec
>>>>>>>> *vm_exec)
>>>>>>>>
>>>>>>>> drm_exec_until_all_locked(exec) {
>>>>>>>> ret = drm_gpuvm_prepare_vm(gpuvm, exec,
>>>>>>>> num_fences);
>>>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> goto err;
>>>>>>>>
>>>>>>>> ret = drm_gpuvm_prepare_objects(gpuvm,
>>>>>>>> exec,
>>>>>>>> num_fences);
>>>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> goto err;
>>>>>>>>
>>>>>>>> if (vm_exec->extra.fn) {
>>>>>>>> ret = vm_exec-
>>>>>>>>> extra.fn(vm_exec);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> goto err;
>>>>>>>> }
>>>>>>>> @@ -1346,7 +1346,7 @@ drm_gpuvm_exec_lock_range(struct
>>>>>>>> drm_gpuvm_exec *vm_exec,
>>>>>>>> drm_exec_until_all_locked(exec) {
>>>>>>>> ret = drm_gpuvm_prepare_range(gpuvm,
>>>>>>>> exec,
>>>>>>>> addr,
>>>>>>>> range,
>>>>>>>> vm_exec-
>>>>>>>>> num_fences);
>>>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> goto err;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/imagination/pvr_job.c
>>>>>>>> b/drivers/gpu/drm/imagination/pvr_job.c
>>>>>>>> index 78c2f3c6dce0..6e0ce6c4576c 100644
>>>>>>>> --- a/drivers/gpu/drm/imagination/pvr_job.c
>>>>>>>> +++ b/drivers/gpu/drm/imagination/pvr_job.c
>>>>>>>> @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct
>>>>>>>> drm_exec
>>>>>>>> *exec, struct pvr_job_data *job_data,
>>>>>>>> drm_exec_until_all_locked(exec) {
>>>>>>>> int err = jobs_lock_all_objs(exec,
>>>>>>>> job_data,
>>>>>>>> job_count);
>>>>>>>>
>>>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>>>> + err = drm_exec_retry_on_contention(exec,
>>>>>>>> err);
>>>>>>>> if (err)
>>>>>>>> return err;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>>>> b/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>>>> index fba78193127d..01992b43ea4b 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
>>>>>>>> @@ -259,7 +259,7 @@ static int submit_lock_objects(struct
>>>>>>>> msm_gem_submit *submit)
>>>>>>>> for (unsigned i = 0; i < submit->nr_bos;
>>>>>>>> i++)
>>>>>>>> {
>>>>>>>> struct drm_gem_object *obj =
>>>>>>>> submit-
>>>>>>>>> bos[i].obj;
>>>>>>>> ret =
>>>>>>>> drm_exec_prepare_obj(&submit-
>>>>>>>>> exec,
>>>>>>>> obj, 1);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_contention(&su
>>>>>>>> bmit-
>>>>>>>>> exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&submit->exec, ret);
>>>>>>>> if (ret)
>>>>>>>> goto error;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>>>> b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>>>> index ee02cd833c5e..0c871634fdfb 100644
>>>>>>>> --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>>>> +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
>>>>>>>> @@ -1350,7 +1350,7 @@ nouveau_uvmm_bind_job_submit(struct
>>>>>>>> nouveau_job *job,
>>>>>>>> drm_exec_init(exec, vme->flags, 0);
>>>>>>>> drm_exec_until_all_locked(exec) {
>>>>>>>> ret = bind_lock_validate(job, exec, vme-
>>>>>>>>> num_fences);
>>>>>>>> - drm_exec_retry_on_contention(exec);
>>>>>>>> + ret = drm_exec_retry_on_contention(exec,
>>>>>>>> ret);
>>>>>>>> if (ret) {
>>>>>>>> op = list_last_op(&bind_job-
>>>>>>>>> ops);
>>>>>>>> goto unwind;
>>>>>>>> diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>>>> b/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>>>> index 81f928a429ba..28558fdb08df 100644
>>>>>>>> --- a/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>>>> +++ b/drivers/gpu/drm/tests/drm_exec_test.c
>>>>>>>> @@ -63,7 +63,7 @@ static void test_lock(struct kunit
>>>>>>>> *test)
>>>>>>>> drm_exec_init(&exec,
>>>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>> @@ -83,14 +83,14 @@ static void test_lock_unlock(struct
>>>>>>>> kunit
>>>>>>>> *test)
>>>>>>>> drm_exec_init(&exec,
>>>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>>
>>>>>>>> drm_exec_unlock_obj(&exec, &gobj);
>>>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>> @@ -110,13 +110,13 @@ static void test_duplicates(struct
>>>>>>>> kunit
>>>>>>>> *test)
>>>>>>>> drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>>
>>>>>>>> ret = drm_exec_lock_obj(&exec, &gobj);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>> @@ -137,7 +137,7 @@ static void test_prepare(struct kunit
>>>>>>>> *test)
>>>>>>>> drm_exec_init(&exec,
>>>>>>>> DRM_EXEC_INTERRUPTIBLE_WAIT,
>>>>>>>> 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = drm_exec_prepare_obj(&exec, &gobj,
>>>>>>>> 1);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> KUNIT_EXPECT_EQ(test, ret, 0);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>>>> b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>>>> index 040dd142c49c..20ec1ab1b52d 100644
>>>>>>>> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>>>> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>>>>>>>> @@ -200,7 +200,7 @@ static int handle_pagefault(struct
>>>>>>>> xe_gt
>>>>>>>> *gt,
>>>>>>>> struct pagefault *pf)
>>>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = xe_pf_begin(&exec, vma, atomic,
>>>>>>>> tile-
>>>>>>>>> id);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> goto unlock_dma_resv;
>>>>>>>>
>>>>>>>> @@ -543,7 +543,7 @@ static int handle_acc(struct xe_gt
>>>>>>>> *gt,
>>>>>>>> struct
>>>>>>>> acc *acc)
>>>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> ret = xe_pf_begin(&exec, vma, true,
>>>>>>>> tile-
>>>>>>>>> id);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + ret =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> ret);
>>>>>>>> if (ret)
>>>>>>>> break;
>>>>>>>> }
>>>>>>>> diff --git a/drivers/gpu/drm/xe/xe_vm.c
>>>>>>>> b/drivers/gpu/drm/xe/xe_vm.c
>>>>>>>> index e2ec148c9c33..335524e803e7 100644
>>>>>>>> --- a/drivers/gpu/drm/xe/xe_vm.c
>>>>>>>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>>>>>>>> @@ -501,7 +501,7 @@ static void
>>>>>>>> preempt_rebind_work_func(struct
>>>>>>>> work_struct *w)
>>>>>>>> bool done = false;
>>>>>>>>
>>>>>>>> err = xe_preempt_work_begin(&exec, vm,
>>>>>>>> &done);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + err =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> err);
>>>>>>>> if (err || done) {
>>>>>>>> drm_exec_fini(&exec);
>>>>>>>> if (err &&
>>>>>>>> xe_vm_validate_should_retry(&exec, err, &end))
>>>>>>>> @@ -1052,7 +1052,7 @@ static void
>>>>>>>> xe_vma_destroy_unlocked(struct
>>>>>>>> xe_vma *vma)
>>>>>>>> drm_exec_init(&exec, 0, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> err = xe_vm_lock_vma(&exec, vma);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + err =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> err);
>>>>>>>> if (XE_WARN_ON(err))
>>>>>>>> break;
>>>>>>>> }
>>>>>>>> @@ -2148,11 +2148,11 @@ static struct xe_vma
>>>>>>>> *new_vma(struct
>>>>>>>> xe_vm
>>>>>>>> *vm, struct drm_gpuva_op_map *op,
>>>>>>>> err = 0;
>>>>>>>> if (!bo->vm) {
>>>>>>>> err =
>>>>>>>> drm_exec_lock_obj(&exec,
>>>>>>>> xe_vm_obj(vm));
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_conten
>>>>>>>> tion
>>>>>>>> (&
>>>>>>>> exec);
>>>>>>>> + err =
>>>>>>>> drm_exec_retry_on_contention(&exec, err);
>>>>>>>> }
>>>>>>>> if (!err) {
>>>>>>>> err =
>>>>>>>> drm_exec_lock_obj(&exec,
>>>>>>>> &bo->ttm.base);
>>>>>>>> -
>>>>>>>> drm_exec_retry_on_conten
>>>>>>>> tion
>>>>>>>> (&
>>>>>>>> exec);
>>>>>>>> + err =
>>>>>>>> drm_exec_retry_on_contention(&exec, err);
>>>>>>>> }
>>>>>>>> if (err) {
>>>>>>>> drm_exec_fini(&exec);
>>>>>>>> @@ -2884,7 +2884,7 @@ static int
>>>>>>>> vm_bind_ioctl_ops_execute(struct
>>>>>>>> xe_vm *vm,
>>>>>>>> DRM_EXEC_IGNORE_DUPLICATES, 0);
>>>>>>>> drm_exec_until_all_locked(&exec) {
>>>>>>>> err =
>>>>>>>> vm_bind_ioctl_ops_lock_and_prep(&exec,
>>>>>>>> vm,
>>>>>>>> vops);
>>>>>>>> - drm_exec_retry_on_contention(&exec);
>>>>>>>> + err =
>>>>>>>> drm_exec_retry_on_contention(&exec,
>>>>>>>> err);
>>>>>>>> if (err)
>>>>>>>> goto unlock;
>>>>>>>>
>>>>>>>> diff --git a/include/drm/drm_exec.h
>>>>>>>> b/include/drm/drm_exec.h
>>>>>>>> index aa786b828a0a..fafb40d96e38 100644
>>>>>>>> --- a/include/drm/drm_exec.h
>>>>>>>> +++ b/include/drm/drm_exec.h
>>>>>>>> @@ -51,6 +51,8 @@ struct drm_exec {
>>>>>>>> struct drm_gem_object *prelocked;
>>>>>>>> };
>>>>>>>>
>>>>>>>> +int drm_exec_handle_contended(struct drm_exec *exec);
>>>>>>>> +
>>>>>>>> /**
>>>>>>>> * drm_exec_obj() - Return the object for a give
>>>>>>>> drm_exec
>>>>>>>> index
>>>>>>>> * @exec: Pointer to the drm_exec context
>>>>>>>> @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
>>>>>>>> __LINE__): \
>>>>>>>> /**
>>>>>>>> * drm_exec_retry_on_contention - restart the loop to
>>>>>>>> grap
>>>>>>>> all
>>>>>>>> locks
>>>>>>>> * @exec: drm_exec object
>>>>>>>> + * @_ret: The current error status
>>>>>>>> *
>>>>>>>> * Control flow helper to continue when a contention
>>>>>>>> was
>>>>>>>> detected
>>>>>>>> and we need to
>>>>>>>> * clean up and re-start the loop to prepare all GEM
>>>>>>>> objects.
>>>>>>>> + *
>>>>>>>> + * Return: If no loop restart occurred: The error
>>>>>>>> status.
>>>>>>>> */
>>>>>>>> -#define
>>>>>>>> drm_exec_retry_on_contention(exec) \
>>>>>>>> - do
>>>>>>>> { \
>>>>>>>> - if
>>>>>>>> (unlikely(drm_exec_is_contended(exec))) \
>>>>>>>> - goto
>>>>>>>> *__drm_exec_retry_ptr; \
>>>>>>>> - } while (0)
>>>>>>>> +#define drm_exec_retry_on_contention(exec,
>>>>>>>> _ret) \
>>>>>>>> + ({
>>>>>>>>
>>>>>>>> \
>>>>>>>> + struct drm_exec *__exec =
>>>>>>>> (exec); \
>>>>>>>> + int __ret =
>>>>>>>> (_ret); \
>>>>>>>> +
>>>>>>>>
>>>>>>>> \
>>>>>>>> + if
>>>>>>>> (unlikely(drm_exec_is_contended(__exec)))
>>>>>>>> { \
>>>>>>>> + WARN_ON(__ret != -
>>>>>>>> EDEADLK); \
>>>>>>>> + __ret =
>>>>>>>> drm_exec_handle_contended(__exec); \
>>>>>>>> + if
>>>>>>>> (!__ret) \
>>>>>>>> + goto
>>>>>>>> *__drm_exec_retry_ptr; \
>>>>>>>> + }
>>>>>>>>
>>>>>>>> \
>>>>>>>> + __ret;
>>>>>>>>
>>>>>>>> \
>>>>>>>> + })
>>>>>>>>
>>>>>>>> /**
>>>>>>>> * drm_exec_is_contended - check for contention
[-- Attachment #2: Type: text/html, Size: 57744 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFC PATCH v3 13/21] drm/exec: Rework contended locking
2024-05-28 11:03 ` Christian König
@ 2024-05-29 7:18 ` Thomas Hellström
0 siblings, 0 replies; 50+ messages in thread
From: Thomas Hellström @ 2024-05-29 7:18 UTC (permalink / raw)
To: Christian König
Cc: Somalapuram Amaranath, Matthew Brost, dri-devel, intel-xe
On Tue, 2024-05-28 at 13:03 +0200, Christian König wrote:
> Am 28.05.24 um 10:07 schrieb Thomas Hellström:
> > On Tue, 2024-05-28 at 08:51 +0200, Christian König wrote:
> > > > 2) Any contended lock held at loop start is completely
> > > > encapsulated
> > > > in
> > > > the ww transaction and can and will be unlocked when exiting
> > > > it, so
> > > > this patch doesn't introduce any additional problems for
> > > > userptr
> > > > handling AFAICT.
> > > The drm_exec object was intentionally design to not have anything
> > > locked
> > > at the beginning of the loop. See the discussion I had with Sima
> > > around
> > > that when pushing the drm_exec object upstream.
> > >
> > > I would really like to stick with that design and honestly don't
> > > see
> > > the
> > > reason to change that. Contenting on a trylock seem to be much
> > > more
> > > questionable.
> > The change here is to make sure we *don't* have contention in a
> > trylock, which is otherwise inherent in the current drm_exec
> > design.
>
> My sentence was probably a bit misleading. What I wanted to say is
> that
> trylock as first thing in the loop sounds really odd to me.
>
> See the intention of a trylock is to acquire something optional. What
> we
> do for the freshly allocated BO and the 'don't try to block with the
> mmap lock held' case is actually kind something different.
>
> A clean approach would be to to have the BO initialization and
> backing
> store allocation steps separated. In this case you don't even need to
> use trylock here.
>
> And for the VM fault locking case the clean approach would be to tell
> the drm_exec object of the vm_fault parameters so that this helper
> can
> do the drop all locks, drop the mmap lock, acquire the blocking lock
> and
> return -EAGAIN.
>
> This has the huge benefit that we not only stop blocking for the
> faulted
> BO, but eventually all others which might need to move so that the
> faulted BO is CPU accessible. I think that this is actually the more
> problematic case.
Yes, this fault handler approach sounds ok to me. Do you mean we make
drm_exec aware of both the mmap lock and the desire not to block while
it is held? I figure that could come in handy for SVM gpu pagefaults as
well.
For the bo initalization, the suggested solution there deviates a lot
from the non-exec case, where a never-failing trylock on creation is
sometimes necessary. This will probably be an unwanted obstacle for
drm_exec conversion.
What do you think about the following for bo init? This also basically
means the user of drm_exec can also *choose* to avoid trylock problems
already at the start of the drm_exec loop.
https://patchwork.freedesktop.org/patch/595863/?series=133643&rev=7
and
https://patchwork.freedesktop.org/patch/595866/?series=133643&rev=7
Then if we also do the fault handler mode we could drop this patch
assuming that drivers have all tools to handle existing cases of
ww_mutex_trylock().
>
> > What I'm trying to say here is that we end up with the contended
> > lock
> > grabbed at loop start you already conceptually have a conflicting
> > lock
> > held (the we_class::acquire_key). Both these can be resolved.
>
> Yeah, I'm perfectly aware of that. But this is just a shortcoming of
> lockdep and not a real problem.
>
> During the drm_exec code review we already moved the
> ww_acquire_init()
> into the cleanup function so that it's only called at the start of
> the
> loop. Background is that we ran into lockdep warnings with that
> otherwise.
>
> But functionally it would still work if we do this in drm_exec_ini().
>
> > > > 3) The need for a fully capable ww transaction helper moving
> > > > forward.
> > > > If we need a tool that also does userptr locking, then I think
> > > > we
> > > > need
> > > > to separate that from the ww transaction tool and only pass the
> > > > latter
> > > > around to TTM.
> > > drm_exec is *not* meant to be a ww_transaction helper.
> > >
> > > The functionality here is to support drivers in their CS
> > > interface
> > > and
> > > that includes userptr handling as well as a couple of other
> > > things.
> > Then if so, I don't think drm_exec is the correct functionality to
> > pass
> > to TTM to resolve the eviction issues, but rather a ww transaction
> > helper that can be used standalone *and* by drm_exec. Now the
> > functionality would be more or less what drm exec is today, but
> > slightly augmented.
> >
> > But then IMHO instead of changing name and more or less replicating
> > what drm_exec is today wouldn't it be a better idea to subclass
> > drm_exec into a full-fledged CS helper at the time when that
> > functionality is indeed added?
>
> Mhm, interesting idea. But it still means that the base object needs
> to
> be designed in a way to not prevent the implementation of the
> subclass.
Sure, although I am still of the opinion that the patch at hand does
not prevent that, but agreed violates a design principle.
I think we need to be careful to avoid a situaion where it is possible
to open-code something that is desriable / needed by drivers, and that
is not possible withing drm_exec, but still the driver needs to use
drm_exec since it's required for other tools.
/Thomas
>
> Christian.
>
> >
> > /Thomas
> >
> > > Regards,
> > > Christian.
> > >
> > > > Thanks,
> > > > Thomas
> > > >
> > > > On Wed, 2024-05-22 at 19:42 +0200, Thomas Hellström wrote:
> > > > > On Wed, 2024-05-22 at 18:52 +0200, Christian König wrote:
> > > > > > Am 22.05.24 um 16:32 schrieb Thomas Hellström:
> > > > > > > On Wed, 2024-05-22 at 07:52 +0200, Christian König wrote:
> > > > > > > > Am 21.05.24 um 09:16 schrieb Thomas Hellström:
> > > > > > > > > If contention and backoff occurs during a drm_exec ww
> > > > > > > > > transaction,
> > > > > > > > > the contended lock is not locked again until the next
> > > > > > > > > orinary
> > > > > > > > > attempt to lock a dma_resv lock. However, with the
> > > > > > > > > introduction
> > > > > > > > > of
> > > > > > > > > drm_exec_trylock(), that doesn't work, since the
> > > > > > > > > locking
> > > > > > > > > of
> > > > > > > > > the
> > > > > > > > > contended lock needs to be a sleeping lock. Neither
> > > > > > > > > can
> > > > > > > > > we
> > > > > > > > > ignore
> > > > > > > > > locking the contended lock during a trylock since
> > > > > > > > > that
> > > > > > > > > would
> > > > > > > > > violate
> > > > > > > > > at least the ww_mutex annotations.
> > > > > > > > >
> > > > > > > > > So resolve this by actually locking the contended
> > > > > > > > > lock
> > > > > > > > > during
> > > > > > > > > drm_exec_retry_on_contention(). However, this
> > > > > > > > > introduces
> > > > > > > > > a
> > > > > > > > > new
> > > > > > > > > point
> > > > > > > > > of failure since locking the contended lock may
> > > > > > > > > return -
> > > > > > > > > EINTR.
> > > > > > > > >
> > > > > > > > > Hence drm_exec_retry_on_contention() must take an
> > > > > > > > > error
> > > > > > > > > parameter
> > > > > > > > > and
> > > > > > > > > also return a value indicating success.
> > > > > > > > After thinking more about that I have to pretty clearly
> > > > > > > > NAK
> > > > > > > > this.
> > > > > > > >
> > > > > > > I thought we were beyond upfront NAKing in the first
> > > > > > > reply :/
> > > > > > Well my memory could fail me, but I mentioned concerns on
> > > > > > this
> > > > > > approach
> > > > > > before.
> > > > > >
> > > > > > I was a bit annoyed seeing that again. But could as well be
> > > > > > that my
> > > > > > response never got out or that I'm mixing things up.
> > > > > I haven't seen it at least. Last discussion on this I saw was
> > > > > here. I didn't see a follow-up on that.
> > > > >
> > > > > https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
> > > > >
> > > > >
> > > > > > > > It's an intentional design decision to guarantee that
> > > > > > > > at
> > > > > > > > the
> > > > > > > > start of
> > > > > > > > the loop no object is locked.
> > > > > > > >
> > > > > > > > This is because Sima and I wanted to integrate userptr
> > > > > > > > handling
> > > > > > > > into
> > > > > > > > drm_exec as well in the long term.
> > > > > > > First I agree the interface looks worse with this patch.
> > > > > > > But I thought generic userptr handling were going to end
> > > > > > > up
> > > > > > > as a
> > > > > > > gpuvm
> > > > > > > helper (without using GEM objects) as we've discussed
> > > > > > > previously.
> > > > > > We might be talking past each other. That sounds like SVM,
> > > > > > e.g.
> > > > > > on
> > > > > > demand paging.
> > > > > >
> > > > > > What I mean is pre-faulting during command submission like
> > > > > > radeon,
> > > > > > amdgpu and i915 do for the userptr handling.
> > > > > Yes, then we're talking about the same thing.
> > > > >
> > > > > We discussed in this thread here, started by Dave.
> > > > >
> > > > > https://lore.kernel.org/dri-devel/CAPM=9twPgn+fpbkig0Vhjt=cJdHQFbNH_Z=sRhSZwuvLKhavbA@mail.gmail.com/
> > > > >
> > > > > I still think the right place is in drm_gpuvm for this sort
> > > > > of
> > > > > stuff.
> > > > > And I think that's the concluding argument by Sima as well.
> > > > >
> > > > > In any case, If the planned drm_exec development is to be a
> > > > > full
> > > > > execbuf helper, I think we need a capable sub-helper for ONLY
> > > > > the
> > > > > ww
> > > > > transaction locking as well, with support for the various
> > > > > locking
> > > > > primitives. In particular if we're going to be able to port
> > > > > i915
> > > > > ww
> > > > > transaction locking over. There are more uses of the ww
> > > > > locking
> > > > > transacions than execbuf.
> > > > >
> > > > > > For that you need to re-start the whole handling similar to
> > > > > > how
> > > > > > you
> > > > > > need
> > > > > > to re-start for the mutex locking when you detect that the
> > > > > > page
> > > > > > array
> > > > > > is
> > > > > > stale, the difference is that you are not allowed to hold
> > > > > > any
> > > > > > resv
> > > > > > locks
> > > > > > while pre-faulting.
> > > > > >
> > > > > > That's why it is a requirement that the drm_exec loop
> > > > > > starts
> > > > > > without
> > > > > > any
> > > > > > locks held.
> > > > > But wouldn't you need an outer (userptr) loop and an inner
> > > > > (ww_transaction) loop for this? Why would we want to re-
> > > > > validate
> > > > > userptrs on -EDEADLKS?
> > > > >
> > > > > > > Anyway if still there would be helpers in drm_exec for
> > > > > > > some
> > > > > > > other
> > > > > > > generic userptr solution, those need to be done before
> > > > > > > the
> > > > > > > ww_acquire_ctx_init(). The contended locking here is done
> > > > > > > after,
> > > > > > > so
> > > > > > > I
> > > > > > > can't really see how these would clash.
> > > > > > Yes, that indeed was a problem. The ww_acquire_ctx_init()
> > > > > > was
> > > > > > intentionally moved into drm_exec_cleanup() to partially
> > > > > > prevent
> > > > > > that
> > > > > > issue.
> > > > > >
> > > > > > I haven't fully figured out how to do handle everything
> > > > > > exactly,
> > > > > > but
> > > > > > at
> > > > > > least in principle it can be made work. With this change
> > > > > > here
> > > > > > it
> > > > > > becomes
> > > > > > impossible.
> > > > > >
> > > > > > > Still, If we need to come up with another solution, I
> > > > > > > think
> > > > > > > it's
> > > > > > > fair
> > > > > > > we clearly sort out why.
> > > > > > >
> > > > > > > > I think we should just document that drm_exec_trylock()
> > > > > > > > can't
> > > > > > > > be
> > > > > > > > used
> > > > > > > > to
> > > > > > > > lock the first BO in the loop and explicitly WARN if
> > > > > > > > that's
> > > > > > > > the
> > > > > > > > case.
> > > > > > > Unfortunately that's not sufficient for the general use-
> > > > > > > case.
> > > > > > > If
> > > > > > > we
> > > > > > > want to keep the ttm_bo_vm approach of dropping the mmap
> > > > > > > lock
> > > > > > > when
> > > > > > > there is contention on the bo resv, we need to be able to
> > > > > > > trylock
> > > > > > > on
> > > > > > > first lock.
> > > > > > Mhm, why exactly do we still have that dance in the first
> > > > > > place?
> > > > > >
> > > > > > I mean we have sorted out the mmap() and dma_resv() locking
> > > > > > order
> > > > > > long
> > > > > > ago. See dma_resv_lockdep() which is enforcing that.
> > > > > I explained that in my reply here:
> > > > >
> > > > > https://lore.kernel.org/dri-devel/953c157bf69df12d831a781f0f638d93717bb044.camel@linux.intel.com/
> > > > >
> > > > > We shouldn't be holding the mmap lock when waiting for stuff.
> > > > > In
> > > > > particular not while waiting for mutexes that may be blocked
> > > > > by
> > > > > gpu
> > > > > activity.
> > > > >
> > > > > > > Also bo creation is using trylock but might be able
> > > > > > > to use
> > > > > > > a sleeping lock there. But if that sleeping lock triggers
> > > > > > > an
> > > > > > > -
> > > > > > > EDEADLK
> > > > > > > (DEBUG_WW_MUTEX_SLOWPATH) we have the weird situation of
> > > > > > > referencing an
> > > > > > > object that never was fully created as a contending
> > > > > > > object.
> > > > > > I wanted to eliminate that as well by not validating the BO
> > > > > > during
> > > > > > initialization any more.
> > > > > > So bo creation would then be:
> > > > > >
> > > > > > ttm_bo_init(bo)
> > > > > >
> > > > > > drm_exec_while_not_all_locked() {
> > > > > > drm_exec_prepare_object(bo, 1);
> > > > > >
> > > > > > ttm_bo_validate(bo);
> > > > > > }
> > > > > >
> > > > > > if (r)
> > > > > > ttm_bo_put(bo);
> > > > > >
> > > > > > return r;
> > > > > >
> > > > > > I have that on a branch here somewhere prepared, but never
> > > > > > got
> > > > > > the
> > > > > > time
> > > > > > to clean it up.
> > > > > Still, bo creation and validation may be part of a ww
> > > > > transaction
> > > > > as
> > > > > well, like page-table bos (Although those are pre-locked so
> > > > > perhaps
> > > > > not
> > > > > a good example). But in the general case, I'm not sure this
> > > > > is
> > > > > sufficient for all use-cases.
> > > > >
> > > > > /Thomas
> > > > >
> > > > >
> > > > >
> > > > > > Regards,
> > > > > > Christian.
> > > > > >
> > > > > > > So the only really working alternative solution I can see
> > > > > > > is
> > > > > > > that
> > > > > > > drm_exec_trylock simply fails if there is a contended
> > > > > > > lock
> > > > > > > and
> > > > > > > we'd
> > > > > > > need to live with the weird bo creation situation
> > > > > > > described
> > > > > > > above.
> > > > > > >
> > > > > > > /Thomas
> > > > > > >
> > > > > > > > Regards,
> > > > > > > > Christian.
> > > > > > > >
> > > > > > > > > Cc: Christian König<christian.koenig@amd.com>
> > > > > > > > > Cc: Somalapuram
> > > > > > > > > Amaranath<Amaranath.Somalapuram@amd.com>
> > > > > > > > > Cc: Matthew Brost<matthew.brost@intel.com>
> > > > > > > > > Cc:<dri-devel@lists.freedesktop.org>
> > > > > > > > > Signed-off-by: Thomas
> > > > > > > > > Hellström<thomas.hellstrom@linux.intel.com>
> > > > > > > > > ---
> > > > > > > > > .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |
> > > > > > > > > 16
> > > > > > > > > ++++---
> > > > > > > > > --
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c |
> > > > > > > > > 6
> > > > > > > > > ++--
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c |
> > > > > > > > > 4 +-
> > > > > > > > > -
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c |
> > > > > > > > > 8
> > > > > > > > > ++---
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c |
> > > > > > > > > 8
> > > > > > > > > ++---
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c |
> > > > > > > > > 4 +-
> > > > > > > > > -
> > > > > > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c |
> > > > > > > > > 8
> > > > > > > > > ++---
> > > > > > > > > drivers/gpu/drm/amd/amdkfd/kfd_svm.c |
> > > > > > > > > 2 +-
> > > > > > > > > drivers/gpu/drm/drm_exec.c |
> > > > > > > > > 35
> > > > > > > > > ++++++++++++++-----
> > > > > > > > > drivers/gpu/drm/drm_gpuvm.c |
> > > > > > > > > 8
> > > > > > > > > ++---
> > > > > > > > > drivers/gpu/drm/imagination/pvr_job.c |
> > > > > > > > > 2 +-
> > > > > > > > > drivers/gpu/drm/msm/msm_gem_submit.c |
> > > > > > > > > 2 +-
> > > > > > > > > drivers/gpu/drm/nouveau/nouveau_uvmm.c |
> > > > > > > > > 2 +-
> > > > > > > > > drivers/gpu/drm/tests/drm_exec_test.c |
> > > > > > > > > 12
> > > > > > > > > +++----
> > > > > > > > > drivers/gpu/drm/xe/xe_gt_pagefault.c |
> > > > > > > > > 4 +-
> > > > > > > > > -
> > > > > > > > > drivers/gpu/drm/xe/xe_vm.c |
> > > > > > > > > 10
> > > > > > > > > +++---
> > > > > > > > > include/drm/drm_exec.h |
> > > > > > > > > 23
> > > > > > > > > +++++++++---
> > > > > > > > > 17 files changed, 92 insertions(+), 62
> > > > > > > > > deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git
> > > > > > > > > a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > > > index e4d4e55c08ad..4a08a692aa1f 100644
> > > > > > > > > ---
> > > > > > > > > a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > > > +++
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> > > > > > > > > @@ -1152,12 +1152,12 @@ static int
> > > > > > > > > reserve_bo_and_vm(struct
> > > > > > > > > kgd_mem
> > > > > > > > > *mem,
> > > > > > > > > drm_exec_init(&ctx->exec,
> > > > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&ctx->exec) {
> > > > > > > > > ret = amdgpu_vm_lock_pd(vm, &ctx-
> > > > > > > > > >exec,
> > > > > > > > > 2);
> > > > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto error;
> > > > > > > > >
> > > > > > > > > ret = drm_exec_prepare_obj(&ctx-
> > > > > > > > > >exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base, 1);
> > > > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > @@ -1199,14 +1199,14 @@ static int
> > > > > > > > > reserve_bo_and_cond_vms(struct
> > > > > > > > > kgd_mem *mem,
> > > > > > > > >
> > > > > > > > > ret =
> > > > > > > > > amdgpu_vm_lock_pd(entry-
> > > > > > > > > > bo_va-
> > > > > > > > > > base.vm,
> > > > > > > > > &ctx
> > > > > > > > > -
> > > > > > > > > > exec,
> > > > > > > > > 2);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&ctx-
> > > > > > > > > > exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec, ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto error;
> > > > > > > > > ++ctx->n_vms;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > ret = drm_exec_prepare_obj(&ctx-
> > > > > > > > > >exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base, 1);
> > > > > > > > > - drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > @@ -2619,7 +2619,7 @@ static int
> > > > > > > > > validate_invalid_user_pages(struct
> > > > > > > > > amdkfd_process_info *process_info)
> > > > > > > > > list_for_each_entry(peer_vm,
> > > > > > > > > &process_info-
> > > > > > > > > > vm_list_head,
> > > > > > > > > vm_list_node) {
> > > > > > > > > ret =
> > > > > > > > > amdgpu_vm_lock_pd(peer_vm,
> > > > > > > > > &exec,
> > > > > > > > > 2);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto unreserve_out;
> > > > > > > > > }
> > > > > > > > > @@ -2631,7 +2631,7 @@ static int
> > > > > > > > > validate_invalid_user_pages(struct
> > > > > > > > > amdkfd_process_info *process_info)
> > > > > > > > >
> > > > > > > > > gobj = &mem->bo->tbo.base;
> > > > > > > > > ret =
> > > > > > > > > drm_exec_prepare_obj(&exec,
> > > > > > > > > gobj,
> > > > > > > > > 1);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret))
> > > > > > > > > goto unreserve_out;
> > > > > > > > > }
> > > > > > > > > @@ -2875,7 +2875,7 @@ int
> > > > > > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
> > > > > > > > > struct
> > > > > > > > > dma_fence __rcu *
> > > > > > > > > list_for_each_entry(peer_vm,
> > > > > > > > > &process_info-
> > > > > > > > > > vm_list_head,
> > > > > > > > > vm_list_node) {
> > > > > > > > > ret =
> > > > > > > > > amdgpu_vm_lock_pd(peer_vm,
> > > > > > > > > &exec,
> > > > > > > > > 2);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret)) {
> > > > > > > > > pr_err("Locking VM
> > > > > > > > > PD
> > > > > > > > > failed,
> > > > > > > > > ret:
> > > > > > > > > %d\n", ret);
> > > > > > > > > goto
> > > > > > > > > ttm_reserve_fail;
> > > > > > > > > @@ -2891,7 +2891,7 @@ int
> > > > > > > > > amdgpu_amdkfd_gpuvm_restore_process_bos(void *info,
> > > > > > > > > struct
> > > > > > > > > dma_fence __rcu *
> > > > > > > > >
> > > > > > > > > gobj = &mem->bo->tbo.base;
> > > > > > > > > ret =
> > > > > > > > > drm_exec_prepare_obj(&exec,
> > > > > > > > > gobj,
> > > > > > > > > 1);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (unlikely(ret)) {
> > > > > > > > > pr_err("drm_exec_pre
> > > > > > > > > pare
> > > > > > > > > _obj
> > > > > > > > > failed, ret: %d\n", ret);
> > > > > > > > > goto
> > > > > > > > > ttm_reserve_fail;
> > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > > > index ec888fc6ead8..299e46a6d934 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > > > > > > > > @@ -897,7 +897,7 @@ static int
> > > > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > > > amdgpu_cs_parser *p,
> > > > > > > > >
> > > > > > > > > drm_exec_until_all_locked(&p->exec) {
> > > > > > > > > r = amdgpu_vm_lock_pd(&fpriv->vm,
> > > > > > > > > &p-
> > > > > > > > > > exec,
> > > > > > > > > 1
> > > > > > > > > + p-
> > > > > > > > > > gang_size);
> > > > > > > > > - drm_exec_retry_on_contention(&p-
> > > > > > > > > >exec);
> > > > > > > > > + r = drm_exec_retry_on_contention(&p-
> > > > > > > > > > exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_free_user_pages;
> > > > > > > > >
> > > > > > > > > @@ -905,7 +905,7 @@ static int
> > > > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > > > amdgpu_cs_parser *p,
> > > > > > > > > /* One fence for TTM and one
> > > > > > > > > for
> > > > > > > > > each
> > > > > > > > > CS
> > > > > > > > > job */
> > > > > > > > > r = drm_exec_prepare_obj(&p-
> > > > > > > > > > exec,
> > > > > > > > > &e-
> > > > > > > > > > bo-
> > > > > > > > > > tbo.base,
> > > > > > > > > 1 +
> > > > > > > > > p-
> > > > > > > > > > gang_size);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > > > exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > > > exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto
> > > > > > > > > out_free_user_pages;
> > > > > > > > >
> > > > > > > > > @@ -915,7 +915,7 @@ static int
> > > > > > > > > amdgpu_cs_parser_bos(struct
> > > > > > > > > amdgpu_cs_parser *p,
> > > > > > > > > if (p->uf_bo) {
> > > > > > > > > r = drm_exec_prepare_obj(&p-
> > > > > > > > > > exec,
> > > > > > > > > &p-
> > > > > > > > > > uf_bo->tbo.base,
> > > > > > > > > 1 +
> > > > > > > > > p-
> > > > > > > > > > gang_size);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > > > exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&p-
> > > > > > > > > > exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto
> > > > > > > > > out_free_user_pages;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > > > index cfdf558b48b6..8b2b86c7a6c5 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
> > > > > > > > > @@ -74,7 +74,7 @@ int amdgpu_map_static_csa(struct
> > > > > > > > > amdgpu_device
> > > > > > > > > *adev, struct amdgpu_vm *vm,
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > if (likely(!r))
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r)) {
> > > > > > > > > DRM_ERROR("failed to reserve
> > > > > > > > > CSA,PD
> > > > > > > > > BOs:
> > > > > > > > > err=%d\n", r);
> > > > > > > > > goto error;
> > > > > > > > > @@ -114,7 +114,7 @@ int
> > > > > > > > > amdgpu_unmap_static_csa(struct
> > > > > > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > if (likely(!r))
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r)) {
> > > > > > > > > DRM_ERROR("failed to reserve
> > > > > > > > > CSA,PD
> > > > > > > > > BOs:
> > > > > > > > > err=%d\n", r);
> > > > > > > > > goto error;
> > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > > > index 67c234bcf89f..17e16c971e21 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > > > > > > > @@ -239,12 +239,12 @@ static void
> > > > > > > > > amdgpu_gem_object_close(struct
> > > > > > > > > drm_gem_object *obj,
> > > > > > > > > drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_IGNORE_DUPLICATES,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > r = drm_exec_prepare_obj(&exec, &bo-
> > > > > > > > > > tbo.base,
> > > > > > > > > 1);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > > }
> > > > > > > > > @@ -776,13 +776,13 @@ int amdgpu_gem_va_ioctl(struct
> > > > > > > > > drm_device
> > > > > > > > > *dev, void *data,
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > if (gobj) {
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > gobj);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(&fpriv->vm,
> > > > > > > > > &exec,
> > > > > > > > > 2);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > > > index 5ca5c47ab54e..1b1a5147606e 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> > > > > > > > > @@ -1221,12 +1221,12 @@ int
> > > > > > > > > amdgpu_mes_ctx_map_meta_data(struct
> > > > > > > > > amdgpu_device *adev,
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &ctx_data-
> > > > > > > > > > meta_data_obj-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error_fini_exec;
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error_fini_exec;
> > > > > > > > > }
> > > > > > > > > @@ -1292,12 +1292,12 @@ int
> > > > > > > > > amdgpu_mes_ctx_unmap_meta_data(struct
> > > > > > > > > amdgpu_device *adev,
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &ctx_data-
> > > > > > > > > > meta_data_obj-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > > }
> > > > > > > > > diff --git
> > > > > > > > > a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > > > index e22cb2b5cd92..72b8213e352c 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
> > > > > > > > > @@ -77,7 +77,7 @@ int amdgpu_seq64_map(struct
> > > > > > > > > amdgpu_device
> > > > > > > > > *adev,
> > > > > > > > > struct amdgpu_vm *vm,
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > if (likely(!r))
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > @@ -138,7 +138,7 @@ void amdgpu_seq64_unmap(struct
> > > > > > > > > amdgpu_device
> > > > > > > > > *adev, struct amdgpu_fpriv *fpriv)
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > if (likely(!r))
> > > > > > > > > r = drm_exec_lock_obj(&exec,
> > > > > > > > > &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > diff --git
> > > > > > > > > a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > > > index e01c1c8e64c4..63392ce43945 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
> > > > > > > > > @@ -89,12 +89,12 @@ static int map_ring_data(struct
> > > > > > > > > amdgpu_device
> > > > > > > > > *adev, struct amdgpu_vm *vm,
> > > > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error_fini_exec;
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto error_fini_exec;
> > > > > > > > > }
> > > > > > > > > @@ -152,12 +152,12 @@ static int
> > > > > > > > > unmap_ring_data(struct
> > > > > > > > > amdgpu_device *adev, struct amdgpu_vm *vm,
> > > > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > r = drm_exec_lock_obj(&exec, &bo-
> > > > > > > > > > tbo.base);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm, &exec, 0);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > r);
> > > > > > > > > if (unlikely(r))
> > > > > > > > > goto out_unlock;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > > > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > > > index 386875e6eb96..a3aa7fd22f6a 100644
> > > > > > > > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> > > > > > > > > @@ -1499,7 +1499,7 @@ static int
> > > > > > > > > svm_range_reserve_bos(struct
> > > > > > > > > svm_validate_context *ctx, bool intr)
> > > > > > > > > vm = drm_priv_to_vm(pdd-
> > > > > > > > > > drm_priv);
> > > > > > > > >
> > > > > > > > > r = amdgpu_vm_lock_pd(vm,
> > > > > > > > > &ctx-
> > > > > > > > > > exec,
> > > > > > > > > 2);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&ctx-
> > > > > > > > > > exec);
> > > > > > > > > + r =
> > > > > > > > > drm_exec_retry_on_contention(&ctx-
> > > > > > > > > > exec, r);
> > > > > > > > > if (unlikely(r)) {
> > > > > > > > > pr_debug("failed %d
> > > > > > > > > to
> > > > > > > > > reserve
> > > > > > > > > bo\n", r);
> > > > > > > > > goto unreserve_out;
> > > > > > > > > diff --git a/drivers/gpu/drm/drm_exec.c
> > > > > > > > > b/drivers/gpu/drm/drm_exec.c
> > > > > > > > > index 2da094bdf8a4..3770a5d30213 100644
> > > > > > > > > --- a/drivers/gpu/drm/drm_exec.c
> > > > > > > > > +++ b/drivers/gpu/drm/drm_exec.c
> > > > > > > > > @@ -28,12 +28,12 @@
> > > > > > > > > * drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT);
> > > > > > > > > * drm_exec_until_all_locked(&exec) {
> > > > > > > > > * ret = drm_exec_prepare_obj(&exec,
> > > > > > > > > boA,
> > > > > > > > > 1);
> > > > > > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > > > > > + * ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > * if (ret)
> > > > > > > > > * goto error;
> > > > > > > > > *
> > > > > > > > > * ret = drm_exec_prepare_obj(&exec,
> > > > > > > > > boB,
> > > > > > > > > 1);
> > > > > > > > > - * drm_exec_retry_on_contention(&exec);
> > > > > > > > > + * ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > * if (ret)
> > > > > > > > > * goto error;
> > > > > > > > > * }
> > > > > > > > > @@ -48,7 +48,8 @@
> > > > > > > > > */
> > > > > > > > >
> > > > > > > > > /* Dummy value used to initially enter the retry
> > > > > > > > > loop
> > > > > > > > > */
> > > > > > > > > -#define DRM_EXEC_DUMMY ((void *)~0)
> > > > > > > > > +#define DRM_EXEC_DUMMY ERR_PTR(-ESTALE)
> > > > > > > > > +#define DRM_EXEC_CONTENDED ERR_PTR(-EDEADLK)
> > > > > > > > >
> > > > > > > > > /* Unlock all objects and drop references */
> > > > > > > > > static void drm_exec_unlock_all(struct drm_exec
> > > > > > > > > *exec)
> > > > > > > > > @@ -131,8 +132,7 @@ bool drm_exec_cleanup(struct
> > > > > > > > > drm_exec
> > > > > > > > > *exec)
> > > > > > > > > return true;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > - drm_exec_unlock_all(exec);
> > > > > > > > > - exec->num_objects = 0;
> > > > > > > > > + exec->contended = NULL;
> > > > > > > > > return true;
> > > > > > > > > }
> > > > > > > > > EXPORT_SYMBOL(drm_exec_cleanup);
> > > > > > > > > @@ -194,6 +194,27 @@ static int
> > > > > > > > > drm_exec_lock_contended(struct
> > > > > > > > > drm_exec *exec)
> > > > > > > > > return ret;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > +/**
> > > > > > > > > + * drm_exec_handle_contended() - Perform cleanup
> > > > > > > > > before
> > > > > > > > > a ww
> > > > > > > > > transaction restart
> > > > > > > > > + * @exec: Pointer to the drm_exec object.
> > > > > > > > > + *
> > > > > > > > > + * Unlocks all held resvs and re-locks the contended
> > > > > > > > > object.
> > > > > > > > > + *
> > > > > > > > > + * Return: 0 on success, negative error code on
> > > > > > > > > failure.
> > > > > > > > > + */
> > > > > > > > > +int drm_exec_handle_contended(struct drm_exec *exec)
> > > > > > > > > +{
> > > > > > > > > + int ret;
> > > > > > > > > +
> > > > > > > > > + drm_exec_unlock_all(exec);
> > > > > > > > > + exec->num_objects = 0;
> > > > > > > > > + ret = drm_exec_lock_contended(exec);
> > > > > > > > > + exec->contended = DRM_EXEC_CONTENDED;
> > > > > > > > > +
> > > > > > > > > + return ret;
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(drm_exec_handle_contended);
> > > > > > > > > +
> > > > > > > > > /**
> > > > > > > > > * drm_exec_lock_obj - lock a GEM object for use
> > > > > > > > > * @exec: the drm_exec object with the state
> > > > > > > > > @@ -209,10 +230,6 @@ int drm_exec_lock_obj(struct
> > > > > > > > > drm_exec
> > > > > > > > > *exec,
> > > > > > > > > struct drm_gem_object *obj)
> > > > > > > > > {
> > > > > > > > > int ret;
> > > > > > > > >
> > > > > > > > > - ret = drm_exec_lock_contended(exec);
> > > > > > > > > - if (unlikely(ret))
> > > > > > > > > - return ret;
> > > > > > > > > -
> > > > > > > > > if (exec->prelocked == obj) {
> > > > > > > > > drm_gem_object_put(exec->prelocked);
> > > > > > > > > exec->prelocked = NULL;
> > > > > > > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > > > b/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > > > index f9eb56f24bef..0923d6ae18e2 100644
> > > > > > > > > --- a/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > > > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > > > > > > > > @@ -1254,18 +1254,18 @@ drm_gpuvm_exec_lock(struct
> > > > > > > > > drm_gpuvm_exec
> > > > > > > > > *vm_exec)
> > > > > > > > >
> > > > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > > > ret = drm_gpuvm_prepare_vm(gpuvm,
> > > > > > > > > exec,
> > > > > > > > > num_fences);
> > > > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto err;
> > > > > > > > >
> > > > > > > > > ret =
> > > > > > > > > drm_gpuvm_prepare_objects(gpuvm,
> > > > > > > > > exec,
> > > > > > > > > num_fences);
> > > > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto err;
> > > > > > > > >
> > > > > > > > > if (vm_exec->extra.fn) {
> > > > > > > > > ret = vm_exec-
> > > > > > > > > > extra.fn(vm_exec);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto err;
> > > > > > > > > }
> > > > > > > > > @@ -1346,7 +1346,7 @@
> > > > > > > > > drm_gpuvm_exec_lock_range(struct
> > > > > > > > > drm_gpuvm_exec *vm_exec,
> > > > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > > > ret = drm_gpuvm_prepare_range(gpuvm,
> > > > > > > > > exec,
> > > > > > > > > addr,
> > > > > > > > > range,
> > > > > > > > >
> > > > > > > > > vm_exec-
> > > > > > > > > > num_fences);
> > > > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto err;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > > > b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > > > index 78c2f3c6dce0..6e0ce6c4576c 100644
> > > > > > > > > --- a/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > > > +++ b/drivers/gpu/drm/imagination/pvr_job.c
> > > > > > > > > @@ -574,7 +574,7 @@ prepare_job_resvs_for_each(struct
> > > > > > > > > drm_exec
> > > > > > > > > *exec, struct pvr_job_data *job_data,
> > > > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > > > int err = jobs_lock_all_objs(exec,
> > > > > > > > > job_data,
> > > > > > > > > job_count);
> > > > > > > > >
> > > > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > err);
> > > > > > > > > if (err)
> > > > > > > > > return err;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > > > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > > > index fba78193127d..01992b43ea4b 100644
> > > > > > > > > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > > > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > > > > > > > > @@ -259,7 +259,7 @@ static int
> > > > > > > > > submit_lock_objects(struct
> > > > > > > > > msm_gem_submit *submit)
> > > > > > > > > for (unsigned i = 0; i < submit-
> > > > > > > > > >nr_bos;
> > > > > > > > > i++)
> > > > > > > > > {
> > > > > > > > > struct drm_gem_object *obj =
> > > > > > > > > submit-
> > > > > > > > > > bos[i].obj;
> > > > > > > > > ret =
> > > > > > > > > drm_exec_prepare_obj(&submit-
> > > > > > > > > > exec,
> > > > > > > > > obj, 1);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_contention
> > > > > > > > > (&su
> > > > > > > > > bmit-
> > > > > > > > > > exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&submit->exec, ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto error;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > > > b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > > > index ee02cd833c5e..0c871634fdfb 100644
> > > > > > > > > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > > > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > > > > > > > > @@ -1350,7 +1350,7 @@
> > > > > > > > > nouveau_uvmm_bind_job_submit(struct
> > > > > > > > > nouveau_job *job,
> > > > > > > > > drm_exec_init(exec, vme->flags, 0);
> > > > > > > > > drm_exec_until_all_locked(exec) {
> > > > > > > > > ret = bind_lock_validate(job, exec,
> > > > > > > > > vme-
> > > > > > > > > > num_fences);
> > > > > > > > > - drm_exec_retry_on_contention(exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret) {
> > > > > > > > > op = list_last_op(&bind_job-
> > > > > > > > > > ops);
> > > > > > > > > goto unwind;
> > > > > > > > > diff --git a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > > > b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > > > index 81f928a429ba..28558fdb08df 100644
> > > > > > > > > --- a/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > > > +++ b/drivers/gpu/drm/tests/drm_exec_test.c
> > > > > > > > > @@ -63,7 +63,7 @@ static void test_lock(struct kunit
> > > > > > > > > *test)
> > > > > > > > > drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = drm_exec_lock_obj(&exec,
> > > > > > > > > &gobj);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > > @@ -83,14 +83,14 @@ static void
> > > > > > > > > test_lock_unlock(struct
> > > > > > > > > kunit
> > > > > > > > > *test)
> > > > > > > > > drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = drm_exec_lock_obj(&exec,
> > > > > > > > > &gobj);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > >
> > > > > > > > > drm_exec_unlock_obj(&exec, &gobj);
> > > > > > > > > ret = drm_exec_lock_obj(&exec,
> > > > > > > > > &gobj);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > > @@ -110,13 +110,13 @@ static void
> > > > > > > > > test_duplicates(struct
> > > > > > > > > kunit
> > > > > > > > > *test)
> > > > > > > > > drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_IGNORE_DUPLICATES,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = drm_exec_lock_obj(&exec,
> > > > > > > > > &gobj);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > >
> > > > > > > > > ret = drm_exec_lock_obj(&exec,
> > > > > > > > > &gobj);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > > @@ -137,7 +137,7 @@ static void test_prepare(struct
> > > > > > > > > kunit
> > > > > > > > > *test)
> > > > > > > > > drm_exec_init(&exec,
> > > > > > > > > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = drm_exec_prepare_obj(&exec,
> > > > > > > > > &gobj,
> > > > > > > > > 1);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > KUNIT_EXPECT_EQ(test, ret, 0);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > > > index 040dd142c49c..20ec1ab1b52d 100644
> > > > > > > > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > > > > > > @@ -200,7 +200,7 @@ static int
> > > > > > > > > handle_pagefault(struct
> > > > > > > > > xe_gt
> > > > > > > > > *gt,
> > > > > > > > > struct pagefault *pf)
> > > > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = xe_pf_begin(&exec, vma,
> > > > > > > > > atomic,
> > > > > > > > > tile-
> > > > > > > > > > id);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > goto unlock_dma_resv;
> > > > > > > > >
> > > > > > > > > @@ -543,7 +543,7 @@ static int handle_acc(struct
> > > > > > > > > xe_gt
> > > > > > > > > *gt,
> > > > > > > > > struct
> > > > > > > > > acc *acc)
> > > > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > ret = xe_pf_begin(&exec, vma, true,
> > > > > > > > > tile-
> > > > > > > > > > id);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + ret =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > ret);
> > > > > > > > > if (ret)
> > > > > > > > > break;
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > > > b/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > > > index e2ec148c9c33..335524e803e7 100644
> > > > > > > > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > > > > > > > @@ -501,7 +501,7 @@ static void
> > > > > > > > > preempt_rebind_work_func(struct
> > > > > > > > > work_struct *w)
> > > > > > > > > bool done = false;
> > > > > > > > >
> > > > > > > > > err = xe_preempt_work_begin(&exec,
> > > > > > > > > vm,
> > > > > > > > > &done);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > err);
> > > > > > > > > if (err || done) {
> > > > > > > > > drm_exec_fini(&exec);
> > > > > > > > > if (err &&
> > > > > > > > > xe_vm_validate_should_retry(&exec, err, &end))
> > > > > > > > > @@ -1052,7 +1052,7 @@ static void
> > > > > > > > > xe_vma_destroy_unlocked(struct
> > > > > > > > > xe_vma *vma)
> > > > > > > > > drm_exec_init(&exec, 0, 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > err = xe_vm_lock_vma(&exec, vma);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > err);
> > > > > > > > > if (XE_WARN_ON(err))
> > > > > > > > > break;
> > > > > > > > > }
> > > > > > > > > @@ -2148,11 +2148,11 @@ static struct xe_vma
> > > > > > > > > *new_vma(struct
> > > > > > > > > xe_vm
> > > > > > > > > *vm, struct drm_gpuva_op_map *op,
> > > > > > > > > err = 0;
> > > > > > > > > if (!bo->vm) {
> > > > > > > > > err =
> > > > > > > > > drm_exec_lock_obj(&exec,
> > > > > > > > > xe_vm_obj(vm));
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_co
> > > > > > > > > nten
> > > > > > > > > tion
> > > > > > > > > (&
> > > > > > > > > exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > > > > > }
> > > > > > > > > if (!err) {
> > > > > > > > > err =
> > > > > > > > > drm_exec_lock_obj(&exec,
> > > > > > > > > &bo->ttm.base);
> > > > > > > > > -
> > > > > > > > > drm_exec_retry_on_co
> > > > > > > > > nten
> > > > > > > > > tion
> > > > > > > > > (&
> > > > > > > > > exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(&exec, err);
> > > > > > > > > }
> > > > > > > > > if (err) {
> > > > > > > > > drm_exec_fini(&exec)
> > > > > > > > > ;
> > > > > > > > > @@ -2884,7 +2884,7 @@ static int
> > > > > > > > > vm_bind_ioctl_ops_execute(struct
> > > > > > > > > xe_vm *vm,
> > > > > > > > > DRM_EXEC_IGNORE_DUPLICATES,
> > > > > > > > > 0);
> > > > > > > > > drm_exec_until_all_locked(&exec) {
> > > > > > > > > err =
> > > > > > > > > vm_bind_ioctl_ops_lock_and_prep(&exec,
> > > > > > > > > vm,
> > > > > > > > > vops);
> > > > > > > > > - drm_exec_retry_on_contention(&exec);
> > > > > > > > > + err =
> > > > > > > > > drm_exec_retry_on_contention(&exec,
> > > > > > > > > err);
> > > > > > > > > if (err)
> > > > > > > > > goto unlock;
> > > > > > > > >
> > > > > > > > > diff --git a/include/drm/drm_exec.h
> > > > > > > > > b/include/drm/drm_exec.h
> > > > > > > > > index aa786b828a0a..fafb40d96e38 100644
> > > > > > > > > --- a/include/drm/drm_exec.h
> > > > > > > > > +++ b/include/drm/drm_exec.h
> > > > > > > > > @@ -51,6 +51,8 @@ struct drm_exec {
> > > > > > > > > struct drm_gem_object *prelocked;
> > > > > > > > > };
> > > > > > > > >
> > > > > > > > > +int drm_exec_handle_contended(struct drm_exec
> > > > > > > > > *exec);
> > > > > > > > > +
> > > > > > > > > /**
> > > > > > > > > * drm_exec_obj() - Return the object for a give
> > > > > > > > > drm_exec
> > > > > > > > > index
> > > > > > > > > * @exec: Pointer to the drm_exec context
> > > > > > > > > @@ -113,15 +115,26 @@ __PASTE(__drm_exec_,
> > > > > > > > > __LINE__):
> > > > > > > > > \
> > > > > > > > > /**
> > > > > > > > > * drm_exec_retry_on_contention - restart the
> > > > > > > > > loop to
> > > > > > > > > grap
> > > > > > > > > all
> > > > > > > > > locks
> > > > > > > > > * @exec: drm_exec object
> > > > > > > > > + * @_ret: The current error status
> > > > > > > > > *
> > > > > > > > > * Control flow helper to continue when a
> > > > > > > > > contention
> > > > > > > > > was
> > > > > > > > > detected
> > > > > > > > > and we need to
> > > > > > > > > * clean up and re-start the loop to prepare all
> > > > > > > > > GEM
> > > > > > > > > objects.
> > > > > > > > > + *
> > > > > > > > > + * Return: If no loop restart occurred: The error
> > > > > > > > > status.
> > > > > > > > > */
> > > > > > > > > -#define
> > > > > > > > > drm_exec_retry_on_contention(exec)
> > > > > > > > > \
> > > > > > > > > - do
> > > > > > > > > {
> > > > > > > > > \
> > > > > > > > > - if
> > > > > > > > > (unlikely(drm_exec_is_contended(exec))) \
> > > > > > > > > - goto
> > > > > > > > > *__drm_exec_retry_ptr; \
> > > > > > > > > - } while (0)
> > > > > > > > > +#define drm_exec_retry_on_contention(exec,
> > > > > > > > > _ret) \
> > > > > > > > > + ({
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > \
> > > > > > > > > + struct drm_exec *__exec =
> > > > > > > > > (exec); \
> > > > > > > > > + int __ret =
> > > > > > > > > (_ret); \
> > > > > > > > > +
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > \
> > > > > > > > > + if
> > > > > > > > > (unlikely(drm_exec_is_contended(__exec)))
> > > > > > > > > { \
> > > > > > > > > + WARN_ON(__ret != -
> > > > > > > > > EDEADLK); \
> > > > > > > > > + __ret =
> > > > > > > > > drm_exec_handle_contended(__exec); \
> > > > > > > > > + if
> > > > > > > > > (!__ret) \
> > > > > > > > > + goto
> > > > > > > > > *__drm_exec_retry_ptr; \
> > > > > > > > > + }
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > \
> > > > > > > > > + __ret;
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > \
> > > > > > > > > + })
> > > > > > > > >
> > > > > > > > > /**
> > > > > > > > > * drm_exec_is_contended - check for contention
^ permalink raw reply [flat|nested] 50+ messages in thread
end of thread, other threads:[~2024-05-29 7:18 UTC | newest]
Thread overview: 50+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-21 7:16 [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 01/21] drm/ttm: Allow TTM LRU list nodes of different types Thomas Hellström
2024-05-21 13:12 ` Matthew Brost
2024-05-28 9:16 ` Christian König
2024-05-21 7:16 ` [PATCH v3 02/21] drm/ttm: Slightly clean up LRU list iteration Thomas Hellström
2024-05-21 15:39 ` Matthew Brost
2024-05-28 9:19 ` Christian König
2024-05-21 7:16 ` [PATCH v3 03/21] drm/ttm: Use LRU hitches Thomas Hellström
2024-05-21 16:09 ` Matthew Brost
2024-05-21 7:16 ` [PATCH v3 04/21] drm/ttm, drm/amdgpu, drm/xe: Consider hitch moves within bulk sublist moves Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 05/21] drm/ttm: Provide a generic LRU walker helper Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 06/21] drm/ttm: Use the LRU walker helper for swapping Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 07/21] drm/ttm: Use the LRU walker for eviction Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 08/21] drm/ttm: Add a virtual base class for graphics memory backup Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 09/21] drm/ttm/pool: Provide a helper to shrink pages Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 10/21] drm/ttm: Use fault-injection to test error paths Thomas Hellström
2024-05-21 7:16 ` [PATCH v3 11/21] drm/ttm, drm/xe: Add a shrinker for xe bos Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 12/21] dma-buf/dma-resv: Introduce dma_resv_trylock_ctx() Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 13/21] drm/exec: Rework contended locking Thomas Hellström
2024-05-22 5:52 ` Christian König
2024-05-22 14:32 ` Thomas Hellström
2024-05-22 16:52 ` Christian König
2024-05-22 17:42 ` Thomas Hellström
2024-05-28 6:36 ` Thomas Hellström
2024-05-28 6:51 ` Christian König
2024-05-28 8:07 ` Thomas Hellström
2024-05-28 11:03 ` Christian König
2024-05-29 7:18 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 14/21] drm/exec: Introduce a drm_exec_trylock_obj() function Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 15/21] drm/exec: Add a snapshot capability Thomas Hellström
2024-05-22 11:27 ` Christian König
2024-05-22 13:54 ` Thomas Hellström
2024-05-22 14:41 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 16/21] drm/exec: Introduce an evict mode Thomas Hellström
2024-05-22 13:28 ` Christian König
2024-05-22 13:44 ` Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 17/21] drm/ttm: Support drm_exec locking for eviction and swapping Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 18/21] drm/ttm: Convert ttm vm to using drm_exec Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 19/21] drm/xe: Use drm_exec for fault locking Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 20/21] drm/ttm: Use drm_exec_trylock for bo initialization Thomas Hellström
2024-05-21 7:16 ` [RFC PATCH v3 21/21] drm/xe: Initial support for drm exec locking during validate Thomas Hellström
2024-05-21 7:22 ` [PATCH v3 00/21] TTM shrinker helpers and xe buffer object shrinker Thomas Hellström
2024-05-21 7:23 ` ✓ CI.Patch_applied: success for TTM shrinker helpers and xe buffer object shrinker (rev3) Patchwork
2024-05-21 7:24 ` ✗ CI.checkpatch: warning " Patchwork
2024-05-21 7:25 ` ✓ CI.KUnit: success " Patchwork
2024-05-21 7:37 ` ✓ CI.Build: " Patchwork
2024-05-21 7:39 ` ✗ CI.Hooks: failure " Patchwork
2024-05-21 7:41 ` ✗ CI.checksparse: warning " Patchwork
2024-05-21 8:03 ` ✓ CI.BAT: success " Patchwork
2024-05-21 9:09 ` ✗ CI.FULL: failure " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox