rockchip: backport latest panthor fixes
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
parent
6503996249
commit
10f9bf6a8c
@ -101,7 +101,7 @@ Signed-off-by: Luben Tuikov <ltuikov89@gmail.com>
|
||||
continue;
|
||||
|
||||
spin_lock(&ring->sched.job_list_lock);
|
||||
@@ -4752,7 +4752,7 @@ int amdgpu_device_pre_asic_reset(struct
|
||||
@@ -4755,7 +4755,7 @@ int amdgpu_device_pre_asic_reset(struct
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
@ -110,7 +110,7 @@ Signed-off-by: Luben Tuikov <ltuikov89@gmail.com>
|
||||
continue;
|
||||
|
||||
/* Clear job fence from fence drv to avoid force_completion
|
||||
@@ -5292,7 +5292,7 @@ int amdgpu_device_gpu_recover(struct amd
|
||||
@@ -5295,7 +5295,7 @@ int amdgpu_device_gpu_recover(struct amd
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
||||
@ -119,7 +119,7 @@ Signed-off-by: Luben Tuikov <ltuikov89@gmail.com>
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, job ? &job->base : NULL);
|
||||
@@ -5367,7 +5367,7 @@ skip_hw_reset:
|
||||
@@ -5370,7 +5370,7 @@ skip_hw_reset:
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
||||
@ -128,7 +128,7 @@ Signed-off-by: Luben Tuikov <ltuikov89@gmail.com>
|
||||
continue;
|
||||
|
||||
drm_sched_start(&ring->sched, true);
|
||||
@@ -5693,7 +5693,7 @@ pci_ers_result_t amdgpu_pci_error_detect
|
||||
@@ -5696,7 +5696,7 @@ pci_ers_result_t amdgpu_pci_error_detect
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
@ -137,7 +137,7 @@ Signed-off-by: Luben Tuikov <ltuikov89@gmail.com>
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, NULL);
|
||||
@@ -5821,7 +5821,7 @@ void amdgpu_pci_resume(struct pci_dev *p
|
||||
@@ -5824,7 +5824,7 @@ void amdgpu_pci_resume(struct pci_dev *p
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
From be2d3e9d061552af6c50220ee7b7e76458a3080f Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 25 Apr 2024 12:39:20 +0200
|
||||
Subject: [PATCH] drm/panthor: Kill the faulty_slots variable in
|
||||
panthor_sched_suspend()
|
||||
|
||||
We can use upd_ctx.timedout_mask directly, and the faulty_slots update
|
||||
in the flush_caches_failed situation is never used.
|
||||
|
||||
Suggested-by: Suggested-by: Steven Price <steven.price@arm.com>
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240425103920.826458-1-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 10 +++-------
|
||||
1 file changed, 3 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -2546,8 +2546,8 @@ void panthor_sched_suspend(struct pantho
|
||||
{
|
||||
struct panthor_scheduler *sched = ptdev->scheduler;
|
||||
struct panthor_csg_slots_upd_ctx upd_ctx;
|
||||
- u32 suspended_slots, faulty_slots;
|
||||
struct panthor_group *group;
|
||||
+ u32 suspended_slots;
|
||||
u32 i;
|
||||
|
||||
mutex_lock(&sched->lock);
|
||||
@@ -2566,10 +2566,9 @@ void panthor_sched_suspend(struct pantho
|
||||
|
||||
csgs_upd_ctx_apply_locked(ptdev, &upd_ctx);
|
||||
suspended_slots &= ~upd_ctx.timedout_mask;
|
||||
- faulty_slots = upd_ctx.timedout_mask;
|
||||
|
||||
- if (faulty_slots) {
|
||||
- u32 slot_mask = faulty_slots;
|
||||
+ if (upd_ctx.timedout_mask) {
|
||||
+ u32 slot_mask = upd_ctx.timedout_mask;
|
||||
|
||||
drm_err(&ptdev->base, "CSG suspend failed, escalating to termination");
|
||||
csgs_upd_ctx_init(&upd_ctx);
|
||||
@@ -2620,9 +2619,6 @@ void panthor_sched_suspend(struct pantho
|
||||
|
||||
slot_mask &= ~BIT(csg_id);
|
||||
}
|
||||
-
|
||||
- if (flush_caches_failed)
|
||||
- faulty_slots |= suspended_slots;
|
||||
}
|
||||
|
||||
for (i = 0; i < sched->csg_slot_count; i++) {
|
||||
@ -0,0 +1,117 @@
|
||||
From 8bdbd8b5580b46c8cae365567f5bf6cc956e6512 Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 17:52:48 +0200
|
||||
Subject: [PATCH] drm/panthor: Make sure we handle 'unknown group state' case
|
||||
properly
|
||||
|
||||
When we check for state values returned by the FW, we only cover part of
|
||||
the 0:7 range. Make sure we catch FW inconsistencies by adding a default
|
||||
to the switch statement, and flagging the group state as unknown in that
|
||||
case.
|
||||
|
||||
When an unknown state is detected, we trigger a reset, and consider the
|
||||
group as unusable after that point, to prevent the potential corruption
|
||||
from creeping in other places if we continue executing stuff on this
|
||||
context.
|
||||
|
||||
v2:
|
||||
- Add Steve's R-b
|
||||
- Fix commit message
|
||||
|
||||
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
|
||||
Closes: https://lore.kernel.org/dri-devel/3b7fd2f2-679e-440c-81cd-42fc2573b515@moroto.mountain/T/#u
|
||||
Suggested-by: Steven Price <steven.price@arm.com>
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502155248.1430582-1-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 37 +++++++++++++++++++++++--
|
||||
1 file changed, 35 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -490,6 +490,18 @@ enum panthor_group_state {
|
||||
* Can no longer be scheduled. The only allowed action is a destruction.
|
||||
*/
|
||||
PANTHOR_CS_GROUP_TERMINATED,
|
||||
+
|
||||
+ /**
|
||||
+ * @PANTHOR_CS_GROUP_UNKNOWN_STATE: Group is an unknown state.
|
||||
+ *
|
||||
+ * The FW returned an inconsistent state. The group is flagged unusable
|
||||
+ * and can no longer be scheduled. The only allowed action is a
|
||||
+ * destruction.
|
||||
+ *
|
||||
+ * When that happens, we also schedule a FW reset, to start from a fresh
|
||||
+ * state.
|
||||
+ */
|
||||
+ PANTHOR_CS_GROUP_UNKNOWN_STATE,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1127,6 +1139,7 @@ csg_slot_sync_state_locked(struct pantho
|
||||
struct panthor_fw_csg_iface *csg_iface;
|
||||
struct panthor_group *group;
|
||||
enum panthor_group_state new_state, old_state;
|
||||
+ u32 csg_state;
|
||||
|
||||
lockdep_assert_held(&ptdev->scheduler->lock);
|
||||
|
||||
@@ -1137,7 +1150,8 @@ csg_slot_sync_state_locked(struct pantho
|
||||
return;
|
||||
|
||||
old_state = group->state;
|
||||
- switch (csg_iface->output->ack & CSG_STATE_MASK) {
|
||||
+ csg_state = csg_iface->output->ack & CSG_STATE_MASK;
|
||||
+ switch (csg_state) {
|
||||
case CSG_STATE_START:
|
||||
case CSG_STATE_RESUME:
|
||||
new_state = PANTHOR_CS_GROUP_ACTIVE;
|
||||
@@ -1148,11 +1162,28 @@ csg_slot_sync_state_locked(struct pantho
|
||||
case CSG_STATE_SUSPEND:
|
||||
new_state = PANTHOR_CS_GROUP_SUSPENDED;
|
||||
break;
|
||||
+ default:
|
||||
+ /* The unknown state might be caused by a FW state corruption,
|
||||
+ * which means the group metadata can't be trusted anymore, and
|
||||
+ * the SUSPEND operation might propagate the corruption to the
|
||||
+ * suspend buffers. Flag the group state as unknown to make
|
||||
+ * sure it's unusable after that point.
|
||||
+ */
|
||||
+ drm_err(&ptdev->base, "Invalid state on CSG %d (state=%d)",
|
||||
+ csg_id, csg_state);
|
||||
+ new_state = PANTHOR_CS_GROUP_UNKNOWN_STATE;
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (old_state == new_state)
|
||||
return;
|
||||
|
||||
+ /* The unknown state might be caused by a FW issue, reset the FW to
|
||||
+ * take a fresh start.
|
||||
+ */
|
||||
+ if (new_state == PANTHOR_CS_GROUP_UNKNOWN_STATE)
|
||||
+ panthor_device_schedule_reset(ptdev);
|
||||
+
|
||||
if (new_state == PANTHOR_CS_GROUP_SUSPENDED)
|
||||
csg_slot_sync_queues_state_locked(ptdev, csg_id);
|
||||
|
||||
@@ -1783,6 +1814,7 @@ static bool
|
||||
group_can_run(struct panthor_group *group)
|
||||
{
|
||||
return group->state != PANTHOR_CS_GROUP_TERMINATED &&
|
||||
+ group->state != PANTHOR_CS_GROUP_UNKNOWN_STATE &&
|
||||
!group->destroyed && group->fatal_queues == 0 &&
|
||||
!group->timedout;
|
||||
}
|
||||
@@ -2557,7 +2589,8 @@ void panthor_sched_suspend(struct pantho
|
||||
|
||||
if (csg_slot->group) {
|
||||
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i,
|
||||
- CSG_STATE_SUSPEND,
|
||||
+ group_can_run(csg_slot->group) ?
|
||||
+ CSG_STATE_SUSPEND : CSG_STATE_TERMINATE,
|
||||
CSG_STATE_MASK);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
From 2fa42fd910c4ede1ae9c18d535b425046fa49351 Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Tue, 30 Apr 2024 13:37:27 +0200
|
||||
Subject: [PATCH] drm/panthor: Fix the FW reset logic
|
||||
|
||||
In the post_reset function, if the fast reset didn't succeed, we
|
||||
are not clearing the fast_reset flag, which prevents firmware
|
||||
sections from being reloaded. While at it, use panthor_fw_stop()
|
||||
instead of manually writing DISABLE to the MCU_CONTROL register.
|
||||
|
||||
Fixes: 2718d91816ee ("drm/panthor: Add the FW logical block")
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240430113727.493155-1-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_fw.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
@@ -1083,10 +1083,11 @@ int panthor_fw_post_reset(struct panthor
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
- /* Force a disable, so we get a fresh boot on the next
|
||||
- * panthor_fw_start() call.
|
||||
+ /* Forcibly reset the MCU and force a slow reset, so we get a
|
||||
+ * fresh boot on the next panthor_fw_start() call.
|
||||
*/
|
||||
- gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_DISABLE);
|
||||
+ panthor_fw_stop(ptdev);
|
||||
+ ptdev->fw->fast_reset = false;
|
||||
drm_err(&ptdev->base, "FW fast reset failed, trying a slow reset");
|
||||
}
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
From d2143297579f12ea22479d403d955819838e7e67 Mon Sep 17 00:00:00 2001
|
||||
From: Antonino Maniscalco <antonino.maniscalco@collabora.com>
|
||||
Date: Thu, 2 May 2024 18:51:54 +0200
|
||||
Subject: [PATCH] drm/panthor: Fix tiler OOM handling to allow incremental
|
||||
rendering
|
||||
|
||||
If the kernel couldn't allocate memory because we reached the maximum
|
||||
number of chunks but no render passes are in flight
|
||||
(panthor_heap_grow() returning -ENOMEM), we should defer the OOM
|
||||
handling to the FW by returning a NULL chunk. The FW will then call
|
||||
the tiler OOM exception handler, which is supposed to implement
|
||||
incremental rendering (execute an intermediate fragment job to flush
|
||||
the pending primitives, release the tiler memory that was used to
|
||||
store those primitives, and start over from where it stopped).
|
||||
|
||||
Instead of checking for both ENOMEM and EBUSY, make panthor_heap_grow()
|
||||
return ENOMEM no matter the reason of this allocation failure, the FW
|
||||
doesn't care anyway.
|
||||
|
||||
v3:
|
||||
- Add R-bs
|
||||
|
||||
v2:
|
||||
- Make panthor_heap_grow() return -ENOMEM for all kind of allocation
|
||||
failures
|
||||
- Document the panthor_heap_grow() semantics
|
||||
|
||||
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
|
||||
Signed-off-by: Antonino Maniscalco <antonino.maniscalco@collabora.com>
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502165158.1458959-2-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_heap.c | 12 ++++++++----
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 7 ++++++-
|
||||
2 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
@@ -410,6 +410,13 @@ out_unlock:
|
||||
* @renderpasses_in_flight: Number of render passes currently in-flight.
|
||||
* @pending_frag_count: Number of fragment jobs waiting for execution/completion.
|
||||
* @new_chunk_gpu_va: Pointer used to return the chunk VA.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * - 0 if a new heap was allocated
|
||||
+ * - -ENOMEM if the tiler context reached the maximum number of chunks
|
||||
+ * or if too many render passes are in-flight
|
||||
+ * or if the allocation failed
|
||||
+ * - -EINVAL if any of the arguments passed to panthor_heap_grow() is invalid
|
||||
*/
|
||||
int panthor_heap_grow(struct panthor_heap_pool *pool,
|
||||
u64 heap_gpu_va,
|
||||
@@ -439,10 +446,7 @@ int panthor_heap_grow(struct panthor_hea
|
||||
* handler provided by the userspace driver, if any).
|
||||
*/
|
||||
if (renderpasses_in_flight > heap->target_in_flight ||
|
||||
- (pending_frag_count > 0 && heap->chunk_count >= heap->max_chunks)) {
|
||||
- ret = -EBUSY;
|
||||
- goto out_unlock;
|
||||
- } else if (heap->chunk_count >= heap->max_chunks) {
|
||||
+ heap->chunk_count >= heap->max_chunks) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -1385,7 +1385,12 @@ static int group_process_tiler_oom(struc
|
||||
pending_frag_count, &new_chunk_va);
|
||||
}
|
||||
|
||||
- if (ret && ret != -EBUSY) {
|
||||
+ /* If the heap context doesn't have memory for us, we want to let the
|
||||
+ * FW try to reclaim memory by waiting for fragment jobs to land or by
|
||||
+ * executing the tiler OOM exception handler, which is supposed to
|
||||
+ * implement incremental rendering.
|
||||
+ */
|
||||
+ if (ret && ret != -ENOMEM) {
|
||||
drm_warn(&ptdev->base, "Failed to extend the tiler heap\n");
|
||||
group->fatal_queues |= BIT(cs_id);
|
||||
sched_queue_delayed_work(sched, tick, 0);
|
||||
@ -0,0 +1,62 @@
|
||||
From e3193f0fbd6d83510ff6879ac248f42a7c0fefe7 Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 18:51:55 +0200
|
||||
Subject: [PATCH] drm/panthor: Make sure the tiler initial/max chunks are
|
||||
consistent
|
||||
|
||||
It doesn't make sense to have a maximum number of chunks smaller than
|
||||
the initial number of chunks attached to the context.
|
||||
|
||||
Fix the uAPI header to reflect the new constraint, and mention the
|
||||
undocumented "initial_chunk_count > 0" constraint while at it.
|
||||
|
||||
v3:
|
||||
- Add R-b
|
||||
|
||||
v2:
|
||||
- Fix the check
|
||||
|
||||
Fixes: 9cca48fa4f89 ("drm/panthor: Add the heap logical block")
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502165158.1458959-3-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_heap.c | 3 +++
|
||||
include/uapi/drm/panthor_drm.h | 8 ++++++--
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
@@ -281,6 +281,9 @@ int panthor_heap_create(struct panthor_h
|
||||
if (initial_chunk_count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (initial_chunk_count > max_chunks)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if (hweight32(chunk_size) != 1 ||
|
||||
chunk_size < SZ_256K || chunk_size > SZ_2M)
|
||||
return -EINVAL;
|
||||
--- a/include/uapi/drm/panthor_drm.h
|
||||
+++ b/include/uapi/drm/panthor_drm.h
|
||||
@@ -895,13 +895,17 @@ struct drm_panthor_tiler_heap_create {
|
||||
/** @vm_id: VM ID the tiler heap should be mapped to */
|
||||
__u32 vm_id;
|
||||
|
||||
- /** @initial_chunk_count: Initial number of chunks to allocate. */
|
||||
+ /** @initial_chunk_count: Initial number of chunks to allocate. Must be at least one. */
|
||||
__u32 initial_chunk_count;
|
||||
|
||||
/** @chunk_size: Chunk size. Must be a power of two at least 256KB large. */
|
||||
__u32 chunk_size;
|
||||
|
||||
- /** @max_chunks: Maximum number of chunks that can be allocated. */
|
||||
+ /**
|
||||
+ * @max_chunks: Maximum number of chunks that can be allocated.
|
||||
+ *
|
||||
+ * Must be at least @initial_chunk_count.
|
||||
+ */
|
||||
__u32 max_chunks;
|
||||
|
||||
/**
|
||||
@ -0,0 +1,76 @@
|
||||
From 69a429905ceccad547e4a532b08f9d32c7f3422a Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 18:51:56 +0200
|
||||
Subject: [PATCH] drm/panthor: Relax the constraints on the tiler chunk size
|
||||
|
||||
The field used to store the chunk size if 12 bits wide, and the encoding
|
||||
is chunk_size = chunk_header.chunk_size << 12, which gives us a
|
||||
theoretical [4k:8M] range. This range is further limited by
|
||||
implementation constraints, and all known implementations seem to
|
||||
impose a [128k:8M] range, so do the same here.
|
||||
|
||||
We also relax the power-of-two constraint, which doesn't seem to
|
||||
exist on v10. This will allow userspace to fine-tune initial/max
|
||||
tiler memory on memory-constrained devices.
|
||||
|
||||
v4:
|
||||
- Actually fix the range in the kerneldoc
|
||||
|
||||
v3:
|
||||
- Add R-bs
|
||||
- Fix valid range in the kerneldoc
|
||||
|
||||
v2:
|
||||
- Turn the power-of-two constraint into a page-aligned constraint to allow
|
||||
fine-tune of the initial/max heap memory size
|
||||
- Fix the panthor_heap_create() kerneldoc
|
||||
|
||||
Fixes: 9cca48fa4f89 ("drm/panthor: Add the heap logical block")
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502165158.1458959-4-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_heap.c | 8 ++++----
|
||||
include/uapi/drm/panthor_drm.h | 6 +++++-
|
||||
2 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
@@ -253,8 +253,8 @@ int panthor_heap_destroy(struct panthor_
|
||||
* @pool: Pool to instantiate the heap context from.
|
||||
* @initial_chunk_count: Number of chunk allocated at initialization time.
|
||||
* Must be at least 1.
|
||||
- * @chunk_size: The size of each chunk. Must be a power of two between 256k
|
||||
- * and 2M.
|
||||
+ * @chunk_size: The size of each chunk. Must be page-aligned and lie in the
|
||||
+ * [128k:8M] range.
|
||||
* @max_chunks: Maximum number of chunks that can be allocated.
|
||||
* @target_in_flight: Maximum number of in-flight render passes.
|
||||
* @heap_ctx_gpu_va: Pointer holding the GPU address of the allocated heap
|
||||
@@ -284,8 +284,8 @@ int panthor_heap_create(struct panthor_h
|
||||
if (initial_chunk_count > max_chunks)
|
||||
return -EINVAL;
|
||||
|
||||
- if (hweight32(chunk_size) != 1 ||
|
||||
- chunk_size < SZ_256K || chunk_size > SZ_2M)
|
||||
+ if (!IS_ALIGNED(chunk_size, PAGE_SIZE) ||
|
||||
+ chunk_size < SZ_128K || chunk_size > SZ_8M)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&pool->lock);
|
||||
--- a/include/uapi/drm/panthor_drm.h
|
||||
+++ b/include/uapi/drm/panthor_drm.h
|
||||
@@ -898,7 +898,11 @@ struct drm_panthor_tiler_heap_create {
|
||||
/** @initial_chunk_count: Initial number of chunks to allocate. Must be at least one. */
|
||||
__u32 initial_chunk_count;
|
||||
|
||||
- /** @chunk_size: Chunk size. Must be a power of two at least 256KB large. */
|
||||
+ /**
|
||||
+ * @chunk_size: Chunk size.
|
||||
+ *
|
||||
+ * Must be page-aligned and lie in the [128k:8M] range.
|
||||
+ */
|
||||
__u32 chunk_size;
|
||||
|
||||
/**
|
||||
@ -0,0 +1,53 @@
|
||||
From 8e43b1e537d4fb313efac1b5d0d01db0fe35f695 Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 18:51:57 +0200
|
||||
Subject: [PATCH] drm/panthor: Fix an off-by-one in the heap context retrieval
|
||||
logic
|
||||
|
||||
The heap ID is used to index the heap context pool, and allocating
|
||||
in the [1:MAX_HEAPS_PER_POOL] leads to an off-by-one. This was
|
||||
originally to avoid returning a zero heap handle, but given the handle
|
||||
is formed with (vm_id << 16) | heap_id, with vm_id > 0, we already can't
|
||||
end up with a valid heap handle that's zero.
|
||||
|
||||
v4:
|
||||
- s/XA_FLAGS_ALLOC1/XA_FLAGS_ALLOC/
|
||||
|
||||
v3:
|
||||
- Allocate in the [0:MAX_HEAPS_PER_POOL-1] range
|
||||
|
||||
v2:
|
||||
- New patch
|
||||
|
||||
Fixes: 9cca48fa4f89 ("drm/panthor: Add the heap logical block")
|
||||
Reported-by: Eric Smith <eric.smith@collabora.com>
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Tested-by: Eric Smith <eric.smith@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502165158.1458959-5-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_heap.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
@@ -323,7 +323,8 @@ int panthor_heap_create(struct panthor_h
|
||||
if (!pool->vm) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
- ret = xa_alloc(&pool->xa, &id, heap, XA_LIMIT(1, MAX_HEAPS_PER_POOL), GFP_KERNEL);
|
||||
+ ret = xa_alloc(&pool->xa, &id, heap,
|
||||
+ XA_LIMIT(0, MAX_HEAPS_PER_POOL - 1), GFP_KERNEL);
|
||||
if (!ret) {
|
||||
void *gpu_ctx = panthor_get_heap_ctx(pool, id);
|
||||
|
||||
@@ -543,7 +544,7 @@ panthor_heap_pool_create(struct panthor_
|
||||
pool->vm = vm;
|
||||
pool->ptdev = ptdev;
|
||||
init_rwsem(&pool->lock);
|
||||
- xa_init_flags(&pool->xa, XA_FLAGS_ALLOC1);
|
||||
+ xa_init_flags(&pool->xa, XA_FLAGS_ALLOC);
|
||||
kref_init(&pool->refcount);
|
||||
|
||||
pool->gpu_contexts = panthor_kernel_bo_create(ptdev, vm, bosize,
|
||||
@ -0,0 +1,58 @@
|
||||
From 2b2a26b3314210585ca6d552a421921a3936713b Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 20:38:09 +0200
|
||||
Subject: [PATCH] drm/panthor: Force an immediate reset on unrecoverable faults
|
||||
|
||||
If the FW reports an unrecoverable fault, we need to reset the GPU
|
||||
before we can start re-using it again.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502183813.1612017-2-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_device.c | 1 +
|
||||
drivers/gpu/drm/panthor/panthor_device.h | 1 +
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 11 ++++++++++-
|
||||
3 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_device.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_device.c
|
||||
@@ -293,6 +293,7 @@ static const struct panthor_exception_in
|
||||
PANTHOR_EXCEPTION(ACTIVE),
|
||||
PANTHOR_EXCEPTION(CS_RES_TERM),
|
||||
PANTHOR_EXCEPTION(CS_CONFIG_FAULT),
|
||||
+ PANTHOR_EXCEPTION(CS_UNRECOVERABLE),
|
||||
PANTHOR_EXCEPTION(CS_ENDPOINT_FAULT),
|
||||
PANTHOR_EXCEPTION(CS_BUS_FAULT),
|
||||
PANTHOR_EXCEPTION(CS_INSTR_INVALID),
|
||||
--- a/drivers/gpu/drm/panthor/panthor_device.h
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_device.h
|
||||
@@ -216,6 +216,7 @@ enum drm_panthor_exception_type {
|
||||
DRM_PANTHOR_EXCEPTION_CS_RES_TERM = 0x0f,
|
||||
DRM_PANTHOR_EXCEPTION_MAX_NON_FAULT = 0x3f,
|
||||
DRM_PANTHOR_EXCEPTION_CS_CONFIG_FAULT = 0x40,
|
||||
+ DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE = 0x41,
|
||||
DRM_PANTHOR_EXCEPTION_CS_ENDPOINT_FAULT = 0x44,
|
||||
DRM_PANTHOR_EXCEPTION_CS_BUS_FAULT = 0x48,
|
||||
DRM_PANTHOR_EXCEPTION_CS_INSTR_INVALID = 0x49,
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -1281,7 +1281,16 @@ cs_slot_process_fatal_event_locked(struc
|
||||
if (group)
|
||||
group->fatal_queues |= BIT(cs_id);
|
||||
|
||||
- sched_queue_delayed_work(sched, tick, 0);
|
||||
+ if (CS_EXCEPTION_TYPE(fatal) == DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE) {
|
||||
+ /* If this exception is unrecoverable, queue a reset, and make
|
||||
+ * sure we stop scheduling groups until the reset has happened.
|
||||
+ */
|
||||
+ panthor_device_schedule_reset(ptdev);
|
||||
+ cancel_delayed_work(&sched->tick_work);
|
||||
+ } else {
|
||||
+ sched_queue_delayed_work(sched, tick, 0);
|
||||
+ }
|
||||
+
|
||||
drm_warn(&ptdev->base,
|
||||
"CSG slot %d CS slot: %d\n"
|
||||
"CS_FATAL.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
@ -0,0 +1,174 @@
|
||||
From ff60c8da0aaf7ecf5f4d48bebeb3c1f52b2088dd Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 20:38:10 +0200
|
||||
Subject: [PATCH] drm/panthor: Keep a ref to the VM at the panthor_kernel_bo
|
||||
level
|
||||
|
||||
Avoids use-after-free situations when panthor_fw_unplug() is called
|
||||
and the kernel BO was mapped to the FW VM.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502183813.1612017-3-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_fw.c | 4 ++--
|
||||
drivers/gpu/drm/panthor/panthor_gem.c | 8 +++++---
|
||||
drivers/gpu/drm/panthor/panthor_gem.h | 8 ++++++--
|
||||
drivers/gpu/drm/panthor/panthor_heap.c | 8 ++++----
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 11 +++++------
|
||||
5 files changed, 22 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
@@ -453,7 +453,7 @@ panthor_fw_alloc_queue_iface_mem(struct
|
||||
|
||||
ret = panthor_kernel_bo_vmap(mem);
|
||||
if (ret) {
|
||||
- panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), mem);
|
||||
+ panthor_kernel_bo_destroy(mem);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
@@ -1134,7 +1134,7 @@ void panthor_fw_unplug(struct panthor_de
|
||||
panthor_fw_stop(ptdev);
|
||||
|
||||
list_for_each_entry(section, &ptdev->fw->sections, node)
|
||||
- panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), section->mem);
|
||||
+ panthor_kernel_bo_destroy(section->mem);
|
||||
|
||||
/* We intentionally don't call panthor_vm_idle() and let
|
||||
* panthor_mmu_unplug() release the AS we acquired with
|
||||
--- a/drivers/gpu/drm/panthor/panthor_gem.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
|
||||
@@ -26,18 +26,18 @@ static void panthor_gem_free_object(stru
|
||||
|
||||
/**
|
||||
* panthor_kernel_bo_destroy() - Destroy a kernel buffer object
|
||||
- * @vm: The VM this BO was mapped to.
|
||||
* @bo: Kernel buffer object to destroy. If NULL or an ERR_PTR(), the destruction
|
||||
* is skipped.
|
||||
*/
|
||||
-void panthor_kernel_bo_destroy(struct panthor_vm *vm,
|
||||
- struct panthor_kernel_bo *bo)
|
||||
+void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
|
||||
{
|
||||
+ struct panthor_vm *vm;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(bo))
|
||||
return;
|
||||
|
||||
+ vm = bo->vm;
|
||||
panthor_kernel_bo_vunmap(bo);
|
||||
|
||||
if (drm_WARN_ON(bo->obj->dev,
|
||||
@@ -53,6 +53,7 @@ void panthor_kernel_bo_destroy(struct pa
|
||||
drm_gem_object_put(bo->obj);
|
||||
|
||||
out_free_bo:
|
||||
+ panthor_vm_put(vm);
|
||||
kfree(bo);
|
||||
}
|
||||
|
||||
@@ -106,6 +107,7 @@ panthor_kernel_bo_create(struct panthor_
|
||||
if (ret)
|
||||
goto err_free_va;
|
||||
|
||||
+ kbo->vm = panthor_vm_get(vm);
|
||||
bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm);
|
||||
drm_gem_object_get(bo->exclusive_vm_root_gem);
|
||||
bo->base.base.resv = bo->exclusive_vm_root_gem->resv;
|
||||
--- a/drivers/gpu/drm/panthor/panthor_gem.h
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
|
||||
@@ -62,6 +62,11 @@ struct panthor_kernel_bo {
|
||||
struct drm_gem_object *obj;
|
||||
|
||||
/**
|
||||
+ * @vm: VM this private buffer is attached to.
|
||||
+ */
|
||||
+ struct panthor_vm *vm;
|
||||
+
|
||||
+ /**
|
||||
* @va_node: VA space allocated to this GEM.
|
||||
*/
|
||||
struct drm_mm_node va_node;
|
||||
@@ -136,7 +141,6 @@ panthor_kernel_bo_create(struct panthor_
|
||||
size_t size, u32 bo_flags, u32 vm_map_flags,
|
||||
u64 gpu_va);
|
||||
|
||||
-void panthor_kernel_bo_destroy(struct panthor_vm *vm,
|
||||
- struct panthor_kernel_bo *bo);
|
||||
+void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo);
|
||||
|
||||
#endif /* __PANTHOR_GEM_H__ */
|
||||
--- a/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
|
||||
@@ -127,7 +127,7 @@ static void panthor_free_heap_chunk(stru
|
||||
heap->chunk_count--;
|
||||
mutex_unlock(&heap->lock);
|
||||
|
||||
- panthor_kernel_bo_destroy(vm, chunk->bo);
|
||||
+ panthor_kernel_bo_destroy(chunk->bo);
|
||||
kfree(chunk);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ static int panthor_alloc_heap_chunk(stru
|
||||
return 0;
|
||||
|
||||
err_destroy_bo:
|
||||
- panthor_kernel_bo_destroy(vm, chunk->bo);
|
||||
+ panthor_kernel_bo_destroy(chunk->bo);
|
||||
|
||||
err_free_chunk:
|
||||
kfree(chunk);
|
||||
@@ -395,7 +395,7 @@ int panthor_heap_return_chunk(struct pan
|
||||
mutex_unlock(&heap->lock);
|
||||
|
||||
if (removed) {
|
||||
- panthor_kernel_bo_destroy(pool->vm, chunk->bo);
|
||||
+ panthor_kernel_bo_destroy(chunk->bo);
|
||||
kfree(chunk);
|
||||
ret = 0;
|
||||
} else {
|
||||
@@ -595,7 +595,7 @@ void panthor_heap_pool_destroy(struct pa
|
||||
drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i));
|
||||
|
||||
if (!IS_ERR_OR_NULL(pool->gpu_contexts))
|
||||
- panthor_kernel_bo_destroy(pool->vm, pool->gpu_contexts);
|
||||
+ panthor_kernel_bo_destroy(pool->gpu_contexts);
|
||||
|
||||
/* Reflects the fact the pool has been destroyed. */
|
||||
pool->vm = NULL;
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -826,8 +826,8 @@ static void group_free_queue(struct pant
|
||||
|
||||
panthor_queue_put_syncwait_obj(queue);
|
||||
|
||||
- panthor_kernel_bo_destroy(group->vm, queue->ringbuf);
|
||||
- panthor_kernel_bo_destroy(panthor_fw_vm(group->ptdev), queue->iface.mem);
|
||||
+ panthor_kernel_bo_destroy(queue->ringbuf);
|
||||
+ panthor_kernel_bo_destroy(queue->iface.mem);
|
||||
|
||||
kfree(queue);
|
||||
}
|
||||
@@ -837,15 +837,14 @@ static void group_release_work(struct wo
|
||||
struct panthor_group *group = container_of(work,
|
||||
struct panthor_group,
|
||||
release_work);
|
||||
- struct panthor_device *ptdev = group->ptdev;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < group->queue_count; i++)
|
||||
group_free_queue(group, group->queues[i]);
|
||||
|
||||
- panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->suspend_buf);
|
||||
- panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->protm_suspend_buf);
|
||||
- panthor_kernel_bo_destroy(group->vm, group->syncobjs);
|
||||
+ panthor_kernel_bo_destroy(group->suspend_buf);
|
||||
+ panthor_kernel_bo_destroy(group->protm_suspend_buf);
|
||||
+ panthor_kernel_bo_destroy(group->syncobjs);
|
||||
|
||||
panthor_vm_put(group->vm);
|
||||
kfree(group);
|
||||
@ -0,0 +1,26 @@
|
||||
From a257e8182261da48b7c34615f2752f8a78ac108b Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 20:38:11 +0200
|
||||
Subject: [PATCH] drm/panthor: Reset the FW VM to NULL on unplug
|
||||
|
||||
This way get NULL derefs instead of use-after-free if the FW VM is
|
||||
referenced after the device has been unplugged.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Acked-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502183813.1612017-4-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_fw.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
|
||||
@@ -1142,6 +1142,7 @@ void panthor_fw_unplug(struct panthor_de
|
||||
* state to keep the active_refcnt balanced.
|
||||
*/
|
||||
panthor_vm_put(ptdev->fw->vm);
|
||||
+ ptdev->fw->vm = NULL;
|
||||
|
||||
panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000);
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
From 3ce4322b1a3a40ca175b16fc54cf22b041ecfd4b Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Thu, 2 May 2024 20:38:12 +0200
|
||||
Subject: [PATCH] drm/panthor: Call panthor_sched_post_reset() even if the
|
||||
reset failed
|
||||
|
||||
We need to undo what was done in panthor_sched_pre_reset() even if the
|
||||
reset failed. We just flag all previously running groups as terminated
|
||||
when that happens to unblock things.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240502183813.1612017-5-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_device.c | 7 +------
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 19 ++++++++++++++-----
|
||||
drivers/gpu/drm/panthor/panthor_sched.h | 2 +-
|
||||
3 files changed, 16 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_device.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_device.c
|
||||
@@ -129,13 +129,8 @@ static void panthor_device_reset_work(st
|
||||
panthor_gpu_l2_power_on(ptdev);
|
||||
panthor_mmu_post_reset(ptdev);
|
||||
ret = panthor_fw_post_reset(ptdev);
|
||||
- if (ret)
|
||||
- goto out_dev_exit;
|
||||
-
|
||||
atomic_set(&ptdev->reset.pending, 0);
|
||||
- panthor_sched_post_reset(ptdev);
|
||||
-
|
||||
-out_dev_exit:
|
||||
+ panthor_sched_post_reset(ptdev, ret != 0);
|
||||
drm_dev_exit(cookie);
|
||||
|
||||
if (ret) {
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -2733,15 +2733,22 @@ void panthor_sched_pre_reset(struct pant
|
||||
mutex_unlock(&sched->reset.lock);
|
||||
}
|
||||
|
||||
-void panthor_sched_post_reset(struct panthor_device *ptdev)
|
||||
+void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed)
|
||||
{
|
||||
struct panthor_scheduler *sched = ptdev->scheduler;
|
||||
struct panthor_group *group, *group_tmp;
|
||||
|
||||
mutex_lock(&sched->reset.lock);
|
||||
|
||||
- list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, run_node)
|
||||
+ list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, run_node) {
|
||||
+ /* Consider all previously running group as terminated if the
|
||||
+ * reset failed.
|
||||
+ */
|
||||
+ if (reset_failed)
|
||||
+ group->state = PANTHOR_CS_GROUP_TERMINATED;
|
||||
+
|
||||
panthor_group_start(group);
|
||||
+ }
|
||||
|
||||
/* We're done resetting the GPU, clear the reset.in_progress bit so we can
|
||||
* kick the scheduler.
|
||||
@@ -2749,9 +2756,11 @@ void panthor_sched_post_reset(struct pan
|
||||
atomic_set(&sched->reset.in_progress, false);
|
||||
mutex_unlock(&sched->reset.lock);
|
||||
|
||||
- sched_queue_delayed_work(sched, tick, 0);
|
||||
-
|
||||
- sched_queue_work(sched, sync_upd);
|
||||
+ /* No need to queue a tick and update syncs if the reset failed. */
|
||||
+ if (!reset_failed) {
|
||||
+ sched_queue_delayed_work(sched, tick, 0);
|
||||
+ sched_queue_work(sched, sync_upd);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void group_sync_upd_work(struct work_struct *work)
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.h
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.h
|
||||
@@ -40,7 +40,7 @@ void panthor_group_pool_destroy(struct p
|
||||
int panthor_sched_init(struct panthor_device *ptdev);
|
||||
void panthor_sched_unplug(struct panthor_device *ptdev);
|
||||
void panthor_sched_pre_reset(struct panthor_device *ptdev);
|
||||
-void panthor_sched_post_reset(struct panthor_device *ptdev);
|
||||
+void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed);
|
||||
void panthor_sched_suspend(struct panthor_device *ptdev);
|
||||
void panthor_sched_resume(struct panthor_device *ptdev);
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From 1a9a71439cc1b270bf127c2f529aac7cf9cb21ab Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Wed, 3 Jul 2024 09:16:39 +0200
|
||||
Subject: [PATCH] drm/panthor: Don't check the array stride on empty uobj
|
||||
arrays
|
||||
|
||||
The user is likely to leave all the drm_panthor_obj_array fields
|
||||
to zero when the array is empty, which will cause an EINVAL failure.
|
||||
|
||||
v2:
|
||||
- Added R-bs
|
||||
|
||||
Fixes: 4bdca1150792 ("drm/panthor: Add the driver frontend block")
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240703071640.231278-2-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_drv.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_drv.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
|
||||
@@ -86,15 +86,15 @@ panthor_get_uobj_array(const struct drm_
|
||||
int ret = 0;
|
||||
void *out_alloc;
|
||||
|
||||
+ if (!in->count)
|
||||
+ return NULL;
|
||||
+
|
||||
/* User stride must be at least the minimum object size, otherwise it might
|
||||
* lack useful information.
|
||||
*/
|
||||
if (in->stride < min_stride)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
- if (!in->count)
|
||||
- return NULL;
|
||||
-
|
||||
out_alloc = kvmalloc_array(in->count, obj_size, GFP_KERNEL);
|
||||
if (!out_alloc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -0,0 +1,135 @@
|
||||
From 7b6f9ec6ad51125facadecf77dc6e62928186d2e Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Wed, 3 Jul 2024 09:16:40 +0200
|
||||
Subject: [PATCH] drm/panthor: Fix sync-only jobs
|
||||
|
||||
A sync-only job is meant to provide a synchronization point on a
|
||||
queue, so we can't return a NULL fence there, we have to add a signal
|
||||
operation to the command stream which executes after all other
|
||||
previously submitted jobs are done.
|
||||
|
||||
v2:
|
||||
- Fixed a UAF bug
|
||||
- Added R-bs
|
||||
|
||||
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Link: https://patchwork.freedesktop.org/patch/msgid/20240703071640.231278-3-boris.brezillon@collabora.com
|
||||
---
|
||||
drivers/gpu/drm/panthor/panthor_sched.c | 44 ++++++++++++++++++-------
|
||||
include/uapi/drm/panthor_drm.h | 5 +++
|
||||
2 files changed, 38 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
|
||||
@@ -459,6 +459,16 @@ struct panthor_queue {
|
||||
atomic64_t seqno;
|
||||
|
||||
/**
|
||||
+ * @last_fence: Fence of the last submitted job.
|
||||
+ *
|
||||
+ * We return this fence when we get an empty command stream.
|
||||
+ * This way, we are guaranteed that all earlier jobs have completed
|
||||
+ * when drm_sched_job::s_fence::finished without having to feed
|
||||
+ * the CS ring buffer with a dummy job that only signals the fence.
|
||||
+ */
|
||||
+ struct dma_fence *last_fence;
|
||||
+
|
||||
+ /**
|
||||
* @in_flight_jobs: List containing all in-flight jobs.
|
||||
*
|
||||
* Used to keep track and signal panthor_job::done_fence when the
|
||||
@@ -829,6 +839,9 @@ static void group_free_queue(struct pant
|
||||
panthor_kernel_bo_destroy(queue->ringbuf);
|
||||
panthor_kernel_bo_destroy(queue->iface.mem);
|
||||
|
||||
+ /* Release the last_fence we were holding, if any. */
|
||||
+ dma_fence_put(queue->fence_ctx.last_fence);
|
||||
+
|
||||
kfree(queue);
|
||||
}
|
||||
|
||||
@@ -2784,9 +2797,6 @@ static void group_sync_upd_work(struct w
|
||||
|
||||
spin_lock(&queue->fence_ctx.lock);
|
||||
list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs, node) {
|
||||
- if (!job->call_info.size)
|
||||
- continue;
|
||||
-
|
||||
if (syncobj->seqno < job->done_fence->seqno)
|
||||
break;
|
||||
|
||||
@@ -2865,11 +2875,14 @@ queue_run_job(struct drm_sched_job *sche
|
||||
static_assert(sizeof(call_instrs) % 64 == 0,
|
||||
"call_instrs is not aligned on a cacheline");
|
||||
|
||||
- /* Stream size is zero, nothing to do => return a NULL fence and let
|
||||
- * drm_sched signal the parent.
|
||||
- */
|
||||
- if (!job->call_info.size)
|
||||
- return NULL;
|
||||
+ /* Stream size is zero, nothing to do except making sure all previously
|
||||
+ * submitted jobs are done before we signal the
|
||||
+ * drm_sched_job::s_fence::finished fence.
|
||||
+ */
|
||||
+ if (!job->call_info.size) {
|
||||
+ job->done_fence = dma_fence_get(queue->fence_ctx.last_fence);
|
||||
+ return dma_fence_get(job->done_fence);
|
||||
+ }
|
||||
|
||||
ret = pm_runtime_resume_and_get(ptdev->base.dev);
|
||||
if (drm_WARN_ON(&ptdev->base, ret))
|
||||
@@ -2928,6 +2941,10 @@ queue_run_job(struct drm_sched_job *sche
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Update the last fence. */
|
||||
+ dma_fence_put(queue->fence_ctx.last_fence);
|
||||
+ queue->fence_ctx.last_fence = dma_fence_get(job->done_fence);
|
||||
+
|
||||
done_fence = dma_fence_get(job->done_fence);
|
||||
|
||||
out_unlock:
|
||||
@@ -3378,10 +3395,15 @@ panthor_job_create(struct panthor_file *
|
||||
goto err_put_job;
|
||||
}
|
||||
|
||||
- job->done_fence = kzalloc(sizeof(*job->done_fence), GFP_KERNEL);
|
||||
- if (!job->done_fence) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err_put_job;
|
||||
+ /* Empty command streams don't need a fence, they'll pick the one from
|
||||
+ * the previously submitted job.
|
||||
+ */
|
||||
+ if (job->call_info.size) {
|
||||
+ job->done_fence = kzalloc(sizeof(*job->done_fence), GFP_KERNEL);
|
||||
+ if (!job->done_fence) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_put_job;
|
||||
+ }
|
||||
}
|
||||
|
||||
ret = drm_sched_job_init(&job->base,
|
||||
--- a/include/uapi/drm/panthor_drm.h
|
||||
+++ b/include/uapi/drm/panthor_drm.h
|
||||
@@ -802,6 +802,9 @@ struct drm_panthor_queue_submit {
|
||||
* Must be 64-bit/8-byte aligned (the size of a CS instruction)
|
||||
*
|
||||
* Can be zero if stream_addr is zero too.
|
||||
+ *
|
||||
+ * When the stream size is zero, the queue submit serves as a
|
||||
+ * synchronization point.
|
||||
*/
|
||||
__u32 stream_size;
|
||||
|
||||
@@ -822,6 +825,8 @@ struct drm_panthor_queue_submit {
|
||||
* ensure the GPU doesn't get garbage when reading the indirect command
|
||||
* stream buffers. If you want the cache flush to happen
|
||||
* unconditionally, pass a zero here.
|
||||
+ *
|
||||
+ * Ignored when stream_size is zero.
|
||||
*/
|
||||
__u32 latest_flush;
|
||||
|
||||
@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
clk_disable_unprepare(dwc->susp_clk);
|
||||
clk_disable_unprepare(dwc->ref_clk);
|
||||
clk_disable_unprepare(dwc->bus_clk);
|
||||
@@ -1824,6 +1838,20 @@ static int dwc3_get_clocks(struct dwc3 *
|
||||
@@ -1842,6 +1856,20 @@ static int dwc3_get_clocks(struct dwc3 *
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
&cpu_b0 {
|
||||
cpu-supply = <&vdd_cpu_big0_s0>;
|
||||
};
|
||||
@@ -733,3 +737,7 @@
|
||||
@@ -734,3 +738,7 @@
|
||||
&usb_host1_ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -697,6 +697,14 @@
|
||||
@@ -698,6 +698,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
&u2phy2 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -720,6 +728,11 @@
|
||||
@@ -721,6 +729,11 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -42,7 +42,7 @@ Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
&usb_host0_ehci {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
@@ -730,6 +743,11 @@
|
||||
@@ -731,6 +744,11 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
status = "okay";
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -710,6 +710,10 @@
|
||||
@@ -711,6 +711,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user