blob: a2ae0236a3ea1bb806f7e1ed5f5c909e66e68035 [file] [log] [blame]
Oded Gabbay19f6d2a2014-07-16 23:25:31 +03001/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#include <linux/mutex.h>
24#include <linux/log2.h>
25#include <linux/sched.h>
Ingo Molnar6e84f312017-02-08 18:51:29 +010026#include <linux/sched/mm.h>
Felix Kuehlingc7b12432017-11-27 18:29:50 -050027#include <linux/sched/task.h>
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030028#include <linux/slab.h>
Oded Gabbayb17f0682014-07-17 00:06:27 +030029#include <linux/amd-iommu.h>
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030030#include <linux/notifier.h>
Alexey Skidanovdd592392014-11-18 13:56:23 +020031#include <linux/compat.h>
Felix Kuehling373d7082017-11-14 16:41:19 -050032#include <linux/mman.h>
Felix Kuehlingb84394e2018-03-15 17:27:44 -040033#include <linux/file.h>
Alexey Skidanovdd592392014-11-18 13:56:23 +020034
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030035struct mm_struct;
36
37#include "kfd_priv.h"
Felix Kuehling403575c2018-02-06 20:32:44 -050038#include "kfd_device_queue_manager.h"
Ben Gozc3447e82015-05-20 18:05:44 +030039#include "kfd_dbgmgr.h"
Felix Kuehling64d1c3a2017-12-08 19:22:12 -050040#include "kfd_iommu.h"
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030041
42/*
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030043 * List of struct kfd_process (field kfd_process).
44 * Unique/indexed by mm_struct*
45 */
Felix Kuehling64d1c3a2017-12-08 19:22:12 -050046DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030047static DEFINE_MUTEX(kfd_processes_mutex);
48
Felix Kuehling64d1c3a2017-12-08 19:22:12 -050049DEFINE_SRCU(kfd_processes_srcu);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030050
51static struct workqueue_struct *kfd_process_wq;
52
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030053static struct kfd_process *find_process(const struct task_struct *thread);
Felix Kuehlingabb208a2017-11-27 18:29:52 -050054static void kfd_process_ref_release(struct kref *ref);
Yong Zhaoc0ede1f2017-11-27 18:29:56 -050055static struct kfd_process *create_process(const struct task_struct *thread,
56 struct file *filep);
Felix Kuehling373d7082017-11-14 16:41:19 -050057static int kfd_process_init_cwsr(struct kfd_process *p, struct file *filep);
58
Felix Kuehling26103432018-02-06 20:32:45 -050059static void evict_process_worker(struct work_struct *work);
60static void restore_process_worker(struct work_struct *work);
61
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030062
63void kfd_process_create_wq(void)
64{
65 if (!kfd_process_wq)
Bhaktipriya Shridharfd320bf2016-05-29 21:14:11 +053066 kfd_process_wq = alloc_workqueue("kfd_process_wq", 0, 0);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030067}
68
69void kfd_process_destroy_wq(void)
70{
71 if (kfd_process_wq) {
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030072 destroy_workqueue(kfd_process_wq);
73 kfd_process_wq = NULL;
74 }
75}
76
Felix Kuehling373d7082017-11-14 16:41:19 -050077struct kfd_process *kfd_create_process(struct file *filep)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030078{
79 struct kfd_process *process;
Felix Kuehling373d7082017-11-14 16:41:19 -050080 struct task_struct *thread = current;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030081
Kent Russell4eacc26b2017-08-15 23:00:06 -040082 if (!thread->mm)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030083 return ERR_PTR(-EINVAL);
84
85 /* Only the pthreads threading model is supported. */
86 if (thread->group_leader->mm != thread->mm)
87 return ERR_PTR(-EINVAL);
88
Oded Gabbay19f6d2a2014-07-16 23:25:31 +030089 /*
90 * take kfd processes mutex before starting of process creation
91 * so there won't be a case where two threads of the same process
92 * create two kfd_process structures
93 */
94 mutex_lock(&kfd_processes_mutex);
95
96 /* A prior open of /dev/kfd could have already created the process. */
97 process = find_process(thread);
98 if (process)
Kent Russell79775b62017-08-15 23:00:05 -040099 pr_debug("Process already found\n");
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500100 else
101 process = create_process(thread, filep);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300102
103 mutex_unlock(&kfd_processes_mutex);
104
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300105 return process;
106}
107
108struct kfd_process *kfd_get_process(const struct task_struct *thread)
109{
110 struct kfd_process *process;
111
Kent Russell4eacc26b2017-08-15 23:00:06 -0400112 if (!thread->mm)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300113 return ERR_PTR(-EINVAL);
114
115 /* Only the pthreads threading model is supported. */
116 if (thread->group_leader->mm != thread->mm)
117 return ERR_PTR(-EINVAL);
118
119 process = find_process(thread);
120
121 return process;
122}
123
124static struct kfd_process *find_process_by_mm(const struct mm_struct *mm)
125{
126 struct kfd_process *process;
127
128 hash_for_each_possible_rcu(kfd_processes_table, process,
129 kfd_processes, (uintptr_t)mm)
130 if (process->mm == mm)
131 return process;
132
133 return NULL;
134}
135
136static struct kfd_process *find_process(const struct task_struct *thread)
137{
138 struct kfd_process *p;
139 int idx;
140
141 idx = srcu_read_lock(&kfd_processes_srcu);
142 p = find_process_by_mm(thread->mm);
143 srcu_read_unlock(&kfd_processes_srcu, idx);
144
145 return p;
146}
147
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500148void kfd_unref_process(struct kfd_process *p)
149{
150 kref_put(&p->ref, kfd_process_ref_release);
151}
152
Felix Kuehling52b29d72018-03-15 17:27:48 -0400153static void kfd_process_device_free_bos(struct kfd_process_device *pdd)
154{
155 struct kfd_process *p = pdd->process;
156 void *mem;
157 int id;
158
159 /*
160 * Remove all handles from idr and release appropriate
161 * local memory object
162 */
163 idr_for_each_entry(&pdd->alloc_idr, mem, id) {
164 struct kfd_process_device *peer_pdd;
165
166 list_for_each_entry(peer_pdd, &p->per_device_data,
167 per_device_list) {
168 if (!peer_pdd->vm)
169 continue;
170 peer_pdd->dev->kfd2kgd->unmap_memory_to_gpu(
171 peer_pdd->dev->kgd, mem, peer_pdd->vm);
172 }
173
174 pdd->dev->kfd2kgd->free_memory_of_gpu(pdd->dev->kgd, mem);
175 kfd_process_device_remove_obj_handle(pdd, id);
176 }
177}
178
179static void kfd_process_free_outstanding_kfd_bos(struct kfd_process *p)
180{
181 struct kfd_process_device *pdd;
182
183 list_for_each_entry(pdd, &p->per_device_data, per_device_list)
184 kfd_process_device_free_bos(pdd);
185}
186
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500187static void kfd_process_destroy_pdds(struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300188{
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300189 struct kfd_process_device *pdd, *temp;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300190
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300191 list_for_each_entry_safe(pdd, temp, &p->per_device_data,
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500192 per_device_list) {
193 pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
Oded Gabbay94a1ee02015-02-24 10:51:59 +0200194 pdd->dev->id, p->pasid);
195
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400196 if (pdd->drm_file)
197 fput(pdd->drm_file);
198 else if (pdd->vm)
Felix Kuehling403575c2018-02-06 20:32:44 -0500199 pdd->dev->kfd2kgd->destroy_process_vm(
200 pdd->dev->kgd, pdd->vm);
201
Yong Zhao733fa1f2017-09-20 18:10:14 -0400202 list_del(&pdd->per_device_list);
Felix Kuehling373d7082017-11-14 16:41:19 -0500203
204 if (pdd->qpd.cwsr_kaddr)
205 free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
206 get_order(KFD_CWSR_TBA_TMA_SIZE));
207
Felix Kuehling52b29d72018-03-15 17:27:48 -0400208 idr_destroy(&pdd->alloc_idr);
209
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300210 kfree(pdd);
211 }
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500212}
213
214/* No process locking is needed in this function, because the process
215 * is not findable any more. We must assume that no other thread is
216 * using it any more, otherwise we couldn't safely free the process
217 * structure in the end.
218 */
219static void kfd_process_wq_release(struct work_struct *work)
220{
221 struct kfd_process *p = container_of(work, struct kfd_process,
222 release_work);
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500223
Felix Kuehling64d1c3a2017-12-08 19:22:12 -0500224 kfd_iommu_unbind_process(p);
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500225
Felix Kuehling52b29d72018-03-15 17:27:48 -0400226 kfd_process_free_outstanding_kfd_bos(p);
227
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500228 kfd_process_destroy_pdds(p);
Felix Kuehling403575c2018-02-06 20:32:44 -0500229 dma_fence_put(p->ef);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300230
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300231 kfd_event_free_process(p);
232
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300233 kfd_pasid_free(p->pasid);
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400234 kfd_free_process_doorbells(p);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300235
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300236 mutex_destroy(&p->mutex);
237
Felix Kuehlingc7b12432017-11-27 18:29:50 -0500238 put_task_struct(p->lead_thread);
239
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300240 kfree(p);
Felix Kuehling5ce10682017-11-27 18:29:51 -0500241}
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300242
Felix Kuehling5ce10682017-11-27 18:29:51 -0500243static void kfd_process_ref_release(struct kref *ref)
244{
245 struct kfd_process *p = container_of(ref, struct kfd_process, ref);
246
247 INIT_WORK(&p->release_work, kfd_process_wq_release);
248 queue_work(kfd_process_wq, &p->release_work);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300249}
250
251static void kfd_process_destroy_delayed(struct rcu_head *rcu)
252{
Felix Kuehling5ce10682017-11-27 18:29:51 -0500253 struct kfd_process *p = container_of(rcu, struct kfd_process, rcu);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300254
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500255 kfd_unref_process(p);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300256}
257
258static void kfd_process_notifier_release(struct mmu_notifier *mn,
259 struct mm_struct *mm)
260{
261 struct kfd_process *p;
Ben Goza82918f2015-03-25 13:12:20 +0200262 struct kfd_process_device *pdd = NULL;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300263
264 /*
265 * The kfd_process structure can not be free because the
266 * mmu_notifier srcu is read locked
267 */
268 p = container_of(mn, struct kfd_process, mmu_notifier);
Felix Kuehling32fa8212017-08-15 23:00:12 -0400269 if (WARN_ON(p->mm != mm))
270 return;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300271
272 mutex_lock(&kfd_processes_mutex);
273 hash_del_rcu(&p->kfd_processes);
274 mutex_unlock(&kfd_processes_mutex);
275 synchronize_srcu(&kfd_processes_srcu);
276
Felix Kuehling26103432018-02-06 20:32:45 -0500277 cancel_delayed_work_sync(&p->eviction_work);
278 cancel_delayed_work_sync(&p->restore_work);
279
Ben Goz45102042014-07-17 01:04:10 +0300280 mutex_lock(&p->mutex);
281
Yair Shachar062c5672017-11-01 19:21:29 -0400282 /* Iterate over all process device data structures and if the
283 * pdd is in debug mode, we should first force unregistration,
284 * then we will be able to destroy the queues
285 */
286 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
287 struct kfd_dev *dev = pdd->dev;
288
289 mutex_lock(kfd_get_dbgmgr_mutex());
290 if (dev && dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
291 if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) {
292 kfd_dbgmgr_destroy(dev->dbgmgr);
293 dev->dbgmgr = NULL;
294 }
295 }
296 mutex_unlock(kfd_get_dbgmgr_mutex());
297 }
298
Felix Kuehling9fd3f1bf2017-09-27 00:09:52 -0400299 kfd_process_dequeue_from_all_devices(p);
Ben Goz45102042014-07-17 01:04:10 +0300300 pqm_uninit(&p->pqm);
301
Felix Kuehling5ce10682017-11-27 18:29:51 -0500302 /* Indicate to other users that MM is no longer valid */
303 p->mm = NULL;
304
Ben Goz45102042014-07-17 01:04:10 +0300305 mutex_unlock(&p->mutex);
306
Felix Kuehling5ce10682017-11-27 18:29:51 -0500307 mmu_notifier_unregister_no_release(&p->mmu_notifier, mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300308 mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed);
309}
310
311static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
312 .release = kfd_process_notifier_release,
313};
314
Felix Kuehling373d7082017-11-14 16:41:19 -0500315static int kfd_process_init_cwsr(struct kfd_process *p, struct file *filep)
316{
Felix Kuehling373d7082017-11-14 16:41:19 -0500317 unsigned long offset;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500318 struct kfd_process_device *pdd = NULL;
Felix Kuehling373d7082017-11-14 16:41:19 -0500319 struct kfd_dev *dev = NULL;
320 struct qcm_process_device *qpd = NULL;
321
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500322 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
Felix Kuehling373d7082017-11-14 16:41:19 -0500323 dev = pdd->dev;
324 qpd = &pdd->qpd;
325 if (!dev->cwsr_enabled || qpd->cwsr_kaddr)
326 continue;
327 offset = (dev->id | KFD_MMAP_RESERVED_MEM_MASK) << PAGE_SHIFT;
328 qpd->tba_addr = (int64_t)vm_mmap(filep, 0,
329 KFD_CWSR_TBA_TMA_SIZE, PROT_READ | PROT_EXEC,
330 MAP_SHARED, offset);
331
332 if (IS_ERR_VALUE(qpd->tba_addr)) {
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500333 int err = qpd->tba_addr;
334
335 pr_err("Failure to set tba address. error %d.\n", err);
Felix Kuehling373d7082017-11-14 16:41:19 -0500336 qpd->tba_addr = 0;
337 qpd->cwsr_kaddr = NULL;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500338 return err;
Felix Kuehling373d7082017-11-14 16:41:19 -0500339 }
340
341 memcpy(qpd->cwsr_kaddr, dev->cwsr_isa, dev->cwsr_isa_size);
342
343 qpd->tma_addr = qpd->tba_addr + KFD_CWSR_TMA_OFFSET;
344 pr_debug("set tba :0x%llx, tma:0x%llx, cwsr_kaddr:%p for pqm.\n",
345 qpd->tba_addr, qpd->tma_addr, qpd->cwsr_kaddr);
346 }
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500347
348 return 0;
Felix Kuehling373d7082017-11-14 16:41:19 -0500349}
350
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500351static struct kfd_process *create_process(const struct task_struct *thread,
352 struct file *filep)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300353{
354 struct kfd_process *process;
355 int err = -ENOMEM;
356
357 process = kzalloc(sizeof(*process), GFP_KERNEL);
358
359 if (!process)
360 goto err_alloc_process;
361
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300362 process->pasid = kfd_pasid_alloc();
363 if (process->pasid == 0)
364 goto err_alloc_pasid;
365
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400366 if (kfd_alloc_process_doorbells(process) < 0)
367 goto err_alloc_doorbells;
368
Felix Kuehling5ce10682017-11-27 18:29:51 -0500369 kref_init(&process->ref);
370
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300371 mutex_init(&process->mutex);
372
373 process->mm = thread->mm;
374
375 /* register notifier */
376 process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500377 err = mmu_notifier_register(&process->mmu_notifier, process->mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300378 if (err)
379 goto err_mmu_notifier;
380
381 hash_add_rcu(kfd_processes_table, &process->kfd_processes,
382 (uintptr_t)process->mm);
383
384 process->lead_thread = thread->group_leader;
Felix Kuehlingc7b12432017-11-27 18:29:50 -0500385 get_task_struct(process->lead_thread);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300386
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300387 INIT_LIST_HEAD(&process->per_device_data);
388
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300389 kfd_event_init_process(process);
390
Ben Goz45102042014-07-17 01:04:10 +0300391 err = pqm_init(&process->pqm, process);
392 if (err != 0)
393 goto err_process_pqm_init;
394
Alexey Skidanovdd592392014-11-18 13:56:23 +0200395 /* init process apertures*/
Andy Lutomirski10f16852016-03-22 14:25:19 -0700396 process->is_32bit_user_mode = in_compat_syscall();
Dan Carpenterb312b2b2017-06-14 13:58:53 +0300397 err = kfd_init_apertures(process);
398 if (err != 0)
Geert Uytterhoeven7a10d632017-06-01 12:28:38 +0200399 goto err_init_apertures;
Alexey Skidanovdd592392014-11-18 13:56:23 +0200400
Felix Kuehling26103432018-02-06 20:32:45 -0500401 INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker);
402 INIT_DELAYED_WORK(&process->restore_work, restore_process_worker);
403 process->last_restore_timestamp = get_jiffies_64();
404
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500405 err = kfd_process_init_cwsr(process, filep);
406 if (err)
407 goto err_init_cwsr;
408
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300409 return process;
410
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500411err_init_cwsr:
Felix Kuehling52b29d72018-03-15 17:27:48 -0400412 kfd_process_free_outstanding_kfd_bos(process);
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500413 kfd_process_destroy_pdds(process);
Geert Uytterhoeven7a10d632017-06-01 12:28:38 +0200414err_init_apertures:
Alexey Skidanovdd592392014-11-18 13:56:23 +0200415 pqm_uninit(&process->pqm);
Ben Goz45102042014-07-17 01:04:10 +0300416err_process_pqm_init:
417 hash_del_rcu(&process->kfd_processes);
418 synchronize_rcu();
419 mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300420err_mmu_notifier:
Oded Gabbay7fd5e032016-06-23 17:54:29 +0300421 mutex_destroy(&process->mutex);
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400422 kfd_free_process_doorbells(process);
423err_alloc_doorbells:
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300424 kfd_pasid_free(process->pasid);
425err_alloc_pasid:
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300426 kfree(process);
427err_alloc_process:
428 return ERR_PTR(err);
429}
430
431struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200432 struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300433{
434 struct kfd_process_device *pdd = NULL;
435
436 list_for_each_entry(pdd, &p->per_device_data, per_device_list)
437 if (pdd->dev == dev)
Yong Zhao733fa1f2017-09-20 18:10:14 -0400438 return pdd;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300439
Yong Zhao733fa1f2017-09-20 18:10:14 -0400440 return NULL;
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200441}
442
443struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
444 struct kfd_process *p)
445{
446 struct kfd_process_device *pdd = NULL;
447
448 pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
Felix Kuehling2d9b36f2017-11-27 18:29:54 -0500449 if (!pdd)
450 return NULL;
451
452 pdd->dev = dev;
453 INIT_LIST_HEAD(&pdd->qpd.queues_list);
454 INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
455 pdd->qpd.dqm = dev->dqm;
456 pdd->qpd.pqm = &p->pqm;
Felix Kuehling26103432018-02-06 20:32:45 -0500457 pdd->qpd.evicted = 0;
Felix Kuehling2d9b36f2017-11-27 18:29:54 -0500458 pdd->process = p;
459 pdd->bound = PDD_UNBOUND;
460 pdd->already_dequeued = false;
461 list_add(&pdd->per_device_list, &p->per_device_data);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300462
Felix Kuehling52b29d72018-03-15 17:27:48 -0400463 /* Init idr used for memory handle translation */
464 idr_init(&pdd->alloc_idr);
465
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300466 return pdd;
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400467}
Felix Kuehling403575c2018-02-06 20:32:44 -0500468
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400469/**
470 * kfd_process_device_init_vm - Initialize a VM for a process-device
471 *
472 * @pdd: The process-device
473 * @drm_file: Optional pointer to a DRM file descriptor
474 *
475 * If @drm_file is specified, it will be used to acquire the VM from
476 * that file descriptor. If successful, the @pdd takes ownership of
477 * the file descriptor.
478 *
479 * If @drm_file is NULL, a new VM is created.
480 *
481 * Returns 0 on success, -errno on failure.
482 */
483int kfd_process_device_init_vm(struct kfd_process_device *pdd,
484 struct file *drm_file)
485{
486 struct kfd_process *p;
487 struct kfd_dev *dev;
488 int ret;
489
490 if (pdd->vm)
491 return drm_file ? -EBUSY : 0;
492
493 p = pdd->process;
494 dev = pdd->dev;
495
496 if (drm_file)
497 ret = dev->kfd2kgd->acquire_process_vm(
498 dev->kgd, drm_file,
499 &pdd->vm, &p->kgd_process_info, &p->ef);
500 else
501 ret = dev->kfd2kgd->create_process_vm(
502 dev->kgd, &pdd->vm, &p->kgd_process_info, &p->ef);
503 if (ret) {
504 pr_err("Failed to create process VM object\n");
505 return ret;
506 }
507
508 pdd->drm_file = drm_file;
509
510 return 0;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300511}
512
513/*
514 * Direct the IOMMU to bind the process (specifically the pasid->mm)
515 * to the device.
516 * Unbinding occurs when the process dies or the device is removed.
517 *
518 * Assumes that the process lock is held.
519 */
520struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
521 struct kfd_process *p)
522{
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200523 struct kfd_process_device *pdd;
Oded Gabbayb17f0682014-07-17 00:06:27 +0300524 int err;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300525
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200526 pdd = kfd_get_process_device_data(dev, p);
527 if (!pdd) {
528 pr_err("Process device data doesn't exist\n");
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300529 return ERR_PTR(-ENOMEM);
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200530 }
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300531
Felix Kuehling64d1c3a2017-12-08 19:22:12 -0500532 err = kfd_iommu_bind_process_to_device(pdd);
533 if (err)
Oded Gabbayb17f0682014-07-17 00:06:27 +0300534 return ERR_PTR(err);
535
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400536 err = kfd_process_device_init_vm(pdd, NULL);
537 if (err)
538 return ERR_PTR(err);
539
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300540 return pdd;
541}
542
Kent Russell8eabaf52017-08-15 23:00:04 -0400543struct kfd_process_device *kfd_get_first_process_device_data(
544 struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300545{
546 return list_first_entry(&p->per_device_data,
547 struct kfd_process_device,
548 per_device_list);
549}
550
Kent Russell8eabaf52017-08-15 23:00:04 -0400551struct kfd_process_device *kfd_get_next_process_device_data(
552 struct kfd_process *p,
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300553 struct kfd_process_device *pdd)
554{
555 if (list_is_last(&pdd->per_device_list, &p->per_device_data))
556 return NULL;
557 return list_next_entry(pdd, per_device_list);
558}
559
560bool kfd_has_process_device_data(struct kfd_process *p)
561{
562 return !(list_empty(&p->per_device_data));
563}
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300564
Felix Kuehling52b29d72018-03-15 17:27:48 -0400565/* Create specific handle mapped to mem from process local memory idr
566 * Assumes that the process lock is held.
567 */
568int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd,
569 void *mem)
570{
571 return idr_alloc(&pdd->alloc_idr, mem, 0, 0, GFP_KERNEL);
572}
573
574/* Translate specific handle from process local memory idr
575 * Assumes that the process lock is held.
576 */
577void *kfd_process_device_translate_handle(struct kfd_process_device *pdd,
578 int handle)
579{
580 if (handle < 0)
581 return NULL;
582
583 return idr_find(&pdd->alloc_idr, handle);
584}
585
586/* Remove specific handle from process local memory idr
587 * Assumes that the process lock is held.
588 */
589void kfd_process_device_remove_obj_handle(struct kfd_process_device *pdd,
590 int handle)
591{
592 if (handle >= 0)
593 idr_remove(&pdd->alloc_idr, handle);
594}
595
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500596/* This increments the process->ref counter. */
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300597struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid)
598{
Yong Zhao82c16b42017-11-27 18:29:53 -0500599 struct kfd_process *p, *ret_p = NULL;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300600 unsigned int temp;
601
602 int idx = srcu_read_lock(&kfd_processes_srcu);
603
604 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
605 if (p->pasid == pasid) {
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500606 kref_get(&p->ref);
Yong Zhao82c16b42017-11-27 18:29:53 -0500607 ret_p = p;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300608 break;
609 }
610 }
611
612 srcu_read_unlock(&kfd_processes_srcu, idx);
613
Yong Zhao82c16b42017-11-27 18:29:53 -0500614 return ret_p;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300615}
Felix Kuehling373d7082017-11-14 16:41:19 -0500616
Felix Kuehling26103432018-02-06 20:32:45 -0500617/* This increments the process->ref counter. */
618struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm)
619{
620 struct kfd_process *p;
621
622 int idx = srcu_read_lock(&kfd_processes_srcu);
623
624 p = find_process_by_mm(mm);
625 if (p)
626 kref_get(&p->ref);
627
628 srcu_read_unlock(&kfd_processes_srcu, idx);
629
630 return p;
631}
632
633/* process_evict_queues - Evict all user queues of a process
634 *
635 * Eviction is reference-counted per process-device. This means multiple
636 * evictions from different sources can be nested safely.
637 */
638static int process_evict_queues(struct kfd_process *p)
639{
640 struct kfd_process_device *pdd;
641 int r = 0;
642 unsigned int n_evicted = 0;
643
644 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
645 r = pdd->dev->dqm->ops.evict_process_queues(pdd->dev->dqm,
646 &pdd->qpd);
647 if (r) {
648 pr_err("Failed to evict process queues\n");
649 goto fail;
650 }
651 n_evicted++;
652 }
653
654 return r;
655
656fail:
657 /* To keep state consistent, roll back partial eviction by
658 * restoring queues
659 */
660 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
661 if (n_evicted == 0)
662 break;
663 if (pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
664 &pdd->qpd))
665 pr_err("Failed to restore queues\n");
666
667 n_evicted--;
668 }
669
670 return r;
671}
672
673/* process_restore_queues - Restore all user queues of a process */
674static int process_restore_queues(struct kfd_process *p)
675{
676 struct kfd_process_device *pdd;
677 int r, ret = 0;
678
679 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
680 r = pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
681 &pdd->qpd);
682 if (r) {
683 pr_err("Failed to restore process queues\n");
684 if (!ret)
685 ret = r;
686 }
687 }
688
689 return ret;
690}
691
692static void evict_process_worker(struct work_struct *work)
693{
694 int ret;
695 struct kfd_process *p;
696 struct delayed_work *dwork;
697
698 dwork = to_delayed_work(work);
699
700 /* Process termination destroys this worker thread. So during the
701 * lifetime of this thread, kfd_process p will be valid
702 */
703 p = container_of(dwork, struct kfd_process, eviction_work);
704 WARN_ONCE(p->last_eviction_seqno != p->ef->seqno,
705 "Eviction fence mismatch\n");
706
707 /* Narrow window of overlap between restore and evict work
708 * item is possible. Once amdgpu_amdkfd_gpuvm_restore_process_bos
709 * unreserves KFD BOs, it is possible to evicted again. But
710 * restore has few more steps of finish. So lets wait for any
711 * previous restore work to complete
712 */
713 flush_delayed_work(&p->restore_work);
714
715 pr_debug("Started evicting pasid %d\n", p->pasid);
716 ret = process_evict_queues(p);
717 if (!ret) {
718 dma_fence_signal(p->ef);
719 dma_fence_put(p->ef);
720 p->ef = NULL;
721 schedule_delayed_work(&p->restore_work,
722 msecs_to_jiffies(PROCESS_RESTORE_TIME_MS));
723
724 pr_debug("Finished evicting pasid %d\n", p->pasid);
725 } else
726 pr_err("Failed to evict queues of pasid %d\n", p->pasid);
727}
728
729static void restore_process_worker(struct work_struct *work)
730{
731 struct delayed_work *dwork;
732 struct kfd_process *p;
733 struct kfd_process_device *pdd;
734 int ret = 0;
735
736 dwork = to_delayed_work(work);
737
738 /* Process termination destroys this worker thread. So during the
739 * lifetime of this thread, kfd_process p will be valid
740 */
741 p = container_of(dwork, struct kfd_process, restore_work);
742
743 /* Call restore_process_bos on the first KGD device. This function
744 * takes care of restoring the whole process including other devices.
745 * Restore can fail if enough memory is not available. If so,
746 * reschedule again.
747 */
748 pdd = list_first_entry(&p->per_device_data,
749 struct kfd_process_device,
750 per_device_list);
751
752 pr_debug("Started restoring pasid %d\n", p->pasid);
753
754 /* Setting last_restore_timestamp before successful restoration.
755 * Otherwise this would have to be set by KGD (restore_process_bos)
756 * before KFD BOs are unreserved. If not, the process can be evicted
757 * again before the timestamp is set.
758 * If restore fails, the timestamp will be set again in the next
759 * attempt. This would mean that the minimum GPU quanta would be
760 * PROCESS_ACTIVE_TIME_MS - (time to execute the following two
761 * functions)
762 */
763
764 p->last_restore_timestamp = get_jiffies_64();
765 ret = pdd->dev->kfd2kgd->restore_process_bos(p->kgd_process_info,
766 &p->ef);
767 if (ret) {
768 pr_debug("Failed to restore BOs of pasid %d, retry after %d ms\n",
769 p->pasid, PROCESS_BACK_OFF_TIME_MS);
770 ret = schedule_delayed_work(&p->restore_work,
771 msecs_to_jiffies(PROCESS_BACK_OFF_TIME_MS));
772 WARN(!ret, "reschedule restore work failed\n");
773 return;
774 }
775
776 ret = process_restore_queues(p);
777 if (!ret)
778 pr_debug("Finished restoring pasid %d\n", p->pasid);
779 else
780 pr_err("Failed to restore queues of pasid %d\n", p->pasid);
781}
782
783void kfd_suspend_all_processes(void)
784{
785 struct kfd_process *p;
786 unsigned int temp;
787 int idx = srcu_read_lock(&kfd_processes_srcu);
788
789 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
790 cancel_delayed_work_sync(&p->eviction_work);
791 cancel_delayed_work_sync(&p->restore_work);
792
793 if (process_evict_queues(p))
794 pr_err("Failed to suspend process %d\n", p->pasid);
795 dma_fence_signal(p->ef);
796 dma_fence_put(p->ef);
797 p->ef = NULL;
798 }
799 srcu_read_unlock(&kfd_processes_srcu, idx);
800}
801
802int kfd_resume_all_processes(void)
803{
804 struct kfd_process *p;
805 unsigned int temp;
806 int ret = 0, idx = srcu_read_lock(&kfd_processes_srcu);
807
808 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
809 if (!schedule_delayed_work(&p->restore_work, 0)) {
810 pr_err("Restore process %d failed during resume\n",
811 p->pasid);
812 ret = -EFAULT;
813 }
814 }
815 srcu_read_unlock(&kfd_processes_srcu, idx);
816 return ret;
817}
818
Felix Kuehling373d7082017-11-14 16:41:19 -0500819int kfd_reserved_mem_mmap(struct kfd_process *process,
820 struct vm_area_struct *vma)
821{
822 struct kfd_dev *dev = kfd_device_by_id(vma->vm_pgoff);
823 struct kfd_process_device *pdd;
824 struct qcm_process_device *qpd;
825
826 if (!dev)
827 return -EINVAL;
828 if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) {
829 pr_err("Incorrect CWSR mapping size.\n");
830 return -EINVAL;
831 }
832
833 pdd = kfd_get_process_device_data(dev, process);
834 if (!pdd)
835 return -EINVAL;
836 qpd = &pdd->qpd;
837
838 qpd->cwsr_kaddr = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
839 get_order(KFD_CWSR_TBA_TMA_SIZE));
840 if (!qpd->cwsr_kaddr) {
841 pr_err("Error allocating per process CWSR buffer.\n");
842 return -ENOMEM;
843 }
844
845 vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND
846 | VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP;
847 /* Mapping pages to user process */
848 return remap_pfn_range(vma, vma->vm_start,
849 PFN_DOWN(__pa(qpd->cwsr_kaddr)),
850 KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot);
851}
Felix Kuehling851a6452017-11-27 18:29:49 -0500852
Felix Kuehling403575c2018-02-06 20:32:44 -0500853void kfd_flush_tlb(struct kfd_process_device *pdd)
854{
855 struct kfd_dev *dev = pdd->dev;
856 const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
857
858 if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
859 /* Nothing to flush until a VMID is assigned, which
860 * only happens when the first queue is created.
861 */
862 if (pdd->qpd.vmid)
863 f2g->invalidate_tlbs_vmid(dev->kgd, pdd->qpd.vmid);
864 } else {
865 f2g->invalidate_tlbs(dev->kgd, pdd->process->pasid);
866 }
867}
868
Felix Kuehling851a6452017-11-27 18:29:49 -0500869#if defined(CONFIG_DEBUG_FS)
870
871int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)
872{
873 struct kfd_process *p;
874 unsigned int temp;
875 int r = 0;
876
877 int idx = srcu_read_lock(&kfd_processes_srcu);
878
879 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
880 seq_printf(m, "Process %d PASID %d:\n",
881 p->lead_thread->tgid, p->pasid);
882
883 mutex_lock(&p->mutex);
884 r = pqm_debugfs_mqds(m, &p->pqm);
885 mutex_unlock(&p->mutex);
886
887 if (r)
888 break;
889 }
890
891 srcu_read_unlock(&kfd_processes_srcu, idx);
892
893 return r;
894}
895
896#endif