[PATCH 15/25] drm/amdkfd: Add GPUVM virtual address space to PDD
Oded Gabbay
oded.gabbay at gmail.com
Mon Feb 12 09:16:53 UTC 2018
On Wed, Feb 7, 2018 at 3:32 AM, Felix Kuehling <Felix.Kuehling at amd.com> wrote:
> Create/destroy the GPUVM context during PDD creation/destruction.
> Get VM page table base and program it during process registration
> (HWS) or VMID allocation (non-HWS).
>
> v2:
> * Used dev instead of pdd->dev in kfd_flush_tlb
>
> Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
> .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 20 +++++++++++++
> drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 13 +++++++++
> drivers/gpu/drm/amd/amdkfd/kfd_process.c | 33 ++++++++++++++++++++++
> 3 files changed, 66 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> index 1a28dc2..b7d0639 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -129,6 +129,15 @@ static int allocate_vmid(struct device_queue_manager *dqm,
> set_pasid_vmid_mapping(dqm, q->process->pasid, q->properties.vmid);
> program_sh_mem_settings(dqm, qpd);
>
> + /* qpd->page_table_base is set earlier when register_process()
> + * is called, i.e. when the first queue is created.
> + */
> + dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->kgd,
> + qpd->vmid,
> + qpd->page_table_base);
> + /* invalidate the VM context after pasid and vmid mapping is set up */
> + kfd_flush_tlb(qpd_to_pdd(qpd));
> +
> return 0;
> }
>
> @@ -138,6 +147,8 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
> {
> int bit = qpd->vmid - dqm->dev->vm_info.first_vmid_kfd;
>
> + kfd_flush_tlb(qpd_to_pdd(qpd));
> +
> /* Release the vmid mapping */
> set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
>
> @@ -450,6 +461,8 @@ static int register_process(struct device_queue_manager *dqm,
> struct qcm_process_device *qpd)
> {
> struct device_process_node *n;
> + struct kfd_process_device *pdd;
> + uint32_t pd_base;
> int retval;
>
> n = kzalloc(sizeof(*n), GFP_KERNEL);
> @@ -458,9 +471,16 @@ static int register_process(struct device_queue_manager *dqm,
>
> n->qpd = qpd;
>
> + pdd = qpd_to_pdd(qpd);
> + /* Retrieve PD base */
> + pd_base = dqm->dev->kfd2kgd->get_process_page_dir(pdd->vm);
> +
> mutex_lock(&dqm->lock);
> list_add(&n->list, &dqm->queues);
>
> + /* Update PD Base in QPD */
> + qpd->page_table_base = pd_base;
> +
> retval = dqm->asic_ops.update_qpd(dqm, qpd);
>
> dqm->processes_count++;
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> index f12eb5d..56c2e36 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> @@ -518,6 +518,9 @@ struct kfd_process_device {
> uint64_t scratch_base;
> uint64_t scratch_limit;
>
> + /* VM context for GPUVM allocations */
> + void *vm;
> +
> /* Flag used to tell the pdd has dequeued from the dqm.
> * This is used to prevent dev->dqm->ops.process_termination() from
> * being called twice when it is already called in IOMMU callback
> @@ -589,6 +592,14 @@ struct kfd_process {
> size_t signal_mapped_size;
> size_t signal_event_count;
> bool signal_event_limit_reached;
> +
> + /* Information used for memory eviction */
> + void *kgd_process_info;
> + /* Eviction fence that is attached to all the BOs of this process. The
> + * fence will be triggered during eviction and new one will be created
> + * during restore
> + */
> + struct dma_fence *ef;
> };
>
> #define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
> @@ -802,6 +813,8 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p,
> uint64_t *event_page_offset, uint32_t *event_slot_index);
> int kfd_event_destroy(struct kfd_process *p, uint32_t event_id);
>
> +void kfd_flush_tlb(struct kfd_process_device *pdd);
> +
> int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p);
>
> /* Debugfs */
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> index e9aee76..cf4fa25 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> @@ -34,6 +34,7 @@
> struct mm_struct;
>
> #include "kfd_priv.h"
> +#include "kfd_device_queue_manager.h"
> #include "kfd_dbgmgr.h"
> #include "kfd_iommu.h"
>
> @@ -154,6 +155,10 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
> pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
> pdd->dev->id, p->pasid);
>
> + if (pdd->vm)
> + pdd->dev->kfd2kgd->destroy_process_vm(
> + pdd->dev->kgd, pdd->vm);
> +
> list_del(&pdd->per_device_list);
>
> if (pdd->qpd.cwsr_kaddr)
> @@ -177,6 +182,7 @@ static void kfd_process_wq_release(struct work_struct *work)
> kfd_iommu_unbind_process(p);
>
> kfd_process_destroy_pdds(p);
> + dma_fence_put(p->ef);
>
> kfd_event_free_process(p);
>
> @@ -401,7 +407,18 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
> pdd->already_dequeued = false;
> list_add(&pdd->per_device_list, &p->per_device_data);
>
> + /* Create the GPUVM context for this specific device */
> + if (dev->kfd2kgd->create_process_vm(dev->kgd, &pdd->vm,
> + &p->kgd_process_info, &p->ef)) {
> + pr_err("Failed to create process VM object\n");
> + goto err_create_pdd;
> + }
> return pdd;
> +
> +err_create_pdd:
> + list_del(&pdd->per_device_list);
> + kfree(pdd);
> + return NULL;
> }
>
> /*
> @@ -507,6 +524,22 @@ int kfd_reserved_mem_mmap(struct kfd_process *process,
> KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot);
> }
>
> +void kfd_flush_tlb(struct kfd_process_device *pdd)
> +{
> + struct kfd_dev *dev = pdd->dev;
> + const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
> +
> + if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
> + /* Nothing to flush until a VMID is assigned, which
> + * only happens when the first queue is created.
> + */
> + if (pdd->qpd.vmid)
> + f2g->invalidate_tlbs_vmid(dev->kgd, pdd->qpd.vmid);
> + } else {
> + f2g->invalidate_tlbs(dev->kgd, pdd->process->pasid);
> + }
> +}
> +
> #if defined(CONFIG_DEBUG_FS)
>
> int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)
> --
> 2.7.4
>
This patch is:
Acked-by: Oded Gabbay <oded.gabbay at gmail.com>
More information about the amd-gfx
mailing list