Commit d2791c45 authored by Felix Kuehling's avatar Felix Kuehling Committed by Alex Deucher

drm/amdkfd: Use PASID manager from KGD

Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a91e70e3
...@@ -103,10 +103,6 @@ static int __init kfd_module_init(void) ...@@ -103,10 +103,6 @@ static int __init kfd_module_init(void)
return -1; return -1;
} }
err = kfd_pasid_init();
if (err < 0)
return err;
err = kfd_chardev_init(); err = kfd_chardev_init();
if (err < 0) if (err < 0)
goto err_ioctl; goto err_ioctl;
...@@ -126,7 +122,6 @@ static int __init kfd_module_init(void) ...@@ -126,7 +122,6 @@ static int __init kfd_module_init(void)
err_topology: err_topology:
kfd_chardev_exit(); kfd_chardev_exit();
err_ioctl: err_ioctl:
kfd_pasid_exit();
return err; return err;
} }
...@@ -137,7 +132,6 @@ static void __exit kfd_module_exit(void) ...@@ -137,7 +132,6 @@ static void __exit kfd_module_exit(void)
kfd_process_destroy_wq(); kfd_process_destroy_wq();
kfd_topology_shutdown(); kfd_topology_shutdown();
kfd_chardev_exit(); kfd_chardev_exit();
kfd_pasid_exit();
dev_info(kfd_device, "Removed module\n"); dev_info(kfd_device, "Removed module\n");
} }
......
...@@ -20,78 +20,64 @@ ...@@ -20,78 +20,64 @@
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include "kfd_priv.h" #include "kfd_priv.h"
static unsigned long *pasid_bitmap; static unsigned int pasid_bits = 16;
static unsigned int pasid_limit; static const struct kfd2kgd_calls *kfd2kgd;
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);
}
bool kfd_set_pasid_limit(unsigned int new_limit) bool kfd_set_pasid_limit(unsigned int new_limit)
{ {
if (new_limit < pasid_limit) { if (new_limit < 2)
bool ok; return false;
mutex_lock(&pasid_mutex);
/* ensure that no pasids >= new_limit are in-use */ if (new_limit < (1U << pasid_bits)) {
ok = (find_next_bit(pasid_bitmap, pasid_limit, new_limit) == if (kfd2kgd)
pasid_limit); /* We've already allocated user PASIDs, too late to
if (ok) * change the limit
pasid_limit = new_limit; */
return false;
mutex_unlock(&pasid_mutex);
return ok; while (new_limit < (1U << pasid_bits))
pasid_bits--;
} }
return true; 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 kfd_pasid_alloc(void)
{ {
unsigned int found; int r;
mutex_lock(&pasid_mutex); /* Find the first best KFD device for calling KGD */
if (!kfd2kgd) {
struct kfd_dev *dev = NULL;
unsigned int i = 0;
found = find_first_zero_bit(pasid_bitmap, pasid_limit); while ((dev = kfd_topology_enum_kfd_devices(i)) != NULL) {
if (found == pasid_limit) if (dev && dev->kfd2kgd) {
found = 0; kfd2kgd = dev->kfd2kgd;
else break;
set_bit(found, pasid_bitmap); }
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) void kfd_pasid_free(unsigned int pasid)
{ {
if (!WARN_ON(pasid == 0 || pasid >= pasid_limit)) if (kfd2kgd)
clear_bit(pasid, pasid_bitmap); kfd2kgd->free_pasid(pasid);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment