Commit f91b3a69 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: fix fence wait in sync_fence, instead should be in sync_rings

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarChunming Zhou <david1.zhou@amd.com>
Reviewed-by: default avatarChristian K?nig <christian.koenig@amd.com>
parent c746ba22
...@@ -704,6 +704,7 @@ void amdgpu_semaphore_free(struct amdgpu_device *adev, ...@@ -704,6 +704,7 @@ void amdgpu_semaphore_free(struct amdgpu_device *adev,
struct amdgpu_sync { struct amdgpu_sync {
struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS]; struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS];
struct amdgpu_fence *sync_to[AMDGPU_MAX_RINGS]; struct amdgpu_fence *sync_to[AMDGPU_MAX_RINGS];
DECLARE_HASHTABLE(fences, 4);
struct amdgpu_fence *last_vm_update; struct amdgpu_fence *last_vm_update;
}; };
...@@ -716,6 +717,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, ...@@ -716,6 +717,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
void *owner); void *owner);
int amdgpu_sync_rings(struct amdgpu_sync *sync, int amdgpu_sync_rings(struct amdgpu_sync *sync,
struct amdgpu_ring *ring); struct amdgpu_ring *ring);
int amdgpu_sync_wait(struct amdgpu_sync *sync);
void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync, void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync,
struct fence *fence); struct fence *fence);
......
...@@ -140,7 +140,11 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, ...@@ -140,7 +140,11 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
dev_err(adev->dev, "couldn't schedule ib\n"); dev_err(adev->dev, "couldn't schedule ib\n");
return -EINVAL; return -EINVAL;
} }
r = amdgpu_sync_wait(&ibs->sync);
if (r) {
dev_err(adev->dev, "IB sync failed (%d).\n", r);
return r;
}
r = amdgpu_ring_lock(ring, (256 + AMDGPU_NUM_SYNCS * 8) * num_ibs); r = amdgpu_ring_lock(ring, (256 + AMDGPU_NUM_SYNCS * 8) * num_ibs);
if (r) { if (r) {
dev_err(adev->dev, "scheduling IB failed (%d).\n", r); dev_err(adev->dev, "scheduling IB failed (%d).\n", r);
......
...@@ -32,6 +32,11 @@ ...@@ -32,6 +32,11 @@
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_trace.h" #include "amdgpu_trace.h"
struct amdgpu_sync_entry {
struct hlist_node node;
struct fence *fence;
};
/** /**
* amdgpu_sync_create - zero init sync object * amdgpu_sync_create - zero init sync object
* *
...@@ -49,6 +54,7 @@ void amdgpu_sync_create(struct amdgpu_sync *sync) ...@@ -49,6 +54,7 @@ void amdgpu_sync_create(struct amdgpu_sync *sync)
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
sync->sync_to[i] = NULL; sync->sync_to[i] = NULL;
hash_init(sync->fences);
sync->last_vm_update = NULL; sync->last_vm_update = NULL;
} }
...@@ -62,6 +68,7 @@ void amdgpu_sync_create(struct amdgpu_sync *sync) ...@@ -62,6 +68,7 @@ void amdgpu_sync_create(struct amdgpu_sync *sync)
int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
struct fence *f) struct fence *f)
{ {
struct amdgpu_sync_entry *e;
struct amdgpu_fence *fence; struct amdgpu_fence *fence;
struct amdgpu_fence *other; struct amdgpu_fence *other;
...@@ -69,8 +76,27 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, ...@@ -69,8 +76,27 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
return 0; return 0;
fence = to_amdgpu_fence(f); fence = to_amdgpu_fence(f);
if (!fence || fence->ring->adev != adev) if (!fence || fence->ring->adev != adev) {
return fence_wait(f, true); hash_for_each_possible(sync->fences, e, node, f->context) {
struct fence *new;
if (unlikely(e->fence->context != f->context))
continue;
new = fence_get(fence_later(e->fence, f));
if (new) {
fence_put(e->fence);
e->fence = new;
}
return 0;
}
e = kmalloc(sizeof(struct amdgpu_sync_entry), GFP_KERNEL);
if (!e)
return -ENOMEM;
hash_add(sync->fences, &e->node, f->context);
e->fence = fence_get(f);
return 0;
}
other = sync->sync_to[fence->ring->idx]; other = sync->sync_to[fence->ring->idx];
sync->sync_to[fence->ring->idx] = amdgpu_fence_ref( sync->sync_to[fence->ring->idx] = amdgpu_fence_ref(
...@@ -147,6 +173,24 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, ...@@ -147,6 +173,24 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
return r; return r;
} }
int amdgpu_sync_wait(struct amdgpu_sync *sync)
{
struct amdgpu_sync_entry *e;
struct hlist_node *tmp;
int i, r;
hash_for_each_safe(sync->fences, i, tmp, e, node) {
r = fence_wait(e->fence, false);
if (r)
return r;
hash_del(&e->node);
fence_put(e->fence);
kfree(e);
}
return 0;
}
/** /**
* amdgpu_sync_rings - sync ring to all registered fences * amdgpu_sync_rings - sync ring to all registered fences
* *
...@@ -236,8 +280,16 @@ void amdgpu_sync_free(struct amdgpu_device *adev, ...@@ -236,8 +280,16 @@ void amdgpu_sync_free(struct amdgpu_device *adev,
struct amdgpu_sync *sync, struct amdgpu_sync *sync,
struct fence *fence) struct fence *fence)
{ {
struct amdgpu_sync_entry *e;
struct hlist_node *tmp;
unsigned i; unsigned i;
hash_for_each_safe(sync->fences, i, tmp, e, node) {
hash_del(&e->node);
fence_put(e->fence);
kfree(e);
}
for (i = 0; i < AMDGPU_NUM_SYNCS; ++i) for (i = 0; i < AMDGPU_NUM_SYNCS; ++i)
amdgpu_semaphore_free(adev, &sync->semaphores[i], fence); amdgpu_semaphore_free(adev, &sync->semaphores[i], fence);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment