Home | History | Annotate | Line # | Download | only in amdkfd
kfd_process.c revision 1.2
      1 /*	$NetBSD: kfd_process.c,v 1.2 2018/08/27 04:58:20 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2014 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: kfd_process.c,v 1.2 2018/08/27 04:58:20 riastradh Exp $");
     27 
     28 #include <linux/mutex.h>
     29 #include <linux/log2.h>
     30 #include <linux/sched.h>
     31 #include <linux/slab.h>
     32 #include <linux/amd-iommu.h>
     33 #include <linux/notifier.h>
     34 #include <linux/compat.h>
     35 
     36 struct mm_struct;
     37 
     38 #include "kfd_priv.h"
     39 #include "kfd_dbgmgr.h"
     40 
     41 /*
     42  * Initial size for the array of queues.
     43  * The allocated size is doubled each time
     44  * it is exceeded up to MAX_PROCESS_QUEUES.
     45  */
     46 #define INITIAL_QUEUE_ARRAY_SIZE 16
     47 
     48 /*
     49  * List of struct kfd_process (field kfd_process).
     50  * Unique/indexed by mm_struct*
     51  */
     52 #define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
     53 static DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE);
     54 static DEFINE_MUTEX(kfd_processes_mutex);
     55 
     56 DEFINE_STATIC_SRCU(kfd_processes_srcu);
     57 
     58 static struct workqueue_struct *kfd_process_wq;
     59 
     60 struct kfd_process_release_work {
     61 	struct work_struct kfd_work;
     62 	struct kfd_process *p;
     63 };
     64 
     65 static struct kfd_process *find_process(const struct task_struct *thread);
     66 static struct kfd_process *create_process(const struct task_struct *thread);
     67 
     68 void kfd_process_create_wq(void)
     69 {
     70 	if (!kfd_process_wq)
     71 		kfd_process_wq = create_workqueue("kfd_process_wq");
     72 }
     73 
     74 void kfd_process_destroy_wq(void)
     75 {
     76 	if (kfd_process_wq) {
     77 		flush_workqueue(kfd_process_wq);
     78 		destroy_workqueue(kfd_process_wq);
     79 		kfd_process_wq = NULL;
     80 	}
     81 }
     82 
     83 struct kfd_process *kfd_create_process(const struct task_struct *thread)
     84 {
     85 	struct kfd_process *process;
     86 
     87 	BUG_ON(!kfd_process_wq);
     88 
     89 	if (thread->mm == NULL)
     90 		return ERR_PTR(-EINVAL);
     91 
     92 	/* Only the pthreads threading model is supported. */
     93 	if (thread->group_leader->mm != thread->mm)
     94 		return ERR_PTR(-EINVAL);
     95 
     96 	/* Take mmap_sem because we call __mmu_notifier_register inside */
     97 	down_write(&thread->mm->mmap_sem);
     98 
     99 	/*
    100 	 * take kfd processes mutex before starting of process creation
    101 	 * so there won't be a case where two threads of the same process
    102 	 * create two kfd_process structures
    103 	 */
    104 	mutex_lock(&kfd_processes_mutex);
    105 
    106 	/* A prior open of /dev/kfd could have already created the process. */
    107 	process = find_process(thread);
    108 	if (process)
    109 		pr_debug("kfd: process already found\n");
    110 
    111 	if (!process)
    112 		process = create_process(thread);
    113 
    114 	mutex_unlock(&kfd_processes_mutex);
    115 
    116 	up_write(&thread->mm->mmap_sem);
    117 
    118 	return process;
    119 }
    120 
    121 struct kfd_process *kfd_get_process(const struct task_struct *thread)
    122 {
    123 	struct kfd_process *process;
    124 
    125 	if (thread->mm == NULL)
    126 		return ERR_PTR(-EINVAL);
    127 
    128 	/* Only the pthreads threading model is supported. */
    129 	if (thread->group_leader->mm != thread->mm)
    130 		return ERR_PTR(-EINVAL);
    131 
    132 	process = find_process(thread);
    133 
    134 	return process;
    135 }
    136 
    137 static struct kfd_process *find_process_by_mm(const struct mm_struct *mm)
    138 {
    139 	struct kfd_process *process;
    140 
    141 	hash_for_each_possible_rcu(kfd_processes_table, process,
    142 					kfd_processes, (uintptr_t)mm)
    143 		if (process->mm == mm)
    144 			return process;
    145 
    146 	return NULL;
    147 }
    148 
    149 static struct kfd_process *find_process(const struct task_struct *thread)
    150 {
    151 	struct kfd_process *p;
    152 	int idx;
    153 
    154 	idx = srcu_read_lock(&kfd_processes_srcu);
    155 	p = find_process_by_mm(thread->mm);
    156 	srcu_read_unlock(&kfd_processes_srcu, idx);
    157 
    158 	return p;
    159 }
    160 
    161 static void kfd_process_wq_release(struct work_struct *work)
    162 {
    163 	struct kfd_process_release_work *my_work;
    164 	struct kfd_process_device *pdd, *temp;
    165 	struct kfd_process *p;
    166 
    167 	my_work = (struct kfd_process_release_work *) work;
    168 
    169 	p = my_work->p;
    170 
    171 	pr_debug("Releasing process (pasid %d) in workqueue\n",
    172 			p->pasid);
    173 
    174 	mutex_lock(&p->mutex);
    175 
    176 	list_for_each_entry_safe(pdd, temp, &p->per_device_data,
    177 							per_device_list) {
    178 		pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n",
    179 				pdd->dev->id, p->pasid);
    180 
    181 		if (pdd->reset_wavefronts)
    182 			dbgdev_wave_reset_wavefronts(pdd->dev, p);
    183 
    184 		amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
    185 		list_del(&pdd->per_device_list);
    186 
    187 		kfree(pdd);
    188 	}
    189 
    190 	kfd_event_free_process(p);
    191 
    192 	kfd_pasid_free(p->pasid);
    193 
    194 	mutex_unlock(&p->mutex);
    195 
    196 	mutex_destroy(&p->mutex);
    197 
    198 	kfree(p->queues);
    199 
    200 	kfree(p);
    201 
    202 	kfree((void *)work);
    203 }
    204 
    205 static void kfd_process_destroy_delayed(struct rcu_head *rcu)
    206 {
    207 	struct kfd_process_release_work *work;
    208 	struct kfd_process *p;
    209 
    210 	BUG_ON(!kfd_process_wq);
    211 
    212 	p = container_of(rcu, struct kfd_process, rcu);
    213 	BUG_ON(atomic_read(&p->mm->mm_count) <= 0);
    214 
    215 	mmdrop(p->mm);
    216 
    217 	work = kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC);
    218 
    219 	if (work) {
    220 		INIT_WORK((struct work_struct *) work, kfd_process_wq_release);
    221 		work->p = p;
    222 		queue_work(kfd_process_wq, (struct work_struct *) work);
    223 	}
    224 }
    225 
    226 static void kfd_process_notifier_release(struct mmu_notifier *mn,
    227 					struct mm_struct *mm)
    228 {
    229 	struct kfd_process *p;
    230 	struct kfd_process_device *pdd = NULL;
    231 
    232 	/*
    233 	 * The kfd_process structure can not be free because the
    234 	 * mmu_notifier srcu is read locked
    235 	 */
    236 	p = container_of(mn, struct kfd_process, mmu_notifier);
    237 	BUG_ON(p->mm != mm);
    238 
    239 	mutex_lock(&kfd_processes_mutex);
    240 	hash_del_rcu(&p->kfd_processes);
    241 	mutex_unlock(&kfd_processes_mutex);
    242 	synchronize_srcu(&kfd_processes_srcu);
    243 
    244 	mutex_lock(&p->mutex);
    245 
    246 	/* In case our notifier is called before IOMMU notifier */
    247 	pqm_uninit(&p->pqm);
    248 
    249 	/* Iterate over all process device data structure and check
    250 	 * if we should delete debug managers and reset all wavefronts
    251 	 */
    252 	list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
    253 		if ((pdd->dev->dbgmgr) &&
    254 				(pdd->dev->dbgmgr->pasid == p->pasid))
    255 			kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
    256 
    257 		if (pdd->reset_wavefronts) {
    258 			pr_warn("amdkfd: Resetting all wave fronts\n");
    259 			dbgdev_wave_reset_wavefronts(pdd->dev, p);
    260 			pdd->reset_wavefronts = false;
    261 		}
    262 	}
    263 
    264 	mutex_unlock(&p->mutex);
    265 
    266 	/*
    267 	 * Because we drop mm_count inside kfd_process_destroy_delayed
    268 	 * and because the mmu_notifier_unregister function also drop
    269 	 * mm_count we need to take an extra count here.
    270 	 */
    271 	atomic_inc(&p->mm->mm_count);
    272 	mmu_notifier_unregister_no_release(&p->mmu_notifier, p->mm);
    273 	mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed);
    274 }
    275 
    276 static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
    277 	.release = kfd_process_notifier_release,
    278 };
    279 
    280 static struct kfd_process *create_process(const struct task_struct *thread)
    281 {
    282 	struct kfd_process *process;
    283 	int err = -ENOMEM;
    284 
    285 	process = kzalloc(sizeof(*process), GFP_KERNEL);
    286 
    287 	if (!process)
    288 		goto err_alloc_process;
    289 
    290 	process->queues = kmalloc_array(INITIAL_QUEUE_ARRAY_SIZE,
    291 					sizeof(process->queues[0]), GFP_KERNEL);
    292 	if (!process->queues)
    293 		goto err_alloc_queues;
    294 
    295 	process->pasid = kfd_pasid_alloc();
    296 	if (process->pasid == 0)
    297 		goto err_alloc_pasid;
    298 
    299 	mutex_init(&process->mutex);
    300 
    301 	process->mm = thread->mm;
    302 
    303 	/* register notifier */
    304 	process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops;
    305 	err = __mmu_notifier_register(&process->mmu_notifier, process->mm);
    306 	if (err)
    307 		goto err_mmu_notifier;
    308 
    309 	hash_add_rcu(kfd_processes_table, &process->kfd_processes,
    310 			(uintptr_t)process->mm);
    311 
    312 	process->lead_thread = thread->group_leader;
    313 
    314 	process->queue_array_size = INITIAL_QUEUE_ARRAY_SIZE;
    315 
    316 	INIT_LIST_HEAD(&process->per_device_data);
    317 
    318 	kfd_event_init_process(process);
    319 
    320 	err = pqm_init(&process->pqm, process);
    321 	if (err != 0)
    322 		goto err_process_pqm_init;
    323 
    324 	/* init process apertures*/
    325 	process->is_32bit_user_mode = is_compat_task();
    326 	if (kfd_init_apertures(process) != 0)
    327 		goto err_init_apretures;
    328 
    329 	return process;
    330 
    331 err_init_apretures:
    332 	pqm_uninit(&process->pqm);
    333 err_process_pqm_init:
    334 	hash_del_rcu(&process->kfd_processes);
    335 	synchronize_rcu();
    336 	mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm);
    337 err_mmu_notifier:
    338 	kfd_pasid_free(process->pasid);
    339 err_alloc_pasid:
    340 	kfree(process->queues);
    341 err_alloc_queues:
    342 	kfree(process);
    343 err_alloc_process:
    344 	return ERR_PTR(err);
    345 }
    346 
    347 struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
    348 							struct kfd_process *p)
    349 {
    350 	struct kfd_process_device *pdd = NULL;
    351 
    352 	list_for_each_entry(pdd, &p->per_device_data, per_device_list)
    353 		if (pdd->dev == dev)
    354 			break;
    355 
    356 	return pdd;
    357 }
    358 
    359 struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
    360 							struct kfd_process *p)
    361 {
    362 	struct kfd_process_device *pdd = NULL;
    363 
    364 	pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
    365 	if (pdd != NULL) {
    366 		pdd->dev = dev;
    367 		INIT_LIST_HEAD(&pdd->qpd.queues_list);
    368 		INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
    369 		pdd->qpd.dqm = dev->dqm;
    370 		pdd->reset_wavefronts = false;
    371 		list_add(&pdd->per_device_list, &p->per_device_data);
    372 	}
    373 
    374 	return pdd;
    375 }
    376 
    377 /*
    378  * Direct the IOMMU to bind the process (specifically the pasid->mm)
    379  * to the device.
    380  * Unbinding occurs when the process dies or the device is removed.
    381  *
    382  * Assumes that the process lock is held.
    383  */
    384 struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
    385 							struct kfd_process *p)
    386 {
    387 	struct kfd_process_device *pdd;
    388 	int err;
    389 
    390 	pdd = kfd_get_process_device_data(dev, p);
    391 	if (!pdd) {
    392 		pr_err("Process device data doesn't exist\n");
    393 		return ERR_PTR(-ENOMEM);
    394 	}
    395 
    396 	if (pdd->bound)
    397 		return pdd;
    398 
    399 	err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread);
    400 	if (err < 0)
    401 		return ERR_PTR(err);
    402 
    403 	pdd->bound = true;
    404 
    405 	return pdd;
    406 }
    407 
    408 void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
    409 {
    410 	struct kfd_process *p;
    411 	struct kfd_process_device *pdd;
    412 	int idx, i;
    413 
    414 	BUG_ON(dev == NULL);
    415 
    416 	idx = srcu_read_lock(&kfd_processes_srcu);
    417 
    418 	/*
    419 	 * Look for the process that matches the pasid. If there is no such
    420 	 * process, we either released it in amdkfd's own notifier, or there
    421 	 * is a bug. Unfortunately, there is no way to tell...
    422 	 */
    423 	hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
    424 		if (p->pasid == pasid) {
    425 
    426 			srcu_read_unlock(&kfd_processes_srcu, idx);
    427 
    428 			pr_debug("Unbinding process %d from IOMMU\n", pasid);
    429 
    430 			mutex_lock(&p->mutex);
    431 
    432 			if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
    433 				kfd_dbgmgr_destroy(dev->dbgmgr);
    434 
    435 			pqm_uninit(&p->pqm);
    436 
    437 			pdd = kfd_get_process_device_data(dev, p);
    438 
    439 			if (!pdd) {
    440 				mutex_unlock(&p->mutex);
    441 				return;
    442 			}
    443 
    444 			if (pdd->reset_wavefronts) {
    445 				dbgdev_wave_reset_wavefronts(pdd->dev, p);
    446 				pdd->reset_wavefronts = false;
    447 			}
    448 
    449 			/*
    450 			 * Just mark pdd as unbound, because we still need it
    451 			 * to call amd_iommu_unbind_pasid() in when the
    452 			 * process exits.
    453 			 * We don't call amd_iommu_unbind_pasid() here
    454 			 * because the IOMMU called us.
    455 			 */
    456 			pdd->bound = false;
    457 
    458 			mutex_unlock(&p->mutex);
    459 
    460 			return;
    461 		}
    462 
    463 	srcu_read_unlock(&kfd_processes_srcu, idx);
    464 }
    465 
    466 struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
    467 {
    468 	return list_first_entry(&p->per_device_data,
    469 				struct kfd_process_device,
    470 				per_device_list);
    471 }
    472 
    473 struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
    474 						struct kfd_process_device *pdd)
    475 {
    476 	if (list_is_last(&pdd->per_device_list, &p->per_device_data))
    477 		return NULL;
    478 	return list_next_entry(pdd, per_device_list);
    479 }
    480 
    481 bool kfd_has_process_device_data(struct kfd_process *p)
    482 {
    483 	return !(list_empty(&p->per_device_data));
    484 }
    485 
    486 /* This returns with process->mutex locked. */
    487 struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid)
    488 {
    489 	struct kfd_process *p;
    490 	unsigned int temp;
    491 
    492 	int idx = srcu_read_lock(&kfd_processes_srcu);
    493 
    494 	hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
    495 		if (p->pasid == pasid) {
    496 			mutex_lock(&p->mutex);
    497 			break;
    498 		}
    499 	}
    500 
    501 	srcu_read_unlock(&kfd_processes_srcu, idx);
    502 
    503 	return p;
    504 }
    505