mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
drm/amdgpu: recreate fence from user seq
And use common fence infrastructure for the wait. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
This commit is contained in:
parent
7cebc72817
commit
03507c4f2f
3 changed files with 44 additions and 9 deletions
|
@ -425,6 +425,8 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
|
||||||
unsigned irq_type);
|
unsigned irq_type);
|
||||||
int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
|
int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
|
||||||
struct amdgpu_fence **fence);
|
struct amdgpu_fence **fence);
|
||||||
|
int amdgpu_fence_recreate(struct amdgpu_ring *ring, void *owner,
|
||||||
|
uint64_t seq, struct amdgpu_fence **fence);
|
||||||
void amdgpu_fence_process(struct amdgpu_ring *ring);
|
void amdgpu_fence_process(struct amdgpu_ring *ring);
|
||||||
int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
|
int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
|
||||||
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
|
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
|
||||||
|
@ -435,9 +437,6 @@ int amdgpu_fence_wait(struct amdgpu_fence *fence, bool interruptible);
|
||||||
int amdgpu_fence_wait_any(struct amdgpu_device *adev,
|
int amdgpu_fence_wait_any(struct amdgpu_device *adev,
|
||||||
struct amdgpu_fence **fences,
|
struct amdgpu_fence **fences,
|
||||||
bool intr);
|
bool intr);
|
||||||
long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
|
|
||||||
u64 *target_seq, bool intr,
|
|
||||||
long timeout);
|
|
||||||
struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
|
struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
|
||||||
void amdgpu_fence_unref(struct amdgpu_fence **fence);
|
void amdgpu_fence_unref(struct amdgpu_fence **fence);
|
||||||
|
|
||||||
|
|
|
@ -739,9 +739,9 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
|
||||||
{
|
{
|
||||||
union drm_amdgpu_wait_cs *wait = data;
|
union drm_amdgpu_wait_cs *wait = data;
|
||||||
struct amdgpu_device *adev = dev->dev_private;
|
struct amdgpu_device *adev = dev->dev_private;
|
||||||
uint64_t seq[AMDGPU_MAX_RINGS] = {0};
|
|
||||||
struct amdgpu_ring *ring = NULL;
|
|
||||||
unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout);
|
unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout);
|
||||||
|
struct amdgpu_fence *fence = NULL;
|
||||||
|
struct amdgpu_ring *ring = NULL;
|
||||||
struct amdgpu_ctx *ctx;
|
struct amdgpu_ctx *ctx;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
|
@ -754,9 +754,12 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
seq[ring->idx] = wait->in.handle;
|
r = amdgpu_fence_recreate(ring, filp, wait->in.handle, &fence);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = amdgpu_fence_wait_seq_timeout(adev, seq, true, timeout);
|
r = fence_wait_timeout(&fence->base, true, timeout);
|
||||||
|
amdgpu_fence_unref(&fence);
|
||||||
amdgpu_ctx_put(ctx);
|
amdgpu_ctx_put(ctx);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -135,6 +135,38 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_fence_recreate - recreate a fence from an user fence
|
||||||
|
*
|
||||||
|
* @ring: ring the fence is associated with
|
||||||
|
* @owner: creator of the fence
|
||||||
|
* @seq: user fence sequence number
|
||||||
|
* @fence: resulting amdgpu fence object
|
||||||
|
*
|
||||||
|
* Recreates a fence command from the user fence sequence number (all asics).
|
||||||
|
* Returns 0 on success, -ENOMEM on failure.
|
||||||
|
*/
|
||||||
|
int amdgpu_fence_recreate(struct amdgpu_ring *ring, void *owner,
|
||||||
|
uint64_t seq, struct amdgpu_fence **fence)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = ring->adev;
|
||||||
|
|
||||||
|
if (seq > ring->fence_drv.sync_seq[ring->idx])
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*fence = kmalloc(sizeof(struct amdgpu_fence), GFP_KERNEL);
|
||||||
|
if ((*fence) == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
(*fence)->seq = seq;
|
||||||
|
(*fence)->ring = ring;
|
||||||
|
(*fence)->owner = owner;
|
||||||
|
fence_init(&(*fence)->base, &amdgpu_fence_ops,
|
||||||
|
&adev->fence_queue.lock, adev->fence_context + ring->idx,
|
||||||
|
(*fence)->seq);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_fence_check_signaled - callback from fence_queue
|
* amdgpu_fence_check_signaled - callback from fence_queue
|
||||||
*
|
*
|
||||||
|
@ -517,8 +549,9 @@ static bool amdgpu_fence_any_seq_signaled(struct amdgpu_device *adev, u64 *seq)
|
||||||
* the wait timeout, or an error for all other cases.
|
* the wait timeout, or an error for all other cases.
|
||||||
* -EDEADLK is returned when a GPU lockup has been detected.
|
* -EDEADLK is returned when a GPU lockup has been detected.
|
||||||
*/
|
*/
|
||||||
long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev, u64 *target_seq,
|
static long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
|
||||||
bool intr, long timeout)
|
u64 *target_seq, bool intr,
|
||||||
|
long timeout)
|
||||||
{
|
{
|
||||||
uint64_t last_seq[AMDGPU_MAX_RINGS];
|
uint64_t last_seq[AMDGPU_MAX_RINGS];
|
||||||
bool signaled;
|
bool signaled;
|
||||||
|
|
Loading…
Reference in a new issue