root/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_queue_by_qid
  2. find_available_queue_slot
  3. kfd_process_dequeue_from_device
  4. pqm_set_gws
  5. kfd_process_dequeue_from_all_devices
  6. pqm_init
  7. pqm_uninit
  8. create_cp_queue
  9. pqm_create_queue
  10. pqm_destroy_queue
  11. pqm_update_queue
  12. pqm_set_cu_mask
  13. pqm_get_kernel_queue
  14. pqm_get_wave_state
  15. pqm_debugfs_mqds

   1 /*
   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 
  24 #include <linux/slab.h>
  25 #include <linux/list.h>
  26 #include "kfd_device_queue_manager.h"
  27 #include "kfd_priv.h"
  28 #include "kfd_kernel_queue.h"
  29 #include "amdgpu_amdkfd.h"
  30 
  31 static inline struct process_queue_node *get_queue_by_qid(
  32                         struct process_queue_manager *pqm, unsigned int qid)
  33 {
  34         struct process_queue_node *pqn;
  35 
  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))
  39                         return pqn;
  40         }
  41 
  42         return NULL;
  43 }
  44 
  45 static int find_available_queue_slot(struct process_queue_manager *pqm,
  46                                         unsigned int *qid)
  47 {
  48         unsigned long found;
  49 
  50         found = find_first_zero_bit(pqm->queue_slot_bitmap,
  51                         KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
  52 
  53         pr_debug("The new slot id %lu\n", found);
  54 
  55         if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
  56                 pr_info("Cannot open more queues for process with pasid %d\n",
  57                                 pqm->process->pasid);
  58                 return -ENOMEM;
  59         }
  60 
  61         set_bit(found, pqm->queue_slot_bitmap);
  62         *qid = found;
  63 
  64         return 0;
  65 }
  66 
  67 void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
  68 {
  69         struct kfd_dev *dev = pdd->dev;
  70 
  71         if (pdd->already_dequeued)
  72                 return;
  73 
  74         dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd);
  75         pdd->already_dequeued = true;
  76 }
  77 
  78 int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
  79                         void *gws)
  80 {
  81         struct kfd_dev *dev = NULL;
  82         struct process_queue_node *pqn;
  83         struct kfd_process_device *pdd;
  84         struct kgd_mem *mem = NULL;
  85         int ret;
  86 
  87         pqn = get_queue_by_qid(pqm, qid);
  88         if (!pqn) {
  89                 pr_err("Queue id does not match any known queue\n");
  90                 return -EINVAL;
  91         }
  92 
  93         if (pqn->q)
  94                 dev = pqn->q->device;
  95         if (WARN_ON(!dev))
  96                 return -ENODEV;
  97 
  98         pdd = kfd_get_process_device_data(dev, pqm->process);
  99         if (!pdd) {
 100                 pr_err("Process device data doesn't exist\n");
 101                 return -EINVAL;
 102         }
 103 
 104         /* Only allow one queue per process can have GWS assigned */
 105         if (gws && pdd->qpd.num_gws)
 106                 return -EBUSY;
 107 
 108         if (!gws && pdd->qpd.num_gws == 0)
 109                 return -EINVAL;
 110 
 111         if (gws)
 112                 ret = amdgpu_amdkfd_add_gws_to_process(pdd->process->kgd_process_info,
 113                         gws, &mem);
 114         else
 115                 ret = amdgpu_amdkfd_remove_gws_from_process(pdd->process->kgd_process_info,
 116                         pqn->q->gws);
 117         if (unlikely(ret))
 118                 return ret;
 119 
 120         pqn->q->gws = mem;
 121         pdd->qpd.num_gws = gws ? amdgpu_amdkfd_get_num_gws(dev->kgd) : 0;
 122 
 123         return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
 124                                                         pqn->q);
 125 }
 126 
 127 void kfd_process_dequeue_from_all_devices(struct kfd_process *p)
 128 {
 129         struct kfd_process_device *pdd;
 130 
 131         list_for_each_entry(pdd, &p->per_device_data, per_device_list)
 132                 kfd_process_dequeue_from_device(pdd);
 133 }
 134 
 135 int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p)
 136 {
 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)
 142                 return -ENOMEM;
 143         pqm->process = p;
 144 
 145         return 0;
 146 }
 147 
 148 void pqm_uninit(struct process_queue_manager *pqm)
 149 {
 150         struct process_queue_node *pqn, *next;
 151 
 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,
 155                                 pqn->q->gws);
 156                 uninit_queue(pqn->q);
 157                 list_del(&pqn->process_queue_list);
 158                 kfree(pqn);
 159         }
 160 
 161         kfree(pqm->queue_slot_bitmap);
 162         pqm->queue_slot_bitmap = NULL;
 163 }
 164 
 165 static int create_cp_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)
 169 {
 170         int retval;
 171 
 172         /* Doorbell initialized in user space*/
 173         q_properties->doorbell_ptr = NULL;
 174 
 175         /* let DQM handle it*/
 176         q_properties->vmid = 0;
 177         q_properties->queue_id = qid;
 178 
 179         retval = init_queue(q, q_properties);
 180         if (retval != 0)
 181                 return retval;
 182 
 183         (*q)->device = dev;
 184         (*q)->process = pqm->process;
 185 
 186         pr_debug("PQM After init queue");
 187 
 188         return retval;
 189 }
 190 
 191 int pqm_create_queue(struct process_queue_manager *pqm,
 192                             struct kfd_dev *dev,
 193                             struct file *f,
 194                             struct queue_properties *properties,
 195                             unsigned int *qid)
 196 {
 197         int retval;
 198         struct kfd_process_device *pdd;
 199         struct queue *q;
 200         struct process_queue_node *pqn;
 201         struct kernel_queue *kq;
 202         enum kfd_queue_type type = properties->type;
 203         unsigned int max_queues = 127; /* HWS limit */
 204 
 205         q = NULL;
 206         kq = NULL;
 207 
 208         pdd = kfd_get_process_device_data(dev, pqm->process);
 209         if (!pdd) {
 210                 pr_err("Process device data doesn't exist\n");
 211                 return -1;
 212         }
 213 
 214         /*
 215          * for debug process, verify that it is within the static queues limit
 216          * currently limit is set to half of the total avail HQD slots
 217          * If we are just about to create DIQ, the is_debug flag is not set yet
 218          * Hence we also check the type as well
 219          */
 220         if ((pdd->qpd.is_debug) || (type == KFD_QUEUE_TYPE_DIQ))
 221                 max_queues = dev->device_info->max_no_of_hqd/2;
 222 
 223         if (pdd->qpd.queue_count >= max_queues)
 224                 return -ENOSPC;
 225 
 226         retval = find_available_queue_slot(pqm, qid);
 227         if (retval != 0)
 228                 return retval;
 229 
 230         if (list_empty(&pdd->qpd.queues_list) &&
 231             list_empty(&pdd->qpd.priv_queue_list))
 232                 dev->dqm->ops.register_process(dev->dqm, &pdd->qpd);
 233 
 234         pqn = kzalloc(sizeof(*pqn), GFP_KERNEL);
 235         if (!pqn) {
 236                 retval = -ENOMEM;
 237                 goto err_allocate_pqn;
 238         }
 239 
 240         switch (type) {
 241         case KFD_QUEUE_TYPE_SDMA:
 242         case KFD_QUEUE_TYPE_SDMA_XGMI:
 243                 if ((type == KFD_QUEUE_TYPE_SDMA && dev->dqm->sdma_queue_count
 244                         >= get_num_sdma_queues(dev->dqm)) ||
 245                         (type == KFD_QUEUE_TYPE_SDMA_XGMI &&
 246                         dev->dqm->xgmi_sdma_queue_count
 247                         >= get_num_xgmi_sdma_queues(dev->dqm))) {
 248                         pr_debug("Over-subscription is not allowed for SDMA.\n");
 249                         retval = -EPERM;
 250                         goto err_create_queue;
 251                 }
 252 
 253                 retval = create_cp_queue(pqm, dev, &q, properties, f, *qid);
 254                 if (retval != 0)
 255                         goto err_create_queue;
 256                 pqn->q = q;
 257                 pqn->kq = NULL;
 258                 retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
 259                 pr_debug("DQM returned %d for create_queue\n", retval);
 260                 print_queue(q);
 261                 break;
 262 
 263         case KFD_QUEUE_TYPE_COMPUTE:
 264                 /* check if there is over subscription */
 265                 if ((dev->dqm->sched_policy ==
 266                      KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
 267                 ((dev->dqm->processes_count >= dev->vm_info.vmid_num_kfd) ||
 268                 (dev->dqm->queue_count >= get_queues_num(dev->dqm)))) {
 269                         pr_debug("Over-subscription is not allowed when amdkfd.sched_policy == 1\n");
 270                         retval = -EPERM;
 271                         goto err_create_queue;
 272                 }
 273 
 274                 retval = create_cp_queue(pqm, dev, &q, properties, f, *qid);
 275                 if (retval != 0)
 276                         goto err_create_queue;
 277                 pqn->q = q;
 278                 pqn->kq = NULL;
 279                 retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
 280                 pr_debug("DQM returned %d for create_queue\n", retval);
 281                 print_queue(q);
 282                 break;
 283         case KFD_QUEUE_TYPE_DIQ:
 284                 kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ);
 285                 if (!kq) {
 286                         retval = -ENOMEM;
 287                         goto err_create_queue;
 288                 }
 289                 kq->queue->properties.queue_id = *qid;
 290                 pqn->kq = kq;
 291                 pqn->q = NULL;
 292                 retval = dev->dqm->ops.create_kernel_queue(dev->dqm,
 293                                                         kq, &pdd->qpd);
 294                 break;
 295         default:
 296                 WARN(1, "Invalid queue type %d", type);
 297                 retval = -EINVAL;
 298         }
 299 
 300         if (retval != 0) {
 301                 pr_err("Pasid %d DQM create queue %d failed. ret %d\n",
 302                         pqm->process->pasid, type, retval);
 303                 goto err_create_queue;
 304         }
 305 
 306         if (q)
 307                 /* Return the doorbell offset within the doorbell page
 308                  * to the caller so it can be passed up to user mode
 309                  * (in bytes).
 310                  */
 311                 properties->doorbell_off =
 312                         (q->properties.doorbell_off * sizeof(uint32_t)) &
 313                         (kfd_doorbell_process_slice(dev) - 1);
 314 
 315         pr_debug("PQM After DQM create queue\n");
 316 
 317         list_add(&pqn->process_queue_list, &pqm->queues);
 318 
 319         if (q) {
 320                 pr_debug("PQM done creating queue\n");
 321                 print_queue_properties(&q->properties);
 322         }
 323 
 324         return retval;
 325 
 326 err_create_queue:
 327         kfree(pqn);
 328 err_allocate_pqn:
 329         /* check if queues list is empty unregister process from device */
 330         clear_bit(*qid, pqm->queue_slot_bitmap);
 331         if (list_empty(&pdd->qpd.queues_list) &&
 332             list_empty(&pdd->qpd.priv_queue_list))
 333                 dev->dqm->ops.unregister_process(dev->dqm, &pdd->qpd);
 334         return retval;
 335 }
 336 
 337 int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
 338 {
 339         struct process_queue_node *pqn;
 340         struct kfd_process_device *pdd;
 341         struct device_queue_manager *dqm;
 342         struct kfd_dev *dev;
 343         int retval;
 344 
 345         dqm = NULL;
 346 
 347         retval = 0;
 348 
 349         pqn = get_queue_by_qid(pqm, qid);
 350         if (!pqn) {
 351                 pr_err("Queue id does not match any known queue\n");
 352                 return -EINVAL;
 353         }
 354 
 355         dev = NULL;
 356         if (pqn->kq)
 357                 dev = pqn->kq->dev;
 358         if (pqn->q)
 359                 dev = pqn->q->device;
 360         if (WARN_ON(!dev))
 361                 return -ENODEV;
 362 
 363         pdd = kfd_get_process_device_data(dev, pqm->process);
 364         if (!pdd) {
 365                 pr_err("Process device data doesn't exist\n");
 366                 return -1;
 367         }
 368 
 369         if (pqn->kq) {
 370                 /* destroy kernel queue (DIQ) */
 371                 dqm = pqn->kq->dev->dqm;
 372                 dqm->ops.destroy_kernel_queue(dqm, pqn->kq, &pdd->qpd);
 373                 kernel_queue_uninit(pqn->kq);
 374         }
 375 
 376         if (pqn->q) {
 377                 dqm = pqn->q->device->dqm;
 378                 retval = dqm->ops.destroy_queue(dqm, &pdd->qpd, pqn->q);
 379                 if (retval) {
 380                         pr_err("Pasid %d destroy queue %d failed, ret %d\n",
 381                                 pqm->process->pasid,
 382                                 pqn->q->properties.queue_id, retval);
 383                         if (retval != -ETIME)
 384                                 goto err_destroy_queue;
 385                 }
 386 
 387                 if (pqn->q->gws) {
 388                         amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info,
 389                                 pqn->q->gws);
 390                         pdd->qpd.num_gws = 0;
 391                 }
 392 
 393                 kfree(pqn->q->properties.cu_mask);
 394                 pqn->q->properties.cu_mask = NULL;
 395                 uninit_queue(pqn->q);
 396         }
 397 
 398         list_del(&pqn->process_queue_list);
 399         kfree(pqn);
 400         clear_bit(qid, pqm->queue_slot_bitmap);
 401 
 402         if (list_empty(&pdd->qpd.queues_list) &&
 403             list_empty(&pdd->qpd.priv_queue_list))
 404                 dqm->ops.unregister_process(dqm, &pdd->qpd);
 405 
 406 err_destroy_queue:
 407         return retval;
 408 }
 409 
 410 int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
 411                         struct queue_properties *p)
 412 {
 413         int retval;
 414         struct process_queue_node *pqn;
 415 
 416         pqn = get_queue_by_qid(pqm, qid);
 417         if (!pqn) {
 418                 pr_debug("No queue %d exists for update operation\n", qid);
 419                 return -EFAULT;
 420         }
 421 
 422         pqn->q->properties.queue_address = p->queue_address;
 423         pqn->q->properties.queue_size = p->queue_size;
 424         pqn->q->properties.queue_percent = p->queue_percent;
 425         pqn->q->properties.priority = p->priority;
 426 
 427         retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
 428                                                         pqn->q);
 429         if (retval != 0)
 430                 return retval;
 431 
 432         return 0;
 433 }
 434 
 435 int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
 436                         struct queue_properties *p)
 437 {
 438         int retval;
 439         struct process_queue_node *pqn;
 440 
 441         pqn = get_queue_by_qid(pqm, qid);
 442         if (!pqn) {
 443                 pr_debug("No queue %d exists for update operation\n", qid);
 444                 return -EFAULT;
 445         }
 446 
 447         /* Free the old CU mask memory if it is already allocated, then
 448          * allocate memory for the new CU mask.
 449          */
 450         kfree(pqn->q->properties.cu_mask);
 451 
 452         pqn->q->properties.cu_mask_count = p->cu_mask_count;
 453         pqn->q->properties.cu_mask = p->cu_mask;
 454 
 455         retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
 456                                                         pqn->q);
 457         if (retval != 0)
 458                 return retval;
 459 
 460         return 0;
 461 }
 462 
 463 struct kernel_queue *pqm_get_kernel_queue(
 464                                         struct process_queue_manager *pqm,
 465                                         unsigned int qid)
 466 {
 467         struct process_queue_node *pqn;
 468 
 469         pqn = get_queue_by_qid(pqm, qid);
 470         if (pqn && pqn->kq)
 471                 return pqn->kq;
 472 
 473         return NULL;
 474 }
 475 
 476 int pqm_get_wave_state(struct process_queue_manager *pqm,
 477                        unsigned int qid,
 478                        void __user *ctl_stack,
 479                        u32 *ctl_stack_used_size,
 480                        u32 *save_area_used_size)
 481 {
 482         struct process_queue_node *pqn;
 483 
 484         pqn = get_queue_by_qid(pqm, qid);
 485         if (!pqn) {
 486                 pr_debug("amdkfd: No queue %d exists for operation\n",
 487                          qid);
 488                 return -EFAULT;
 489         }
 490 
 491         return pqn->q->device->dqm->ops.get_wave_state(pqn->q->device->dqm,
 492                                                        pqn->q,
 493                                                        ctl_stack,
 494                                                        ctl_stack_used_size,
 495                                                        save_area_used_size);
 496 }
 497 
 498 #if defined(CONFIG_DEBUG_FS)
 499 
 500 int pqm_debugfs_mqds(struct seq_file *m, void *data)
 501 {
 502         struct process_queue_manager *pqm = data;
 503         struct process_queue_node *pqn;
 504         struct queue *q;
 505         enum KFD_MQD_TYPE mqd_type;
 506         struct mqd_manager *mqd_mgr;
 507         int r = 0;
 508 
 509         list_for_each_entry(pqn, &pqm->queues, process_queue_list) {
 510                 if (pqn->q) {
 511                         q = pqn->q;
 512                         switch (q->properties.type) {
 513                         case KFD_QUEUE_TYPE_SDMA:
 514                         case KFD_QUEUE_TYPE_SDMA_XGMI:
 515                                 seq_printf(m, "  SDMA queue on device %x\n",
 516                                            q->device->id);
 517                                 mqd_type = KFD_MQD_TYPE_SDMA;
 518                                 break;
 519                         case KFD_QUEUE_TYPE_COMPUTE:
 520                                 seq_printf(m, "  Compute queue on device %x\n",
 521                                            q->device->id);
 522                                 mqd_type = KFD_MQD_TYPE_CP;
 523                                 break;
 524                         default:
 525                                 seq_printf(m,
 526                                 "  Bad user queue type %d on device %x\n",
 527                                            q->properties.type, q->device->id);
 528                                 continue;
 529                         }
 530                         mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type];
 531                 } else if (pqn->kq) {
 532                         q = pqn->kq->queue;
 533                         mqd_mgr = pqn->kq->mqd_mgr;
 534                         switch (q->properties.type) {
 535                         case KFD_QUEUE_TYPE_DIQ:
 536                                 seq_printf(m, "  DIQ on device %x\n",
 537                                            pqn->kq->dev->id);
 538                                 break;
 539                         default:
 540                                 seq_printf(m,
 541                                 "  Bad kernel queue type %d on device %x\n",
 542                                            q->properties.type,
 543                                            pqn->kq->dev->id);
 544                                 continue;
 545                         }
 546                 } else {
 547                         seq_printf(m,
 548                 "  Weird: Queue node with neither kernel nor user queue\n");
 549                         continue;
 550                 }
 551 
 552                 r = mqd_mgr->debugfs_show_mqd(m, q->mqd);
 553                 if (r != 0)
 554                         break;
 555         }
 556 
 557         return r;
 558 }
 559 
 560 #endif

/* [<][>][^][v][top][bottom][index][help] */