2 * Copyright 2014 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
24 #include <linux/slab.h>
25 #include <linux/list.h>
26 #include "kfd_device_queue_manager.h"
28 #include "kfd_kernel_queue.h"
29 #include "amdgpu_amdkfd.h"
31 static inline struct process_queue_node
*get_queue_by_qid(
32 struct process_queue_manager
*pqm
, unsigned int qid
)
34 struct process_queue_node
*pqn
;
36 list_for_each_entry(pqn
, &pqm
->queues
, process_queue_list
) {
37 if ((pqn
->q
&& pqn
->q
->properties
.queue_id
== qid
) ||
38 (pqn
->kq
&& pqn
->kq
->queue
->properties
.queue_id
== qid
))
45 static int find_available_queue_slot(struct process_queue_manager
*pqm
,
50 found
= find_first_zero_bit(pqm
->queue_slot_bitmap
,
51 KFD_MAX_NUM_OF_QUEUES_PER_PROCESS
);
53 pr_debug("The new slot id %lu\n", found
);
55 if (found
>= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS
) {
56 pr_info("Cannot open more queues for process with pasid 0x%x\n",
61 set_bit(found
, pqm
->queue_slot_bitmap
);
67 void kfd_process_dequeue_from_device(struct kfd_process_device
*pdd
)
69 struct kfd_dev
*dev
= pdd
->dev
;
71 if (pdd
->already_dequeued
)
74 dev
->dqm
->ops
.process_termination(dev
->dqm
, &pdd
->qpd
);
75 pdd
->already_dequeued
= true;
78 int pqm_set_gws(struct process_queue_manager
*pqm
, unsigned int qid
,
81 struct kfd_dev
*dev
= NULL
;
82 struct process_queue_node
*pqn
;
83 struct kfd_process_device
*pdd
;
84 struct kgd_mem
*mem
= NULL
;
87 pqn
= get_queue_by_qid(pqm
, qid
);
89 pr_err("Queue id does not match any known queue\n");
98 pdd
= kfd_get_process_device_data(dev
, pqm
->process
);
100 pr_err("Process device data doesn't exist\n");
104 /* Only allow one queue per process can have GWS assigned */
105 if (gws
&& pdd
->qpd
.num_gws
)
108 if (!gws
&& pdd
->qpd
.num_gws
== 0)
112 ret
= amdgpu_amdkfd_add_gws_to_process(pdd
->process
->kgd_process_info
,
115 ret
= amdgpu_amdkfd_remove_gws_from_process(pdd
->process
->kgd_process_info
,
121 pdd
->qpd
.num_gws
= gws
? amdgpu_amdkfd_get_num_gws(dev
->kgd
) : 0;
123 return pqn
->q
->device
->dqm
->ops
.update_queue(pqn
->q
->device
->dqm
,
127 void kfd_process_dequeue_from_all_devices(struct kfd_process
*p
)
129 struct kfd_process_device
*pdd
;
131 list_for_each_entry(pdd
, &p
->per_device_data
, per_device_list
)
132 kfd_process_dequeue_from_device(pdd
);
135 int pqm_init(struct process_queue_manager
*pqm
, struct kfd_process
*p
)
137 INIT_LIST_HEAD(&pqm
->queues
);
138 pqm
->queue_slot_bitmap
=
139 kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS
,
140 BITS_PER_BYTE
), GFP_KERNEL
);
141 if (!pqm
->queue_slot_bitmap
)
148 void pqm_uninit(struct process_queue_manager
*pqm
)
150 struct process_queue_node
*pqn
, *next
;
152 list_for_each_entry_safe(pqn
, next
, &pqm
->queues
, process_queue_list
) {
153 if (pqn
->q
&& pqn
->q
->gws
)
154 amdgpu_amdkfd_remove_gws_from_process(pqm
->process
->kgd_process_info
,
156 uninit_queue(pqn
->q
);
157 list_del(&pqn
->process_queue_list
);
161 kfree(pqm
->queue_slot_bitmap
);
162 pqm
->queue_slot_bitmap
= NULL
;
165 static int init_user_queue(struct process_queue_manager
*pqm
,
166 struct kfd_dev
*dev
, struct queue
**q
,
167 struct queue_properties
*q_properties
,
168 struct file
*f
, unsigned int qid
)
172 /* Doorbell initialized in user space*/
173 q_properties
->doorbell_ptr
= NULL
;
175 /* let DQM handle it*/
176 q_properties
->vmid
= 0;
177 q_properties
->queue_id
= qid
;
179 retval
= init_queue(q
, q_properties
);
184 (*q
)->process
= pqm
->process
;
186 pr_debug("PQM After init queue");
191 int pqm_create_queue(struct process_queue_manager
*pqm
,
194 struct queue_properties
*properties
,
196 uint32_t *p_doorbell_offset_in_process
)
199 struct kfd_process_device
*pdd
;
201 struct process_queue_node
*pqn
;
202 struct kernel_queue
*kq
;
203 enum kfd_queue_type type
= properties
->type
;
204 unsigned int max_queues
= 127; /* HWS limit */
209 pdd
= kfd_get_process_device_data(dev
, pqm
->process
);
211 pr_err("Process device data doesn't exist\n");
216 * for debug process, verify that it is within the static queues limit
217 * currently limit is set to half of the total avail HQD slots
218 * If we are just about to create DIQ, the is_debug flag is not set yet
219 * Hence we also check the type as well
221 if ((pdd
->qpd
.is_debug
) || (type
== KFD_QUEUE_TYPE_DIQ
))
222 max_queues
= dev
->device_info
->max_no_of_hqd
/2;
224 if (pdd
->qpd
.queue_count
>= max_queues
)
227 retval
= find_available_queue_slot(pqm
, qid
);
231 if (list_empty(&pdd
->qpd
.queues_list
) &&
232 list_empty(&pdd
->qpd
.priv_queue_list
))
233 dev
->dqm
->ops
.register_process(dev
->dqm
, &pdd
->qpd
);
235 pqn
= kzalloc(sizeof(*pqn
), GFP_KERNEL
);
238 goto err_allocate_pqn
;
242 case KFD_QUEUE_TYPE_SDMA
:
243 case KFD_QUEUE_TYPE_SDMA_XGMI
:
244 if ((type
== KFD_QUEUE_TYPE_SDMA
&& dev
->dqm
->sdma_queue_count
245 >= get_num_sdma_queues(dev
->dqm
)) ||
246 (type
== KFD_QUEUE_TYPE_SDMA_XGMI
&&
247 dev
->dqm
->xgmi_sdma_queue_count
248 >= get_num_xgmi_sdma_queues(dev
->dqm
))) {
249 pr_debug("Over-subscription is not allowed for SDMA.\n");
251 goto err_create_queue
;
254 retval
= init_user_queue(pqm
, dev
, &q
, properties
, f
, *qid
);
256 goto err_create_queue
;
259 retval
= dev
->dqm
->ops
.create_queue(dev
->dqm
, q
, &pdd
->qpd
);
260 pr_debug("DQM returned %d for create_queue\n", retval
);
264 case KFD_QUEUE_TYPE_COMPUTE
:
265 /* check if there is over subscription */
266 if ((dev
->dqm
->sched_policy
==
267 KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION
) &&
268 ((dev
->dqm
->processes_count
>= dev
->vm_info
.vmid_num_kfd
) ||
269 (dev
->dqm
->queue_count
>= get_queues_num(dev
->dqm
)))) {
270 pr_debug("Over-subscription is not allowed when amdkfd.sched_policy == 1\n");
272 goto err_create_queue
;
275 retval
= init_user_queue(pqm
, dev
, &q
, properties
, f
, *qid
);
277 goto err_create_queue
;
280 retval
= dev
->dqm
->ops
.create_queue(dev
->dqm
, q
, &pdd
->qpd
);
281 pr_debug("DQM returned %d for create_queue\n", retval
);
284 case KFD_QUEUE_TYPE_DIQ
:
285 kq
= kernel_queue_init(dev
, KFD_QUEUE_TYPE_DIQ
);
288 goto err_create_queue
;
290 kq
->queue
->properties
.queue_id
= *qid
;
293 retval
= dev
->dqm
->ops
.create_kernel_queue(dev
->dqm
,
297 WARN(1, "Invalid queue type %d", type
);
302 pr_err("Pasid 0x%x DQM create queue %d failed. ret %d\n",
303 pqm
->process
->pasid
, type
, retval
);
304 goto err_create_queue
;
307 if (q
&& p_doorbell_offset_in_process
)
308 /* Return the doorbell offset within the doorbell page
309 * to the caller so it can be passed up to user mode
311 * There are always 1024 doorbells per process, so in case
312 * of 8-byte doorbells, there are two doorbell pages per
315 *p_doorbell_offset_in_process
=
316 (q
->properties
.doorbell_off
* sizeof(uint32_t)) &
317 (kfd_doorbell_process_slice(dev
) - 1);
319 pr_debug("PQM After DQM create queue\n");
321 list_add(&pqn
->process_queue_list
, &pqm
->queues
);
324 pr_debug("PQM done creating queue\n");
325 print_queue_properties(&q
->properties
);
333 /* check if queues list is empty unregister process from device */
334 clear_bit(*qid
, pqm
->queue_slot_bitmap
);
335 if (list_empty(&pdd
->qpd
.queues_list
) &&
336 list_empty(&pdd
->qpd
.priv_queue_list
))
337 dev
->dqm
->ops
.unregister_process(dev
->dqm
, &pdd
->qpd
);
341 int pqm_destroy_queue(struct process_queue_manager
*pqm
, unsigned int qid
)
343 struct process_queue_node
*pqn
;
344 struct kfd_process_device
*pdd
;
345 struct device_queue_manager
*dqm
;
353 pqn
= get_queue_by_qid(pqm
, qid
);
355 pr_err("Queue id does not match any known queue\n");
363 dev
= pqn
->q
->device
;
367 pdd
= kfd_get_process_device_data(dev
, pqm
->process
);
369 pr_err("Process device data doesn't exist\n");
374 /* destroy kernel queue (DIQ) */
375 dqm
= pqn
->kq
->dev
->dqm
;
376 dqm
->ops
.destroy_kernel_queue(dqm
, pqn
->kq
, &pdd
->qpd
);
377 kernel_queue_uninit(pqn
->kq
, false);
381 dqm
= pqn
->q
->device
->dqm
;
382 retval
= dqm
->ops
.destroy_queue(dqm
, &pdd
->qpd
, pqn
->q
);
384 pr_err("Pasid 0x%x destroy queue %d failed, ret %d\n",
386 pqn
->q
->properties
.queue_id
, retval
);
387 if (retval
!= -ETIME
)
388 goto err_destroy_queue
;
392 amdgpu_amdkfd_remove_gws_from_process(pqm
->process
->kgd_process_info
,
394 pdd
->qpd
.num_gws
= 0;
397 kfree(pqn
->q
->properties
.cu_mask
);
398 pqn
->q
->properties
.cu_mask
= NULL
;
399 uninit_queue(pqn
->q
);
402 list_del(&pqn
->process_queue_list
);
404 clear_bit(qid
, pqm
->queue_slot_bitmap
);
406 if (list_empty(&pdd
->qpd
.queues_list
) &&
407 list_empty(&pdd
->qpd
.priv_queue_list
))
408 dqm
->ops
.unregister_process(dqm
, &pdd
->qpd
);
414 int pqm_update_queue(struct process_queue_manager
*pqm
, unsigned int qid
,
415 struct queue_properties
*p
)
418 struct process_queue_node
*pqn
;
420 pqn
= get_queue_by_qid(pqm
, qid
);
422 pr_debug("No queue %d exists for update operation\n", qid
);
426 pqn
->q
->properties
.queue_address
= p
->queue_address
;
427 pqn
->q
->properties
.queue_size
= p
->queue_size
;
428 pqn
->q
->properties
.queue_percent
= p
->queue_percent
;
429 pqn
->q
->properties
.priority
= p
->priority
;
431 retval
= pqn
->q
->device
->dqm
->ops
.update_queue(pqn
->q
->device
->dqm
,
439 int pqm_set_cu_mask(struct process_queue_manager
*pqm
, unsigned int qid
,
440 struct queue_properties
*p
)
443 struct process_queue_node
*pqn
;
445 pqn
= get_queue_by_qid(pqm
, qid
);
447 pr_debug("No queue %d exists for update operation\n", qid
);
451 /* Free the old CU mask memory if it is already allocated, then
452 * allocate memory for the new CU mask.
454 kfree(pqn
->q
->properties
.cu_mask
);
456 pqn
->q
->properties
.cu_mask_count
= p
->cu_mask_count
;
457 pqn
->q
->properties
.cu_mask
= p
->cu_mask
;
459 retval
= pqn
->q
->device
->dqm
->ops
.update_queue(pqn
->q
->device
->dqm
,
467 struct kernel_queue
*pqm_get_kernel_queue(
468 struct process_queue_manager
*pqm
,
471 struct process_queue_node
*pqn
;
473 pqn
= get_queue_by_qid(pqm
, qid
);
480 int pqm_get_wave_state(struct process_queue_manager
*pqm
,
482 void __user
*ctl_stack
,
483 u32
*ctl_stack_used_size
,
484 u32
*save_area_used_size
)
486 struct process_queue_node
*pqn
;
488 pqn
= get_queue_by_qid(pqm
, qid
);
490 pr_debug("amdkfd: No queue %d exists for operation\n",
495 return pqn
->q
->device
->dqm
->ops
.get_wave_state(pqn
->q
->device
->dqm
,
499 save_area_used_size
);
502 #if defined(CONFIG_DEBUG_FS)
504 int pqm_debugfs_mqds(struct seq_file
*m
, void *data
)
506 struct process_queue_manager
*pqm
= data
;
507 struct process_queue_node
*pqn
;
509 enum KFD_MQD_TYPE mqd_type
;
510 struct mqd_manager
*mqd_mgr
;
513 list_for_each_entry(pqn
, &pqm
->queues
, process_queue_list
) {
516 switch (q
->properties
.type
) {
517 case KFD_QUEUE_TYPE_SDMA
:
518 case KFD_QUEUE_TYPE_SDMA_XGMI
:
519 seq_printf(m
, " SDMA queue on device %x\n",
521 mqd_type
= KFD_MQD_TYPE_SDMA
;
523 case KFD_QUEUE_TYPE_COMPUTE
:
524 seq_printf(m
, " Compute queue on device %x\n",
526 mqd_type
= KFD_MQD_TYPE_CP
;
530 " Bad user queue type %d on device %x\n",
531 q
->properties
.type
, q
->device
->id
);
534 mqd_mgr
= q
->device
->dqm
->mqd_mgrs
[mqd_type
];
535 } else if (pqn
->kq
) {
537 mqd_mgr
= pqn
->kq
->mqd_mgr
;
538 switch (q
->properties
.type
) {
539 case KFD_QUEUE_TYPE_DIQ
:
540 seq_printf(m
, " DIQ on device %x\n",
545 " Bad kernel queue type %d on device %x\n",
552 " Weird: Queue node with neither kernel nor user queue\n");
556 r
= mqd_mgr
->debugfs_show_mqd(m
, q
->mqd
);