* [PATCH 2/8] drm/scheduler: add drm_sched_entity_error and use rcu for last_scheduled
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 3/8] drm/amdgpu: add amdgpu_error_* debugfs file Christian König
` (7 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
Switch to using RCU handling for the last scheduled job and add a
function to return the error code of it.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/scheduler/sched_entity.c | 39 +++++++++++++++++++-----
include/drm/gpu_scheduler.h | 3 +-
2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index eaf71fe15ed3..d3f4ada6a68e 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -72,7 +72,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->num_sched_list = num_sched_list;
entity->priority = priority;
entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
- entity->last_scheduled = NULL;
+ RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
if(num_sched_list)
@@ -140,6 +140,27 @@ bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)
return true;
}
+/**
+ * drm_sched_entity_error - return error of last scheduled job
+ * @entity: scheduler entity to check
+ *
+ * Opportunistically return the error of the last scheduled job. Result can
+ * change any time when new jobs are pushed to the hw.
+ */
+int drm_sched_entity_error(struct drm_sched_entity *entity)
+{
+ struct dma_fence *fence;
+ int r;
+
+ rcu_read_lock();
+ fence = rcu_dereference(entity->last_scheduled);
+ r = fence ? fence->error : 0;
+ rcu_read_unlock();
+
+ return r;
+}
+EXPORT_SYMBOL(drm_sched_entity_error);
+
static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
{
struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
@@ -191,7 +212,9 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
/* Make sure this entity is not used by the scheduler at the moment */
wait_for_completion(&entity->entity_idle);
- prev = dma_fence_get(entity->last_scheduled);
+ /* The entity is guaranteed to not be used by the scheduler */
+ prev = rcu_dereference_check(entity->last_scheduled, true);
+ dma_fence_get(prev);
while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
struct drm_sched_fence *s_fence = job->s_fence;
@@ -278,8 +301,8 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
entity->dependency = NULL;
}
- dma_fence_put(entity->last_scheduled);
- entity->last_scheduled = NULL;
+ dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
+ RCU_INIT_POINTER(entity->last_scheduled, NULL);
}
EXPORT_SYMBOL(drm_sched_entity_fini);
@@ -421,9 +444,9 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
if (entity->guilty && atomic_read(entity->guilty))
dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
- dma_fence_put(entity->last_scheduled);
-
- entity->last_scheduled = dma_fence_get(&sched_job->s_fence->finished);
+ dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
+ rcu_assign_pointer(entity->last_scheduled,
+ dma_fence_get(&sched_job->s_fence->finished));
/*
* If the queue is empty we allow drm_sched_entity_select_rq() to
@@ -471,7 +494,7 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
*/
smp_rmb();
- fence = entity->last_scheduled;
+ fence = rcu_dereference_check(entity->last_scheduled, true);
/* stay on the same engine if the previous job hasn't finished */
if (fence && !dma_fence_is_signaled(fence))
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 5c1df6b12ced..6084459b2def 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -190,7 +190,7 @@ struct drm_sched_entity {
* by the scheduler thread, can be accessed locklessly from
* drm_sched_job_arm() iff the queue is empty.
*/
- struct dma_fence *last_scheduled;
+ struct dma_fence __rcu *last_scheduled;
/**
* @last_user: last group leader pushing a job into the entity.
@@ -561,6 +561,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
enum drm_sched_priority priority);
bool drm_sched_entity_is_ready(struct drm_sched_entity *entity);
+int drm_sched_entity_error(struct drm_sched_entity *entity);
struct drm_sched_fence *drm_sched_fence_alloc(
struct drm_sched_entity *s_entity, void *owner);
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 3/8] drm/amdgpu: add amdgpu_error_* debugfs file
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
2023-04-20 11:57 ` [PATCH 2/8] drm/scheduler: add drm_sched_entity_error and use rcu for last_scheduled Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 4/8] drm/amdgpu: mark force completed fences with -ECANCELED Christian König
` (6 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
This allows us to insert some error codes into the bottom of the pipeline
on an engine.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 24 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 15 ++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 +
3 files changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index f52d0ba91a77..877fae84b8ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -693,6 +693,30 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)
}
}
+/**
+ * amdgpu_fence_driver_set_error - set error code on fences
+ * @ring: the ring which contains the fences
+ * @error: the error code to set
+ *
+ * Set an error code to all the fences pending on the ring.
+ */
+void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error)
+{
+ struct amdgpu_fence_driver *drv = &ring->fence_drv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv->lock, flags);
+ for (unsigned int i = 0; i <= drv->num_fences_mask; ++i) {
+ struct dma_fence *fence;
+
+ fence = rcu_dereference_protected(drv->fences[i],
+ lockdep_is_held(&drv->lock));
+ if (fence && !dma_fence_is_signaled_locked(fence))
+ dma_fence_set_error(fence, error);
+ }
+ spin_unlock_irqrestore(&drv->lock, flags);
+}
+
/**
* amdgpu_fence_driver_force_completion - force signal latest fence of ring
*
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index f676c236b657..d3ad29d932b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -507,6 +507,17 @@ static const struct file_operations amdgpu_debugfs_ring_fops = {
.llseek = default_llseek
};
+static int amdgpu_debugfs_ring_error(void *data, u64 val)
+{
+ struct amdgpu_ring *ring = data;
+
+ amdgpu_fence_driver_set_error(ring, val);
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(amdgpu_debugfs_error_fops, NULL,
+ amdgpu_debugfs_ring_error, "%lld\n");
+
#endif
void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
@@ -522,6 +533,10 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
&amdgpu_debugfs_ring_fops,
ring->ring_size + 12);
+ sprintf(name, "amdgpu_error_%s", ring->name);
+ debugfs_create_file(name, 0200, root, ring,
+ &amdgpu_debugfs_error_fops);
+
#endif
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index e0d02cd8e63c..04ac055c3942 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -125,6 +125,7 @@ struct amdgpu_fence_driver {
extern const struct drm_sched_backend_ops amdgpu_sched_ops;
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
+void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 4/8] drm/amdgpu: mark force completed fences with -ECANCELED
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
2023-04-20 11:57 ` [PATCH 2/8] drm/scheduler: add drm_sched_entity_error and use rcu for last_scheduled Christian König
2023-04-20 11:57 ` [PATCH 3/8] drm/amdgpu: add amdgpu_error_* debugfs file Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 5/8] drm/amdgpu: mark soft recovered fences with -ENODATA Christian König
` (5 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
When we force complete fences we should mark them as canceled.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 877fae84b8ed..a7627cc0118d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -725,6 +725,7 @@ void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error)
*/
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
{
+ amdgpu_fence_driver_set_error(ring, -ECANCELED);
amdgpu_fence_write(ring, ring->fence_drv.sync_seq);
amdgpu_fence_process(ring);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 5/8] drm/amdgpu: mark soft recovered fences with -ENODATA
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (2 preceding siblings ...)
2023-04-20 11:57 ` [PATCH 4/8] drm/amdgpu: mark force completed fences with -ECANCELED Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 6/8] drm/amdgpu: abort submissions during prepare on error Christian König
` (4 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
Set the fence error code before trying to soft-recover it.
It gets overwritten when a hard recovery is required.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index d3ad29d932b8..083b1020b421 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -432,11 +432,18 @@ void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
struct dma_fence *fence)
{
+ unsigned long flags;
+
ktime_t deadline = ktime_add_us(ktime_get(), 10000);
if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
return false;
+ spin_lock_irqsave(fence->lock, flags);
+ if (!dma_fence_is_signaled_locked(fence))
+ dma_fence_set_error(fence, -ENODATA);
+ spin_unlock_irqrestore(fence->lock, flags);
+
atomic_inc(&ring->adev->gpu_reset_counter);
while (!dma_fence_is_signaled(fence) &&
ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0)
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 6/8] drm/amdgpu: abort submissions during prepare on error
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (3 preceding siblings ...)
2023-04-20 11:57 ` [PATCH 5/8] drm/amdgpu: mark soft recovered fences with -ENODATA Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 7/8] drm/amdgpu: reset VM when an error is detected Christian König
` (3 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
Forward errors from previous submissions to this one.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 0a950c1c8782..5462f0406b02 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -256,16 +256,27 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job,
struct dma_fence *fence = NULL;
int r;
+ /* Ignore soft recovered fences here */
+ r = drm_sched_entity_error(s_entity);
+ if (r && r != -ENODATA)
+ goto error;
+
if (job->gang_submit)
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
while (!fence && job->vm && !job->vmid) {
r = amdgpu_vmid_grab(job->vm, ring, job, &fence);
- if (r)
+ if (r) {
DRM_ERROR("Error getting VM ID (%d)\n", r);
+ goto error;
+ }
}
return fence;
+
+error:
+ dma_fence_set_error(&job->base.s_fence->finished, r);
+ return NULL;
}
static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 7/8] drm/amdgpu: reset VM when an error is detected
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (4 preceding siblings ...)
2023-04-20 11:57 ` [PATCH 6/8] drm/amdgpu: abort submissions during prepare on error Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-20 11:57 ` [PATCH 8/8] drm/amdgpu: add VM generation token Christian König
` (2 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
When some problem with the updates of page tables is detected reset the
state machine of the VM and re-create all page tables from scratch.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 81 +++++++++++++++++++++-----
1 file changed, 65 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index fa8f48a0fa84..8082c9e006b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -265,6 +265,32 @@ static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
spin_unlock(&vm_bo->vm->status_lock);
}
+/**
+ * amdgpu_vm_bo_reset_state_machine - reset the vm_bo state machine
+ * @vm: the VM which state machine to reset
+ *
+ * Move all vm_bo object in the VM into a state where they will be updated
+ * again during validation.
+ */
+static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
+{
+ struct amdgpu_vm_bo_base *vm_bo, *tmp;
+
+ spin_lock(&vm->status_lock);
+ list_splice_init(&vm->done, &vm->invalidated);
+ list_for_each_entry(vm_bo, &vm->invalidated, vm_status)
+ vm_bo->moved = true;
+ list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) {
+ struct amdgpu_bo *bo = vm_bo->bo;
+
+ if (!bo || bo->tbo.type != ttm_bo_type_kernel)
+ list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
+ else if (bo->parent)
+ list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
+ }
+ spin_unlock(&vm->status_lock);
+}
+
/**
* amdgpu_vm_bo_base_init - Adds bo to the list of bos associated with the vm
*
@@ -350,6 +376,34 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
spin_unlock(&adev->mman.bdev.lru_lock);
}
+/* Create scheduler entities for page table updates */
+static int amdgpu_vm_init_entities(struct amdgpu_device *adev,
+ struct amdgpu_vm *vm)
+{
+ int r;
+
+ r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
+ adev->vm_manager.vm_pte_scheds,
+ adev->vm_manager.vm_pte_num_scheds, NULL);
+ if (r)
+ goto error;
+
+ return drm_sched_entity_init(&vm->delayed, DRM_SCHED_PRIORITY_NORMAL,
+ adev->vm_manager.vm_pte_scheds,
+ adev->vm_manager.vm_pte_num_scheds, NULL);
+
+error:
+ drm_sched_entity_destroy(&vm->immediate);
+ return r;
+}
+
+/* Destroy the entities for page table updates again */
+static void amdgpu_vm_fini_entities(struct amdgpu_vm *vm)
+{
+ drm_sched_entity_destroy(&vm->immediate);
+ drm_sched_entity_destroy(&vm->delayed);
+}
+
/**
* amdgpu_vm_validate_pt_bos - validate the page table BOs
*
@@ -372,6 +426,14 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo *bo;
int r;
+ if (drm_sched_entity_error(&vm->delayed)) {
+ amdgpu_vm_bo_reset_state_machine(vm);
+ amdgpu_vm_fini_entities(vm);
+ r = amdgpu_vm_init_entities(adev, vm);
+ if (r)
+ return r;
+ }
+
spin_lock(&vm->status_lock);
while (!list_empty(&vm->evicted)) {
bo_base = list_first_entry(&vm->evicted,
@@ -2037,19 +2099,10 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
INIT_LIST_HEAD(&vm->pt_freed);
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
- /* create scheduler entities for page table updates */
- r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
- adev->vm_manager.vm_pte_scheds,
- adev->vm_manager.vm_pte_num_scheds, NULL);
+ r = amdgpu_vm_init_entities(adev, vm);
if (r)
return r;
- r = drm_sched_entity_init(&vm->delayed, DRM_SCHED_PRIORITY_NORMAL,
- adev->vm_manager.vm_pte_scheds,
- adev->vm_manager.vm_pte_num_scheds, NULL);
- if (r)
- goto error_free_immediate;
-
vm->pte_support_ats = false;
vm->is_compute_context = false;
@@ -2109,10 +2162,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);
- drm_sched_entity_destroy(&vm->delayed);
-
-error_free_immediate:
- drm_sched_entity_destroy(&vm->immediate);
+ amdgpu_vm_fini_entities(vm);
return r;
}
@@ -2265,8 +2315,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
amdgpu_bo_unref(&root);
WARN_ON(vm->root.bo);
- drm_sched_entity_destroy(&vm->immediate);
- drm_sched_entity_destroy(&vm->delayed);
+ amdgpu_vm_fini_entities(vm);
if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
dev_err(adev->dev, "still active bo inside vm\n");
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH 8/8] drm/amdgpu: add VM generation token
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (5 preceding siblings ...)
2023-04-20 11:57 ` [PATCH 7/8] drm/amdgpu: reset VM when an error is detected Christian König
@ 2023-04-20 11:57 ` Christian König
2023-04-21 5:22 ` [PATCH 1/8] drm/scheduler: properly forward fence errors Luben Tuikov
2023-04-27 10:35 ` Yin, ZhenGuo (Chris)
8 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-20 11:57 UTC (permalink / raw)
To: amd-gfx; +Cc: luben.tuikov
Instead of using the VRAM lost counter add a 64bit token which indicates
if a context or job is still valid to use.
Should the VRAM be lost or the page tables need re-creation the token will
change indicating that userspace needs to act and re-create the contexts
and re-submit the work.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 5 +++--
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 ++--
drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 26 +++++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 4 ++++
7 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 49db1d0c923a..4beec4220aed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -306,7 +306,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
}
p->gang_leader = p->jobs[p->gang_leader_idx];
- if (p->ctx->vram_lost_counter != p->gang_leader->vram_lost_counter) {
+ if (p->ctx->generation != p->gang_leader->generation) {
ret = -ECANCELED;
goto free_all_kdata;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index d2139ac12159..24994c9e65ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -303,6 +303,7 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
struct drm_file *filp, struct amdgpu_ctx *ctx)
{
+ struct amdgpu_fpriv *fpriv = filp->driver_priv;
u32 current_stable_pstate;
int r;
@@ -318,7 +319,7 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
ctx->reset_counter_query = ctx->reset_counter;
- ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
+ ctx->generation = amdgpu_vm_generation(mgr->adev, &fpriv->vm);
ctx->init_priority = priority;
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
@@ -570,7 +571,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
if (ctx->reset_counter != atomic_read(&adev->gpu_reset_counter))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RESET;
- if (ctx->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
+ if (ctx->generation != amdgpu_vm_generation(adev, &fpriv->vm))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
if (atomic_read(&ctx->guilty))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
index 0fa0e56daf67..5fd79f94e2d0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
@@ -47,7 +47,7 @@ struct amdgpu_ctx {
struct amdgpu_ctx_mgr *mgr;
unsigned reset_counter;
unsigned reset_counter_query;
- uint32_t vram_lost_counter;
+ uint64_t generation;
spinlock_t ring_lock;
struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
bool preamble_presented;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 5462f0406b02..57f8f8b3cd8a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -107,7 +107,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
(*job)->vm = vm;
amdgpu_sync_create(&(*job)->explicit_sync);
- (*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
+ (*job)->generation = amdgpu_vm_generation(adev, vm);
(*job)->vm_pd_addr = AMDGPU_BO_INVALID_OFFSET;
if (!entity)
@@ -293,7 +293,7 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
trace_amdgpu_sched_run_job(job);
/* Skip job if VRAM is lost and never resubmit gangs */
- if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter) ||
+ if (job->generation != amdgpu_vm_generation(adev, job->vm) ||
(job->job_run_counter && job->gang_submit))
dma_fence_set_error(finished, -ECANCELED);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index 52f2e313ea17..a2931ff08dad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -61,7 +61,7 @@ struct amdgpu_job {
uint32_t gds_base, gds_size;
uint32_t gws_base, gws_size;
uint32_t oa_base, oa_size;
- uint32_t vram_lost_counter;
+ uint64_t generation;
/* user fence handling */
uint64_t uf_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 8082c9e006b1..158176b2f47e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -404,6 +404,30 @@ static void amdgpu_vm_fini_entities(struct amdgpu_vm *vm)
drm_sched_entity_destroy(&vm->delayed);
}
+/**
+ * amdgpu_vm_generation - return the page table re-generation counter
+ * @adev: the amdgpu_device
+ * @vm: optional VM to check, might be NULL
+ *
+ * Returns a page table re-generation token to allow checking if submissions
+ * are still valid to use this VM. The VM parameter might be NULL in which case
+ * just the VRAM lost counter will be used.
+ */
+uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+{
+ uint64_t result = (u64)atomic_read(&adev->vram_lost_counter) << 32;
+
+ if (!vm)
+ return result;
+
+ result += vm->generation;
+ /* Add one if the page tables will be re-generated on next CS */
+ if (drm_sched_entity_error(&vm->delayed))
+ ++result;
+
+ return result;
+}
+
/**
* amdgpu_vm_validate_pt_bos - validate the page table BOs
*
@@ -427,6 +451,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int r;
if (drm_sched_entity_error(&vm->delayed)) {
+ ++vm->generation;
amdgpu_vm_bo_reset_state_machine(vm);
amdgpu_vm_fini_entities(vm);
r = amdgpu_vm_init_entities(adev, vm);
@@ -2122,6 +2147,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
vm->last_update = NULL;
vm->last_unlocked = dma_fence_get_stub();
vm->last_tlb_flush = dma_fence_get_stub();
+ vm->generation = 0;
mutex_init(&vm->eviction_lock);
vm->evicting = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 8ae45a0896cd..e8390d439895 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -292,6 +292,9 @@ struct amdgpu_vm {
atomic64_t tlb_seq;
struct dma_fence *last_tlb_flush;
+ /* How many times we had to re-generate the page tables */
+ uint64_t generation;
+
/* Last unlocked submission to the scheduler entities */
struct dma_fence *last_unlocked;
@@ -391,6 +394,7 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
struct list_head *validated,
struct amdgpu_bo_list_entry *entry);
bool amdgpu_vm_ready(struct amdgpu_vm *vm);
+uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm);
int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int (*callback)(void *p, struct amdgpu_bo *bo),
void *param);
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (6 preceding siblings ...)
2023-04-20 11:57 ` [PATCH 8/8] drm/amdgpu: add VM generation token Christian König
@ 2023-04-21 5:22 ` Luben Tuikov
2023-04-21 13:27 ` Christian König
2023-04-27 10:35 ` Yin, ZhenGuo (Chris)
8 siblings, 1 reply; 17+ messages in thread
From: Luben Tuikov @ 2023-04-21 5:22 UTC (permalink / raw)
To: Christian König, amd-gfx
Hi Christian,
Thanks for working on this.
Series is,
Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
Regards,
Luben
On 2023-04-20 07:57, Christian König wrote:
> When a hw fence is signaled with an error properly forward that to the
> finished fence.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/scheduler/sched_entity.c | 4 +---
> drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
> include/drm/gpu_scheduler.h | 2 +-
> 4 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
> index 15d04a0ec623..eaf71fe15ed3 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
> {
> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>
> - drm_sched_fence_finished(job->s_fence);
> + drm_sched_fence_finished(job->s_fence, -ESRCH);
> WARN_ON(job->s_fence->parent);
> job->sched->ops->free_job(job);
> }
> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
> struct drm_sched_fence *s_fence = job->s_fence;
>
> - dma_fence_set_error(&s_fence->finished, -ESRCH);
> -
> dma_fence_get(&s_fence->finished);
> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
> drm_sched_entity_kill_jobs_cb))
> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
> index 7fd869520ef2..1a6bea98c5cc 100644
> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
> dma_fence_signal(&fence->scheduled);
> }
>
> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result)
> {
> + if (result)
> + dma_fence_set_error(&fence->finished, result);
> dma_fence_signal(&fence->finished);
> }
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
> *
> * Finish the job's fence and wake up the worker thread.
> */
> -static void drm_sched_job_done(struct drm_sched_job *s_job)
> +static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
> {
> struct drm_sched_fence *s_fence = s_job->s_fence;
> struct drm_gpu_scheduler *sched = s_fence->sched;
> @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
> trace_drm_sched_process_job(s_fence);
>
> dma_fence_get(&s_fence->finished);
> - drm_sched_fence_finished(s_fence);
> + drm_sched_fence_finished(s_fence, result);
> dma_fence_put(&s_fence->finished);
> wake_up_interruptible(&sched->wake_up_worker);
> }
> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb)
> {
> struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
>
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, f->error);
> }
>
> /**
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
> r = dma_fence_add_callback(fence, &sched_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else {
> - if (IS_ERR(fence))
> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
> -
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
> + PTR_ERR(fence) : 0);
> }
>
> wake_up(&sched->job_scheduled);
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index ca857ec9e7eb..5c1df6b12ced 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
> void drm_sched_fence_free(struct drm_sched_fence *fence);
>
> void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
> -void drm_sched_fence_finished(struct drm_sched_fence *fence);
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
>
> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
> void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-21 5:22 ` [PATCH 1/8] drm/scheduler: properly forward fence errors Luben Tuikov
@ 2023-04-21 13:27 ` Christian König
2023-04-21 13:40 ` Deucher, Alexander
0 siblings, 1 reply; 17+ messages in thread
From: Christian König @ 2023-04-21 13:27 UTC (permalink / raw)
To: amd-gfx, Alex Deucher; +Cc: Luben Tuikov
Alex can I merge that through drm-misc-next or do we really need
amd-staging-drm-next?
Christian.
Am 21.04.23 um 07:22 schrieb Luben Tuikov:
> Hi Christian,
>
> Thanks for working on this.
>
> Series is,
> Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
>
> Regards,
> Luben
>
> On 2023-04-20 07:57, Christian König wrote:
>> When a hw fence is signaled with an error properly forward that to the
>> finished fence.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>> drivers/gpu/drm/scheduler/sched_entity.c | 4 +---
>> drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
>> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
>> include/drm/gpu_scheduler.h | 2 +-
>> 4 files changed, 13 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
>> index 15d04a0ec623..eaf71fe15ed3 100644
>> --- a/drivers/gpu/drm/scheduler/sched_entity.c
>> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
>> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
>> {
>> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>>
>> - drm_sched_fence_finished(job->s_fence);
>> + drm_sched_fence_finished(job->s_fence, -ESRCH);
>> WARN_ON(job->s_fence->parent);
>> job->sched->ops->free_job(job);
>> }
>> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
>> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
>> struct drm_sched_fence *s_fence = job->s_fence;
>>
>> - dma_fence_set_error(&s_fence->finished, -ESRCH);
>> -
>> dma_fence_get(&s_fence->finished);
>> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
>> drm_sched_entity_kill_jobs_cb))
>> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
>> index 7fd869520ef2..1a6bea98c5cc 100644
>> --- a/drivers/gpu/drm/scheduler/sched_fence.c
>> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
>> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
>> dma_fence_signal(&fence->scheduled);
>> }
>>
>> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result)
>> {
>> + if (result)
>> + dma_fence_set_error(&fence->finished, result);
>> dma_fence_signal(&fence->finished);
>> }
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
>> index fcd4bfef7415..649fac2e1ccb 100644
>> --- a/drivers/gpu/drm/scheduler/sched_main.c
>> +++ b/drivers/gpu/drm/scheduler/sched_main.c
>> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
>> *
>> * Finish the job's fence and wake up the worker thread.
>> */
>> -static void drm_sched_job_done(struct drm_sched_job *s_job)
>> +static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
>> {
>> struct drm_sched_fence *s_fence = s_job->s_fence;
>> struct drm_gpu_scheduler *sched = s_fence->sched;
>> @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
>> trace_drm_sched_process_job(s_fence);
>>
>> dma_fence_get(&s_fence->finished);
>> - drm_sched_fence_finished(s_fence);
>> + drm_sched_fence_finished(s_fence, result);
>> dma_fence_put(&s_fence->finished);
>> wake_up_interruptible(&sched->wake_up_worker);
>> }
>> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb)
>> {
>> struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
>>
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, f->error);
>> }
>>
>> /**
>> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
>> r = dma_fence_add_callback(fence, &s_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, 0);
>> }
>>
>> if (full_recovery) {
>> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
>> r = dma_fence_add_callback(fence, &sched_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else {
>> - if (IS_ERR(fence))
>> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
>> -
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
>> + PTR_ERR(fence) : 0);
>> }
>>
>> wake_up(&sched->job_scheduled);
>> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
>> index ca857ec9e7eb..5c1df6b12ced 100644
>> --- a/include/drm/gpu_scheduler.h
>> +++ b/include/drm/gpu_scheduler.h
>> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
>> void drm_sched_fence_free(struct drm_sched_fence *fence);
>>
>> void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
>> -void drm_sched_fence_finished(struct drm_sched_fence *fence);
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
>>
>> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
>> void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-21 13:27 ` Christian König
@ 2023-04-21 13:40 ` Deucher, Alexander
2023-04-24 10:06 ` Christian König
0 siblings, 1 reply; 17+ messages in thread
From: Deucher, Alexander @ 2023-04-21 13:40 UTC (permalink / raw)
To: Christian König, amd-gfx@lists.freedesktop.org; +Cc: Tuikov, Luben
[-- Attachment #1: Type: text/plain, Size: 7041 bytes --]
[AMD Official Use Only - General]
Sure. We can pull it into amd-staging-drm-next as well if we need it for any customers in the short term.
Alex
________________________________
From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Friday, April 21, 2023 9:27 AM
To: amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
Subject: Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
Alex can I merge that through drm-misc-next or do we really need
amd-staging-drm-next?
Christian.
Am 21.04.23 um 07:22 schrieb Luben Tuikov:
> Hi Christian,
>
> Thanks for working on this.
>
> Series is,
> Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
>
> Regards,
> Luben
>
> On 2023-04-20 07:57, Christian König wrote:
>> When a hw fence is signaled with an error properly forward that to the
>> finished fence.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>> drivers/gpu/drm/scheduler/sched_entity.c | 4 +---
>> drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
>> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
>> include/drm/gpu_scheduler.h | 2 +-
>> 4 files changed, 13 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
>> index 15d04a0ec623..eaf71fe15ed3 100644
>> --- a/drivers/gpu/drm/scheduler/sched_entity.c
>> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
>> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
>> {
>> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>>
>> - drm_sched_fence_finished(job->s_fence);
>> + drm_sched_fence_finished(job->s_fence, -ESRCH);
>> WARN_ON(job->s_fence->parent);
>> job->sched->ops->free_job(job);
>> }
>> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
>> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
>> struct drm_sched_fence *s_fence = job->s_fence;
>>
>> - dma_fence_set_error(&s_fence->finished, -ESRCH);
>> -
>> dma_fence_get(&s_fence->finished);
>> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
>> drm_sched_entity_kill_jobs_cb))
>> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
>> index 7fd869520ef2..1a6bea98c5cc 100644
>> --- a/drivers/gpu/drm/scheduler/sched_fence.c
>> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
>> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
>> dma_fence_signal(&fence->scheduled);
>> }
>>
>> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result)
>> {
>> + if (result)
>> + dma_fence_set_error(&fence->finished, result);
>> dma_fence_signal(&fence->finished);
>> }
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
>> index fcd4bfef7415..649fac2e1ccb 100644
>> --- a/drivers/gpu/drm/scheduler/sched_main.c
>> +++ b/drivers/gpu/drm/scheduler/sched_main.c
>> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
>> *
>> * Finish the job's fence and wake up the worker thread.
>> */
>> -static void drm_sched_job_done(struct drm_sched_job *s_job)
>> +static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
>> {
>> struct drm_sched_fence *s_fence = s_job->s_fence;
>> struct drm_gpu_scheduler *sched = s_fence->sched;
>> @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
>> trace_drm_sched_process_job(s_fence);
>>
>> dma_fence_get(&s_fence->finished);
>> - drm_sched_fence_finished(s_fence);
>> + drm_sched_fence_finished(s_fence, result);
>> dma_fence_put(&s_fence->finished);
>> wake_up_interruptible(&sched->wake_up_worker);
>> }
>> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb)
>> {
>> struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
>>
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, f->error);
>> }
>>
>> /**
>> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
>> r = dma_fence_add_callback(fence, &s_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, 0);
>> }
>>
>> if (full_recovery) {
>> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
>> r = dma_fence_add_callback(fence, &sched_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else {
>> - if (IS_ERR(fence))
>> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
>> -
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
>> + PTR_ERR(fence) : 0);
>> }
>>
>> wake_up(&sched->job_scheduled);
>> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
>> index ca857ec9e7eb..5c1df6b12ced 100644
>> --- a/include/drm/gpu_scheduler.h
>> +++ b/include/drm/gpu_scheduler.h
>> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
>> void drm_sched_fence_free(struct drm_sched_fence *fence);
>>
>> void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
>> -void drm_sched_fence_finished(struct drm_sched_fence *fence);
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
>>
>> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
>> void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
[-- Attachment #2: Type: text/html, Size: 14883 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-21 13:40 ` Deucher, Alexander
@ 2023-04-24 10:06 ` Christian König
0 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-04-24 10:06 UTC (permalink / raw)
To: Deucher, Alexander, amd-gfx@lists.freedesktop.org; +Cc: Tuikov, Luben
[-- Attachment #1: Type: text/plain, Size: 7582 bytes --]
I've pushed the scheduler patch to drm-misc-next and the whole set to
amd-staging-drm-next.
Christian.
Am 21.04.23 um 15:40 schrieb Deucher, Alexander:
>
> [AMD Official Use Only - General]
>
>
> Sure. We can pull it into amd-staging-drm-next as well if we need it
> for any customers in the short term.
>
> Alex
> ------------------------------------------------------------------------
> *From:* Christian König <ckoenig.leichtzumerken@gmail.com>
> *Sent:* Friday, April 21, 2023 9:27 AM
> *To:* amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>;
> Deucher, Alexander <Alexander.Deucher@amd.com>
> *Cc:* Tuikov, Luben <Luben.Tuikov@amd.com>
> *Subject:* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
> Alex can I merge that through drm-misc-next or do we really need
> amd-staging-drm-next?
>
> Christian.
>
> Am 21.04.23 um 07:22 schrieb Luben Tuikov:
> > Hi Christian,
> >
> > Thanks for working on this.
> >
> > Series is,
> > Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
> >
> > Regards,
> > Luben
> >
> > On 2023-04-20 07:57, Christian König wrote:
> >> When a hw fence is signaled with an error properly forward that to the
> >> finished fence.
> >>
> >> Signed-off-by: Christian König <christian.koenig@amd.com>
> >> ---
> >> drivers/gpu/drm/scheduler/sched_entity.c | 4 +---
> >> drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
> >> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
> >> include/drm/gpu_scheduler.h | 2 +-
> >> 4 files changed, 13 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> b/drivers/gpu/drm/scheduler/sched_entity.c
> >> index 15d04a0ec623..eaf71fe15ed3 100644
> >> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> >> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> >> @@ -144,7 +144,7 @@ static void
> drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
> >> {
> >> struct drm_sched_job *job = container_of(wrk, typeof(*job),
> work);
> >>
> >> - drm_sched_fence_finished(job->s_fence);
> >> + drm_sched_fence_finished(job->s_fence, -ESRCH);
> >> WARN_ON(job->s_fence->parent);
> >> job->sched->ops->free_job(job);
> >> }
> >> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct
> drm_sched_entity *entity)
> >> while ((job =
> to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
> >> struct drm_sched_fence *s_fence = job->s_fence;
> >>
> >> - dma_fence_set_error(&s_fence->finished, -ESRCH);
> >> -
> >> dma_fence_get(&s_fence->finished);
> >> if (!prev || dma_fence_add_callback(prev,
> &job->finish_cb,
> >> drm_sched_entity_kill_jobs_cb))
> >> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c
> b/drivers/gpu/drm/scheduler/sched_fence.c
> >> index 7fd869520ef2..1a6bea98c5cc 100644
> >> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> >> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> >> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct
> drm_sched_fence *fence)
> >> dma_fence_signal(&fence->scheduled);
> >> }
> >>
> >> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
> >> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> result)
> >> {
> >> + if (result)
> >> + dma_fence_set_error(&fence->finished, result);
> >> dma_fence_signal(&fence->finished);
> >> }
> >>
> >> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> >> index fcd4bfef7415..649fac2e1ccb 100644
> >> --- a/drivers/gpu/drm/scheduler/sched_main.c
> >> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> >> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct
> drm_sched_rq *rq)
> >> *
> >> * Finish the job's fence and wake up the worker thread.
> >> */
> >> -static void drm_sched_job_done(struct drm_sched_job *s_job)
> >> +static void drm_sched_job_done(struct drm_sched_job *s_job, int
> result)
> >> {
> >> struct drm_sched_fence *s_fence = s_job->s_fence;
> >> struct drm_gpu_scheduler *sched = s_fence->sched;
> >> @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct
> drm_sched_job *s_job)
> >> trace_drm_sched_process_job(s_fence);
> >>
> >> dma_fence_get(&s_fence->finished);
> >> - drm_sched_fence_finished(s_fence);
> >> + drm_sched_fence_finished(s_fence, result);
> >> dma_fence_put(&s_fence->finished);
> >> wake_up_interruptible(&sched->wake_up_worker);
> >> }
> >> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct
> dma_fence *f, struct dma_fence_cb *cb)
> >> {
> >> struct drm_sched_job *s_job = container_of(cb, struct
> drm_sched_job, cb);
> >>
> >> - drm_sched_job_done(s_job);
> >> + drm_sched_job_done(s_job, f->error);
> >> }
> >>
> >> /**
> >> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler
> *sched, bool full_recovery)
> >> r = dma_fence_add_callback(fence, &s_job->cb,
> >> drm_sched_job_done_cb);
> >> if (r == -ENOENT)
> >> - drm_sched_job_done(s_job);
> >> + drm_sched_job_done(s_job, fence->error);
> >> else if (r)
> >> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> >> r);
> >> } else
> >> - drm_sched_job_done(s_job);
> >> + drm_sched_job_done(s_job, 0);
> >> }
> >>
> >> if (full_recovery) {
> >> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
> >> r = dma_fence_add_callback(fence, &sched_job->cb,
> >> drm_sched_job_done_cb);
> >> if (r == -ENOENT)
> >> - drm_sched_job_done(sched_job);
> >> + drm_sched_job_done(sched_job, fence->error);
> >> else if (r)
> >> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> >> r);
> >> } else {
> >> - if (IS_ERR(fence))
> >> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
> >> -
> >> - drm_sched_job_done(sched_job);
> >> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
> >> + PTR_ERR(fence) : 0);
> >> }
> >>
> >> wake_up(&sched->job_scheduled);
> >> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> >> index ca857ec9e7eb..5c1df6b12ced 100644
> >> --- a/include/drm/gpu_scheduler.h
> >> +++ b/include/drm/gpu_scheduler.h
> >> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct
> drm_sched_fence *fence,
> >> void drm_sched_fence_free(struct drm_sched_fence *fence);
> >>
> >> void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
> >> -void drm_sched_fence_finished(struct drm_sched_fence *fence);
> >> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> result);
> >>
> >> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler
> *sched);
> >> void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
>
[-- Attachment #2: Type: text/html, Size: 15537 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-20 11:57 [PATCH 1/8] drm/scheduler: properly forward fence errors Christian König
` (7 preceding siblings ...)
2023-04-21 5:22 ` [PATCH 1/8] drm/scheduler: properly forward fence errors Luben Tuikov
@ 2023-04-27 10:35 ` Yin, ZhenGuo (Chris)
2023-04-27 12:05 ` Christian König
8 siblings, 1 reply; 17+ messages in thread
From: Yin, ZhenGuo (Chris) @ 2023-04-27 10:35 UTC (permalink / raw)
To: Christian König, amd-gfx@lists.freedesktop.org
Cc: Chen, JingWen (Wayne), Tuikov, Luben, Liu, Monk
[AMD Official Use Only - General]
Hi, Christian
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index fcd4bfef7415..649fac2e1ccb 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
r = dma_fence_add_callback(fence, &s_job->cb,
drm_sched_job_done_cb);
if (r == -ENOENT)
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, fence->error);
else if (r)
DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
r);
} else
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, 0);
}
if (full_recovery) {
I believe that the finished fence of some skipped jobs during FLR HASN'T been set to -ECANCELED.
In function drm_sched_stop, the callback has been removed from hw_fence and s_fence->parent has been set to NULL, see commit 45ecaea738830b9d521c93520c8f201359dcbd95(drm/sched: Partial revert of 'drm/sched: Keep s_fence->parent pointer').
In functnion drm_sched_start, jobs in the pending list pretend to be done without any errors(drm_sched_job_done(s_job, 0)).
Best,
Zhenguo
Cloud-GPU Core team, SRDC
-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
Sent: Thursday, April 20, 2023 7:58 PM
To: amd-gfx@lists.freedesktop.org
Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
Subject: [PATCH 1/8] drm/scheduler: properly forward fence errors
When a hw fence is signaled with an error properly forward that to the finished fence.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/scheduler/sched_entity.c | 4 +--- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
include/drm/gpu_scheduler.h | 2 +-
4 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 15d04a0ec623..eaf71fe15ed3 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) {
struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
- drm_sched_fence_finished(job->s_fence);
+ drm_sched_fence_finished(job->s_fence, -ESRCH);
WARN_ON(job->s_fence->parent);
job->sched->ops->free_job(job);
}
@@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
struct drm_sched_fence *s_fence = job->s_fence;
- dma_fence_set_error(&s_fence->finished, -ESRCH);
-
dma_fence_get(&s_fence->finished);
if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
drm_sched_entity_kill_jobs_cb)) diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
index 7fd869520ef2..1a6bea98c5cc 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
dma_fence_signal(&fence->scheduled);
}
-void drm_sched_fence_finished(struct drm_sched_fence *fence)
+void drm_sched_fence_finished(struct drm_sched_fence *fence, int
+result)
{
+ if (result)
+ dma_fence_set_error(&fence->finished, result);
dma_fence_signal(&fence->finished);
}
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index fcd4bfef7415..649fac2e1ccb 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
*
* Finish the job's fence and wake up the worker thread.
*/
-static void drm_sched_job_done(struct drm_sched_job *s_job)
+static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
{
struct drm_sched_fence *s_fence = s_job->s_fence;
struct drm_gpu_scheduler *sched = s_fence->sched; @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
trace_drm_sched_process_job(s_fence);
dma_fence_get(&s_fence->finished);
- drm_sched_fence_finished(s_fence);
+ drm_sched_fence_finished(s_fence, result);
dma_fence_put(&s_fence->finished);
wake_up_interruptible(&sched->wake_up_worker);
}
@@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb) {
struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, f->error);
}
/**
@@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
r = dma_fence_add_callback(fence, &s_job->cb,
drm_sched_job_done_cb);
if (r == -ENOENT)
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, fence->error);
else if (r)
DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
r);
} else
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, 0);
}
if (full_recovery) {
@@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
r = dma_fence_add_callback(fence, &sched_job->cb,
drm_sched_job_done_cb);
if (r == -ENOENT)
- drm_sched_job_done(sched_job);
+ drm_sched_job_done(sched_job, fence->error);
else if (r)
DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
r);
} else {
- if (IS_ERR(fence))
- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
-
- drm_sched_job_done(sched_job);
+ drm_sched_job_done(sched_job, IS_ERR(fence) ?
+ PTR_ERR(fence) : 0);
}
wake_up(&sched->job_scheduled);
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index ca857ec9e7eb..5c1df6b12ced 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence, void drm_sched_fence_free(struct drm_sched_fence *fence);
void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void drm_sched_fence_finished(struct drm_sched_fence *fence);
+void drm_sched_fence_finished(struct drm_sched_fence *fence, int
+result);
unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-27 10:35 ` Yin, ZhenGuo (Chris)
@ 2023-04-27 12:05 ` Christian König
2023-08-17 8:17 ` Yin, ZhenGuo (Chris)
0 siblings, 1 reply; 17+ messages in thread
From: Christian König @ 2023-04-27 12:05 UTC (permalink / raw)
To: Yin, ZhenGuo (Chris), amd-gfx@lists.freedesktop.org
Cc: Chen, JingWen (Wayne), Tuikov, Luben, Liu, Monk
Well good point, but as part of the effort of the Intel team to move the
scheduler over to a work item based design those two functions are
probably about to be removed.
Since we will probably have that in the internal package for a bit
longer I'm going to send a fix for this.
Regards,
Christian.
Am 27.04.23 um 12:35 schrieb Yin, ZhenGuo (Chris):
> [AMD Official Use Only - General]
>
> Hi, Christian
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
>
> I believe that the finished fence of some skipped jobs during FLR HASN'T been set to -ECANCELED.
> In function drm_sched_stop, the callback has been removed from hw_fence and s_fence->parent has been set to NULL, see commit 45ecaea738830b9d521c93520c8f201359dcbd95(drm/sched: Partial revert of 'drm/sched: Keep s_fence->parent pointer').
> In functnion drm_sched_start, jobs in the pending list pretend to be done without any errors(drm_sched_job_done(s_job, 0)).
>
>
> Best,
> Zhenguo
> Cloud-GPU Core team, SRDC
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
> Sent: Thursday, April 20, 2023 7:58 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
> Subject: [PATCH 1/8] drm/scheduler: properly forward fence errors
>
> When a hw fence is signaled with an error properly forward that to the finished fence.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/scheduler/sched_entity.c | 4 +--- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
> include/drm/gpu_scheduler.h | 2 +-
> 4 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
> index 15d04a0ec623..eaf71fe15ed3 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) {
> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>
> - drm_sched_fence_finished(job->s_fence);
> + drm_sched_fence_finished(job->s_fence, -ESRCH);
> WARN_ON(job->s_fence->parent);
> job->sched->ops->free_job(job);
> }
> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
> struct drm_sched_fence *s_fence = job->s_fence;
>
> - dma_fence_set_error(&s_fence->finished, -ESRCH);
> -
> dma_fence_get(&s_fence->finished);
> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
> drm_sched_entity_kill_jobs_cb)) diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
> index 7fd869520ef2..1a6bea98c5cc 100644
> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
> dma_fence_signal(&fence->scheduled);
> }
>
> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result)
> {
> + if (result)
> + dma_fence_set_error(&fence->finished, result);
> dma_fence_signal(&fence->finished);
> }
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
> *
> * Finish the job's fence and wake up the worker thread.
> */
> -static void drm_sched_job_done(struct drm_sched_job *s_job)
> +static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
> {
> struct drm_sched_fence *s_fence = s_job->s_fence;
> struct drm_gpu_scheduler *sched = s_fence->sched; @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
> trace_drm_sched_process_job(s_fence);
>
> dma_fence_get(&s_fence->finished);
> - drm_sched_fence_finished(s_fence);
> + drm_sched_fence_finished(s_fence, result);
> dma_fence_put(&s_fence->finished);
> wake_up_interruptible(&sched->wake_up_worker);
> }
> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb) {
> struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
>
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, f->error);
> }
>
> /**
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
> r = dma_fence_add_callback(fence, &sched_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else {
> - if (IS_ERR(fence))
> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
> -
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
> + PTR_ERR(fence) : 0);
> }
>
> wake_up(&sched->job_scheduled);
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index ca857ec9e7eb..5c1df6b12ced 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence, void drm_sched_fence_free(struct drm_sched_fence *fence);
>
> void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void drm_sched_fence_finished(struct drm_sched_fence *fence);
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result);
>
> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
> --
> 2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread* RE: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-04-27 12:05 ` Christian König
@ 2023-08-17 8:17 ` Yin, ZhenGuo (Chris)
2023-08-23 8:12 ` Yin, ZhenGuo (Chris)
0 siblings, 1 reply; 17+ messages in thread
From: Yin, ZhenGuo (Chris) @ 2023-08-17 8:17 UTC (permalink / raw)
To: Christian König, amd-gfx@lists.freedesktop.org
Cc: Chen, JingWen (Wayne), Tuikov, Luben, cao, lin, Li, Chong(Alan),
Liu, Monk
[AMD Official Use Only - General]
Hi, @Christian König
Any updates for the fix?
Recently we found that there will be a page fault after FLR, since an SDMA job in the pending list was dropped without forwarding fence errors.
Best,
Zhenguo
Cloud-GPU Core team, SRDC
-----Original Message-----
From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 27, 2023 8:05 PM
To: Yin, ZhenGuo (Chris) <ZhenGuo.Yin@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Tuikov, Luben <Luben.Tuikov@amd.com>; Chen, JingWen (Wayne) <JingWen.Chen2@amd.com>; Liu, Monk <Monk.Liu@amd.com>
Subject: Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
Well good point, but as part of the effort of the Intel team to move the scheduler over to a work item based design those two functions are probably about to be removed.
Since we will probably have that in the internal package for a bit longer I'm going to send a fix for this.
Regards,
Christian.
Am 27.04.23 um 12:35 schrieb Yin, ZhenGuo (Chris):
> [AMD Official Use Only - General]
>
> Hi, Christian
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
>
> I believe that the finished fence of some skipped jobs during FLR HASN'T been set to -ECANCELED.
> In function drm_sched_stop, the callback has been removed from hw_fence and s_fence->parent has been set to NULL, see commit 45ecaea738830b9d521c93520c8f201359dcbd95(drm/sched: Partial revert of 'drm/sched: Keep s_fence->parent pointer').
> In functnion drm_sched_start, jobs in the pending list pretend to be done without any errors(drm_sched_job_done(s_job, 0)).
>
>
> Best,
> Zhenguo
> Cloud-GPU Core team, SRDC
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
> Christian König
> Sent: Thursday, April 20, 2023 7:58 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
> Subject: [PATCH 1/8] drm/scheduler: properly forward fence errors
>
> When a hw fence is signaled with an error properly forward that to the finished fence.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/scheduler/sched_entity.c | 4 +--- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
> include/drm/gpu_scheduler.h | 2 +-
> 4 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> b/drivers/gpu/drm/scheduler/sched_entity.c
> index 15d04a0ec623..eaf71fe15ed3 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) {
> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>
> - drm_sched_fence_finished(job->s_fence);
> + drm_sched_fence_finished(job->s_fence, -ESRCH);
> WARN_ON(job->s_fence->parent);
> job->sched->ops->free_job(job);
> }
> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
> struct drm_sched_fence *s_fence = job->s_fence;
>
> - dma_fence_set_error(&s_fence->finished, -ESRCH);
> -
> dma_fence_get(&s_fence->finished);
> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
> drm_sched_entity_kill_jobs_cb)) diff --git
> a/drivers/gpu/drm/scheduler/sched_fence.c
> b/drivers/gpu/drm/scheduler/sched_fence.c
> index 7fd869520ef2..1a6bea98c5cc 100644
> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
> dma_fence_signal(&fence->scheduled);
> }
>
> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result)
> {
> + if (result)
> + dma_fence_set_error(&fence->finished, result);
> dma_fence_signal(&fence->finished);
> }
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
> *
> * Finish the job's fence and wake up the worker thread.
> */
> -static void drm_sched_job_done(struct drm_sched_job *s_job)
> +static void drm_sched_job_done(struct drm_sched_job *s_job, int
> +result)
> {
> struct drm_sched_fence *s_fence = s_job->s_fence;
> struct drm_gpu_scheduler *sched = s_fence->sched; @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
> trace_drm_sched_process_job(s_fence);
>
> dma_fence_get(&s_fence->finished);
> - drm_sched_fence_finished(s_fence);
> + drm_sched_fence_finished(s_fence, result);
> dma_fence_put(&s_fence->finished);
> wake_up_interruptible(&sched->wake_up_worker);
> }
> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb) {
> struct drm_sched_job *s_job = container_of(cb, struct
> drm_sched_job, cb);
>
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, f->error);
> }
>
> /**
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
> r = dma_fence_add_callback(fence, &sched_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else {
> - if (IS_ERR(fence))
> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
> -
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
> + PTR_ERR(fence) : 0);
> }
>
> wake_up(&sched->job_scheduled);
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index ca857ec9e7eb..5c1df6b12ced 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence
> *fence, void drm_sched_fence_free(struct drm_sched_fence *fence);
>
> void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void
> drm_sched_fence_finished(struct drm_sched_fence *fence);
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result);
>
> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler
> *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler
> *sched,
> --
> 2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread* RE: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-08-17 8:17 ` Yin, ZhenGuo (Chris)
@ 2023-08-23 8:12 ` Yin, ZhenGuo (Chris)
2023-08-23 8:26 ` Christian König
0 siblings, 1 reply; 17+ messages in thread
From: Yin, ZhenGuo (Chris) @ 2023-08-23 8:12 UTC (permalink / raw)
To: Christian König, amd-gfx@lists.freedesktop.org
Cc: Chen, JingWen (Wayne), Tuikov, Luben, cao, lin, Li, Chong(Alan),
Liu, Monk
[AMD Official Use Only - General]
Ping..
Actually, I prepare a patch aiming to fix this issue.
But I'm not sure whether this is proper for drm/scheduler.
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 9654e8942382..35dc0b86a18e 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -463,6 +463,7 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
&s_job->cb)) {
dma_fence_put(s_job->s_fence->parent);
s_job->s_fence->parent = NULL;
+ dma_fence_set_error(&s_job->s_fence->finished, -EHWPOISON);
atomic_dec(&sched->hw_rq_count);
} else {
/*
Best,
Zhenguo
Cloud-GPU Core team, SRDC
-----Original Message-----
From: Yin, ZhenGuo (Chris)
Sent: Thursday, August 17, 2023 4:17 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com>; amd-gfx@lists.freedesktop.org
Cc: Tuikov, Luben <Luben.Tuikov@amd.com>; Chen, JingWen (Wayne) <JingWen.Chen2@amd.com>; Liu, Monk <Monk.Liu@amd.com>; Li, Chong(Alan) <chong.li@amd.com>; cao, lin <lin.cao@amd.com>
Subject: RE: [PATCH 1/8] drm/scheduler: properly forward fence errors
Hi, @Christian König
Any updates for the fix?
Recently we found that there will be a page fault after FLR, since an SDMA job in the pending list was dropped without forwarding fence errors.
Best,
Zhenguo
Cloud-GPU Core team, SRDC
-----Original Message-----
From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 27, 2023 8:05 PM
To: Yin, ZhenGuo (Chris) <ZhenGuo.Yin@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Tuikov, Luben <Luben.Tuikov@amd.com>; Chen, JingWen (Wayne) <JingWen.Chen2@amd.com>; Liu, Monk <Monk.Liu@amd.com>
Subject: Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
Well good point, but as part of the effort of the Intel team to move the scheduler over to a work item based design those two functions are probably about to be removed.
Since we will probably have that in the internal package for a bit longer I'm going to send a fix for this.
Regards,
Christian.
Am 27.04.23 um 12:35 schrieb Yin, ZhenGuo (Chris):
> [AMD Official Use Only - General]
>
> Hi, Christian
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
>
> I believe that the finished fence of some skipped jobs during FLR HASN'T been set to -ECANCELED.
> In function drm_sched_stop, the callback has been removed from hw_fence and s_fence->parent has been set to NULL, see commit 45ecaea738830b9d521c93520c8f201359dcbd95(drm/sched: Partial revert of 'drm/sched: Keep s_fence->parent pointer').
> In functnion drm_sched_start, jobs in the pending list pretend to be done without any errors(drm_sched_job_done(s_job, 0)).
>
>
> Best,
> Zhenguo
> Cloud-GPU Core team, SRDC
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
> Christian König
> Sent: Thursday, April 20, 2023 7:58 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
> Subject: [PATCH 1/8] drm/scheduler: properly forward fence errors
>
> When a hw fence is signaled with an error properly forward that to the finished fence.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/scheduler/sched_entity.c | 4 +--- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
> include/drm/gpu_scheduler.h | 2 +-
> 4 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> b/drivers/gpu/drm/scheduler/sched_entity.c
> index 15d04a0ec623..eaf71fe15ed3 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) {
> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>
> - drm_sched_fence_finished(job->s_fence);
> + drm_sched_fence_finished(job->s_fence, -ESRCH);
> WARN_ON(job->s_fence->parent);
> job->sched->ops->free_job(job);
> }
> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
> struct drm_sched_fence *s_fence = job->s_fence;
>
> - dma_fence_set_error(&s_fence->finished, -ESRCH);
> -
> dma_fence_get(&s_fence->finished);
> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
> drm_sched_entity_kill_jobs_cb)) diff --git
> a/drivers/gpu/drm/scheduler/sched_fence.c
> b/drivers/gpu/drm/scheduler/sched_fence.c
> index 7fd869520ef2..1a6bea98c5cc 100644
> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
> dma_fence_signal(&fence->scheduled);
> }
>
> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result)
> {
> + if (result)
> + dma_fence_set_error(&fence->finished, result);
> dma_fence_signal(&fence->finished);
> }
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index fcd4bfef7415..649fac2e1ccb 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
> *
> * Finish the job's fence and wake up the worker thread.
> */
> -static void drm_sched_job_done(struct drm_sched_job *s_job)
> +static void drm_sched_job_done(struct drm_sched_job *s_job, int
> +result)
> {
> struct drm_sched_fence *s_fence = s_job->s_fence;
> struct drm_gpu_scheduler *sched = s_fence->sched; @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
> trace_drm_sched_process_job(s_fence);
>
> dma_fence_get(&s_fence->finished);
> - drm_sched_fence_finished(s_fence);
> + drm_sched_fence_finished(s_fence, result);
> dma_fence_put(&s_fence->finished);
> wake_up_interruptible(&sched->wake_up_worker);
> }
> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb) {
> struct drm_sched_job *s_job = container_of(cb, struct
> drm_sched_job, cb);
>
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, f->error);
> }
>
> /**
> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
> r = dma_fence_add_callback(fence, &s_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else
> - drm_sched_job_done(s_job);
> + drm_sched_job_done(s_job, 0);
> }
>
> if (full_recovery) {
> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
> r = dma_fence_add_callback(fence, &sched_job->cb,
> drm_sched_job_done_cb);
> if (r == -ENOENT)
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, fence->error);
> else if (r)
> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
> r);
> } else {
> - if (IS_ERR(fence))
> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
> -
> - drm_sched_job_done(sched_job);
> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
> + PTR_ERR(fence) : 0);
> }
>
> wake_up(&sched->job_scheduled);
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index ca857ec9e7eb..5c1df6b12ced 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence
> *fence, void drm_sched_fence_free(struct drm_sched_fence *fence);
>
> void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void
> drm_sched_fence_finished(struct drm_sched_fence *fence);
> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
> +result);
>
> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler
> *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler
> *sched,
> --
> 2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
2023-08-23 8:12 ` Yin, ZhenGuo (Chris)
@ 2023-08-23 8:26 ` Christian König
0 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2023-08-23 8:26 UTC (permalink / raw)
To: Yin, ZhenGuo (Chris), amd-gfx@lists.freedesktop.org
Cc: Chen, JingWen (Wayne), Tuikov, Luben, cao, lin, Li, Chong(Alan),
Liu, Monk
This was fixed here:
commit 03877d621db082610c9b7602c6e8cd6ebcb75a8f
Author: Christian König <christian.koenig@amd.com>
Date: Thu Apr 27 14:05:43 2023 +0200
drm/scheduler: mark jobs without fence as canceled
When no hw fence is provided for a job that means that the job
didn't executed.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
Link:
https://patchwork.freedesktop.org/patch/msgid/20230427122726.1290170-1-christian.koenig@amd.com
Could be that the patch hasn't been merged into the internal branches yet.
Regards,
Christian.
Am 23.08.23 um 10:12 schrieb Yin, ZhenGuo (Chris):
> [AMD Official Use Only - General]
>
> Ping..
>
> Actually, I prepare a patch aiming to fix this issue.
> But I'm not sure whether this is proper for drm/scheduler.
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index 9654e8942382..35dc0b86a18e 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -463,6 +463,7 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
> &s_job->cb)) {
> dma_fence_put(s_job->s_fence->parent);
> s_job->s_fence->parent = NULL;
> + dma_fence_set_error(&s_job->s_fence->finished, -EHWPOISON);
> atomic_dec(&sched->hw_rq_count);
> } else {
> /*
> Best,
> Zhenguo
> Cloud-GPU Core team, SRDC
>
> -----Original Message-----
> From: Yin, ZhenGuo (Chris)
> Sent: Thursday, August 17, 2023 4:17 PM
> To: Christian König <ckoenig.leichtzumerken@gmail.com>; amd-gfx@lists.freedesktop.org
> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>; Chen, JingWen (Wayne) <JingWen.Chen2@amd.com>; Liu, Monk <Monk.Liu@amd.com>; Li, Chong(Alan) <chong.li@amd.com>; cao, lin <lin.cao@amd.com>
> Subject: RE: [PATCH 1/8] drm/scheduler: properly forward fence errors
>
> Hi, @Christian König
>
> Any updates for the fix?
> Recently we found that there will be a page fault after FLR, since an SDMA job in the pending list was dropped without forwarding fence errors.
>
>
> Best,
> Zhenguo
> Cloud-GPU Core team, SRDC
>
> -----Original Message-----
> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> Sent: Thursday, April 27, 2023 8:05 PM
> To: Yin, ZhenGuo (Chris) <ZhenGuo.Yin@amd.com>; amd-gfx@lists.freedesktop.org
> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>; Chen, JingWen (Wayne) <JingWen.Chen2@amd.com>; Liu, Monk <Monk.Liu@amd.com>
> Subject: Re: [PATCH 1/8] drm/scheduler: properly forward fence errors
>
> Well good point, but as part of the effort of the Intel team to move the scheduler over to a work item based design those two functions are probably about to be removed.
>
> Since we will probably have that in the internal package for a bit longer I'm going to send a fix for this.
>
> Regards,
> Christian.
>
> Am 27.04.23 um 12:35 schrieb Yin, ZhenGuo (Chris):
>> [AMD Official Use Only - General]
>>
>> Hi, Christian
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
>> b/drivers/gpu/drm/scheduler/sched_main.c
>> index fcd4bfef7415..649fac2e1ccb 100644
>> --- a/drivers/gpu/drm/scheduler/sched_main.c
>> +++ b/drivers/gpu/drm/scheduler/sched_main.c
>> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
>> r = dma_fence_add_callback(fence, &s_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, 0);
>> }
>>
>> if (full_recovery) {
>>
>> I believe that the finished fence of some skipped jobs during FLR HASN'T been set to -ECANCELED.
>> In function drm_sched_stop, the callback has been removed from hw_fence and s_fence->parent has been set to NULL, see commit 45ecaea738830b9d521c93520c8f201359dcbd95(drm/sched: Partial revert of 'drm/sched: Keep s_fence->parent pointer').
>> In functnion drm_sched_start, jobs in the pending list pretend to be done without any errors(drm_sched_job_done(s_job, 0)).
>>
>>
>> Best,
>> Zhenguo
>> Cloud-GPU Core team, SRDC
>>
>> -----Original Message-----
>> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
>> Christian König
>> Sent: Thursday, April 20, 2023 7:58 PM
>> To: amd-gfx@lists.freedesktop.org
>> Cc: Tuikov, Luben <Luben.Tuikov@amd.com>
>> Subject: [PATCH 1/8] drm/scheduler: properly forward fence errors
>>
>> When a hw fence is signaled with an error properly forward that to the finished fence.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>> drivers/gpu/drm/scheduler/sched_entity.c | 4 +--- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++-
>> drivers/gpu/drm/scheduler/sched_main.c | 18 ++++++++----------
>> include/drm/gpu_scheduler.h | 2 +-
>> 4 files changed, 13 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
>> b/drivers/gpu/drm/scheduler/sched_entity.c
>> index 15d04a0ec623..eaf71fe15ed3 100644
>> --- a/drivers/gpu/drm/scheduler/sched_entity.c
>> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
>> @@ -144,7 +144,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) {
>> struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
>>
>> - drm_sched_fence_finished(job->s_fence);
>> + drm_sched_fence_finished(job->s_fence, -ESRCH);
>> WARN_ON(job->s_fence->parent);
>> job->sched->ops->free_job(job);
>> }
>> @@ -195,8 +195,6 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
>> while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
>> struct drm_sched_fence *s_fence = job->s_fence;
>>
>> - dma_fence_set_error(&s_fence->finished, -ESRCH);
>> -
>> dma_fence_get(&s_fence->finished);
>> if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
>> drm_sched_entity_kill_jobs_cb)) diff --git
>> a/drivers/gpu/drm/scheduler/sched_fence.c
>> b/drivers/gpu/drm/scheduler/sched_fence.c
>> index 7fd869520ef2..1a6bea98c5cc 100644
>> --- a/drivers/gpu/drm/scheduler/sched_fence.c
>> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
>> @@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
>> dma_fence_signal(&fence->scheduled);
>> }
>>
>> -void drm_sched_fence_finished(struct drm_sched_fence *fence)
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
>> +result)
>> {
>> + if (result)
>> + dma_fence_set_error(&fence->finished, result);
>> dma_fence_signal(&fence->finished);
>> }
>>
>> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
>> b/drivers/gpu/drm/scheduler/sched_main.c
>> index fcd4bfef7415..649fac2e1ccb 100644
>> --- a/drivers/gpu/drm/scheduler/sched_main.c
>> +++ b/drivers/gpu/drm/scheduler/sched_main.c
>> @@ -257,7 +257,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
>> *
>> * Finish the job's fence and wake up the worker thread.
>> */
>> -static void drm_sched_job_done(struct drm_sched_job *s_job)
>> +static void drm_sched_job_done(struct drm_sched_job *s_job, int
>> +result)
>> {
>> struct drm_sched_fence *s_fence = s_job->s_fence;
>> struct drm_gpu_scheduler *sched = s_fence->sched; @@ -268,7 +268,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
>> trace_drm_sched_process_job(s_fence);
>>
>> dma_fence_get(&s_fence->finished);
>> - drm_sched_fence_finished(s_fence);
>> + drm_sched_fence_finished(s_fence, result);
>> dma_fence_put(&s_fence->finished);
>> wake_up_interruptible(&sched->wake_up_worker);
>> }
>> @@ -282,7 +282,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb) {
>> struct drm_sched_job *s_job = container_of(cb, struct
>> drm_sched_job, cb);
>>
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, f->error);
>> }
>>
>> /**
>> @@ -533,12 +533,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
>> r = dma_fence_add_callback(fence, &s_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else
>> - drm_sched_job_done(s_job);
>> + drm_sched_job_done(s_job, 0);
>> }
>>
>> if (full_recovery) {
>> @@ -1010,15 +1010,13 @@ static int drm_sched_main(void *param)
>> r = dma_fence_add_callback(fence, &sched_job->cb,
>> drm_sched_job_done_cb);
>> if (r == -ENOENT)
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, fence->error);
>> else if (r)
>> DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
>> r);
>> } else {
>> - if (IS_ERR(fence))
>> - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
>> -
>> - drm_sched_job_done(sched_job);
>> + drm_sched_job_done(sched_job, IS_ERR(fence) ?
>> + PTR_ERR(fence) : 0);
>> }
>>
>> wake_up(&sched->job_scheduled);
>> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
>> index ca857ec9e7eb..5c1df6b12ced 100644
>> --- a/include/drm/gpu_scheduler.h
>> +++ b/include/drm/gpu_scheduler.h
>> @@ -569,7 +569,7 @@ void drm_sched_fence_init(struct drm_sched_fence
>> *fence, void drm_sched_fence_free(struct drm_sched_fence *fence);
>>
>> void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void
>> drm_sched_fence_finished(struct drm_sched_fence *fence);
>> +void drm_sched_fence_finished(struct drm_sched_fence *fence, int
>> +result);
>>
>> unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler
>> *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler
>> *sched,
>> --
>> 2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread