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

Commit 33f86ff6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'amdkfd-next-3.19' of git://people.freedesktop.org/~gabbayo/linux into drm-next

- Fixes for sparse warnings
- Memory leak fixes
- Fix for deadlock between amdkfd and iommu

* 'amdkfd-next-3.19' of git://people.freedesktop.org/~gabbayo/linux:
  amdkfd: delete some dead code
  amdkfd: Fix memory leak of mqds on dqm fini
  amdkfd: fix an error handling bug in pqm_create_queue()
  amdkfd: fix some error handling in ioctl
  amdkfd: Remove DRM_AMDGPU dependency from Kconfig
  amdkfd: explicitely include io.h in kfd_doorbell.c
  amdkfd: Clear ctx cb before suspend
  amdkfd: Instead of using get function, use container_of
  amdkfd: use schedule() in sync_with_hw
  amdkfd: Fix memory leak on process deregistration
  amdkfd: add __iomem attribute to doorbell_ptr
  amdkfd: fence_wait_timeout() can be static
  amdkfd: is_occupied() can be static
  amdkfd: Fix sparse warnings in kfd_flat_memory.c
  amdkfd: pqm_get_kernel_queue() can be static
  amdkfd: test_kq() can be static
  amdkfd: Fix sparse warnings in kfd_topology.c
  amdkfd: Fix sparse warnings in kfd_chardev.c
parents e38648f9 9cf4a281
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,6 +4,6 @@

config HSA_AMD
	tristate "HSA kernel driver for AMD GPU devices"
	depends on (DRM_RADEON || DRM_AMDGPU) && AMD_IOMMU_V2 && X86_64
	depends on DRM_RADEON && AMD_IOMMU_V2 && X86_64
	help
	  Enable this if you want to use HSA features on AMD GPU devices.
+14 −6
Original line number Diff line number Diff line
@@ -149,7 +149,9 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
	}

	if ((args->ring_base_address) &&
		(!access_ok(VERIFY_WRITE, args->ring_base_address, sizeof(uint64_t)))) {
		(!access_ok(VERIFY_WRITE,
			(const void __user *) args->ring_base_address,
			sizeof(uint64_t)))) {
		pr_err("kfd: can't access ring base address\n");
		return -EFAULT;
	}
@@ -159,12 +161,16 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
		return -EINVAL;
	}

	if (!access_ok(VERIFY_WRITE, args->read_pointer_address, sizeof(uint32_t))) {
	if (!access_ok(VERIFY_WRITE,
			(const void __user *) args->read_pointer_address,
			sizeof(uint32_t))) {
		pr_err("kfd: can't access read pointer\n");
		return -EFAULT;
	}

	if (!access_ok(VERIFY_WRITE, args->write_pointer_address, sizeof(uint32_t))) {
	if (!access_ok(VERIFY_WRITE,
			(const void __user *) args->write_pointer_address,
			sizeof(uint32_t))) {
		pr_err("kfd: can't access write pointer\n");
		return -EFAULT;
	}
@@ -236,7 +242,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
	mutex_lock(&p->mutex);

	pdd = kfd_bind_process_to_device(dev, p);
	if (IS_ERR(pdd) < 0) {
	if (IS_ERR(pdd)) {
		err = PTR_ERR(pdd);
		goto err_bind_process;
	}
@@ -325,7 +331,9 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
	}

	if ((args.ring_base_address) &&
		(!access_ok(VERIFY_WRITE, args.ring_base_address, sizeof(uint64_t)))) {
		(!access_ok(VERIFY_WRITE,
			(const void __user *) args.ring_base_address,
			sizeof(uint64_t)))) {
		pr_err("kfd: can't access ring base address\n");
		return -EFAULT;
	}
@@ -381,7 +389,7 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,
	mutex_lock(&p->mutex);

	pdd = kfd_bind_process_to_device(dev, p);
	if (IS_ERR(pdd) < 0) {
	if (IS_ERR(pdd)) {
		err = PTR_ERR(pdd);
		goto out;
	}
+1 −0
Original line number Diff line number Diff line
@@ -267,6 +267,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd)

	if (kfd->init_complete) {
		kfd->dqm->stop(kfd->dqm);
		amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
		amd_iommu_free_device(kfd->pdev);
	}
}
+17 −14
Original line number Diff line number Diff line
@@ -67,26 +67,21 @@ static inline unsigned int get_pipes_num_cpsch(void)
	return PIPE_PER_ME_CP_SCHEDULING;
}

static unsigned int get_sh_mem_bases_nybble_64(struct kfd_process *process,
						struct kfd_dev *dev)
static inline unsigned int
get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd)
{
	struct kfd_process_device *pdd;
	uint32_t nybble;

	pdd = kfd_get_process_device_data(dev, process, 1);
	nybble = (pdd->lds_base >> 60) & 0x0E;

	return nybble;

}

static unsigned int get_sh_mem_bases_32(struct kfd_process *process,
					struct kfd_dev *dev)
static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
{
	struct kfd_process_device *pdd;
	unsigned int shared_base;

	pdd = kfd_get_process_device_data(dev, process, 1);
	shared_base = (pdd->lds_base >> 16) & 0xFF;

	return shared_base;
@@ -96,10 +91,13 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
static void init_process_memory(struct device_queue_manager *dqm,
				struct qcm_process_device *qpd)
{
	struct kfd_process_device *pdd;
	unsigned int temp;

	BUG_ON(!dqm || !qpd);

	pdd = qpd_to_pdd(qpd);

	/* check if sh_mem_config register already configured */
	if (qpd->sh_mem_config == 0) {
		qpd->sh_mem_config =
@@ -111,11 +109,11 @@ static void init_process_memory(struct device_queue_manager *dqm,
	}

	if (qpd->pqm->process->is_32bit_user_mode) {
		temp = get_sh_mem_bases_32(qpd->pqm->process, dqm->dev);
		temp = get_sh_mem_bases_32(pdd);
		qpd->sh_mem_bases = SHARED_BASE(temp);
		qpd->sh_mem_config |= PTR32;
	} else {
		temp = get_sh_mem_bases_nybble_64(qpd->pqm->process, dqm->dev);
		temp = get_sh_mem_bases_nybble_64(pdd);
		qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
	}

@@ -409,6 +407,7 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm,
	list_for_each_entry_safe(cur, next, &dqm->queues, list) {
		if (qpd == cur->qpd) {
			list_del(&cur->list);
			kfree(cur);
			dqm->processes_count--;
			goto out;
		}
@@ -576,11 +575,15 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)

static void uninitialize_nocpsch(struct device_queue_manager *dqm)
{
	int i;

	BUG_ON(!dqm);

	BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0);

	kfree(dqm->allocated_queues);
	for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++)
		kfree(dqm->mqds[i]);
	mutex_destroy(&dqm->lock);
	kfd2kgd->free_mem(dqm->dev->kgd,
			(struct kgd_mem *) dqm->pipeline_mem);
@@ -706,8 +709,7 @@ static int stop_cpsch(struct device_queue_manager *dqm)
	destroy_queues_cpsch(dqm, true);

	list_for_each_entry(node, &dqm->queues, list) {
		pdd = kfd_get_process_device_data(dqm->dev,
						node->qpd->pqm->process, 1);
		pdd = qpd_to_pdd(node->qpd);
		pdd->bound = false;
	}
	kfd2kgd->free_mem(dqm->dev->kgd,
@@ -789,7 +791,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
	return retval;
}

int fence_wait_timeout(unsigned int *fence_addr, unsigned int fence_value,
static int fence_wait_timeout(unsigned int *fence_addr,
				unsigned int fence_value,
				unsigned long timeout)
{
	BUG_ON(!fence_addr);
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/io.h>

/*
 * This extension supports a kernel level doorbells management for
Loading