linux/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
<<
>>
Prefs
   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
  31static 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
  45static 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
  67void 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
  78int 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
 127void 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
 135int 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
 148void 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
 165static 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
 191int 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
 326err_create_queue:
 327        kfree(pqn);
 328err_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
 337int 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
 406err_destroy_queue:
 407        return retval;
 408}
 409
 410int 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
 435int 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
 463struct 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
 476int 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
 500int 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
 561