aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2018-02-06 20:32:44 -0500
committerOded Gabbay <oded.gabbay@gmail.com>2018-02-06 20:32:44 -0500
commit403575c44e61722ae443b47df66e188b367d7324 (patch)
treea12e3a6e8770068e58363cb9076346fe9a9600b3
parent4252bf686622f6c71958c4fabbcb6a64deba1cf7 (diff)
drm/amdkfd: Add GPUVM virtual address space to PDD
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@amd.com> Acked-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c20
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h13
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c33
3 files changed, 66 insertions, 0 deletions
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 1a28dc2c661e..b7d06395d592 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,
129 set_pasid_vmid_mapping(dqm, q->process->pasid, q->properties.vmid); 129 set_pasid_vmid_mapping(dqm, q->process->pasid, q->properties.vmid);
130 program_sh_mem_settings(dqm, qpd); 130 program_sh_mem_settings(dqm, qpd);
131 131
132 /* qpd->page_table_base is set earlier when register_process()
133 * is called, i.e. when the first queue is created.
134 */
135 dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->kgd,
136 qpd->vmid,
137 qpd->page_table_base);
138 /* invalidate the VM context after pasid and vmid mapping is set up */
139 kfd_flush_tlb(qpd_to_pdd(qpd));
140
132 return 0; 141 return 0;
133} 142}
134 143
@@ -138,6 +147,8 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
138{ 147{
139 int bit = qpd->vmid - dqm->dev->vm_info.first_vmid_kfd; 148 int bit = qpd->vmid - dqm->dev->vm_info.first_vmid_kfd;
140 149
150 kfd_flush_tlb(qpd_to_pdd(qpd));
151
141 /* Release the vmid mapping */ 152 /* Release the vmid mapping */
142 set_pasid_vmid_mapping(dqm, 0, qpd->vmid); 153 set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
143 154
@@ -450,6 +461,8 @@ static int register_process(struct device_queue_manager *dqm,
450 struct qcm_process_device *qpd) 461 struct qcm_process_device *qpd)
451{ 462{
452 struct device_process_node *n; 463 struct device_process_node *n;
464 struct kfd_process_device *pdd;
465 uint32_t pd_base;
453 int retval; 466 int retval;
454 467
455 n = kzalloc(sizeof(*n), GFP_KERNEL); 468 n = kzalloc(sizeof(*n), GFP_KERNEL);
@@ -458,9 +471,16 @@ static int register_process(struct device_queue_manager *dqm,
458 471
459 n->qpd = qpd; 472 n->qpd = qpd;
460 473
474 pdd = qpd_to_pdd(qpd);
475 /* Retrieve PD base */
476 pd_base = dqm->dev->kfd2kgd->get_process_page_dir(pdd->vm);
477
461 mutex_lock(&dqm->lock); 478 mutex_lock(&dqm->lock);
462 list_add(&n->list, &dqm->queues); 479 list_add(&n->list, &dqm->queues);
463 480
481 /* Update PD Base in QPD */
482 qpd->page_table_base = pd_base;
483
464 retval = dqm->asic_ops.update_qpd(dqm, qpd); 484 retval = dqm->asic_ops.update_qpd(dqm, qpd);
465 485
466 dqm->processes_count++; 486 dqm->processes_count++;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index f12eb5d98be8..56c2e368f702 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 {
518 uint64_t scratch_base; 518 uint64_t scratch_base;
519 uint64_t scratch_limit; 519 uint64_t scratch_limit;
520 520
521 /* VM context for GPUVM allocations */
522 void *vm;
523
521 /* Flag used to tell the pdd has dequeued from the dqm. 524 /* Flag used to tell the pdd has dequeued from the dqm.
522 * This is used to prevent dev->dqm->ops.process_termination() from 525 * This is used to prevent dev->dqm->ops.process_termination() from
523 * being called twice when it is already called in IOMMU callback 526 * being called twice when it is already called in IOMMU callback
@@ -589,6 +592,14 @@ struct kfd_process {
589 size_t signal_mapped_size; 592 size_t signal_mapped_size;
590 size_t signal_event_count; 593 size_t signal_event_count;
591 bool signal_event_limit_reached; 594 bool signal_event_limit_reached;
595
596 /* Information used for memory eviction */
597 void *kgd_process_info;
598 /* Eviction fence that is attached to all the BOs of this process. The
599 * fence will be triggered during eviction and new one will be created
600 * during restore
601 */
602 struct dma_fence *ef;
592}; 603};
593 604
594#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */ 605#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
@@ -802,6 +813,8 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p,
802 uint64_t *event_page_offset, uint32_t *event_slot_index); 813 uint64_t *event_page_offset, uint32_t *event_slot_index);
803int kfd_event_destroy(struct kfd_process *p, uint32_t event_id); 814int kfd_event_destroy(struct kfd_process *p, uint32_t event_id);
804 815
816void kfd_flush_tlb(struct kfd_process_device *pdd);
817
805int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p); 818int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p);
806 819
807/* Debugfs */ 820/* Debugfs */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index e9aee76ceba9..cf4fa25cc430 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -34,6 +34,7 @@
34struct mm_struct; 34struct mm_struct;
35 35
36#include "kfd_priv.h" 36#include "kfd_priv.h"
37#include "kfd_device_queue_manager.h"
37#include "kfd_dbgmgr.h" 38#include "kfd_dbgmgr.h"
38#include "kfd_iommu.h" 39#include "kfd_iommu.h"
39 40
@@ -154,6 +155,10 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
154 pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n", 155 pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
155 pdd->dev->id, p->pasid); 156 pdd->dev->id, p->pasid);
156 157
158 if (pdd->vm)
159 pdd->dev->kfd2kgd->destroy_process_vm(
160 pdd->dev->kgd, pdd->vm);
161
157 list_del(&pdd->per_device_list); 162 list_del(&pdd->per_device_list);
158 163
159 if (pdd->qpd.cwsr_kaddr) 164 if (pdd->qpd.cwsr_kaddr)
@@ -177,6 +182,7 @@ static void kfd_process_wq_release(struct work_struct *work)
177 kfd_iommu_unbind_process(p); 182 kfd_iommu_unbind_process(p);
178 183
179 kfd_process_destroy_pdds(p); 184 kfd_process_destroy_pdds(p);
185 dma_fence_put(p->ef);
180 186
181 kfd_event_free_process(p); 187 kfd_event_free_process(p);
182 188
@@ -401,7 +407,18 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
401 pdd->already_dequeued = false; 407 pdd->already_dequeued = false;
402 list_add(&pdd->per_device_list, &p->per_device_data); 408 list_add(&pdd->per_device_list, &p->per_device_data);
403 409
410 /* Create the GPUVM context for this specific device */
411 if (dev->kfd2kgd->create_process_vm(dev->kgd, &pdd->vm,
412 &p->kgd_process_info, &p->ef)) {
413 pr_err("Failed to create process VM object\n");
414 goto err_create_pdd;
415 }
404 return pdd; 416 return pdd;
417
418err_create_pdd:
419 list_del(&pdd->per_device_list);
420 kfree(pdd);
421 return NULL;
405} 422}
406 423
407/* 424/*
@@ -507,6 +524,22 @@ int kfd_reserved_mem_mmap(struct kfd_process *process,
507 KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot); 524 KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot);
508} 525}
509 526
527void kfd_flush_tlb(struct kfd_process_device *pdd)
528{
529 struct kfd_dev *dev = pdd->dev;
530 const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
531
532 if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
533 /* Nothing to flush until a VMID is assigned, which
534 * only happens when the first queue is created.
535 */
536 if (pdd->qpd.vmid)
537 f2g->invalidate_tlbs_vmid(dev->kgd, pdd->qpd.vmid);
538 } else {
539 f2g->invalidate_tlbs(dev->kgd, pdd->process->pasid);
540 }
541}
542
510#if defined(CONFIG_DEBUG_FS) 543#if defined(CONFIG_DEBUG_FS)
511 544
512int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data) 545int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)