Commit b84394e2 authored by Felix Kuehling's avatar Felix Kuehling Committed by Oded Gabbay

drm/amdkfd: Create KFD VMs on demand

Instead of creating all VMs on process creation, create them when
a process is bound to a device. This will later allow registering
an existing VM from a DRM render node FD at runtime, before the
process is bound to the device. This way the render node VM can be
used for KFD instead of creating our own redundant VM.
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent ede0dd86
...@@ -536,6 +536,7 @@ struct kfd_process_device { ...@@ -536,6 +536,7 @@ struct kfd_process_device {
uint64_t scratch_limit; uint64_t scratch_limit;
/* VM context for GPUVM allocations */ /* VM context for GPUVM allocations */
struct file *drm_file;
void *vm; void *vm;
/* Flag used to tell the pdd has dequeued from the dqm. /* Flag used to tell the pdd has dequeued from the dqm.
...@@ -661,6 +662,8 @@ void kfd_unref_process(struct kfd_process *p); ...@@ -661,6 +662,8 @@ void kfd_unref_process(struct kfd_process *p);
void kfd_suspend_all_processes(void); void kfd_suspend_all_processes(void);
int kfd_resume_all_processes(void); int kfd_resume_all_processes(void);
int kfd_process_device_init_vm(struct kfd_process_device *pdd,
struct file *drm_file);
struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
struct kfd_process *p); struct kfd_process *p);
struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/file.h>
struct mm_struct; struct mm_struct;
...@@ -158,7 +159,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) ...@@ -158,7 +159,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n", pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
pdd->dev->id, p->pasid); pdd->dev->id, p->pasid);
if (pdd->vm) if (pdd->drm_file)
fput(pdd->drm_file);
else if (pdd->vm)
pdd->dev->kfd2kgd->destroy_process_vm( pdd->dev->kfd2kgd->destroy_process_vm(
pdd->dev->kgd, pdd->vm); pdd->dev->kgd, pdd->vm);
...@@ -418,18 +421,51 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, ...@@ -418,18 +421,51 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
pdd->already_dequeued = false; pdd->already_dequeued = false;
list_add(&pdd->per_device_list, &p->per_device_data); list_add(&pdd->per_device_list, &p->per_device_data);
/* Create the GPUVM context for this specific device */ return pdd;
if (dev->kfd2kgd->create_process_vm(dev->kgd, &pdd->vm, }
&p->kgd_process_info, &p->ef)) {
/**
* kfd_process_device_init_vm - Initialize a VM for a process-device
*
* @pdd: The process-device
* @drm_file: Optional pointer to a DRM file descriptor
*
* If @drm_file is specified, it will be used to acquire the VM from
* that file descriptor. If successful, the @pdd takes ownership of
* the file descriptor.
*
* If @drm_file is NULL, a new VM is created.
*
* Returns 0 on success, -errno on failure.
*/
int kfd_process_device_init_vm(struct kfd_process_device *pdd,
struct file *drm_file)
{
struct kfd_process *p;
struct kfd_dev *dev;
int ret;
if (pdd->vm)
return drm_file ? -EBUSY : 0;
p = pdd->process;
dev = pdd->dev;
if (drm_file)
ret = dev->kfd2kgd->acquire_process_vm(
dev->kgd, drm_file,
&pdd->vm, &p->kgd_process_info, &p->ef);
else
ret = dev->kfd2kgd->create_process_vm(
dev->kgd, &pdd->vm, &p->kgd_process_info, &p->ef);
if (ret) {
pr_err("Failed to create process VM object\n"); pr_err("Failed to create process VM object\n");
goto err_create_pdd; return ret;
} }
return pdd;
err_create_pdd: pdd->drm_file = drm_file;
list_del(&pdd->per_device_list);
kfree(pdd); return 0;
return NULL;
} }
/* /*
...@@ -455,6 +491,10 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, ...@@ -455,6 +491,10 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
err = kfd_process_device_init_vm(pdd, NULL);
if (err)
return ERR_PTR(err);
return pdd; return pdd;
} }
......
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