Commit e2b3f7c8 authored by Christian König's avatar Christian König
Browse files

drm/radeon: switch over to drm_exec v2



Just a straightforward conversion without any optimization.

Smoke tested on actual hardware.

v2: rebase

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241114153020.6209-2-christian.koenig@amd.com
parent c2adb84d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ config DRM_RADEON
        select DRM_TTM
	select DRM_TTM_HELPER
	select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
	select DRM_EXEC
	select SND_HDA_COMPONENT if SND_HDA_CORE
	select POWER_SUPPLY
	select HWMON
+4 −3
Original line number Diff line number Diff line
@@ -75,8 +75,8 @@

#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_execbuf_util.h>

#include <drm/drm_exec.h>
#include <drm/drm_gem.h>
#include <drm/drm_audio_component.h>
#include <drm/drm_suballoc.h>
@@ -457,7 +457,8 @@ struct radeon_mman {

struct radeon_bo_list {
	struct radeon_bo		*robj;
	struct ttm_validate_buffer	tv;
	struct list_head		list;
	bool				shared;
	uint64_t			gpu_offset;
	unsigned			preferred_domains;
	unsigned			allowed_domains;
@@ -1030,6 +1031,7 @@ struct radeon_cs_parser {
	struct radeon_bo_list	*vm_bos;
	struct list_head	validated;
	unsigned		dma_reloc_idx;
	struct drm_exec		exec;
	/* indices of various chunks */
	struct radeon_cs_chunk  *chunk_ib;
	struct radeon_cs_chunk  *chunk_relocs;
@@ -1043,7 +1045,6 @@ struct radeon_cs_parser {
	u32			cs_flags;
	u32			ring;
	s32			priority;
	struct ww_acquire_ctx	ticket;
};

static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
+23 −22
Original line number Diff line number Diff line
@@ -182,11 +182,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
			}
		}

		p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
		p->relocs[i].tv.num_shared = !r->write_domain;

		radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head,
				      priority);
		p->relocs[i].shared = !r->write_domain;
		radeon_cs_buckets_add(&buckets, &p->relocs[i].list, priority);
	}

	radeon_cs_buckets_get_list(&buckets, &p->validated);
@@ -197,7 +194,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
	if (need_mmap_lock)
		mmap_read_lock(current->mm);

	r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
	r = radeon_bo_list_validate(p->rdev, &p->exec, &p->validated, p->ring);

	if (need_mmap_lock)
		mmap_read_unlock(current->mm);
@@ -253,12 +250,11 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
	struct radeon_bo_list *reloc;
	int r;

	list_for_each_entry(reloc, &p->validated, tv.head) {
	list_for_each_entry(reloc, &p->validated, list) {
		struct dma_resv *resv;

		resv = reloc->robj->tbo.base.resv;
		r = radeon_sync_resv(p->rdev, &p->ib.sync, resv,
				     reloc->tv.num_shared);
		r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, reloc->shared);
		if (r)
			return r;
	}
@@ -276,6 +272,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
	s32 priority = 0;

	INIT_LIST_HEAD(&p->validated);
	drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);

	if (!cs->num_chunks) {
		return 0;
@@ -397,8 +394,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
static int cmp_size_smaller_first(void *priv, const struct list_head *a,
				  const struct list_head *b)
{
	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);
	struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, list);
	struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, list);

	/* Sort A before B if A is smaller. */
	if (la->robj->tbo.base.size > lb->robj->tbo.base.size)
@@ -417,11 +414,13 @@ static int cmp_size_smaller_first(void *priv, const struct list_head *a,
 * If error is set than unvalidate buffer, otherwise just free memory
 * used by parsing context.
 **/
static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bool backoff)
static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
{
	unsigned i;

	if (!error) {
		struct radeon_bo_list *reloc;

		/* Sort the buffer list from the smallest to largest buffer,
		 * which affects the order of buffers in the LRU list.
		 * This assures that the smallest buffers are added first
@@ -433,15 +432,17 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
		 * per frame under memory pressure.
		 */
		list_sort(NULL, &parser->validated, cmp_size_smaller_first);

		ttm_eu_fence_buffer_objects(&parser->ticket,
					    &parser->validated,
					    &parser->ib.fence->base);
	} else if (backoff) {
		ttm_eu_backoff_reservation(&parser->ticket,
					   &parser->validated);
		list_for_each_entry(reloc, &parser->validated, list) {
			dma_resv_add_fence(reloc->robj->tbo.base.resv,
					   &parser->ib.fence->base,
					   reloc->shared ?
					   DMA_RESV_USAGE_READ :
					   DMA_RESV_USAGE_WRITE);
		}
	}

	drm_exec_fini(&parser->exec);

	if (parser->relocs != NULL) {
		for (i = 0; i < parser->nrelocs; i++) {
			struct radeon_bo *bo = parser->relocs[i].robj;
@@ -693,7 +694,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
	r = radeon_cs_parser_init(&parser, data);
	if (r) {
		DRM_ERROR("Failed to initialize parser !\n");
		radeon_cs_parser_fini(&parser, r, false);
		radeon_cs_parser_fini(&parser, r);
		up_read(&rdev->exclusive_lock);
		r = radeon_cs_handle_lockup(rdev, r);
		return r;
@@ -707,7 +708,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
	}

	if (r) {
		radeon_cs_parser_fini(&parser, r, false);
		radeon_cs_parser_fini(&parser, r);
		up_read(&rdev->exclusive_lock);
		r = radeon_cs_handle_lockup(rdev, r);
		return r;
@@ -724,7 +725,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
		goto out;
	}
out:
	radeon_cs_parser_fini(&parser, r, true);
	radeon_cs_parser_fini(&parser, r);
	up_read(&rdev->exclusive_lock);
	r = radeon_cs_handle_lockup(rdev, r);
	return r;
+22 −17
Original line number Diff line number Diff line
@@ -605,33 +605,40 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
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_bo_list *vm_bos;
	struct ww_acquire_ctx ticket;
	struct radeon_bo_list *vm_bos, *entry;
	struct list_head list;
	struct drm_exec exec;
	unsigned domain;
	int r;

	INIT_LIST_HEAD(&list);

	tv.bo = &bo_va->bo->tbo;
	tv.num_shared = 1;
	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, NULL);
	if (r)
		goto error_free;
	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
	drm_exec_until_all_locked(&exec) {
		list_for_each_entry(entry, &list, list) {
			r = drm_exec_prepare_obj(&exec, &entry->robj->tbo.base,
						 1);
			drm_exec_retry_on_contention(&exec);
			if (unlikely(r))
				goto error_cleanup;
		}

	list_for_each_entry(entry, &list, head) {
		domain = radeon_mem_type_to_domain(entry->bo->resource->mem_type);
		r = drm_exec_prepare_obj(&exec, &bo_va->bo->tbo.base, 1);
		drm_exec_retry_on_contention(&exec);
		if (unlikely(r))
			goto error_cleanup;
	}

	list_for_each_entry(entry, &list, list) {
		domain = radeon_mem_type_to_domain(entry->robj->tbo.resource->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;
			goto error_cleanup;
	}

	mutex_lock(&bo_va->vm->mutex);
@@ -645,10 +652,8 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
error_unlock:
	mutex_unlock(&bo_va->vm->mutex);

error_unreserve:
	ttm_eu_backoff_reservation(&ticket, &list);

error_free:
error_cleanup:
	drm_exec_fini(&exec);
	kvfree(vm_bos);

	if (r && r != -ERESTARTSYS)
+11 −14
Original line number Diff line number Diff line
@@ -464,23 +464,26 @@ static u64 radeon_bo_get_threshold_for_moves(struct radeon_device *rdev)
}

int radeon_bo_list_validate(struct radeon_device *rdev,
			    struct ww_acquire_ctx *ticket,
			    struct drm_exec *exec,
			    struct list_head *head, int ring)
{
	struct ttm_operation_ctx ctx = { true, false };
	struct radeon_bo_list *lobj;
	struct list_head duplicates;
	int r;
	u64 bytes_moved = 0, initial_bytes_moved;
	u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev);
	int r;

	INIT_LIST_HEAD(&duplicates);
	r = ttm_eu_reserve_buffers(ticket, head, true, &duplicates);
	if (unlikely(r != 0)) {
	drm_exec_until_all_locked(exec) {
		list_for_each_entry(lobj, head, list) {
			r = drm_exec_prepare_obj(exec, &lobj->robj->tbo.base,
						 1);
			drm_exec_retry_on_contention(exec);
			if (unlikely(r && r != -EALREADY))
				return r;
		}
	}

	list_for_each_entry(lobj, head, tv.head) {
	list_for_each_entry(lobj, head, list) {
		struct radeon_bo *bo = lobj->robj;
		if (!bo->tbo.pin_count) {
			u32 domain = lobj->preferred_domains;
@@ -519,7 +522,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
					domain = lobj->allowed_domains;
					goto retry;
				}
				ttm_eu_backoff_reservation(ticket, head);
				return r;
			}
		}
@@ -527,11 +529,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
		lobj->tiling_flags = bo->tiling_flags;
	}

	list_for_each_entry(lobj, &duplicates, tv.head) {
		lobj->gpu_offset = radeon_bo_gpu_offset(lobj->robj);
		lobj->tiling_flags = lobj->robj->tiling_flags;
	}

	return 0;
}

Loading