blob: 6618aaa6b84f7029c1fcb99ac9a9fbd16782d181 [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 Kuehlingde1450a2017-11-27 18:29:55 -0500153static void kfd_process_destroy_pdds(struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300154{
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300155 struct kfd_process_device *pdd, *temp;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300156
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300157 list_for_each_entry_safe(pdd, temp, &p->per_device_data,
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500158 per_device_list) {
159 pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
Oded Gabbay94a1ee02015-02-24 10:51:59 +0200160 pdd->dev->id, p->pasid);
161
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400162 if (pdd->drm_file)
163 fput(pdd->drm_file);
164 else if (pdd->vm)
Felix Kuehling403575c2018-02-06 20:32:44 -0500165 pdd->dev->kfd2kgd->destroy_process_vm(
166 pdd->dev->kgd, pdd->vm);
167
Yong Zhao733fa1f2017-09-20 18:10:14 -0400168 list_del(&pdd->per_device_list);
Felix Kuehling373d7082017-11-14 16:41:19 -0500169
170 if (pdd->qpd.cwsr_kaddr)
171 free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
172 get_order(KFD_CWSR_TBA_TMA_SIZE));
173
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300174 kfree(pdd);
175 }
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500176}
177
178/* No process locking is needed in this function, because the process
179 * is not findable any more. We must assume that no other thread is
180 * using it any more, otherwise we couldn't safely free the process
181 * structure in the end.
182 */
183static void kfd_process_wq_release(struct work_struct *work)
184{
185 struct kfd_process *p = container_of(work, struct kfd_process,
186 release_work);
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500187
Felix Kuehling64d1c3a2017-12-08 19:22:12 -0500188 kfd_iommu_unbind_process(p);
Felix Kuehlingde1450a2017-11-27 18:29:55 -0500189
190 kfd_process_destroy_pdds(p);
Felix Kuehling403575c2018-02-06 20:32:44 -0500191 dma_fence_put(p->ef);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300192
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300193 kfd_event_free_process(p);
194
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300195 kfd_pasid_free(p->pasid);
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400196 kfd_free_process_doorbells(p);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300197
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300198 mutex_destroy(&p->mutex);
199
Felix Kuehlingc7b12432017-11-27 18:29:50 -0500200 put_task_struct(p->lead_thread);
201
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300202 kfree(p);
Felix Kuehling5ce10682017-11-27 18:29:51 -0500203}
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300204
Felix Kuehling5ce10682017-11-27 18:29:51 -0500205static void kfd_process_ref_release(struct kref *ref)
206{
207 struct kfd_process *p = container_of(ref, struct kfd_process, ref);
208
209 INIT_WORK(&p->release_work, kfd_process_wq_release);
210 queue_work(kfd_process_wq, &p->release_work);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300211}
212
213static void kfd_process_destroy_delayed(struct rcu_head *rcu)
214{
Felix Kuehling5ce10682017-11-27 18:29:51 -0500215 struct kfd_process *p = container_of(rcu, struct kfd_process, rcu);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300216
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500217 kfd_unref_process(p);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300218}
219
220static void kfd_process_notifier_release(struct mmu_notifier *mn,
221 struct mm_struct *mm)
222{
223 struct kfd_process *p;
Ben Goza82918f2015-03-25 13:12:20 +0200224 struct kfd_process_device *pdd = NULL;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300225
226 /*
227 * The kfd_process structure can not be free because the
228 * mmu_notifier srcu is read locked
229 */
230 p = container_of(mn, struct kfd_process, mmu_notifier);
Felix Kuehling32fa8212017-08-15 23:00:12 -0400231 if (WARN_ON(p->mm != mm))
232 return;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300233
234 mutex_lock(&kfd_processes_mutex);
235 hash_del_rcu(&p->kfd_processes);
236 mutex_unlock(&kfd_processes_mutex);
237 synchronize_srcu(&kfd_processes_srcu);
238
Felix Kuehling26103432018-02-06 20:32:45 -0500239 cancel_delayed_work_sync(&p->eviction_work);
240 cancel_delayed_work_sync(&p->restore_work);
241
Ben Goz45102042014-07-17 01:04:10 +0300242 mutex_lock(&p->mutex);
243
Yair Shachar062c5672017-11-01 19:21:29 -0400244 /* Iterate over all process device data structures and if the
245 * pdd is in debug mode, we should first force unregistration,
246 * then we will be able to destroy the queues
247 */
248 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
249 struct kfd_dev *dev = pdd->dev;
250
251 mutex_lock(kfd_get_dbgmgr_mutex());
252 if (dev && dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
253 if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) {
254 kfd_dbgmgr_destroy(dev->dbgmgr);
255 dev->dbgmgr = NULL;
256 }
257 }
258 mutex_unlock(kfd_get_dbgmgr_mutex());
259 }
260
Felix Kuehling9fd3f1bf2017-09-27 00:09:52 -0400261 kfd_process_dequeue_from_all_devices(p);
Ben Goz45102042014-07-17 01:04:10 +0300262 pqm_uninit(&p->pqm);
263
Felix Kuehling5ce10682017-11-27 18:29:51 -0500264 /* Indicate to other users that MM is no longer valid */
265 p->mm = NULL;
266
Ben Goz45102042014-07-17 01:04:10 +0300267 mutex_unlock(&p->mutex);
268
Felix Kuehling5ce10682017-11-27 18:29:51 -0500269 mmu_notifier_unregister_no_release(&p->mmu_notifier, mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300270 mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed);
271}
272
273static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
274 .release = kfd_process_notifier_release,
275};
276
Felix Kuehling373d7082017-11-14 16:41:19 -0500277static int kfd_process_init_cwsr(struct kfd_process *p, struct file *filep)
278{
Felix Kuehling373d7082017-11-14 16:41:19 -0500279 unsigned long offset;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500280 struct kfd_process_device *pdd = NULL;
Felix Kuehling373d7082017-11-14 16:41:19 -0500281 struct kfd_dev *dev = NULL;
282 struct qcm_process_device *qpd = NULL;
283
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500284 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
Felix Kuehling373d7082017-11-14 16:41:19 -0500285 dev = pdd->dev;
286 qpd = &pdd->qpd;
287 if (!dev->cwsr_enabled || qpd->cwsr_kaddr)
288 continue;
289 offset = (dev->id | KFD_MMAP_RESERVED_MEM_MASK) << PAGE_SHIFT;
290 qpd->tba_addr = (int64_t)vm_mmap(filep, 0,
291 KFD_CWSR_TBA_TMA_SIZE, PROT_READ | PROT_EXEC,
292 MAP_SHARED, offset);
293
294 if (IS_ERR_VALUE(qpd->tba_addr)) {
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500295 int err = qpd->tba_addr;
296
297 pr_err("Failure to set tba address. error %d.\n", err);
Felix Kuehling373d7082017-11-14 16:41:19 -0500298 qpd->tba_addr = 0;
299 qpd->cwsr_kaddr = NULL;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500300 return err;
Felix Kuehling373d7082017-11-14 16:41:19 -0500301 }
302
303 memcpy(qpd->cwsr_kaddr, dev->cwsr_isa, dev->cwsr_isa_size);
304
305 qpd->tma_addr = qpd->tba_addr + KFD_CWSR_TMA_OFFSET;
306 pr_debug("set tba :0x%llx, tma:0x%llx, cwsr_kaddr:%p for pqm.\n",
307 qpd->tba_addr, qpd->tma_addr, qpd->cwsr_kaddr);
308 }
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500309
310 return 0;
Felix Kuehling373d7082017-11-14 16:41:19 -0500311}
312
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500313static struct kfd_process *create_process(const struct task_struct *thread,
314 struct file *filep)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300315{
316 struct kfd_process *process;
317 int err = -ENOMEM;
318
319 process = kzalloc(sizeof(*process), GFP_KERNEL);
320
321 if (!process)
322 goto err_alloc_process;
323
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300324 process->pasid = kfd_pasid_alloc();
325 if (process->pasid == 0)
326 goto err_alloc_pasid;
327
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400328 if (kfd_alloc_process_doorbells(process) < 0)
329 goto err_alloc_doorbells;
330
Felix Kuehling5ce10682017-11-27 18:29:51 -0500331 kref_init(&process->ref);
332
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300333 mutex_init(&process->mutex);
334
335 process->mm = thread->mm;
336
337 /* register notifier */
338 process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops;
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500339 err = mmu_notifier_register(&process->mmu_notifier, process->mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300340 if (err)
341 goto err_mmu_notifier;
342
343 hash_add_rcu(kfd_processes_table, &process->kfd_processes,
344 (uintptr_t)process->mm);
345
346 process->lead_thread = thread->group_leader;
Felix Kuehlingc7b12432017-11-27 18:29:50 -0500347 get_task_struct(process->lead_thread);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300348
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300349 INIT_LIST_HEAD(&process->per_device_data);
350
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300351 kfd_event_init_process(process);
352
Ben Goz45102042014-07-17 01:04:10 +0300353 err = pqm_init(&process->pqm, process);
354 if (err != 0)
355 goto err_process_pqm_init;
356
Alexey Skidanovdd592392014-11-18 13:56:23 +0200357 /* init process apertures*/
Andy Lutomirski10f16852016-03-22 14:25:19 -0700358 process->is_32bit_user_mode = in_compat_syscall();
Dan Carpenterb312b2b2017-06-14 13:58:53 +0300359 err = kfd_init_apertures(process);
360 if (err != 0)
Geert Uytterhoeven7a10d632017-06-01 12:28:38 +0200361 goto err_init_apertures;
Alexey Skidanovdd592392014-11-18 13:56:23 +0200362
Felix Kuehling26103432018-02-06 20:32:45 -0500363 INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker);
364 INIT_DELAYED_WORK(&process->restore_work, restore_process_worker);
365 process->last_restore_timestamp = get_jiffies_64();
366
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500367 err = kfd_process_init_cwsr(process, filep);
368 if (err)
369 goto err_init_cwsr;
370
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300371 return process;
372
Yong Zhaoc0ede1f2017-11-27 18:29:56 -0500373err_init_cwsr:
374 kfd_process_destroy_pdds(process);
Geert Uytterhoeven7a10d632017-06-01 12:28:38 +0200375err_init_apertures:
Alexey Skidanovdd592392014-11-18 13:56:23 +0200376 pqm_uninit(&process->pqm);
Ben Goz45102042014-07-17 01:04:10 +0300377err_process_pqm_init:
378 hash_del_rcu(&process->kfd_processes);
379 synchronize_rcu();
380 mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300381err_mmu_notifier:
Oded Gabbay7fd5e032016-06-23 17:54:29 +0300382 mutex_destroy(&process->mutex);
Felix Kuehlinga91e70e2017-08-26 02:00:57 -0400383 kfd_free_process_doorbells(process);
384err_alloc_doorbells:
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300385 kfd_pasid_free(process->pasid);
386err_alloc_pasid:
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300387 kfree(process);
388err_alloc_process:
389 return ERR_PTR(err);
390}
391
392struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200393 struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300394{
395 struct kfd_process_device *pdd = NULL;
396
397 list_for_each_entry(pdd, &p->per_device_data, per_device_list)
398 if (pdd->dev == dev)
Yong Zhao733fa1f2017-09-20 18:10:14 -0400399 return pdd;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300400
Yong Zhao733fa1f2017-09-20 18:10:14 -0400401 return NULL;
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200402}
403
404struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
405 struct kfd_process *p)
406{
407 struct kfd_process_device *pdd = NULL;
408
409 pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
Felix Kuehling2d9b36f2017-11-27 18:29:54 -0500410 if (!pdd)
411 return NULL;
412
413 pdd->dev = dev;
414 INIT_LIST_HEAD(&pdd->qpd.queues_list);
415 INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
416 pdd->qpd.dqm = dev->dqm;
417 pdd->qpd.pqm = &p->pqm;
Felix Kuehling26103432018-02-06 20:32:45 -0500418 pdd->qpd.evicted = 0;
Felix Kuehling2d9b36f2017-11-27 18:29:54 -0500419 pdd->process = p;
420 pdd->bound = PDD_UNBOUND;
421 pdd->already_dequeued = false;
422 list_add(&pdd->per_device_list, &p->per_device_data);
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300423
424 return pdd;
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400425}
Felix Kuehling403575c2018-02-06 20:32:44 -0500426
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400427/**
428 * kfd_process_device_init_vm - Initialize a VM for a process-device
429 *
430 * @pdd: The process-device
431 * @drm_file: Optional pointer to a DRM file descriptor
432 *
433 * If @drm_file is specified, it will be used to acquire the VM from
434 * that file descriptor. If successful, the @pdd takes ownership of
435 * the file descriptor.
436 *
437 * If @drm_file is NULL, a new VM is created.
438 *
439 * Returns 0 on success, -errno on failure.
440 */
441int kfd_process_device_init_vm(struct kfd_process_device *pdd,
442 struct file *drm_file)
443{
444 struct kfd_process *p;
445 struct kfd_dev *dev;
446 int ret;
447
448 if (pdd->vm)
449 return drm_file ? -EBUSY : 0;
450
451 p = pdd->process;
452 dev = pdd->dev;
453
454 if (drm_file)
455 ret = dev->kfd2kgd->acquire_process_vm(
456 dev->kgd, drm_file,
457 &pdd->vm, &p->kgd_process_info, &p->ef);
458 else
459 ret = dev->kfd2kgd->create_process_vm(
460 dev->kgd, &pdd->vm, &p->kgd_process_info, &p->ef);
461 if (ret) {
462 pr_err("Failed to create process VM object\n");
463 return ret;
464 }
465
466 pdd->drm_file = drm_file;
467
468 return 0;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300469}
470
471/*
472 * Direct the IOMMU to bind the process (specifically the pasid->mm)
473 * to the device.
474 * Unbinding occurs when the process dies or the device is removed.
475 *
476 * Assumes that the process lock is held.
477 */
478struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
479 struct kfd_process *p)
480{
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200481 struct kfd_process_device *pdd;
Oded Gabbayb17f0682014-07-17 00:06:27 +0300482 int err;
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300483
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200484 pdd = kfd_get_process_device_data(dev, p);
485 if (!pdd) {
486 pr_err("Process device data doesn't exist\n");
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300487 return ERR_PTR(-ENOMEM);
Alexey Skidanov093c7d82014-11-18 14:00:04 +0200488 }
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300489
Felix Kuehling64d1c3a2017-12-08 19:22:12 -0500490 err = kfd_iommu_bind_process_to_device(pdd);
491 if (err)
Oded Gabbayb17f0682014-07-17 00:06:27 +0300492 return ERR_PTR(err);
493
Felix Kuehlingb84394e2018-03-15 17:27:44 -0400494 err = kfd_process_device_init_vm(pdd, NULL);
495 if (err)
496 return ERR_PTR(err);
497
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300498 return pdd;
499}
500
Kent Russell8eabaf52017-08-15 23:00:04 -0400501struct kfd_process_device *kfd_get_first_process_device_data(
502 struct kfd_process *p)
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300503{
504 return list_first_entry(&p->per_device_data,
505 struct kfd_process_device,
506 per_device_list);
507}
508
Kent Russell8eabaf52017-08-15 23:00:04 -0400509struct kfd_process_device *kfd_get_next_process_device_data(
510 struct kfd_process *p,
Oded Gabbay19f6d2a2014-07-16 23:25:31 +0300511 struct kfd_process_device *pdd)
512{
513 if (list_is_last(&pdd->per_device_list, &p->per_device_data))
514 return NULL;
515 return list_next_entry(pdd, per_device_list);
516}
517
518bool kfd_has_process_device_data(struct kfd_process *p)
519{
520 return !(list_empty(&p->per_device_data));
521}
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300522
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500523/* This increments the process->ref counter. */
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300524struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid)
525{
Yong Zhao82c16b42017-11-27 18:29:53 -0500526 struct kfd_process *p, *ret_p = NULL;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300527 unsigned int temp;
528
529 int idx = srcu_read_lock(&kfd_processes_srcu);
530
531 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
532 if (p->pasid == pasid) {
Felix Kuehlingabb208a2017-11-27 18:29:52 -0500533 kref_get(&p->ref);
Yong Zhao82c16b42017-11-27 18:29:53 -0500534 ret_p = p;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300535 break;
536 }
537 }
538
539 srcu_read_unlock(&kfd_processes_srcu, idx);
540
Yong Zhao82c16b42017-11-27 18:29:53 -0500541 return ret_p;
Andrew Lewyckyf3a39812015-05-10 12:15:46 +0300542}
Felix Kuehling373d7082017-11-14 16:41:19 -0500543
Felix Kuehling26103432018-02-06 20:32:45 -0500544/* This increments the process->ref counter. */
545struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm)
546{
547 struct kfd_process *p;
548
549 int idx = srcu_read_lock(&kfd_processes_srcu);
550
551 p = find_process_by_mm(mm);
552 if (p)
553 kref_get(&p->ref);
554
555 srcu_read_unlock(&kfd_processes_srcu, idx);
556
557 return p;
558}
559
560/* process_evict_queues - Evict all user queues of a process
561 *
562 * Eviction is reference-counted per process-device. This means multiple
563 * evictions from different sources can be nested safely.
564 */
565static int process_evict_queues(struct kfd_process *p)
566{
567 struct kfd_process_device *pdd;
568 int r = 0;
569 unsigned int n_evicted = 0;
570
571 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
572 r = pdd->dev->dqm->ops.evict_process_queues(pdd->dev->dqm,
573 &pdd->qpd);
574 if (r) {
575 pr_err("Failed to evict process queues\n");
576 goto fail;
577 }
578 n_evicted++;
579 }
580
581 return r;
582
583fail:
584 /* To keep state consistent, roll back partial eviction by
585 * restoring queues
586 */
587 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
588 if (n_evicted == 0)
589 break;
590 if (pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
591 &pdd->qpd))
592 pr_err("Failed to restore queues\n");
593
594 n_evicted--;
595 }
596
597 return r;
598}
599
600/* process_restore_queues - Restore all user queues of a process */
601static int process_restore_queues(struct kfd_process *p)
602{
603 struct kfd_process_device *pdd;
604 int r, ret = 0;
605
606 list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
607 r = pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
608 &pdd->qpd);
609 if (r) {
610 pr_err("Failed to restore process queues\n");
611 if (!ret)
612 ret = r;
613 }
614 }
615
616 return ret;
617}
618
619static void evict_process_worker(struct work_struct *work)
620{
621 int ret;
622 struct kfd_process *p;
623 struct delayed_work *dwork;
624
625 dwork = to_delayed_work(work);
626
627 /* Process termination destroys this worker thread. So during the
628 * lifetime of this thread, kfd_process p will be valid
629 */
630 p = container_of(dwork, struct kfd_process, eviction_work);
631 WARN_ONCE(p->last_eviction_seqno != p->ef->seqno,
632 "Eviction fence mismatch\n");
633
634 /* Narrow window of overlap between restore and evict work
635 * item is possible. Once amdgpu_amdkfd_gpuvm_restore_process_bos
636 * unreserves KFD BOs, it is possible to evicted again. But
637 * restore has few more steps of finish. So lets wait for any
638 * previous restore work to complete
639 */
640 flush_delayed_work(&p->restore_work);
641
642 pr_debug("Started evicting pasid %d\n", p->pasid);
643 ret = process_evict_queues(p);
644 if (!ret) {
645 dma_fence_signal(p->ef);
646 dma_fence_put(p->ef);
647 p->ef = NULL;
648 schedule_delayed_work(&p->restore_work,
649 msecs_to_jiffies(PROCESS_RESTORE_TIME_MS));
650
651 pr_debug("Finished evicting pasid %d\n", p->pasid);
652 } else
653 pr_err("Failed to evict queues of pasid %d\n", p->pasid);
654}
655
656static void restore_process_worker(struct work_struct *work)
657{
658 struct delayed_work *dwork;
659 struct kfd_process *p;
660 struct kfd_process_device *pdd;
661 int ret = 0;
662
663 dwork = to_delayed_work(work);
664
665 /* Process termination destroys this worker thread. So during the
666 * lifetime of this thread, kfd_process p will be valid
667 */
668 p = container_of(dwork, struct kfd_process, restore_work);
669
670 /* Call restore_process_bos on the first KGD device. This function
671 * takes care of restoring the whole process including other devices.
672 * Restore can fail if enough memory is not available. If so,
673 * reschedule again.
674 */
675 pdd = list_first_entry(&p->per_device_data,
676 struct kfd_process_device,
677 per_device_list);
678
679 pr_debug("Started restoring pasid %d\n", p->pasid);
680
681 /* Setting last_restore_timestamp before successful restoration.
682 * Otherwise this would have to be set by KGD (restore_process_bos)
683 * before KFD BOs are unreserved. If not, the process can be evicted
684 * again before the timestamp is set.
685 * If restore fails, the timestamp will be set again in the next
686 * attempt. This would mean that the minimum GPU quanta would be
687 * PROCESS_ACTIVE_TIME_MS - (time to execute the following two
688 * functions)
689 */
690
691 p->last_restore_timestamp = get_jiffies_64();
692 ret = pdd->dev->kfd2kgd->restore_process_bos(p->kgd_process_info,
693 &p->ef);
694 if (ret) {
695 pr_debug("Failed to restore BOs of pasid %d, retry after %d ms\n",
696 p->pasid, PROCESS_BACK_OFF_TIME_MS);
697 ret = schedule_delayed_work(&p->restore_work,
698 msecs_to_jiffies(PROCESS_BACK_OFF_TIME_MS));
699 WARN(!ret, "reschedule restore work failed\n");
700 return;
701 }
702
703 ret = process_restore_queues(p);
704 if (!ret)
705 pr_debug("Finished restoring pasid %d\n", p->pasid);
706 else
707 pr_err("Failed to restore queues of pasid %d\n", p->pasid);
708}
709
710void kfd_suspend_all_processes(void)
711{
712 struct kfd_process *p;
713 unsigned int temp;
714 int idx = srcu_read_lock(&kfd_processes_srcu);
715
716 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
717 cancel_delayed_work_sync(&p->eviction_work);
718 cancel_delayed_work_sync(&p->restore_work);
719
720 if (process_evict_queues(p))
721 pr_err("Failed to suspend process %d\n", p->pasid);
722 dma_fence_signal(p->ef);
723 dma_fence_put(p->ef);
724 p->ef = NULL;
725 }
726 srcu_read_unlock(&kfd_processes_srcu, idx);
727}
728
729int kfd_resume_all_processes(void)
730{
731 struct kfd_process *p;
732 unsigned int temp;
733 int ret = 0, idx = srcu_read_lock(&kfd_processes_srcu);
734
735 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
736 if (!schedule_delayed_work(&p->restore_work, 0)) {
737 pr_err("Restore process %d failed during resume\n",
738 p->pasid);
739 ret = -EFAULT;
740 }
741 }
742 srcu_read_unlock(&kfd_processes_srcu, idx);
743 return ret;
744}
745
Felix Kuehling373d7082017-11-14 16:41:19 -0500746int kfd_reserved_mem_mmap(struct kfd_process *process,
747 struct vm_area_struct *vma)
748{
749 struct kfd_dev *dev = kfd_device_by_id(vma->vm_pgoff);
750 struct kfd_process_device *pdd;
751 struct qcm_process_device *qpd;
752
753 if (!dev)
754 return -EINVAL;
755 if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) {
756 pr_err("Incorrect CWSR mapping size.\n");
757 return -EINVAL;
758 }
759
760 pdd = kfd_get_process_device_data(dev, process);
761 if (!pdd)
762 return -EINVAL;
763 qpd = &pdd->qpd;
764
765 qpd->cwsr_kaddr = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
766 get_order(KFD_CWSR_TBA_TMA_SIZE));
767 if (!qpd->cwsr_kaddr) {
768 pr_err("Error allocating per process CWSR buffer.\n");
769 return -ENOMEM;
770 }
771
772 vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND
773 | VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP;
774 /* Mapping pages to user process */
775 return remap_pfn_range(vma, vma->vm_start,
776 PFN_DOWN(__pa(qpd->cwsr_kaddr)),
777 KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot);
778}
Felix Kuehling851a6452017-11-27 18:29:49 -0500779
Felix Kuehling403575c2018-02-06 20:32:44 -0500780void kfd_flush_tlb(struct kfd_process_device *pdd)
781{
782 struct kfd_dev *dev = pdd->dev;
783 const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
784
785 if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
786 /* Nothing to flush until a VMID is assigned, which
787 * only happens when the first queue is created.
788 */
789 if (pdd->qpd.vmid)
790 f2g->invalidate_tlbs_vmid(dev->kgd, pdd->qpd.vmid);
791 } else {
792 f2g->invalidate_tlbs(dev->kgd, pdd->process->pasid);
793 }
794}
795
Felix Kuehling851a6452017-11-27 18:29:49 -0500796#if defined(CONFIG_DEBUG_FS)
797
798int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)
799{
800 struct kfd_process *p;
801 unsigned int temp;
802 int r = 0;
803
804 int idx = srcu_read_lock(&kfd_processes_srcu);
805
806 hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
807 seq_printf(m, "Process %d PASID %d:\n",
808 p->lead_thread->tgid, p->pasid);
809
810 mutex_lock(&p->mutex);
811 r = pqm_debugfs_mqds(m, &p->pqm);
812 mutex_unlock(&p->mutex);
813
814 if (r)
815 break;
816 }
817
818 srcu_read_unlock(&kfd_processes_srcu, idx);
819
820 return r;
821}
822
823#endif