Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 180639
b: refs/heads/master
c: 91cb91b
h: refs/heads/master
i:
  180637: a5e4a5b
  180635: e8232bd
  180631: ed333f5
  180623: 011a41e
  180607: 27b6b1c
v: v3
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Feb 18, 2010
1 parent 661a223 commit d2bd319
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 73 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: b58db2c6dd18d35f59862d3352c86a0a58838bf3
refs/heads/master: 91cb91becf372b5308cdd7d2e15b2e3ef66bae7e
3 changes: 0 additions & 3 deletions trunk/drivers/gpu/drm/radeon/r600_blit_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device *rdev)
void r600_vb_ib_put(struct radeon_device *rdev)
{
radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
mutex_lock(&rdev->ib_pool.mutex);
list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
mutex_unlock(&rdev->ib_pool.mutex);
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
}

Expand Down
9 changes: 5 additions & 4 deletions trunk/drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ extern int radeon_audio;
* symbol;
*/
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
/* RADEON_IB_POOL_SIZE must be a power of 2 */
#define RADEON_IB_POOL_SIZE 16
#define RADEON_DEBUGFS_MAX_NUM_FILES 32
#define RADEONFB_CONN_LIMIT 4
Expand Down Expand Up @@ -363,11 +364,12 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
*/
struct radeon_ib {
struct list_head list;
unsigned long idx;
unsigned idx;
uint64_t gpu_addr;
struct radeon_fence *fence;
uint32_t *ptr;
uint32_t *ptr;
uint32_t length_dw;
bool free;
};

/*
Expand All @@ -377,10 +379,9 @@ struct radeon_ib {
struct radeon_ib_pool {
struct mutex mutex;
struct radeon_bo *robj;
struct list_head scheduled_ibs;
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
bool ready;
DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE);
unsigned head_id;
};

struct radeon_cp {
Expand Down
105 changes: 40 additions & 65 deletions trunk/drivers/gpu/drm/radeon/radeon_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,68 +41,55 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
{
struct radeon_fence *fence;
struct radeon_ib *nib;
unsigned long i;
int r = 0;
int r = 0, i, c;

*ib = NULL;
r = radeon_fence_create(rdev, &fence);
if (r) {
DRM_ERROR("failed to create fence for new IB\n");
dev_err(rdev->dev, "failed to create fence for new IB\n");
return r;
}
mutex_lock(&rdev->ib_pool.mutex);
i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
if (i < RADEON_IB_POOL_SIZE) {
set_bit(i, rdev->ib_pool.alloc_bm);
rdev->ib_pool.ibs[i].length_dw = 0;
*ib = &rdev->ib_pool.ibs[i];
mutex_unlock(&rdev->ib_pool.mutex);
goto out;
for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
i &= (RADEON_IB_POOL_SIZE - 1);
if (rdev->ib_pool.ibs[i].free) {
nib = &rdev->ib_pool.ibs[i];
break;
}
}
if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
/* we go do nothings here */
if (nib == NULL) {
/* This should never happen, it means we allocated all
* IB and haven't scheduled one yet, return EBUSY to
* userspace hoping that on ioctl recall we get better
* luck
*/
dev_err(rdev->dev, "no free indirect buffer !\n");
mutex_unlock(&rdev->ib_pool.mutex);
DRM_ERROR("all IB allocated none scheduled.\n");
r = -EINVAL;
goto out;
radeon_fence_unref(&fence);
return -EBUSY;
}
/* get the first ib on the scheduled list */
nib = list_entry(rdev->ib_pool.scheduled_ibs.next,
struct radeon_ib, list);
if (nib->fence == NULL) {
/* we go do nothings here */
rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
nib->free = false;
if (nib->fence) {
mutex_unlock(&rdev->ib_pool.mutex);
DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
r = -EINVAL;
goto out;
}
mutex_unlock(&rdev->ib_pool.mutex);

r = radeon_fence_wait(nib->fence, false);
if (r) {
DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
(unsigned long)nib->gpu_addr, nib->length_dw);
DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n");
goto out;
r = radeon_fence_wait(nib->fence, false);
if (r) {
dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
mutex_lock(&rdev->ib_pool.mutex);
nib->free = true;
mutex_unlock(&rdev->ib_pool.mutex);
radeon_fence_unref(&fence);
return r;
}
mutex_lock(&rdev->ib_pool.mutex);
}
radeon_fence_unref(&nib->fence);

nib->fence = fence;
nib->length_dw = 0;

/* scheduled list is accessed here */
mutex_lock(&rdev->ib_pool.mutex);
list_del(&nib->list);
INIT_LIST_HEAD(&nib->list);
mutex_unlock(&rdev->ib_pool.mutex);

*ib = nib;
out:
if (r) {
radeon_fence_unref(&fence);
} else {
(*ib)->fence = fence;
}
return r;
return 0;
}

void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
Expand All @@ -114,18 +101,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
return;
}
mutex_lock(&rdev->ib_pool.mutex);
if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) {
/* IB is scheduled & not signaled don't do anythings */
mutex_unlock(&rdev->ib_pool.mutex);
return;
}
list_del(&tmp->list);
INIT_LIST_HEAD(&tmp->list);
if (tmp->fence)
radeon_fence_unref(&tmp->fence);

tmp->length_dw = 0;
clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
tmp->free = true;
mutex_unlock(&rdev->ib_pool.mutex);
}

Expand All @@ -135,7 +111,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)

if (!ib->length_dw || !rdev->cp.ready) {
/* TODO: Nothings in the ib we should report. */
DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx);
DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
return -EINVAL;
}

Expand All @@ -148,7 +124,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
radeon_ring_ib_execute(rdev, ib);
radeon_fence_emit(rdev, ib->fence);
mutex_lock(&rdev->ib_pool.mutex);
list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
/* once scheduled IB is considered free and protected by the fence */
ib->free = true;
mutex_unlock(&rdev->ib_pool.mutex);
radeon_ring_unlock_commit(rdev);
return 0;
Expand All @@ -164,7 +141,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
if (rdev->ib_pool.robj)
return 0;
/* Allocate 1M object buffer */
INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
true, RADEON_GEM_DOMAIN_GTT,
&rdev->ib_pool.robj);
Expand Down Expand Up @@ -195,9 +171,9 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
rdev->ib_pool.ibs[i].ptr = ptr + offset;
rdev->ib_pool.ibs[i].idx = i;
rdev->ib_pool.ibs[i].length_dw = 0;
INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list);
rdev->ib_pool.ibs[i].free = true;
}
bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
rdev->ib_pool.head_id = 0;
rdev->ib_pool.ready = true;
DRM_INFO("radeon: ib pool ready.\n");
if (radeon_debugfs_ib_init(rdev)) {
Expand All @@ -214,7 +190,6 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
return;
}
mutex_lock(&rdev->ib_pool.mutex);
bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
if (rdev->ib_pool.robj) {
r = radeon_bo_reserve(rdev->ib_pool.robj, false);
if (likely(r == 0)) {
Expand Down Expand Up @@ -363,7 +338,7 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data)
if (ib == NULL) {
return 0;
}
seq_printf(m, "IB %04lu\n", ib->idx);
seq_printf(m, "IB %04u\n", ib->idx);
seq_printf(m, "IB fence %p\n", ib->fence);
seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
for (i = 0; i < ib->length_dw; i++) {
Expand Down

0 comments on commit d2bd319

Please sign in to comment.