From e5fd91f1ef340da553f7a79da9540c3db711c937 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Tue, 8 Sep 2015 01:01:14 -0300 Subject: Linux-libre 4.2-gnu --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 58 +++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/amdkfd/kfd_process.c') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 945d6226d..9be007081 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -31,6 +31,7 @@ struct mm_struct; #include "kfd_priv.h" +#include "kfd_dbgmgr.h" /* * Initial size for the array of queues. @@ -172,12 +173,17 @@ static void kfd_process_wq_release(struct work_struct *work) pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n", pdd->dev->id, p->pasid); + if (pdd->reset_wavefronts) + dbgdev_wave_reset_wavefronts(pdd->dev, p); + amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); list_del(&pdd->per_device_list); kfree(pdd); } + kfd_event_free_process(p); + kfd_pasid_free(p->pasid); mutex_unlock(&p->mutex); @@ -203,8 +209,7 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu) mmdrop(p->mm); - work = (struct kfd_process_release_work *) - kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC); + work = kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC); if (work) { INIT_WORK((struct work_struct *) work, kfd_process_wq_release); @@ -217,6 +222,7 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, struct mm_struct *mm) { struct kfd_process *p; + struct kfd_process_device *pdd = NULL; /* * The kfd_process structure can not be free because the @@ -235,6 +241,15 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, /* In case our notifier is called before IOMMU notifier */ pqm_uninit(&p->pqm); + /* Iterate over all process device data structure and check + * if we should reset all wavefronts */ + list_for_each_entry(pdd, &p->per_device_data, per_device_list) + if (pdd->reset_wavefronts) { + pr_warn("amdkfd: Resetting all wave fronts\n"); + dbgdev_wave_reset_wavefronts(pdd->dev, p); + pdd->reset_wavefronts = false; + } + mutex_unlock(&p->mutex); /* @@ -289,6 +304,8 @@ static struct kfd_process *create_process(const struct task_struct *thread) INIT_LIST_HEAD(&process->per_device_data); + kfd_event_init_process(process); + err = pqm_init(&process->pqm, process); if (err != 0) goto err_process_pqm_init; @@ -339,6 +356,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, INIT_LIST_HEAD(&pdd->qpd.queues_list); INIT_LIST_HEAD(&pdd->qpd.priv_queue_list); pdd->qpd.dqm = dev->dqm; + pdd->reset_wavefronts = false; list_add(&pdd->per_device_list, &p->per_device_data); } @@ -396,18 +414,30 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) mutex_lock(&p->mutex); + if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) + kfd_dbgmgr_destroy(dev->dbgmgr); + pqm_uninit(&p->pqm); pdd = kfd_get_process_device_data(dev, p); + if (!pdd) { + mutex_unlock(&p->mutex); + return; + } + + if (pdd->reset_wavefronts) { + dbgdev_wave_reset_wavefronts(pdd->dev, p); + pdd->reset_wavefronts = false; + } + /* * Just mark pdd as unbound, because we still need it to call * amd_iommu_unbind_pasid() in when the process exits. * We don't call amd_iommu_unbind_pasid() here * because the IOMMU called us. */ - if (pdd) - pdd->bound = false; + pdd->bound = false; mutex_unlock(&p->mutex); } @@ -431,3 +461,23 @@ bool kfd_has_process_device_data(struct kfd_process *p) { return !(list_empty(&p->per_device_data)); } + +/* This returns with process->mutex locked. */ +struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid) +{ + struct kfd_process *p; + unsigned int temp; + + int idx = srcu_read_lock(&kfd_processes_srcu); + + hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) { + if (p->pasid == pasid) { + mutex_lock(&p->mutex); + break; + } + } + + srcu_read_unlock(&kfd_processes_srcu, idx); + + return p; +} -- cgit v1.2.3-54-g00ecf