Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 307218
b: refs/heads/master
c: 8f676c4
h: refs/heads/master
v: v3
  • Loading branch information
Christian König authored and Dave Airlie committed May 3, 2012
1 parent d7b0095 commit 45abf6a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bfb9a07785fea0c41dff1a38890bc9b4679a9430
refs/heads/master: 8f676c4c6f0f500616560f13c0276ab6b4e39a6a
4 changes: 4 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,10 @@ void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
int radeon_semaphore_sync_rings(struct radeon_device *rdev,
struct radeon_semaphore *semaphore,
bool sync_to[RADEON_NUM_RINGS],
int dst_ring);
void radeon_semaphore_free(struct radeon_device *rdev,
struct radeon_semaphore *semaphore);

Expand Down
35 changes: 12 additions & 23 deletions trunk/drivers/gpu/drm/radeon/radeon_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
{
bool sync_to_ring[RADEON_NUM_RINGS] = { };
bool need_sync = false;
int i, r;

for (i = 0; i < p->nrelocs; i++) {
Expand All @@ -126,36 +127,24 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p)

if (!(p->relocs[i].flags & RADEON_RELOC_DONT_SYNC)) {
struct radeon_fence *fence = p->relocs[i].robj->tbo.sync_obj;
if (!radeon_fence_signaled(fence)) {
if (fence->ring != p->ring && !radeon_fence_signaled(fence)) {
sync_to_ring[fence->ring] = true;
need_sync = true;
}
}
}

for (i = 0; i < RADEON_NUM_RINGS; ++i) {
/* no need to sync to our own or unused rings */
if (i == p->ring || !sync_to_ring[i] || !p->rdev->ring[i].ready)
continue;

if (!p->ib->fence->semaphore) {
r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore);
if (r)
return r;
}

r = radeon_ring_lock(p->rdev, &p->rdev->ring[i], 3);
if (r)
return r;
radeon_semaphore_emit_signal(p->rdev, i, p->ib->fence->semaphore);
radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[i]);
if (!need_sync) {
return 0;
}

r = radeon_ring_lock(p->rdev, &p->rdev->ring[p->ring], 3);
if (r)
return r;
radeon_semaphore_emit_wait(p->rdev, p->ring, p->ib->fence->semaphore);
radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[p->ring]);
r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore);
if (r) {
return r;
}
return 0;

return radeon_semaphore_sync_rings(p->rdev, p->ib->fence->semaphore,
sync_to_ring, p->ring);
}

int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
Expand Down
56 changes: 56 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_semaphore.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,62 @@ void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true);
}

int radeon_semaphore_sync_rings(struct radeon_device *rdev,
struct radeon_semaphore *semaphore,
bool sync_to[RADEON_NUM_RINGS],
int dst_ring)
{
int i, r;

for (i = 0; i < RADEON_NUM_RINGS; ++i) {
unsigned num_ops = i == dst_ring ? RADEON_NUM_RINGS : 1;

/* don't lock unused rings */
if (!sync_to[i] && i != dst_ring)
continue;

/* prevent GPU deadlocks */
if (!rdev->ring[i].ready) {
dev_err(rdev->dev, "Trying to sync to a disabled ring!");
r = -EINVAL;
goto error;
}

r = radeon_ring_lock(rdev, &rdev->ring[i], num_ops * 8);
if (r)
goto error;
}

for (i = 0; i < RADEON_NUM_RINGS; ++i) {
/* no need to sync to our own or unused rings */
if (!sync_to[i] || i == dst_ring)
continue;

radeon_semaphore_emit_signal(rdev, i, semaphore);
radeon_semaphore_emit_wait(rdev, dst_ring, semaphore);
}

for (i = 0; i < RADEON_NUM_RINGS; ++i) {

/* don't unlock unused rings */
if (!sync_to[i] && i != dst_ring)
continue;

radeon_ring_unlock_commit(rdev, &rdev->ring[i]);
}

return 0;

error:
/* unlock all locks taken so far */
for (--i; i >= 0; --i) {
if (sync_to[i] || i == dst_ring) {
radeon_ring_unlock_undo(rdev, &rdev->ring[i]);
}
}
return r;
}

void radeon_semaphore_free(struct radeon_device *rdev,
struct radeon_semaphore *semaphore)
{
Expand Down
48 changes: 21 additions & 27 deletions trunk/drivers/gpu/drm/radeon/radeon_ttm.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
{
struct radeon_device *rdev;
uint64_t old_start, new_start;
struct radeon_fence *fence;
int r, i;
struct radeon_fence *fence, *old_fence;
int r;

rdev = radeon_get_rdev(bo->bdev);
r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev));
Expand All @@ -242,6 +242,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
break;
default:
DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
radeon_fence_unref(&fence);
return -EINVAL;
}
switch (new_mem->mem_type) {
Expand All @@ -253,42 +254,35 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
break;
default:
DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
radeon_fence_unref(&fence);
return -EINVAL;
}
if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) {
DRM_ERROR("Trying to move memory with ring turned off.\n");
radeon_fence_unref(&fence);
return -EINVAL;
}

BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);

/* sync other rings */
if (rdev->family >= CHIP_R600) {
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
/* no need to sync to our own or unused rings */
if (i == radeon_copy_ring_index(rdev) || !rdev->ring[i].ready)
continue;

if (!fence->semaphore) {
r = radeon_semaphore_create(rdev, &fence->semaphore);
/* FIXME: handle semaphore error */
if (r)
continue;
}
old_fence = bo->sync_obj;
if (old_fence && old_fence->ring != fence->ring
&& !radeon_fence_signaled(old_fence)) {
bool sync_to_ring[RADEON_NUM_RINGS] = { };
sync_to_ring[old_fence->ring] = true;

r = radeon_semaphore_create(rdev, &fence->semaphore);
if (r) {
radeon_fence_unref(&fence);
return r;
}

r = radeon_ring_lock(rdev, &rdev->ring[i], 3);
/* FIXME: handle ring lock error */
if (r)
continue;
radeon_semaphore_emit_signal(rdev, i, fence->semaphore);
radeon_ring_unlock_commit(rdev, &rdev->ring[i]);

r = radeon_ring_lock(rdev, &rdev->ring[radeon_copy_ring_index(rdev)], 3);
/* FIXME: handle ring lock error */
if (r)
continue;
radeon_semaphore_emit_wait(rdev, radeon_copy_ring_index(rdev), fence->semaphore);
radeon_ring_unlock_commit(rdev, &rdev->ring[radeon_copy_ring_index(rdev)]);
r = radeon_semaphore_sync_rings(rdev, fence->semaphore,
sync_to_ring, fence->ring);
if (r) {
radeon_fence_unref(&fence);
return r;
}
}

Expand Down

0 comments on commit 45abf6a

Please sign in to comment.