Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panfrost: Handle job HW submit errors

Avoid waiting for the DRM scheduler job timedout handler, and instead, let
the DRM scheduler core signal the error fence immediately when HW job
submission fails.

That means we must also decrement the runtime-PM refcnt for the device,
because the job will never be enqueued or inflight.

Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Link: https://lore.kernel.org/r/20251019145225.3621989-4-adrian.larumbe@collabora.com
Signed-off-by: Steven Price <steven.price@arm.com>

authored by

Adrián Larumbe and committed by
Steven Price
616c5b6f 16dd7e03

+18 -6
+18 -6
drivers/gpu/drm/panfrost/panfrost_job.c
··· 200 200 return 1; 201 201 } 202 202 203 - static void panfrost_job_hw_submit(struct panfrost_job *job, int js) 203 + static int panfrost_job_hw_submit(struct panfrost_job *job, int js) 204 204 { 205 205 struct panfrost_device *pfdev = job->pfdev; 206 206 unsigned int subslot; ··· 208 208 u64 jc_head = job->jc; 209 209 int ret; 210 210 211 - panfrost_devfreq_record_busy(&pfdev->pfdevfreq); 212 - 213 211 ret = pm_runtime_get_sync(pfdev->base.dev); 214 212 if (ret < 0) 215 - return; 213 + goto err_hwsubmit; 216 214 217 215 if (WARN_ON(job_read(pfdev, JS_COMMAND_NEXT(js)))) { 218 - return; 216 + ret = -EINVAL; 217 + goto err_hwsubmit; 219 218 } 220 219 221 220 cfg = panfrost_mmu_as_get(pfdev, job->mmu); 221 + 222 + panfrost_devfreq_record_busy(&pfdev->pfdevfreq); 222 223 223 224 job_write(pfdev, JS_HEAD_NEXT_LO(js), lower_32_bits(jc_head)); 224 225 job_write(pfdev, JS_HEAD_NEXT_HI(js), upper_32_bits(jc_head)); ··· 267 266 job, js, subslot, jc_head, cfg & 0xf); 268 267 } 269 268 spin_unlock(&pfdev->js->job_lock); 269 + 270 + return 0; 271 + 272 + err_hwsubmit: 273 + pm_runtime_put_autosuspend(pfdev->base.dev); 274 + return ret; 270 275 } 271 276 272 277 static int panfrost_acquire_object_fences(struct drm_gem_object **bos, ··· 395 388 struct panfrost_device *pfdev = job->pfdev; 396 389 int slot = panfrost_job_get_slot(job); 397 390 struct dma_fence *fence = NULL; 391 + int ret; 398 392 399 393 if (job->ctx->destroyed) 400 394 return ERR_PTR(-ECANCELED); ··· 417 409 dma_fence_put(job->done_fence); 418 410 job->done_fence = dma_fence_get(fence); 419 411 420 - panfrost_job_hw_submit(job, slot); 412 + ret = panfrost_job_hw_submit(job, slot); 413 + if (ret) { 414 + dma_fence_put(fence); 415 + return ERR_PTR(ret); 416 + } 421 417 422 418 return fence; 423 419 }