Skip to content

Commit

Permalink
Merge branch 'amdkfd-next-3.19' of git://people.freedesktop.org/~gabb…
Browse files Browse the repository at this point in the history
…ayo/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
  • Loading branch information
Dave Airlie committed Nov 26, 2014
2 parents e38648f + 9cf4a28 commit 33f86ff
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 64 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdkfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
20 changes: 14 additions & 6 deletions drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdkfd/kfd_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
31 changes: 17 additions & 14 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 =
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -789,8 +791,9 @@ 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,
unsigned long timeout)
static int fence_wait_timeout(unsigned int *fence_addr,
unsigned int fence_value,
unsigned long timeout)
{
BUG_ON(!fence_addr);
timeout += jiffies;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,22 @@
*/

#define MAKE_GPUVM_APP_BASE(gpu_num) \
(((uint64_t)(gpu_num) << 61) + 0x1000000000000)
(((uint64_t)(gpu_num) << 61) + 0x1000000000000L)

#define MAKE_GPUVM_APP_LIMIT(base) \
(((uint64_t)(base) & 0xFFFFFF0000000000) | 0xFFFFFFFFFF)
(((uint64_t)(base) & \
0xFFFFFF0000000000UL) | 0xFFFFFFFFFFL)

#define MAKE_SCRATCH_APP_BASE(gpu_num) \
(((uint64_t)(gpu_num) << 61) + 0x100000000)
(((uint64_t)(gpu_num) << 61) + 0x100000000L)

#define MAKE_SCRATCH_APP_LIMIT(base) \
(((uint64_t)base & 0xFFFFFFFF00000000) | 0xFFFFFFFF)
(((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)

#define MAKE_LDS_APP_BASE(gpu_num) \
(((uint64_t)(gpu_num) << 61) + 0x0)
#define MAKE_LDS_APP_LIMIT(base) \
(((uint64_t)(base) & 0xFFFFFFFF00000000) | 0xFFFFFFFF)
(((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)

int kfd_init_apertures(struct kfd_process *process)
{
Expand Down
14 changes: 7 additions & 7 deletions drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/printk.h>
#include <linux/sched.h>
#include "kfd_kernel_queue.h"
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
Expand Down Expand Up @@ -66,8 +67,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
if (kq->mqd == NULL)
return false;

prop.doorbell_ptr =
(uint32_t *)kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);

if (prop.doorbell_ptr == NULL)
goto err_get_kernel_doorbell;
Expand Down Expand Up @@ -172,7 +172,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq);
err_pq_allocate_vidmem:
pr_err("kfd: error init pq\n");
kfd_release_kernel_doorbell(dev, (u32 *)prop.doorbell_ptr);
kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
err_get_kernel_doorbell:
pr_err("kfd: error init doorbell");
return false;
Expand All @@ -195,7 +195,7 @@ static void uninitialize(struct kernel_queue *kq)
kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->wptr_mem);
kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->pq);
kfd_release_kernel_doorbell(kq->dev,
(u32 *)kq->queue->properties.doorbell_ptr);
kq->queue->properties.doorbell_ptr);
uninit_queue(kq->queue);
}

Expand Down Expand Up @@ -255,7 +255,7 @@ static void submit_packet(struct kernel_queue *kq)
#endif

*kq->wptr_kernel = kq->pending_wptr;
write_kernel_doorbell((u32 *)kq->queue->properties.doorbell_ptr,
write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
kq->pending_wptr);
}

Expand All @@ -275,7 +275,7 @@ static int sync_with_hw(struct kernel_queue *kq, unsigned long timeout_ms)
*kq->wptr_kernel, *kq->rptr_kernel);
return -ETIME;
}
cpu_relax();
schedule();
}

return 0;
Expand Down Expand Up @@ -321,7 +321,7 @@ void kernel_queue_uninit(struct kernel_queue *kq)
kfree(kq);
}

void test_kq(struct kfd_dev *dev)
static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
{
struct kernel_queue *kq;
uint32_t *buffer, i;
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
pipe_id, queue_id);
}

bool is_occupied(struct mqd_manager *mm, void *mqd,
uint64_t queue_address, uint32_t pipe_id,
uint32_t queue_id)
static bool is_occupied(struct mqd_manager *mm, void *mqd,
uint64_t queue_address, uint32_t pipe_id,
uint32_t queue_id)
{

return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address,
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/amd/amdkfd/kfd_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ struct queue_properties {
uint32_t queue_percent;
uint32_t *read_ptr;
uint32_t *write_ptr;
uint32_t *doorbell_ptr;
uint32_t __iomem *doorbell_ptr;
uint32_t doorbell_off;
bool is_interop;
bool is_active;
Expand Down Expand Up @@ -414,6 +414,8 @@ struct kfd_process_device {
bool bound;
};

#define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd)

/* Process data */
struct kfd_process {
/*
Expand Down
5 changes: 0 additions & 5 deletions drivers/gpu/drm/amd/amdkfd/kfd_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,6 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
if (err < 0)
return ERR_PTR(err);

if (err < 0) {
amd_iommu_unbind_pasid(dev->pdev, p->pasid);
return ERR_PTR(err);
}

pdd->bound = true;

return pdd;
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
case KFD_QUEUE_TYPE_DIQ:
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ);
if (kq == NULL) {
kernel_queue_uninit(kq);
retval = -ENOMEM;
goto err_create_queue;
}
kq->queue->properties.queue_id = *qid;
Expand Down Expand Up @@ -325,7 +325,8 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
return 0;
}

struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
static __attribute__((unused)) struct kernel_queue *pqm_get_kernel_queue(
struct process_queue_manager *pqm,
unsigned int qid)
{
struct process_queue_node *pqn;
Expand Down
Loading

0 comments on commit 33f86ff

Please sign in to comment.