[PATCH 5/9] drm/amdkfd: Use PASID manager from KGD
Felix Kuehling
Felix.Kuehling at amd.com
Sat Aug 26 07:19:05 UTC 2017
Also fixed PASID limit setting for dGPUs.
Change-Id: If3bb8c0742019745bedf09077a271b1ed14deea1
Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_device.c | 11 ++---
drivers/gpu/drm/amd/amdkfd/kfd_module.c | 6 ---
drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | 84 +++++++++++++--------------------
3 files changed, 39 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 378a9cf..1915e93 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -391,7 +391,6 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd)
AMD_IOMMU_DEVICE_FLAG_PASID_SUP;
struct amd_iommu_device_info iommu_info;
- unsigned int pasid_limit;
int err;
err = amd_iommu_device_info(kfd->pdev, &iommu_info);
@@ -410,11 +409,7 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd)
return false;
}
- pasid_limit = min_t(unsigned int,
- (unsigned int)(1 << kfd->device_info->max_pasid_bits),
- iommu_info.max_pasids);
-
- if (!kfd_set_pasid_limit(pasid_limit)) {
+ if (!kfd_set_pasid_limit(iommu_info.max_pasids)) {
dev_err(kfd_device, "error setting pasid limit\n");
return false;
}
@@ -605,6 +600,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
goto device_queue_manager_error;
}
+ if (!kfd_set_pasid_limit(1U << kfd->device_info->max_pasid_bits)) {
+ dev_err(kfd_device, "Error setting pasid limit\n");
+ goto device_iommu_pasid_error;
+ }
#if defined(CONFIG_AMD_IOMMU_V2_MODULE) || defined(CONFIG_AMD_IOMMU_V2)
if (kfd->device_info->is_need_iommu_device) {
if (!device_iommu_pasid_init(kfd)) {
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index aba3e9d..9846d58 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -131,10 +131,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;
@@ -162,7 +158,6 @@ static int __init kfd_module_init(void)
err_topology:
kfd_chardev_exit();
err_ioctl:
- kfd_pasid_exit();
return err;
}
@@ -175,7 +170,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");
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
index 1e06de0..ed78937 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
@@ -20,78 +20,62 @@
* 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;
+ int r;
+
+ /* Find the first best KFD device for calling KGD */
+ if (!kfd2kgd) {
+ struct kfd_dev *dev = NULL;
+ unsigned int i;
- mutex_lock(&pasid_mutex);
+ for (i = 0; kfd_topology_enum_kfd_devices(i, &dev) == 0; i++)
+ if (dev && dev->kfd2kgd) {
+ kfd2kgd = dev->kfd2kgd;
+ break;
+ }
- found = find_first_zero_bit(pasid_bitmap, pasid_limit);
- if (found == pasid_limit)
- found = 0;
- else
- set_bit(found, pasid_bitmap);
+ 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);
}
--
2.7.4
More information about the amd-gfx
mailing list