From: Andrew Lewycky <andrew.lewy...@amd.com>

Permanently bind the process to the device.
The binding survives even when all queues are destroyed.
Process exit and device removal terminate the binding.

Signed-off-by: Andrew Lewycky <andrew.lewy...@amd.com>
Signed-off-by: Oded Gabbay <oded.gab...@amd.com>
---
 drivers/gpu/hsa/radeon/kfd_chardev.c | 27 +++------------------------
 drivers/gpu/hsa/radeon/kfd_priv.h    |  3 ---
 drivers/gpu/hsa/radeon/kfd_process.c | 21 ++++++++++-----------
 3 files changed, 13 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/hsa/radeon/kfd_chardev.c 
b/drivers/gpu/hsa/radeon/kfd_chardev.c
index 4e7d5d0..e0b276d 100644
--- a/drivers/gpu/hsa/radeon/kfd_chardev.c
+++ b/drivers/gpu/hsa/radeon/kfd_chardev.c
@@ -141,20 +141,13 @@ kfd_ioctl_create_queue(struct file *filep, struct 
kfd_process *p, void __user *a
        pdd = radeon_kfd_bind_process_to_device(dev, p);
        if (IS_ERR(pdd) < 0) {
                err = PTR_ERR(pdd);
-               goto err_bind_pasid;
+               goto err_bind_process;
        }
 
-       pr_debug("kfd: creating queue number %d for PASID %d on GPU 0x%x\n",
-                       pdd->queue_count,
+       pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n",
                        p->pasid,
                        dev->id);
 
-       if (pdd->queue_count++ == 0) {
-               err = 
dev->device_info->scheduler_class->register_process(dev->scheduler, p, 
&pdd->scheduler_process);
-               if (err < 0)
-                       goto err_register_process;
-       }
-
        if (!radeon_kfd_allocate_queue_id(p, &queue_id))
                goto err_allocate_queue_id;
 
@@ -198,12 +191,7 @@ err_copy_args_out:
 err_create_queue:
        radeon_kfd_remove_queue(p, queue_id);
 err_allocate_queue_id:
-       if (--pdd->queue_count == 0) {
-               
dev->device_info->scheduler_class->deregister_process(dev->scheduler, 
pdd->scheduler_process);
-               pdd->scheduler_process = NULL;
-       }
-err_register_process:
-err_bind_pasid:
+err_bind_process:
        kfree(queue);
        mutex_unlock(&p->mutex);
        return err;
@@ -215,7 +203,6 @@ kfd_ioctl_destroy_queue(struct file *filp, struct 
kfd_process *p, void __user *a
        struct kfd_ioctl_destroy_queue_args args;
        struct kfd_queue *queue;
        struct kfd_dev *dev;
-       struct kfd_process_device *pdd;
 
        if (copy_from_user(&args, arg, sizeof(args)))
                return -EFAULT;
@@ -239,14 +226,6 @@ kfd_ioctl_destroy_queue(struct file *filp, struct 
kfd_process *p, void __user *a
 
        kfree(queue);
 
-       pdd = radeon_kfd_get_process_device_data(dev, p);
-       BUG_ON(pdd == NULL); /* Because a queue exists. */
-
-       if (--pdd->queue_count == 0) {
-               
dev->device_info->scheduler_class->deregister_process(dev->scheduler, 
pdd->scheduler_process);
-               pdd->scheduler_process = NULL;
-       }
-
        mutex_unlock(&p->mutex);
        return 0;
 }
diff --git a/drivers/gpu/hsa/radeon/kfd_priv.h 
b/drivers/gpu/hsa/radeon/kfd_priv.h
index 630d690..bca9cce 100644
--- a/drivers/gpu/hsa/radeon/kfd_priv.h
+++ b/drivers/gpu/hsa/radeon/kfd_priv.h
@@ -166,9 +166,6 @@ struct kfd_process_device {
        /* The user-mode address of the doorbell mapping for this device. */
        doorbell_t __user *doorbell_mapping;
 
-       /* The number of queues created by this process for this device. */
-       uint32_t queue_count;
-
        /* Scheduler process data for this device. */
        struct kfd_scheduler_process *scheduler_process;
 
diff --git a/drivers/gpu/hsa/radeon/kfd_process.c 
b/drivers/gpu/hsa/radeon/kfd_process.c
index 145ee38..f89f855 100644
--- a/drivers/gpu/hsa/radeon/kfd_process.c
+++ b/drivers/gpu/hsa/radeon/kfd_process.c
@@ -120,15 +120,6 @@ destroy_queues(struct kfd_process *p, struct kfd_dev 
*dev_filter)
                        
dev->device_info->scheduler_class->destroy_queue(dev->scheduler, 
&queue->scheduler_queue);
 
                        kfree(queue);
-
-                       BUG_ON(pdd->queue_count == 0);
-                       BUG_ON(pdd->scheduler_process == NULL);
-
-                       if (--pdd->queue_count == 0) {
-                               
dev->device_info->scheduler_class->deregister_process(dev->scheduler,
-                                                       pdd->scheduler_process);
-                               pdd->scheduler_process = NULL;
-                       }
                }
        }
 }
@@ -144,6 +135,8 @@ static void free_process(struct kfd_process *p)
        /* doorbell mappings: automatic */
 
        list_for_each_entry_safe(pdd, temp, &p->per_device_data, 
per_device_list) {
+               
pdd->dev->device_info->scheduler_class->deregister_process(pdd->dev->scheduler, 
pdd->scheduler_process);
+               pdd->scheduler_process = NULL;
                amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
                list_del(&pdd->per_device_list);
                kfree(pdd);
@@ -255,6 +248,12 @@ struct kfd_process_device 
*radeon_kfd_bind_process_to_device(struct kfd_dev *dev
        if (err < 0)
                return ERR_PTR(err);
 
+       err = 
dev->device_info->scheduler_class->register_process(dev->scheduler, p, 
&pdd->scheduler_process);
+       if (err < 0) {
+               amd_iommu_unbind_pasid(dev->pdev, p->pasid);
+               return ERR_PTR(err);
+       }
+
        pdd->bound = true;
 
        return pdd;
@@ -285,8 +284,8 @@ void radeon_kfd_unbind_process_from_device(struct kfd_dev 
*dev, pasid_t pasid)
 
        destroy_queues(p, dev);
 
-       /* All queues just got destroyed so this should be gone. */
-       BUG_ON(pdd->scheduler_process != NULL);
+       dev->device_info->scheduler_class->deregister_process(dev->scheduler, 
pdd->scheduler_process);
+       pdd->scheduler_process = NULL;
 
        /*
         * Just mark pdd as unbound, because we still need it to call
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to