drm/amdkfd: Use PASID manager from KGD
authorFelix Kuehling <Felix.Kuehling@amd.com>
Sat, 26 Aug 2017 06:10:12 +0000 (02:10 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 17:07:04 +0000 (13:07 -0400)
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_module.c
drivers/gpu/drm/amd/amdkfd/kfd_pasid.c

index 0d73bea..6c5a9ca 100644 (file)
@@ -103,10 +103,6 @@ static int __init kfd_module_init(void)
                return -1;
        }
 
-       err = kfd_pasid_init();
-       if (err < 0)
-               return err;
-
        err = kfd_chardev_init();
        if (err < 0)
                goto err_ioctl;
@@ -126,7 +122,6 @@ static int __init kfd_module_init(void)
 err_topology:
        kfd_chardev_exit();
 err_ioctl:
-       kfd_pasid_exit();
        return err;
 }
 
@@ -137,7 +132,6 @@ static void __exit kfd_module_exit(void)
        kfd_process_destroy_wq();
        kfd_topology_shutdown();
        kfd_chardev_exit();
-       kfd_pasid_exit();
        dev_info(kfd_device, "Removed module\n");
 }
 
index 1e06de0..d6a7961 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include <linux/slab.h>
 #include <linux/types.h>
 #include "kfd_priv.h"
 
-static unsigned long *pasid_bitmap;
-static unsigned int pasid_limit;
-static DEFINE_MUTEX(pasid_mutex);
-
-int kfd_pasid_init(void)
-{
-       pasid_limit = KFD_MAX_NUM_OF_PROCESSES;
-
-       pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long),
-                               GFP_KERNEL);
-       if (!pasid_bitmap)
-               return -ENOMEM;
-
-       set_bit(0, pasid_bitmap); /* PASID 0 is reserved. */
-
-       return 0;
-}
-
-void kfd_pasid_exit(void)
-{
-       kfree(pasid_bitmap);
-}
+static unsigned int pasid_bits = 16;
+static const struct kfd2kgd_calls *kfd2kgd;
 
 bool kfd_set_pasid_limit(unsigned int new_limit)
 {
-       if (new_limit < pasid_limit) {
-               bool ok;
-
-               mutex_lock(&pasid_mutex);
-
-               /* ensure that no pasids >= new_limit are in-use */
-               ok = (find_next_bit(pasid_bitmap, pasid_limit, new_limit) ==
-                                                               pasid_limit);
-               if (ok)
-                       pasid_limit = new_limit;
-
-               mutex_unlock(&pasid_mutex);
-
-               return ok;
+       if (new_limit < 2)
+               return false;
+
+       if (new_limit < (1U << pasid_bits)) {
+               if (kfd2kgd)
+                       /* We've already allocated user PASIDs, too late to
+                        * change the limit
+                        */
+                       return false;
+
+               while (new_limit < (1U << pasid_bits))
+                       pasid_bits--;
        }
 
        return true;
 }
 
-inline unsigned int kfd_get_pasid_limit(void)
+unsigned int kfd_get_pasid_limit(void)
 {
-       return pasid_limit;
+       return 1U << pasid_bits;
 }
 
 unsigned int kfd_pasid_alloc(void)
 {
-       unsigned int found;
-
-       mutex_lock(&pasid_mutex);
-
-       found = find_first_zero_bit(pasid_bitmap, pasid_limit);
-       if (found == pasid_limit)
-               found = 0;
-       else
-               set_bit(found, pasid_bitmap);
+       int r;
+
+       /* Find the first best KFD device for calling KGD */
+       if (!kfd2kgd) {
+               struct kfd_dev *dev = NULL;
+               unsigned int i = 0;
+
+               while ((dev = kfd_topology_enum_kfd_devices(i)) != NULL) {
+                       if (dev && dev->kfd2kgd) {
+                               kfd2kgd = dev->kfd2kgd;
+                               break;
+                       }
+                       i++;
+               }
+
+               if (!kfd2kgd)
+                       return false;
+       }
 
-       mutex_unlock(&pasid_mutex);
+       r = kfd2kgd->alloc_pasid(pasid_bits);
 
-       return found;
+       return r > 0 ? r : 0;
 }
 
 void kfd_pasid_free(unsigned int pasid)
 {
-       if (!WARN_ON(pasid == 0 || pasid >= pasid_limit))
-               clear_bit(pasid, pasid_bitmap);
+       if (kfd2kgd)
+               kfd2kgd->free_pasid(pasid);
 }