From 85761f605a21ef7f3feda9d272565f97ecf1aa56 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 19 Nov 2014 14:01:20 +0100 Subject: drm/radeon: stop re-reserving the BO in radeon_vm_bo_set_addr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That's useless when all callers drop the reservation immediately after calling the function. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/radeon_gem.c') diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c194497aa586..f752c7f56015 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -601,6 +601,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, if (bo_va->it.start) { args->operation = RADEON_VA_RESULT_VA_EXIST; args->offset = bo_va->it.start * RADEON_GPU_PAGE_SIZE; + radeon_bo_unreserve(rbo); goto out; } r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags); @@ -616,7 +617,6 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, args->operation = RADEON_VA_RESULT_ERROR; } out: - radeon_bo_unreserve(rbo); drm_gem_object_unreference_unlocked(gobj); return r; } -- cgit From 2f2624c23511b4bf0dd3d4c5ae167715513f351d Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 12 Sep 2014 12:25:45 +0200 Subject: drm/radeon: update the VM after setting BO address v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way the necessary VM update is kicked off immediately if all BOs involved are in GPU accessible memory. v2: fix vm lock v3: immediately update unmaps as well v4: use drm_free_large instead of kfree Tested-by: Kai Wasserbäch Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'drivers/gpu/drm/radeon/radeon_gem.c') diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f752c7f56015..a748a64b38b9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -518,6 +518,68 @@ out: return r; } +/** + * radeon_gem_va_update_vm -update the bo_va in its VM + * + * @rdev: radeon_device pointer + * @bo_va: bo_va to update + * + * Update the bo_va directly after setting it's address. Errors are not + * vital here, so they are not reported back to userspace. + */ +static void radeon_gem_va_update_vm(struct radeon_device *rdev, + struct radeon_bo_va *bo_va) +{ + struct ttm_validate_buffer tv, *entry; + struct radeon_cs_reloc *vm_bos; + struct ww_acquire_ctx ticket; + struct list_head list; + unsigned domain; + int r; + + INIT_LIST_HEAD(&list); + + tv.bo = &bo_va->bo->tbo; + tv.shared = true; + list_add(&tv.head, &list); + + vm_bos = radeon_vm_get_bos(rdev, bo_va->vm, &list); + if (!vm_bos) + return; + + r = ttm_eu_reserve_buffers(&ticket, &list, true); + if (r) + goto error_free; + + list_for_each_entry(entry, &list, head) { + domain = radeon_mem_type_to_domain(entry->bo->mem.mem_type); + /* if anything is swapped out don't swap it in here, + just abort and wait for the next CS */ + if (domain == RADEON_GEM_DOMAIN_CPU) + goto error_unreserve; + } + + mutex_lock(&bo_va->vm->mutex); + r = radeon_vm_clear_freed(rdev, bo_va->vm); + if (r) + goto error_unlock; + + if (bo_va->it.start) + r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem); + +error_unlock: + mutex_unlock(&bo_va->vm->mutex); + +error_unreserve: + ttm_eu_backoff_reservation(&ticket, &list); + +error_free: + drm_free_large(vm_bos); + + if (r) + DRM_ERROR("Couldn't update BO_VA (%d)\n", r); +} + int radeon_gem_va_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -612,6 +674,8 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, default: break; } + if (!r) + radeon_gem_va_update_vm(rdev, bo_va); args->operation = RADEON_VA_RESULT_OK; if (r) { args->operation = RADEON_VA_RESULT_ERROR; -- cgit From 355a70183848f21198e9f6296bd646df3478a26d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 20 Nov 2014 09:56:25 +0100 Subject: drm/gem: Warn on illegal use of the dumb buffer interface v2 It happens on occasion that developers of generic user-space applications abuse the dumb buffer API to get hold of drm buffers that they can both mmap() and use for GPU acceleration, using the assumptions that dumb buffers and buffers available for GPU are a) The same type and can be aribtrarily type-casted. b) fully coherent. This patch makes the most widely used drivers warn nicely when that happens, the next step will be to fail. v2: Move drmP.h changes to drm_gem.h. Fix Radeon dumb mmap breakage. Signed-off-by: Thomas Hellstrom Acked-by: Daniel Vetter Acked-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 +++-- drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++++++++++++++++----- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_display.c | 9 +++++++++ drivers/gpu/drm/nouveau/nouveau_gem.c | 3 +++ drivers/gpu/drm/radeon/radeon_gem.c | 26 ++++++++++++++++++++++---- drivers/gpu/drm/radeon/radeon_object.c | 3 +++ include/drm/drm_gem.h | 7 +++++++ 9 files changed, 74 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/radeon/radeon_gem.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2404b2baa01e..c743908b0a7e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1593,7 +1593,7 @@ static struct drm_driver driver = { .gem_prime_import = i915_gem_prime_import, .dumb_create = i915_gem_dumb_create, - .dumb_map_offset = i915_gem_mmap_gtt, + .dumb_map_offset = i915_gem_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, .ioctls = i915_ioctls, .fops = &i915_driver_fops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f830596faa9e..4ba1aca071da 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2523,8 +2523,9 @@ void i915_vma_move_to_active(struct i915_vma *vma, int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle, uint64_t *offset); +int i915_gem_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *dev, uint32_t handle, + uint64_t *offset); /** * Returns true if seq1 is later than seq2. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3e0cabe9b544..50b842231c26 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -346,6 +346,7 @@ static int i915_gem_create(struct drm_file *file, struct drm_device *dev, uint64_t size, + bool dumb, uint32_t *handle_p) { struct drm_i915_gem_object *obj; @@ -361,6 +362,7 @@ i915_gem_create(struct drm_file *file, if (obj == NULL) return -ENOMEM; + obj->base.dumb = dumb; ret = drm_gem_handle_create(file, &obj->base, &handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(&obj->base); @@ -380,7 +382,7 @@ i915_gem_dumb_create(struct drm_file *file, args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); args->size = args->pitch * args->height; return i915_gem_create(file, dev, - args->size, &args->handle); + args->size, true, &args->handle); } /** @@ -393,7 +395,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_create *args = data; return i915_gem_create(file, dev, - args->size, &args->handle); + args->size, false, &args->handle); } static inline int @@ -1773,10 +1775,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) drm_gem_free_mmap_offset(&obj->base); } -int +static int i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, + uint32_t handle, bool dumb, uint64_t *offset) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1793,6 +1795,13 @@ i915_gem_mmap_gtt(struct drm_file *file, goto unlock; } + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach), + "Illegal dumb map of accelerated buffer.\n"); + if (obj->base.size > dev_priv->gtt.mappable_end) { ret = -E2BIG; goto out; @@ -1817,6 +1826,15 @@ unlock: return ret; } +int +i915_gem_dumb_map_offset(struct drm_file *file, + struct drm_device *dev, + uint32_t handle, + uint64_t *offset) +{ + return i915_gem_mmap_gtt(file, dev, handle, true, offset); +} + /** * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing * @dev: DRM device @@ -1838,7 +1856,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_mmap_gtt *args = data; - return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); + return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset); } static inline int diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e1ed85a6dc6d..2b02fcfae534 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -121,6 +121,9 @@ eb_lookup_vmas(struct eb_vmas *eb, goto err; } + WARN_ONCE(obj->base.dumb, + "GPU use of dumb buffer is illegal.\n"); + drm_gem_object_reference(&obj->base); list_add_tail(&obj->obj_exec_link, &objects); } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index a88e6927f571..2640fcfa5c37 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -871,6 +871,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, if (ret) return ret; + bo->gem.dumb = true; ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); drm_gem_object_unreference_unlocked(&bo->gem); return ret; @@ -886,6 +887,14 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, gem = drm_gem_object_lookup(dev, file_priv, handle); if (gem) { struct nouveau_bo *bo = nouveau_gem_object(gem); + + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(!(gem->dumb || gem->import_attach), + "Illegal dumb map of accelerated buffer.\n"); + *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); drm_gem_object_unreference_unlocked(gem); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 36951ee4b157..ebba9deb0d04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -444,6 +444,9 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; + WARN_ONCE(nvbo->gem.dumb, + "GPU use of dumb buffer is illegal.\n"); + ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, b->write_domains, b->valid_domains); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c194497aa586..429213b6ed0f 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -394,9 +394,10 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, return r; } -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) +static int radeon_mode_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, bool dumb, + uint64_t *offset_p) { struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -405,6 +406,14 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, if (gobj == NULL) { return -ENOENT; } + + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(dumb && !(gobj->dumb || gobj->import_attach), + "Illegal dumb map of GPU buffer.\n"); + robj = gem_to_radeon_bo(gobj); if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { drm_gem_object_unreference_unlocked(gobj); @@ -415,12 +424,20 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, return 0; } +int radeon_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p) +{ + return radeon_mode_mmap(filp, dev, handle, true, offset_p); +} + int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct drm_radeon_gem_mmap *args = data; - return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); + return radeon_mode_mmap(filp, dev, args->handle, false, + &args->addr_ptr); } int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, @@ -682,6 +699,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, return -ENOMEM; r = drm_gem_handle_create(file_priv, gobj, &handle); + gobj->dumb = true; /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 33e6c7a89c32..76eedd6a34f0 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -521,6 +521,9 @@ int radeon_bo_list_validate(struct radeon_device *rdev, u32 current_domain = radeon_mem_type_to_domain(bo->tbo.mem.mem_type); + WARN_ONCE(bo->gem_base.dumb, + "GPU use of dumb buffer is illegal.\n"); + /* Check if this buffer will be moved and don't move it * if we have moved too many buffers for this IB already. * diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 1e6ae1458f7a..780511a459c0 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -119,6 +119,13 @@ struct drm_gem_object { * simply leave it as NULL. */ struct dma_buf_attachment *import_attach; + + /** + * dumb - created as dumb buffer + * Whether the gem object was created using the dumb buffer interface + * as such it may not be used for GPU rendering. + */ + bool dumb; }; void drm_gem_object_release(struct drm_gem_object *obj); -- cgit From 1d0c094201bd4cae03118a1dfcb45516bb6a3ec7 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 27 Nov 2014 14:48:42 +0100 Subject: drm/radeon: rename radeon_cs_reloc to radeon_bo_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Better match what it is actually doing. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 8 ++++---- drivers/gpu/drm/radeon/r100.c | 8 ++++---- drivers/gpu/drm/radeon/r200.c | 2 +- drivers/gpu/drm/radeon/r300.c | 4 ++-- drivers/gpu/drm/radeon/r600_cs.c | 10 +++++----- drivers/gpu/drm/radeon/radeon.h | 28 ++++++++++++++-------------- drivers/gpu/drm/radeon/radeon_cs.c | 10 +++++----- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 2 +- drivers/gpu/drm/radeon/radeon_uvd.c | 2 +- drivers/gpu/drm/radeon/radeon_vce.c | 2 +- drivers/gpu/drm/radeon/radeon_vm.c | 6 +++--- 12 files changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers/gpu/drm/radeon/radeon_gem.c') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 5c8b358f9fba..a1dece6f9b9e 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -35,7 +35,7 @@ #define MIN(a,b) (((a)<(b))?(a):(b)) int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); + struct radeon_bo_list **cs_reloc); struct evergreen_cs_track { u32 group_size; u32 nbanks; @@ -1094,7 +1094,7 @@ static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p, static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 last_reg; u32 m, i, tmp, *ib; int r; @@ -1792,7 +1792,7 @@ static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) static int evergreen_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct evergreen_cs_track *track; volatile u32 *ib; unsigned idx; @@ -2685,7 +2685,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) int evergreen_dma_cs_parse(struct radeon_cs_parser *p) { struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; + struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc; u32 header, cmd, count, sub_cmd; volatile u32 *ib = p->ib.ptr; u32 idx; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index b53b31a7b76f..9314edfb687a 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1254,7 +1254,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, int r; u32 tile_flags = 0; u32 tmp; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 value; r = radeon_cs_packet_next_reloc(p, &reloc, 0); @@ -1293,7 +1293,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, int idx) { unsigned c, i; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; int r = 0; volatile uint32_t *ib; @@ -1542,7 +1542,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp; @@ -1901,7 +1901,7 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, static int r100_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; unsigned idx; volatile uint32_t *ib; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 732d4938aab7..c70e6d5bcd19 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -146,7 +146,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 1bc4704034ce..91d2442ca395 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -598,7 +598,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp, tile_flags = 0; @@ -1142,7 +1142,7 @@ fail: static int r300_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; unsigned idx; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index c47537a1ddba..b81ba1926fa8 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -969,7 +969,7 @@ static int r600_cs_parse_packet0(struct radeon_cs_parser *p, static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { struct r600_cs_track *track = (struct r600_cs_track *)p->track; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 m, i, tmp, *ib; int r; @@ -1626,7 +1626,7 @@ static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) static int r600_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r600_cs_track *track; volatile u32 *ib; unsigned idx; @@ -2354,7 +2354,7 @@ static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) if (p->chunk_relocs_idx == -1) { return 0; } - p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); + p->relocs = kzalloc(sizeof(struct radeon_bo_list), GFP_KERNEL); if (p->relocs == NULL) { return -ENOMEM; } @@ -2435,7 +2435,7 @@ void r600_cs_legacy_init(void) * GPU offset using the provided start. **/ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) + struct radeon_bo_list **cs_reloc) { struct radeon_cs_chunk *relocs_chunk; unsigned idx; @@ -2473,7 +2473,7 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, int r600_dma_cs_parse(struct radeon_cs_parser *p) { struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - struct radeon_cs_reloc *src_reloc, *dst_reloc; + struct radeon_bo_list *src_reloc, *dst_reloc; u32 header, cmd, count, tiled; volatile u32 *ib = p->ib.ptr; u32 idx, idx_value; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 17db846808ae..da1c549fc732 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -450,6 +450,15 @@ struct radeon_mman { #endif }; +struct radeon_bo_list { + struct radeon_bo *robj; + struct ttm_validate_buffer tv; + uint64_t gpu_offset; + unsigned prefered_domains; + unsigned allowed_domains; + uint32_t tiling_flags; +}; + /* bo virtual address in a specific vm */ struct radeon_bo_va { /* protected by bo being reserved */ @@ -1044,15 +1053,6 @@ void cayman_dma_fini(struct radeon_device *rdev); /* * CS. */ -struct radeon_cs_reloc { - struct radeon_bo *robj; - struct ttm_validate_buffer tv; - uint64_t gpu_offset; - unsigned prefered_domains; - unsigned allowed_domains; - uint32_t tiling_flags; -}; - struct radeon_cs_chunk { uint32_t chunk_id; uint32_t length_dw; @@ -1072,9 +1072,9 @@ struct radeon_cs_parser { unsigned idx; /* relocations */ unsigned nrelocs; - struct radeon_cs_reloc *relocs; - struct radeon_cs_reloc **relocs_ptr; - struct radeon_cs_reloc *vm_bos; + struct radeon_bo_list *relocs; + struct radeon_bo_list **relocs_ptr; + struct radeon_bo_list *vm_bos; struct list_head validated; unsigned dma_reloc_idx; /* indices of various chunks */ @@ -2973,7 +2973,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); -struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, +struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_vm *vm, struct list_head *head); struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, @@ -3087,7 +3087,7 @@ bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); void radeon_cs_dump_packet(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt); int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc, + struct radeon_bo_list **cs_reloc, int nomm); int r600_cs_common_vline_parse(struct radeon_cs_parser *p, uint32_t *vline_start_end, diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f1f584ae6c71..fb776cb2c8e9 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -92,7 +92,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->relocs_ptr == NULL) { return -ENOMEM; } - p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL); + p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL); if (p->relocs == NULL) { return -ENOMEM; } @@ -251,7 +251,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) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; int r; list_for_each_entry(reloc, &p->validated, tv.head) { @@ -397,8 +397,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) static int cmp_size_smaller_first(void *priv, struct list_head *a, struct list_head *b) { - struct radeon_cs_reloc *la = list_entry(a, struct radeon_cs_reloc, tv.head); - struct radeon_cs_reloc *lb = list_entry(b, struct radeon_cs_reloc, tv.head); + struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head); + struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head); /* Sort A before B if A is smaller. */ return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; @@ -832,7 +832,7 @@ void radeon_cs_dump_packet(struct radeon_cs_parser *p, * GPU offset using the provided start. **/ int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc, + struct radeon_bo_list **cs_reloc, int nomm) { struct radeon_cs_chunk *relocs_chunk; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 12cfaeac1205..6162bd29a598 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -548,7 +548,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, struct radeon_bo_va *bo_va) { struct ttm_validate_buffer tv, *entry; - struct radeon_cs_reloc *vm_bos; + struct radeon_bo_list *vm_bos; struct ww_acquire_ctx ticket; struct list_head list; unsigned domain; diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 87b00d902bf7..4ab07473bb28 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -502,7 +502,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, struct ww_acquire_ctx *ticket, struct list_head *head, int ring) { - struct radeon_cs_reloc *lobj; + struct radeon_bo_list *lobj; struct radeon_bo *bo; int r; u64 bytes_moved = 0, initial_bytes_moved; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 11b662469253..7c22b9369aea 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -488,7 +488,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, unsigned buf_sizes[], bool *has_msg_cmd) { struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; unsigned idx, cmd, offset; uint64_t start, end; int r; diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 9e85757d5599..8b4eea48159d 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -453,7 +453,7 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, unsigned size) { struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; uint64_t start, end, offset; unsigned idx; diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index c4ffe026d249..0423e297a42a 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -125,15 +125,15 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) * Add the page directory to the list of BOs to * validate for command submission (cayman+). */ -struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, +struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_vm *vm, struct list_head *head) { - struct radeon_cs_reloc *list; + struct radeon_bo_list *list; unsigned i, idx; list = drm_malloc_ab(vm->max_pde_used + 2, - sizeof(struct radeon_cs_reloc)); + sizeof(struct radeon_bo_list)); if (!list) return NULL; -- cgit From aa35071c590461f95d0179cc8e730d49d610f773 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 3 Dec 2014 15:46:48 +0100 Subject: drm/ttm: optionally move duplicates to a separate list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds an optional list_head parameter to ttm_eu_reserve_buffers. If specified duplicates in the execbuf list are no longer reported as errors, but moved to this list instead. Reviewed-by: Thomas Hellstrom Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/qxl/qxl_release.c | 3 ++- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 2 +- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 10 +++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++++-- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 2 +- include/drm/ttm/ttm_execbuf_util.h | 9 ++++++++- 7 files changed, 26 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/radeon/radeon_gem.c') diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 446e71ca36cb..d9b25684ac98 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -264,7 +264,8 @@ int qxl_release_reserve_list(struct qxl_release *release, bool no_intr) if (list_is_singular(&release->bos)) return 0; - ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, !no_intr); + ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, + !no_intr, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 6162bd29a598..fe48f229043e 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -564,7 +564,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, if (!vm_bos) return; - r = ttm_eu_reserve_buffers(&ticket, &list, true); + r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); if (r) goto error_free; diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 4ab07473bb28..a4a3ac824b45 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -508,7 +508,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, u64 bytes_moved = 0, initial_bytes_moved; u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev); - r = ttm_eu_reserve_buffers(ticket, head, true); + r = ttm_eu_reserve_buffers(ticket, head, true, NULL); if (unlikely(r != 0)) { return r; } diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index 8ce508e76208..3820ae97a030 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -93,7 +93,8 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation); */ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, - struct list_head *list, bool intr) + struct list_head *list, bool intr, + struct list_head *dups) { struct ttm_bo_global *glob; struct ttm_validate_buffer *entry; @@ -117,6 +118,13 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, __ttm_bo_unreserve(bo); ret = -EBUSY; + + } else if (ret == -EALREADY && dups) { + struct ttm_validate_buffer *safe = entry; + entry = list_prev_entry(entry, head); + list_del(&safe->head); + list_add(&safe->head, dups); + continue; } if (!ret) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 596cd6dafd33..33176d05db35 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2487,7 +2487,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, if (unlikely(ret != 0)) goto out_err_nores; - ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, true); + ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, + true, NULL); if (unlikely(ret != 0)) goto out_err; @@ -2677,7 +2678,8 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, query_val.shared = false; list_add_tail(&query_val.head, &validate_list); - ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); + ret = ttm_eu_reserve_buffers(&ticket, &validate_list, + false, NULL); if (unlikely(ret != 0)) { vmw_execbuf_unpin_panic(dev_priv); goto out_no_reserve; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 026de7cea0f6..210ef15b1d09 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1222,7 +1222,7 @@ vmw_resource_check_buffer(struct vmw_resource *res, val_buf->bo = ttm_bo_reference(&res->backup->base); val_buf->shared = false; list_add_tail(&val_buf->head, &val_list); - ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible); + ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible, NULL); if (unlikely(ret != 0)) goto out_no_reserve; diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index 460441714413..b620c317c772 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -68,6 +68,7 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, * non-blocking reserves should be tried. * @list: thread private list of ttm_validate_buffer structs. * @intr: should the wait be interruptible + * @dups: [out] optional list of duplicates. * * Tries to reserve bos pointed to by the list entries for validation. * If the function returns 0, all buffers are marked as "unfenced", @@ -83,6 +84,11 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, * calling process receives a signal while waiting. In that case, no * buffers on the list will be reserved upon return. * + * If dups is non NULL all buffers already reserved by the current thread + * (e.g. duplicates) are added to this list, otherwise -EALREADY is returned + * on the first already reserved buffer and all buffers from the list are + * unreserved again. + * * Buffers reserved by this function should be unreserved by * a call to either ttm_eu_backoff_reservation() or * ttm_eu_fence_buffer_objects() when command submission is complete or @@ -90,7 +96,8 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, */ extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, - struct list_head *list, bool intr); + struct list_head *list, bool intr, + struct list_head *dups); /** * function ttm_eu_fence_buffer_objects. -- cgit