Re: [PATCH] radeon: preallocate memory for command stream parsing
From: Pekka Enberg
Date: Tue Jun 23 2009 - 15:52:44 EST
Hi Jerome,
On Tue, Jun 23, 2009 at 10:46 PM, Jerome Glisse<jglisse@xxxxxxxxxx> wrote:
> Command stream parsing is the most common operation and can
> happen hundred of times per second, we don't want to allocate/free
> memory each time this ioctl is call. This rework the ioctl
> to avoid doing so by allocating temporary memory along the
> ib pool.
>
> Signed-off-by: Jerome Glisse <jglisse@xxxxxxxxxx>
So how much does this help (i.e. where are the numbers)? I am bit
surprised "hundred of times per second" is an issue for our slab
allocators. Hmm?
> ---
> drivers/gpu/drm/radeon/r100.c | 27 +++---
> drivers/gpu/drm/radeon/r300.c | 6 +-
> drivers/gpu/drm/radeon/radeon.h | 110 ++++++++++----------
> drivers/gpu/drm/radeon/radeon_cs.c | 186 +++++++++++++++-------------------
> drivers/gpu/drm/radeon/radeon_ring.c | 23 ++++
> 5 files changed, 177 insertions(+), 175 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index c550932..56ef9f7 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -699,7 +699,7 @@ void r100_cs_dump_packet(struct radeon_cs_parser *p,
> unsigned idx;
>
> ib = p->ib->ptr;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> idx = pkt->idx;
> for (i = 0; i <= (pkt->count + 1); i++, idx++) {
> DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]);
> @@ -718,14 +718,15 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
> struct radeon_cs_packet *pkt,
> unsigned idx)
> {
> - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
> - uint32_t header = ib_chunk->kdata[idx];
> + struct radeon_cs_chunk *ib_chunk = &p->ibc;
> + uint32_t header;
>
> if (idx >= ib_chunk->length_dw) {
> DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
> idx, ib_chunk->length_dw);
> return -EINVAL;
> }
> + header = ib_chunk->kdata[idx];
> pkt->idx = idx;
> pkt->type = CP_PACKET_GET_TYPE(header);
> pkt->count = CP_PACKET_GET_COUNT(header);
> @@ -767,18 +768,16 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
> struct radeon_cs_reloc **cs_reloc)
> {
> struct radeon_cs_chunk *ib_chunk;
> - struct radeon_cs_chunk *relocs_chunk;
> struct radeon_cs_packet p3reloc;
> unsigned idx;
> int r;
>
> - if (p->chunk_relocs_idx == -1) {
> + if (p->relocs == NULL) {
> DRM_ERROR("No relocation chunk !\n");
> return -EINVAL;
> }
> *cs_reloc = NULL;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> - relocs_chunk = &p->chunks[p->chunk_relocs_idx];
> + ib_chunk = &p->ibc;
> r = r100_cs_packet_parse(p, &p3reloc, p->idx);
> if (r) {
> return r;
> @@ -791,14 +790,14 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
> return -EINVAL;
> }
> idx = ib_chunk->kdata[p3reloc.idx + 1];
> - if (idx >= relocs_chunk->length_dw) {
> + if ((idx / 4) >= p->nrelocs) {
> DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
> - idx, relocs_chunk->length_dw);
> + idx, p->nrelocs * 4);
> r100_cs_dump_packet(p, &p3reloc);
> return -EINVAL;
> }
> /* FIXME: we assume reloc size is 4 dwords */
> - *cs_reloc = p->relocs_ptr[(idx / 4)];
> + *cs_reloc = p->relocs_ptr[idx / 4];
> return 0;
> }
>
> @@ -816,7 +815,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
> int r;
>
> ib = p->ib->ptr;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> idx = pkt->idx + 1;
> reg = pkt->reg;
> onereg = false;
> @@ -897,7 +896,7 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
> struct radeon_cs_chunk *ib_chunk;
> unsigned idx;
>
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> idx = pkt->idx + 1;
> if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) {
> DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
> @@ -920,7 +919,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
> int r;
>
> ib = p->ib->ptr;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> idx = pkt->idx + 1;
> switch (pkt->opcode) {
> case PACKET3_3D_LOAD_VBPNTR:
> @@ -1027,7 +1026,7 @@ int r100_cs_parse(struct radeon_cs_parser *p)
> if (r) {
> return r;
> }
> - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
> + } while (p->idx < p->ibc.length_dw);
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
> index e2ed5bc..2b2199e 100644
> --- a/drivers/gpu/drm/radeon/r300.c
> +++ b/drivers/gpu/drm/radeon/r300.c
> @@ -1024,7 +1024,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
> int r;
>
> ib = p->ib->ptr;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> track = (struct r300_cs_track*)p->track;
> switch(reg) {
> case RADEON_DST_PITCH_OFFSET:
> @@ -1361,7 +1361,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
> int r;
>
> ib = p->ib->ptr;
> - ib_chunk = &p->chunks[p->chunk_ib_idx];
> + ib_chunk = &p->ibc;
> idx = pkt->idx + 1;
> track = (struct r300_cs_track*)p->track;
> switch(pkt->opcode) {
> @@ -1520,7 +1520,7 @@ int r300_cs_parse(struct radeon_cs_parser *p)
> if (r) {
> return r;
> }
> - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
> + } while (p->idx < p->ibc.length_dw);
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index d61f2fc..1bea78a 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -352,6 +352,56 @@ void radeon_irq_kms_fini(struct radeon_device *rdev);
>
>
> /*
> + * CS.
> + */
> +struct radeon_ib;
> +
> +struct radeon_cs_reloc {
> + struct drm_gem_object *gobj;
> + struct radeon_object *robj;
> + struct radeon_object_list lobj;
> + uint32_t handle;
> + uint32_t flags;
> +};
> +
> +struct radeon_cs_chunk {
> + uint32_t chunk_id;
> + uint32_t length_dw;
> + uint32_t *kdata;
> +};
> +
> +struct radeon_cs_parser {
> + struct radeon_device *rdev;
> + struct drm_file *filp;
> + struct radeon_cs_chunk ibc;
> + /* IB */
> + unsigned idx;
> + /* relocations */
> + unsigned nrelocs;
> + struct radeon_cs_reloc *relocs;
> + struct radeon_cs_reloc **relocs_ptr;
> + struct list_head validated;
> + struct radeon_ib *ib;
> + void *track;
> +};
> +
> +struct radeon_cs_packet {
> + unsigned idx;
> + unsigned type;
> + unsigned reg;
> + unsigned opcode;
> + int count;
> + unsigned one_reg_wr;
> +};
> +
> +typedef int (*radeon_packet0_check_t)(struct radeon_cs_parser *p,
> + struct radeon_cs_packet *pkt,
> + unsigned idx, unsigned reg);
> +typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
> + struct radeon_cs_packet *pkt);
> +
> +
> +/*
> * CP & ring.
> */
> struct radeon_ib {
> @@ -360,12 +410,18 @@ struct radeon_ib {
> uint64_t gpu_addr;
> struct radeon_fence *fence;
> volatile uint32_t *ptr;
> + uint32_t *ib;
> + struct radeon_cs_reloc *relocs;
> + struct radeon_cs_reloc **relocs_ptr;
> uint32_t length_dw;
> };
>
> struct radeon_ib_pool {
> struct mutex mutex;
> struct radeon_object *robj;
> + uint32_t *ib;
> + struct radeon_cs_reloc *relocs;
> + struct radeon_cs_reloc **relocs_ptr;
> struct list_head scheduled_ibs;
> struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
> bool ready;
> @@ -405,60 +461,6 @@ void radeon_ring_fini(struct radeon_device *rdev);
>
>
> /*
> - * CS.
> - */
> -struct radeon_cs_reloc {
> - struct drm_gem_object *gobj;
> - struct radeon_object *robj;
> - struct radeon_object_list lobj;
> - uint32_t handle;
> - uint32_t flags;
> -};
> -
> -struct radeon_cs_chunk {
> - uint32_t chunk_id;
> - uint32_t length_dw;
> - uint32_t *kdata;
> -};
> -
> -struct radeon_cs_parser {
> - struct radeon_device *rdev;
> - struct drm_file *filp;
> - /* chunks */
> - unsigned nchunks;
> - struct radeon_cs_chunk *chunks;
> - uint64_t *chunks_array;
> - /* IB */
> - unsigned idx;
> - /* relocations */
> - unsigned nrelocs;
> - struct radeon_cs_reloc *relocs;
> - struct radeon_cs_reloc **relocs_ptr;
> - struct list_head validated;
> - /* indices of various chunks */
> - int chunk_ib_idx;
> - int chunk_relocs_idx;
> - struct radeon_ib *ib;
> - void *track;
> -};
> -
> -struct radeon_cs_packet {
> - unsigned idx;
> - unsigned type;
> - unsigned reg;
> - unsigned opcode;
> - int count;
> - unsigned one_reg_wr;
> -};
> -
> -typedef int (*radeon_packet0_check_t)(struct radeon_cs_parser *p,
> - struct radeon_cs_packet *pkt,
> - unsigned idx, unsigned reg);
> -typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
> - struct radeon_cs_packet *pkt);
> -
> -
> -/*
> * AGP
> */
> int radeon_agp_init(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
> index b843f9b..8fb08fa 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -29,61 +29,52 @@
> #include "radeon_reg.h"
> #include "radeon.h"
>
> -void r100_cs_dump_packet(struct radeon_cs_parser *p,
> - struct radeon_cs_packet *pkt);
> -
> -int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
> +static int radeon_cs_parser_reloc(struct radeon_cs_parser *p,
> + struct drm_radeon_cs_chunk *chunk)
> {
> - struct drm_device *ddev = p->rdev->ddev;
> - struct radeon_cs_chunk *chunk;
> - unsigned i, j;
> + struct drm_radeon_cs_reloc __user *reloc_ptr;
> + struct drm_radeon_cs_reloc reloc;
> + unsigned i, j, c;
> bool duplicate;
>
> - if (p->chunk_relocs_idx == -1) {
> - return 0;
> - }
> - chunk = &p->chunks[p->chunk_relocs_idx];
> - /* FIXME: we assume that each relocs use 4 dwords */
> p->nrelocs = chunk->length_dw / 4;
> - p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL);
> - if (p->relocs_ptr == NULL) {
> - return -ENOMEM;
> - }
> - p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
> - if (p->relocs == NULL) {
> - return -ENOMEM;
> + if (p->nrelocs > 1024) {
> + DRM_ERROR("Too many relocations %d\n", p->nrelocs);
> + return -EINVAL;
> }
> - for (i = 0; i < p->nrelocs; i++) {
> - struct drm_radeon_cs_reloc *r;
> -
> + for (i = 0, c = 0; i < p->nrelocs; i++) {
> + reloc_ptr = (void __user*)(unsigned long)(chunk->chunk_data + i * 16);
> + if (DRM_COPY_FROM_USER(&reloc, reloc_ptr, 16)) {
> + return -EFAULT;
> + }
> duplicate = false;
> - r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4];
> - for (j = 0; j < p->nrelocs; j++) {
> - if (r->handle == p->relocs[j].handle) {
> + for (j = 0; j < c; j++) {
> + if (reloc.handle == p->relocs[j].handle) {
> p->relocs_ptr[i] = &p->relocs[j];
> duplicate = true;
> break;
> }
> }
> if (!duplicate) {
> - p->relocs[i].gobj = drm_gem_object_lookup(ddev,
> + p->relocs[i].gobj = drm_gem_object_lookup(p->rdev->ddev,
> p->filp,
> - r->handle);
> + reloc.handle);
> if (p->relocs[i].gobj == NULL) {
> DRM_ERROR("gem object lookup failed 0x%x\n",
> - r->handle);
> + reloc.handle);
> return -EINVAL;
> }
> p->relocs_ptr[i] = &p->relocs[i];
> p->relocs[i].robj = p->relocs[i].gobj->driver_private;
> p->relocs[i].lobj.robj = p->relocs[i].robj;
> - p->relocs[i].lobj.rdomain = r->read_domains;
> - p->relocs[i].lobj.wdomain = r->write_domain;
> - p->relocs[i].handle = r->handle;
> - p->relocs[i].flags = r->flags;
> + p->relocs[i].lobj.rdomain = reloc.read_domains;
> + p->relocs[i].lobj.wdomain = reloc.write_domain;
> + p->relocs[i].handle = reloc.handle;
> + p->relocs[i].flags = reloc.flags;
> INIT_LIST_HEAD(&p->relocs[i].lobj.list);
> radeon_object_list_add_object(&p->relocs[i].lobj,
> &p->validated);
> + c++;
> }
> }
> return radeon_object_list_validate(&p->validated, p->ib->fence);
> @@ -92,65 +83,53 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
> int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
> {
> struct drm_radeon_cs *cs = data;
> - uint64_t *chunk_array_ptr;
> - unsigned size, i;
> + unsigned i;
> + int r;
> + bool found_ib = false;
>
> - if (!cs->num_chunks) {
> - return 0;
> - }
> - /* get chunks */
> - INIT_LIST_HEAD(&p->validated);
> - p->idx = 0;
> - p->chunk_ib_idx = -1;
> - p->chunk_relocs_idx = -1;
> - p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL);
> - if (p->chunks_array == NULL) {
> - return -ENOMEM;
> - }
> - chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
> - if (DRM_COPY_FROM_USER(p->chunks_array, chunk_array_ptr,
> - sizeof(uint64_t)*cs->num_chunks)) {
> - return -EFAULT;
> - }
> - p->nchunks = cs->num_chunks;
> - p->chunks = kcalloc(p->nchunks, sizeof(struct radeon_cs_chunk), GFP_KERNEL);
> - if (p->chunks == NULL) {
> - return -ENOMEM;
> - }
> - for (i = 0; i < p->nchunks; i++) {
> - struct drm_radeon_cs_chunk __user **chunk_ptr = NULL;
> - struct drm_radeon_cs_chunk user_chunk;
> + for (i = 0; i < cs->num_chunks; i++) {
> + struct drm_radeon_cs_chunk __user *chunk_ptr = NULL;
> + struct drm_radeon_cs_chunk chunk;
> uint32_t __user *cdata;
> + unsigned tmp;
> + u64 ptr;
>
> - chunk_ptr = (void __user*)(unsigned long)p->chunks_array[i];
> - if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr,
> - sizeof(struct drm_radeon_cs_chunk))) {
> + chunk_ptr = (void __user*)(unsigned long)(cs->chunks + i * 8);
> + if (DRM_COPY_FROM_USER(&ptr, chunk_ptr, sizeof(u64))) {
> return -EFAULT;
> }
> - p->chunks[i].chunk_id = user_chunk.chunk_id;
> - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) {
> - p->chunk_relocs_idx = i;
> - }
> - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) {
> - p->chunk_ib_idx = i;
> - }
> - p->chunks[i].length_dw = user_chunk.length_dw;
> - cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
> -
> - p->chunks[i].kdata = NULL;
> - size = p->chunks[i].length_dw * sizeof(uint32_t);
> - p->chunks[i].kdata = kzalloc(size, GFP_KERNEL);
> - if (p->chunks[i].kdata == NULL) {
> - return -ENOMEM;
> - }
> - if (DRM_COPY_FROM_USER(p->chunks[i].kdata, cdata, size)) {
> + chunk_ptr = (void __user*)(unsigned long)ptr;
> + if (DRM_COPY_FROM_USER(&chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))) {
> return -EFAULT;
> }
> - }
> - if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) {
> - DRM_ERROR("cs IB too big: %d\n",
> - p->chunks[p->chunk_ib_idx].length_dw);
> - return -EINVAL;
> + switch (chunk.chunk_id) {
> + case RADEON_CHUNK_ID_RELOCS:
> + r = radeon_cs_parser_reloc(p, &chunk);
> + if (r) {
> + return r;
> + }
> + break;
> + case RADEON_CHUNK_ID_IB:
> + if (found_ib) {
> + DRM_ERROR("Multiple IB chunks not supported\n");
> + return -EINVAL;
> + }
> + found_ib = true;
> + if (chunk.length_dw > 16 * 1024) {
> + DRM_ERROR("cs IB too big: %d\n", chunk.length_dw);
> + return -EINVAL;
> + }
> + p->ibc.chunk_id = chunk.chunk_id;
> + p->ibc.length_dw = chunk.length_dw;
> + tmp = p->ibc.length_dw * sizeof(u32);
> + cdata = (uint32_t *)(unsigned long)chunk.chunk_data;
> + if (DRM_COPY_FROM_USER(p->ibc.kdata, cdata, tmp)) {
> + return -EFAULT;
> + }
> + break;
> + default:
> + break;
> + }
> }
> return 0;
> }
> @@ -179,13 +158,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
> mutex_unlock(&parser->rdev->ddev->struct_mutex);
> }
> }
> - kfree(parser->relocs);
> - kfree(parser->relocs_ptr);
> - for (i = 0; i < parser->nchunks; i++) {
> - kfree(parser->chunks[i].kdata);
> - }
> - kfree(parser->chunks);
> - kfree(parser->chunks_array);
> radeon_ib_free(parser->rdev, &parser->ib);
> }
>
> @@ -193,7 +165,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
> {
> struct radeon_device *rdev = dev->dev_private;
> struct radeon_cs_parser parser;
> - struct radeon_cs_chunk *ib_chunk;
> int r;
>
> mutex_lock(&rdev->cs_mutex);
> @@ -202,36 +173,43 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
> return -EINVAL;
> }
> /* initialize parser */
> - memset(&parser, 0, sizeof(struct radeon_cs_parser));
> + INIT_LIST_HEAD(&parser.validated);
> + parser.idx = 0;
> + parser.ibc.kdata = NULL;
> + parser.ibc.length_dw = 0;
> + parser.relocs = NULL;
> + parser.relocs_ptr = NULL;
> + parser.ib = NULL;
> parser.filp = filp;
> parser.rdev = rdev;
> - r = radeon_cs_parser_init(&parser, data);
> + r = radeon_ib_get(rdev, &parser.ib);
> if (r) {
> - DRM_ERROR("Failed to initialize parser !\n");
> + DRM_ERROR("Failed to get ib !\n");
> radeon_cs_parser_fini(&parser, r);
> mutex_unlock(&rdev->cs_mutex);
> return r;
> }
> - r = radeon_ib_get(rdev, &parser.ib);
> + parser.ibc.kdata = parser.ib->ib;
> + parser.relocs = parser.ib->relocs;
> + parser.relocs_ptr = parser.ib->relocs_ptr;
> + r = radeon_cs_parser_init(&parser, data);
> if (r) {
> - DRM_ERROR("Failed to get ib !\n");
> + DRM_ERROR("Failed to initialize parser !\n");
> radeon_cs_parser_fini(&parser, r);
> mutex_unlock(&rdev->cs_mutex);
> return r;
> }
> - r = radeon_cs_parser_relocs(&parser);
> - if (r) {
> - DRM_ERROR("Failed to parse relocation !\n");
> + if (parser.ibc.kdata == NULL) {
> + DRM_INFO("No IB chunk in cs, nothing to do\n");
> radeon_cs_parser_fini(&parser, r);
> mutex_unlock(&rdev->cs_mutex);
> - return r;
> + return 0;
> }
> /* Copy the packet into the IB, the parser will read from the
> * input memory (cached) and write to the IB (which can be
> * uncached). */
> - ib_chunk = &parser.chunks[parser.chunk_ib_idx];
> - parser.ib->length_dw = ib_chunk->length_dw;
> - memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4);
> + parser.ib->length_dw = parser.ibc.length_dw;
> + memcpy((void *)parser.ib->ptr, parser.ibc.kdata, parser.ibc.length_dw * 4);
> r = radeon_cs_parse(&parser);
> if (r) {
> DRM_ERROR("Invalid command stream !\n");
> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
> index a853261..0026a11 100644
> --- a/drivers/gpu/drm/radeon/radeon_ring.c
> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
> @@ -177,6 +177,20 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
>
> /* Allocate 1M object buffer */
> INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
> + rdev->ib_pool.ib = drm_calloc_large(RADEON_IB_POOL_SIZE, 64 * 1024);
> + if (rdev->ib_pool.ib == NULL) {
> + return -ENOMEM;
> + }
> + rdev->ib_pool.relocs = drm_calloc_large(RADEON_IB_POOL_SIZE * 1024,
> + sizeof(struct radeon_cs_reloc));
> + if (rdev->ib_pool.relocs == NULL) {
> + return -ENOMEM;
> + }
> + rdev->ib_pool.relocs_ptr = drm_calloc_large(RADEON_IB_POOL_SIZE * 1024,
> + sizeof(void *));
> + if (rdev->ib_pool.relocs == NULL) {
> + return -ENOMEM;
> + }
> r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
> true, RADEON_GEM_DOMAIN_GTT,
> false, &rdev->ib_pool.robj);
> @@ -202,6 +216,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;
> + rdev->ib_pool.ibs[i].ib = &rdev->ib_pool.ib[i * 16 * 1024];
> + rdev->ib_pool.ibs[i].relocs = &rdev->ib_pool.relocs[i * 1024];
> + rdev->ib_pool.ibs[i].relocs_ptr = &rdev->ib_pool.relocs_ptr[i * 1024];
> INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list);
> }
> bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
> @@ -225,6 +242,12 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
> radeon_object_unref(&rdev->ib_pool.robj);
> rdev->ib_pool.robj = NULL;
> }
> + if (rdev->ib_pool.ib)
> + drm_free_large(rdev->ib_pool.ib);
> + if (rdev->ib_pool.relocs)
> + drm_free_large(rdev->ib_pool.relocs);
> + if (rdev->ib_pool.relocs_ptr)
> + drm_free_large(rdev->ib_pool.relocs_ptr);
> mutex_unlock(&rdev->ib_pool.mutex);
> }
>
> --
> 1.6.2.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/