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

drm/amdgpu/userq: add force completion helpers

Add support for forcing completion of userq fences.
This is needed for userq resets and asic resets so that we
can set the error on the fence and force completion.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+43
+42
drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
··· 67 67 return le64_to_cpu(*fence_drv->cpu_addr); 68 68 } 69 69 70 + static void 71 + amdgpu_userq_fence_write(struct amdgpu_userq_fence_driver *fence_drv, 72 + u64 seq) 73 + { 74 + if (fence_drv->cpu_addr) 75 + *fence_drv->cpu_addr = cpu_to_le64(seq); 76 + } 77 + 70 78 int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev, 71 79 struct amdgpu_usermode_queue *userq) 72 80 { ··· 414 406 static void amdgpu_userq_fence_cleanup(struct dma_fence *fence) 415 407 { 416 408 dma_fence_put(fence); 409 + } 410 + 411 + static void 412 + amdgpu_userq_fence_driver_set_error(struct amdgpu_userq_fence *fence, 413 + int error) 414 + { 415 + struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv; 416 + unsigned long flags; 417 + struct dma_fence *f; 418 + 419 + spin_lock_irqsave(&fence_drv->fence_list_lock, flags); 420 + 421 + f = rcu_dereference_protected(&fence->base, 422 + lockdep_is_held(&fence_drv->fence_list_lock)); 423 + if (f && !dma_fence_is_signaled_locked(f)) 424 + dma_fence_set_error(f, error); 425 + spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); 426 + } 427 + 428 + void 429 + amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq) 430 + { 431 + struct dma_fence *f = userq->last_fence; 432 + 433 + if (f) { 434 + struct amdgpu_userq_fence *fence = to_amdgpu_userq_fence(f); 435 + struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv; 436 + u64 wptr = fence->base.seqno; 437 + 438 + amdgpu_userq_fence_driver_set_error(fence, -ECANCELED); 439 + amdgpu_userq_fence_write(fence_drv, wptr); 440 + amdgpu_userq_fence_driver_process(fence_drv); 441 + 442 + } 417 443 } 418 444 419 445 int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
··· 67 67 struct amdgpu_usermode_queue *userq); 68 68 void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq); 69 69 void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv); 70 + void amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq); 70 71 void amdgpu_userq_fence_driver_destroy(struct kref *ref); 71 72 int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, 72 73 struct drm_file *filp);