Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 940fbcb7 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next



Fixes for 4.19:
- Fix UVD 7.2 instance handling
- Fix UVD 7.2 harvesting
- GPU scheduler fix for when a process is killed
- TTM cleanups
- amdgpu CS bo_list fixes
- Powerplay fixes for polaris12 and CZ/ST
- DC fixes for link training certain HMDs
- DC fix for vega10 blank screen in certain cases

From: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180801222906.1016-1-alexander.deucher@amd.com
parents 569f0a86 df36b2fb
Loading
Loading
Loading
Loading
+2 −39
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
#include "amdgpu_gart.h"
#include "amdgpu_debugfs.h"
#include "amdgpu_job.h"
#include "amdgpu_bo_list.h"

/*
 * Modules parameters.
@@ -689,45 +690,6 @@ struct amdgpu_fpriv {
	struct amdgpu_ctx_mgr	ctx_mgr;
};

/*
 * residency list
 */
struct amdgpu_bo_list_entry {
	struct amdgpu_bo		*robj;
	struct ttm_validate_buffer	tv;
	struct amdgpu_bo_va		*bo_va;
	uint32_t			priority;
	struct page			**user_pages;
	int				user_invalidated;
};

struct amdgpu_bo_list {
	struct mutex lock;
	struct rcu_head rhead;
	struct kref refcount;
	struct amdgpu_bo *gds_obj;
	struct amdgpu_bo *gws_obj;
	struct amdgpu_bo *oa_obj;
	unsigned first_userptr;
	unsigned num_entries;
	struct amdgpu_bo_list_entry *array;
};

struct amdgpu_bo_list *
amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id);
void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
			     struct list_head *validated);
void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
				      struct drm_amdgpu_bo_list_entry **info_param);

int amdgpu_bo_list_create(struct amdgpu_device *adev,
				 struct drm_file *filp,
				 struct drm_amdgpu_bo_list_entry *info,
				 unsigned num_entries,
				 struct amdgpu_bo_list **list);

/*
 * GFX stuff
 */
@@ -1748,6 +1710,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr)))
#define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
#define amdgpu_ring_patch_cs_in_place(r, p, ib) ((r)->funcs->patch_cs_in_place((p), (ib)))
#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
+74 −115
Original line number Diff line number Diff line
@@ -35,83 +35,53 @@
#define AMDGPU_BO_LIST_MAX_PRIORITY	32u
#define AMDGPU_BO_LIST_NUM_BUCKETS	(AMDGPU_BO_LIST_MAX_PRIORITY + 1)

static int amdgpu_bo_list_set(struct amdgpu_device *adev,
				     struct drm_file *filp,
				     struct amdgpu_bo_list *list,
				     struct drm_amdgpu_bo_list_entry *info,
				     unsigned num_entries);
static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
{
	struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
						   rhead);

static void amdgpu_bo_list_release_rcu(struct kref *ref)
	kvfree(list);
}

static void amdgpu_bo_list_free(struct kref *ref)
{
	unsigned i;
	struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
						   refcount);
	struct amdgpu_bo_list_entry *e;

	for (i = 0; i < list->num_entries; ++i)
		amdgpu_bo_unref(&list->array[i].robj);
	amdgpu_bo_list_for_each_entry(e, list)
		amdgpu_bo_unref(&e->robj);

	mutex_destroy(&list->lock);
	kvfree(list->array);
	kfree_rcu(list, rhead);
	call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
}

int amdgpu_bo_list_create(struct amdgpu_device *adev,
				 struct drm_file *filp,
int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
			  struct drm_amdgpu_bo_list_entry *info,
				 unsigned num_entries,
				 struct amdgpu_bo_list **list_out)
			  unsigned num_entries, struct amdgpu_bo_list **result)
{
	unsigned last_entry = 0, first_userptr = num_entries;
	struct amdgpu_bo_list_entry *array;
	struct amdgpu_bo_list *list;
	uint64_t total_size = 0;
	size_t size;
	unsigned i;
	int r;

	if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry))
		return -EINVAL;

	list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL);
	size = sizeof(struct amdgpu_bo_list);
	size += num_entries * sizeof(struct amdgpu_bo_list_entry);
	list = kvmalloc(size, GFP_KERNEL);
	if (!list)
		return -ENOMEM;

	/* initialize bo list*/
	mutex_init(&list->lock);
	kref_init(&list->refcount);
	r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
	if (r) {
		kfree(list);
		return r;
	}
	list->gds_obj = adev->gds.gds_gfx_bo;
	list->gws_obj = adev->gds.gws_gfx_bo;
	list->oa_obj = adev->gds.oa_gfx_bo;

	*list_out = list;
	return 0;
}

static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
{
	struct amdgpu_bo_list *list;

	mutex_lock(&fpriv->bo_list_lock);
	list = idr_remove(&fpriv->bo_list_handles, id);
	mutex_unlock(&fpriv->bo_list_lock);
	if (list)
		kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
}

static int amdgpu_bo_list_set(struct amdgpu_device *adev,
				     struct drm_file *filp,
				     struct amdgpu_bo_list *list,
				     struct drm_amdgpu_bo_list_entry *info,
				     unsigned num_entries)
{
	struct amdgpu_bo_list_entry *array;
	struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
	struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
	struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;

	unsigned last_entry = 0, first_userptr = num_entries;
	unsigned i;
	int r;
	unsigned long total_size = 0;

	array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
	if (!array)
		return -ENOMEM;
	array = amdgpu_bo_list_array_entry(list, 0);
	memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));

	for (i = 0; i < num_entries; ++i) {
@@ -148,59 +118,56 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
		entry->tv.shared = !entry->robj->prime_shared_count;

		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
			gds_obj = entry->robj;
			list->gds_obj = entry->robj;
		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
			gws_obj = entry->robj;
			list->gws_obj = entry->robj;
		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
			oa_obj = entry->robj;
			list->oa_obj = entry->robj;

		total_size += amdgpu_bo_size(entry->robj);
		trace_amdgpu_bo_list_set(list, entry->robj);
	}

	for (i = 0; i < list->num_entries; ++i)
		amdgpu_bo_unref(&list->array[i].robj);

	kvfree(list->array);

	list->gds_obj = gds_obj;
	list->gws_obj = gws_obj;
	list->oa_obj = oa_obj;
	list->first_userptr = first_userptr;
	list->array = array;
	list->num_entries = num_entries;

	trace_amdgpu_cs_bo_status(list->num_entries, total_size);

	*result = list;
	return 0;

error_free:
	while (i--)
		amdgpu_bo_unref(&array[i].robj);
	kvfree(array);
	kvfree(list);
	return r;

}

struct amdgpu_bo_list *
amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
{
	struct amdgpu_bo_list *result;
	struct amdgpu_bo_list *list;

	mutex_lock(&fpriv->bo_list_lock);
	list = idr_remove(&fpriv->bo_list_handles, id);
	mutex_unlock(&fpriv->bo_list_lock);
	if (list)
		kref_put(&list->refcount, amdgpu_bo_list_free);
}

int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
		       struct amdgpu_bo_list **result)
{
	rcu_read_lock();
	result = idr_find(&fpriv->bo_list_handles, id);
	*result = idr_find(&fpriv->bo_list_handles, id);

	if (result) {
		if (kref_get_unless_zero(&result->refcount)) {
			rcu_read_unlock();
			mutex_lock(&result->lock);
		} else {
			rcu_read_unlock();
			result = NULL;
		}
	} else {
	if (*result && kref_get_unless_zero(&(*result)->refcount)) {
		rcu_read_unlock();
		return 0;
	}

	return result;
	rcu_read_unlock();
	return -ENOENT;
}

void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
@@ -211,6 +178,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
	 * concatenated in descending order.
	 */
	struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS];
	struct amdgpu_bo_list_entry *e;
	unsigned i;

	for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++)
@@ -221,14 +189,13 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
	 * in the list, the sort mustn't change the ordering of buffers
	 * with the same priority, i.e. it must be stable.
	 */
	for (i = 0; i < list->num_entries; i++) {
		unsigned priority = list->array[i].priority;
	amdgpu_bo_list_for_each_entry(e, list) {
		unsigned priority = e->priority;

		if (!list->array[i].robj->parent)
			list_add_tail(&list->array[i].tv.head,
				      &bucket[priority]);
		if (!e->robj->parent)
			list_add_tail(&e->tv.head, &bucket[priority]);

		list->array[i].user_pages = NULL;
		e->user_pages = NULL;
	}

	/* Connect the sorted buckets in the output list. */
@@ -238,20 +205,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,

void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
{
	mutex_unlock(&list->lock);
	kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
}

void amdgpu_bo_list_free(struct amdgpu_bo_list *list)
{
	unsigned i;

	for (i = 0; i < list->num_entries; ++i)
		amdgpu_bo_unref(&list->array[i].robj);

	mutex_destroy(&list->lock);
	kvfree(list->array);
	kfree(list);
	kref_put(&list->refcount, amdgpu_bo_list_free);
}

int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
@@ -304,7 +258,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
	union drm_amdgpu_bo_list *args = data;
	uint32_t handle = args->in.list_handle;
	struct drm_amdgpu_bo_list_entry *info = NULL;
	struct amdgpu_bo_list *list;
	struct amdgpu_bo_list *list, *old;
	int r;

	r = amdgpu_bo_create_list_entry_array(&args->in, &info);
@@ -322,7 +276,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
		r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
		mutex_unlock(&fpriv->bo_list_lock);
		if (r < 0) {
			amdgpu_bo_list_free(list);
			amdgpu_bo_list_put(list);
			return r;
		}

@@ -335,17 +289,22 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
		break;

	case AMDGPU_BO_LIST_OP_UPDATE:
		r = -ENOENT;
		list = amdgpu_bo_list_get(fpriv, handle);
		if (!list)
		r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number,
					  &list);
		if (r)
			goto error_free;

		r = amdgpu_bo_list_set(adev, filp, list, info,
					      args->in.bo_number);
		mutex_lock(&fpriv->bo_list_lock);
		old = idr_replace(&fpriv->bo_list_handles, list, handle);
		mutex_unlock(&fpriv->bo_list_lock);

		if (IS_ERR(old)) {
			amdgpu_bo_list_put(list);
		if (r)
			r = PTR_ERR(old);
			goto error_free;
		}

		amdgpu_bo_list_put(old);
		break;

	default:
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 * Copyright 2018 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -19,88 +19,67 @@
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */
#ifndef __AMDGPU_BO_LIST_H__
#define __AMDGPU_BO_LIST_H__

#ifndef __DAL_ENGINE_H__
#define __DAL_ENGINE_H__

#include "dc_ddc_types.h"
#include <drm/ttm/ttm_execbuf_util.h>
#include <drm/amdgpu_drm.h>

enum i2caux_transaction_operation {
	I2CAUX_TRANSACTION_READ,
	I2CAUX_TRANSACTION_WRITE
};

enum i2caux_transaction_address_space {
	I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C = 1,
	I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD
};
struct amdgpu_device;
struct amdgpu_bo;
struct amdgpu_bo_va;
struct amdgpu_fpriv;

struct i2caux_transaction_payload {
	enum i2caux_transaction_address_space address_space;
	uint32_t address;
	uint32_t length;
	uint8_t *data;
struct amdgpu_bo_list_entry {
	struct amdgpu_bo		*robj;
	struct ttm_validate_buffer	tv;
	struct amdgpu_bo_va		*bo_va;
	uint32_t			priority;
	struct page			**user_pages;
	int				user_invalidated;
};

enum i2caux_transaction_status {
	I2CAUX_TRANSACTION_STATUS_UNKNOWN = (-1L),
	I2CAUX_TRANSACTION_STATUS_SUCCEEDED,
	I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY,
	I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT,
	I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR,
	I2CAUX_TRANSACTION_STATUS_FAILED_NACK,
	I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE,
	I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION,
	I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
	I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW,
	I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON
struct amdgpu_bo_list {
	struct rcu_head rhead;
	struct kref refcount;
	struct amdgpu_bo *gds_obj;
	struct amdgpu_bo *gws_obj;
	struct amdgpu_bo *oa_obj;
	unsigned first_userptr;
	unsigned num_entries;
};

struct i2caux_transaction_request {
	enum i2caux_transaction_operation operation;
	struct i2caux_transaction_payload payload;
	enum i2caux_transaction_status status;
};
int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
		       struct amdgpu_bo_list **result);
void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
			     struct list_head *validated);
void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
				      struct drm_amdgpu_bo_list_entry **info_param);

enum i2caux_engine_type {
	I2CAUX_ENGINE_TYPE_UNKNOWN = (-1L),
	I2CAUX_ENGINE_TYPE_AUX,
	I2CAUX_ENGINE_TYPE_I2C_DDC_HW,
	I2CAUX_ENGINE_TYPE_I2C_GENERIC_HW,
	I2CAUX_ENGINE_TYPE_I2C_SW
};
int amdgpu_bo_list_create(struct amdgpu_device *adev,
				 struct drm_file *filp,
				 struct drm_amdgpu_bo_list_entry *info,
				 unsigned num_entries,
				 struct amdgpu_bo_list **list);

enum i2c_default_speed {
	I2CAUX_DEFAULT_I2C_HW_SPEED = 50,
	I2CAUX_DEFAULT_I2C_SW_SPEED = 50
};
static inline struct amdgpu_bo_list_entry *
amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index)
{
	struct amdgpu_bo_list_entry *array = (void *)&list[1];

struct engine;
	return &array[index];
}

struct engine_funcs {
	enum i2caux_engine_type (*get_engine_type)(
		const struct engine *engine);
	struct aux_engine* (*acquire)(
		struct engine *engine,
		struct ddc *ddc);
	bool (*submit_request)(
		struct engine *engine,
		struct i2caux_transaction_request *request,
		bool middle_of_transaction);
	void (*release_engine)(
		struct engine *engine);
	void (*destroy_engine)(
		struct engine **engine);
};
#define amdgpu_bo_list_for_each_entry(e, list) \
	for (e = amdgpu_bo_list_array_entry(list, 0); \
	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
	     ++e)

struct engine {
	const struct engine_funcs *funcs;
	uint32_t inst;
	struct ddc *ddc;
	struct dc_context *ctx;
};
#define amdgpu_bo_list_for_each_userptr_entry(e, list) \
	for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
	     ++e)

#endif
+79 −90
Original line number Diff line number Diff line
@@ -561,27 +561,37 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
				union drm_amdgpu_cs *cs)
{
	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
	struct amdgpu_vm *vm = &fpriv->vm;
	struct amdgpu_bo_list_entry *e;
	struct list_head duplicates;
	unsigned i, tries = 10;
	struct amdgpu_bo *gds;
	struct amdgpu_bo *gws;
	struct amdgpu_bo *oa;
	unsigned tries = 10;
	int r;

	INIT_LIST_HEAD(&p->validated);

	/* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */
	if (!p->bo_list)
		p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);
	else
		mutex_lock(&p->bo_list->lock);
	if (cs->in.bo_list_handle) {
		if (p->bo_list)
			return -EINVAL;

		r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle,
				       &p->bo_list);
		if (r)
			return r;
	} else if (!p->bo_list) {
		/* Create a empty bo_list when no handle is provided */
		r = amdgpu_bo_list_create(p->adev, p->filp, NULL, 0,
					  &p->bo_list);
		if (r)
			return r;
	}

	if (p->bo_list) {
	amdgpu_bo_list_get_list(p->bo_list, &p->validated);
	if (p->bo_list->first_userptr != p->bo_list->num_entries)
		p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX);
	}

	INIT_LIST_HEAD(&duplicates);
	amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
@@ -591,7 +601,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,

	while (1) {
		struct list_head need_pages;
		unsigned i;

		r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true,
					   &duplicates);
@@ -601,17 +610,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
			goto error_free_pages;
		}

		/* Without a BO list we don't have userptr BOs */
		if (!p->bo_list)
			break;

		INIT_LIST_HEAD(&need_pages);
		for (i = p->bo_list->first_userptr;
		     i < p->bo_list->num_entries; ++i) {
			struct amdgpu_bo *bo;

			e = &p->bo_list->array[i];
			bo = e->robj;
		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
			struct amdgpu_bo *bo = e->robj;

			if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm,
				 &e->user_invalidated) && e->user_pages) {
@@ -703,23 +704,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
	amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
				     p->bytes_moved_vis);

	if (p->bo_list) {
		struct amdgpu_vm *vm = &fpriv->vm;
		unsigned i;

	gds = p->bo_list->gds_obj;
	gws = p->bo_list->gws_obj;
	oa = p->bo_list->oa_obj;
		for (i = 0; i < p->bo_list->num_entries; i++) {
			struct amdgpu_bo *bo = p->bo_list->array[i].robj;

			p->bo_list->array[i].bo_va = amdgpu_vm_bo_find(vm, bo);
		}
	} else {
		gds = p->adev->gds.gds_gfx_bo;
		gws = p->adev->gds.gws_gfx_bo;
		oa = p->adev->gds.oa_gfx_bo;
	}
	amdgpu_bo_list_for_each_entry(e, p->bo_list)
		e->bo_va = amdgpu_vm_bo_find(vm, e->robj);

	if (gds) {
		p->job->gds_base = amdgpu_bo_gpu_offset(gds);
@@ -747,11 +737,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,

error_free_pages:

	if (p->bo_list) {
		for (i = p->bo_list->first_userptr;
		     i < p->bo_list->num_entries; ++i) {
			e = &p->bo_list->array[i];

	amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
		if (!e->user_pages)
			continue;

@@ -759,7 +745,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
			      e->robj->tbo.ttm->num_pages);
		kvfree(e->user_pages);
	}
	}

	return r;
}
@@ -820,12 +805,13 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,

static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
{
	struct amdgpu_device *adev = p->adev;
	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
	struct amdgpu_device *adev = p->adev;
	struct amdgpu_vm *vm = &fpriv->vm;
	struct amdgpu_bo_list_entry *e;
	struct amdgpu_bo_va *bo_va;
	struct amdgpu_bo *bo;
	int i, r;
	int r;

	r = amdgpu_vm_clear_freed(adev, vm, NULL);
	if (r)
@@ -855,16 +841,15 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
			return r;
	}

	if (p->bo_list) {
		for (i = 0; i < p->bo_list->num_entries; i++) {
	amdgpu_bo_list_for_each_entry(e, p->bo_list) {
		struct dma_fence *f;

		/* ignore duplicates */
			bo = p->bo_list->array[i].robj;
		bo = e->robj;
		if (!bo)
			continue;

			bo_va = p->bo_list->array[i].bo_va;
		bo_va = e->bo_va;
		if (bo_va == NULL)
			continue;

@@ -878,8 +863,6 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
			return r;
	}

	}

	r = amdgpu_vm_handle_moved(adev, vm);
	if (r)
		return r;
@@ -892,15 +875,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
	if (r)
		return r;

	if (amdgpu_vm_debug && p->bo_list) {
	if (amdgpu_vm_debug) {
		/* Invalidate all BOs to test for userspace bugs */
		for (i = 0; i < p->bo_list->num_entries; i++) {
		amdgpu_bo_list_for_each_entry(e, p->bo_list) {
			/* ignore duplicates */
			bo = p->bo_list->array[i].robj;
			if (!bo)
			if (!e->robj)
				continue;

			amdgpu_vm_bo_invalidate(adev, bo, false);
			amdgpu_vm_bo_invalidate(adev, e->robj, false);
		}
	}

@@ -916,7 +898,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
	int r;

	/* Only for UVD/VCE VM emulation */
	if (p->ring->funcs->parse_cs) {
	if (p->ring->funcs->parse_cs || p->ring->funcs->patch_cs_in_place) {
		unsigned i, j;

		for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) {
@@ -957,12 +939,20 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
			offset = m->start * AMDGPU_GPU_PAGE_SIZE;
			kptr += va_start - offset;

			if (p->ring->funcs->parse_cs) {
				memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
				amdgpu_bo_kunmap(aobj);

				r = amdgpu_ring_parse_cs(ring, p, j);
				if (r)
					return r;
			} else {
				ib->ptr = (uint32_t *)kptr;
				r = amdgpu_ring_patch_cs_in_place(ring, p, j);
				amdgpu_bo_kunmap(aobj);
				if (r)
					return r;
			}

			j++;
		}
@@ -1207,27 +1197,25 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
			    union drm_amdgpu_cs *cs)
{
	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
	struct amdgpu_ring *ring = p->ring;
	struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity;
	enum drm_sched_priority priority;
	struct amdgpu_bo_list_entry *e;
	struct amdgpu_job *job;
	unsigned i;
	uint64_t seq;

	int r;

	amdgpu_mn_lock(p->mn);
	if (p->bo_list) {
		for (i = p->bo_list->first_userptr;
		     i < p->bo_list->num_entries; ++i) {
			struct amdgpu_bo *bo = p->bo_list->array[i].robj;
	amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
		struct amdgpu_bo *bo = e->robj;

		if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
			amdgpu_mn_unlock(p->mn);
			return -ERESTARTSYS;
		}
	}
	}

	job = p->job;
	p->job = NULL;
@@ -1259,6 +1247,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
	amdgpu_job_free_resources(job);

	trace_amdgpu_cs_ioctl(job);
	amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
	priority = job->base.s_priority;
	drm_sched_entity_push_job(&job->base, entity);

+13 −6
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
	struct drm_crtc *crtc;
	uint32_t ui32 = 0;
	uint64_t ui64 = 0;
	int i, found;
	int i, j, found;
	int ui32_size = sizeof(ui32);

	if (!info->return_size || !info->return_pointer)
@@ -348,7 +348,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
			break;
		case AMDGPU_HW_IP_UVD:
			type = AMD_IP_BLOCK_TYPE_UVD;
			ring_mask |= adev->uvd.inst[0].ring.ready;
			for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
				if (adev->uvd.harvest_config & (1 << i))
					continue;
				ring_mask |= adev->uvd.inst[i].ring.ready;
			}
			ib_start_alignment = 64;
			ib_size_alignment = 64;
			break;
@@ -361,9 +365,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
			break;
		case AMDGPU_HW_IP_UVD_ENC:
			type = AMD_IP_BLOCK_TYPE_UVD;
			for (i = 0; i < adev->uvd.num_enc_rings; i++)
				ring_mask |=
					adev->uvd.inst[0].ring_enc[i].ready << i;
			for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
				if (adev->uvd.harvest_config & (1 << i))
					continue;
				for (j = 0; j < adev->uvd.num_enc_rings; j++)
					ring_mask |= adev->uvd.inst[i].ring_enc[j].ready << j;
			}
			ib_start_alignment = 64;
			ib_size_alignment = 64;
			break;
@@ -960,7 +967,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
	amdgpu_bo_unref(&pd);

	idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
		amdgpu_bo_list_free(list);
		amdgpu_bo_list_put(list);

	idr_destroy(&fpriv->bo_list_handles);
	mutex_destroy(&fpriv->bo_list_lock);
Loading