linux/drivers/dma/idxd/init.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
   3#include <linux/init.h>
   4#include <linux/kernel.h>
   5#include <linux/module.h>
   6#include <linux/slab.h>
   7#include <linux/pci.h>
   8#include <linux/interrupt.h>
   9#include <linux/delay.h>
  10#include <linux/dma-mapping.h>
  11#include <linux/workqueue.h>
  12#include <linux/aer.h>
  13#include <linux/fs.h>
  14#include <linux/io-64-nonatomic-lo-hi.h>
  15#include <linux/device.h>
  16#include <linux/idr.h>
  17#include <uapi/linux/idxd.h>
  18#include <linux/dmaengine.h>
  19#include "../dmaengine.h"
  20#include "registers.h"
  21#include "idxd.h"
  22
  23MODULE_VERSION(IDXD_DRIVER_VERSION);
  24MODULE_LICENSE("GPL v2");
  25MODULE_AUTHOR("Intel Corporation");
  26
  27#define DRV_NAME "idxd"
  28
  29static struct idr idxd_idrs[IDXD_TYPE_MAX];
  30static struct mutex idxd_idr_lock;
  31
  32static struct pci_device_id idxd_pci_tbl[] = {
  33        /* DSA ver 1.0 platforms */
  34        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_DSA_SPR0) },
  35        { 0, }
  36};
  37MODULE_DEVICE_TABLE(pci, idxd_pci_tbl);
  38
  39static char *idxd_name[] = {
  40        "dsa",
  41};
  42
  43const char *idxd_get_dev_name(struct idxd_device *idxd)
  44{
  45        return idxd_name[idxd->type];
  46}
  47
  48static int idxd_setup_interrupts(struct idxd_device *idxd)
  49{
  50        struct pci_dev *pdev = idxd->pdev;
  51        struct device *dev = &pdev->dev;
  52        struct msix_entry *msix;
  53        struct idxd_irq_entry *irq_entry;
  54        int i, msixcnt;
  55        int rc = 0;
  56
  57        msixcnt = pci_msix_vec_count(pdev);
  58        if (msixcnt < 0) {
  59                dev_err(dev, "Not MSI-X interrupt capable.\n");
  60                goto err_no_irq;
  61        }
  62
  63        idxd->msix_entries = devm_kzalloc(dev, sizeof(struct msix_entry) *
  64                        msixcnt, GFP_KERNEL);
  65        if (!idxd->msix_entries) {
  66                rc = -ENOMEM;
  67                goto err_no_irq;
  68        }
  69
  70        for (i = 0; i < msixcnt; i++)
  71                idxd->msix_entries[i].entry = i;
  72
  73        rc = pci_enable_msix_exact(pdev, idxd->msix_entries, msixcnt);
  74        if (rc) {
  75                dev_err(dev, "Failed enabling %d MSIX entries.\n", msixcnt);
  76                goto err_no_irq;
  77        }
  78        dev_dbg(dev, "Enabled %d msix vectors\n", msixcnt);
  79
  80        /*
  81         * We implement 1 completion list per MSI-X entry except for
  82         * entry 0, which is for errors and others.
  83         */
  84        idxd->irq_entries = devm_kcalloc(dev, msixcnt,
  85                                         sizeof(struct idxd_irq_entry),
  86                                         GFP_KERNEL);
  87        if (!idxd->irq_entries) {
  88                rc = -ENOMEM;
  89                goto err_no_irq;
  90        }
  91
  92        for (i = 0; i < msixcnt; i++) {
  93                idxd->irq_entries[i].id = i;
  94                idxd->irq_entries[i].idxd = idxd;
  95        }
  96
  97        msix = &idxd->msix_entries[0];
  98        irq_entry = &idxd->irq_entries[0];
  99        rc = devm_request_threaded_irq(dev, msix->vector, idxd_irq_handler,
 100                                       idxd_misc_thread, 0, "idxd-misc",
 101                                       irq_entry);
 102        if (rc < 0) {
 103                dev_err(dev, "Failed to allocate misc interrupt.\n");
 104                goto err_no_irq;
 105        }
 106
 107        dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n",
 108                msix->vector);
 109
 110        /* first MSI-X entry is not for wq interrupts */
 111        idxd->num_wq_irqs = msixcnt - 1;
 112
 113        for (i = 1; i < msixcnt; i++) {
 114                msix = &idxd->msix_entries[i];
 115                irq_entry = &idxd->irq_entries[i];
 116
 117                init_llist_head(&idxd->irq_entries[i].pending_llist);
 118                INIT_LIST_HEAD(&idxd->irq_entries[i].work_list);
 119                rc = devm_request_threaded_irq(dev, msix->vector,
 120                                               idxd_irq_handler,
 121                                               idxd_wq_thread, 0,
 122                                               "idxd-portal", irq_entry);
 123                if (rc < 0) {
 124                        dev_err(dev, "Failed to allocate irq %d.\n",
 125                                msix->vector);
 126                        goto err_no_irq;
 127                }
 128                dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n",
 129                        i, msix->vector);
 130        }
 131
 132        idxd_unmask_error_interrupts(idxd);
 133
 134        return 0;
 135
 136 err_no_irq:
 137        /* Disable error interrupt generation */
 138        idxd_mask_error_interrupts(idxd);
 139        pci_disable_msix(pdev);
 140        dev_err(dev, "No usable interrupts\n");
 141        return rc;
 142}
 143
 144static void idxd_wqs_free_lock(struct idxd_device *idxd)
 145{
 146        int i;
 147
 148        for (i = 0; i < idxd->max_wqs; i++) {
 149                struct idxd_wq *wq = &idxd->wqs[i];
 150
 151                percpu_free_rwsem(&wq->submit_lock);
 152        }
 153}
 154
 155static int idxd_setup_internals(struct idxd_device *idxd)
 156{
 157        struct device *dev = &idxd->pdev->dev;
 158        int i;
 159
 160        idxd->groups = devm_kcalloc(dev, idxd->max_groups,
 161                                    sizeof(struct idxd_group), GFP_KERNEL);
 162        if (!idxd->groups)
 163                return -ENOMEM;
 164
 165        for (i = 0; i < idxd->max_groups; i++) {
 166                idxd->groups[i].idxd = idxd;
 167                idxd->groups[i].id = i;
 168                idxd->groups[i].tc_a = -1;
 169                idxd->groups[i].tc_b = -1;
 170        }
 171
 172        idxd->wqs = devm_kcalloc(dev, idxd->max_wqs, sizeof(struct idxd_wq),
 173                                 GFP_KERNEL);
 174        if (!idxd->wqs)
 175                return -ENOMEM;
 176
 177        idxd->engines = devm_kcalloc(dev, idxd->max_engines,
 178                                     sizeof(struct idxd_engine), GFP_KERNEL);
 179        if (!idxd->engines)
 180                return -ENOMEM;
 181
 182        for (i = 0; i < idxd->max_wqs; i++) {
 183                struct idxd_wq *wq = &idxd->wqs[i];
 184                int rc;
 185
 186                wq->id = i;
 187                wq->idxd = idxd;
 188                mutex_init(&wq->wq_lock);
 189                atomic_set(&wq->dq_count, 0);
 190                init_waitqueue_head(&wq->submit_waitq);
 191                wq->idxd_cdev.minor = -1;
 192                rc = percpu_init_rwsem(&wq->submit_lock);
 193                if (rc < 0) {
 194                        idxd_wqs_free_lock(idxd);
 195                        return rc;
 196                }
 197        }
 198
 199        for (i = 0; i < idxd->max_engines; i++) {
 200                idxd->engines[i].idxd = idxd;
 201                idxd->engines[i].id = i;
 202        }
 203
 204        return 0;
 205}
 206
 207static void idxd_read_table_offsets(struct idxd_device *idxd)
 208{
 209        union offsets_reg offsets;
 210        struct device *dev = &idxd->pdev->dev;
 211
 212        offsets.bits[0] = ioread64(idxd->reg_base + IDXD_TABLE_OFFSET);
 213        offsets.bits[1] = ioread64(idxd->reg_base + IDXD_TABLE_OFFSET
 214                        + sizeof(u64));
 215        idxd->grpcfg_offset = offsets.grpcfg * 0x100;
 216        dev_dbg(dev, "IDXD Group Config Offset: %#x\n", idxd->grpcfg_offset);
 217        idxd->wqcfg_offset = offsets.wqcfg * 0x100;
 218        dev_dbg(dev, "IDXD Work Queue Config Offset: %#x\n",
 219                idxd->wqcfg_offset);
 220        idxd->msix_perm_offset = offsets.msix_perm * 0x100;
 221        dev_dbg(dev, "IDXD MSIX Permission Offset: %#x\n",
 222                idxd->msix_perm_offset);
 223        idxd->perfmon_offset = offsets.perfmon * 0x100;
 224        dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset);
 225}
 226
 227static void idxd_read_caps(struct idxd_device *idxd)
 228{
 229        struct device *dev = &idxd->pdev->dev;
 230        int i;
 231
 232        /* reading generic capabilities */
 233        idxd->hw.gen_cap.bits = ioread64(idxd->reg_base + IDXD_GENCAP_OFFSET);
 234        dev_dbg(dev, "gen_cap: %#llx\n", idxd->hw.gen_cap.bits);
 235        idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift;
 236        dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes);
 237        idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift;
 238        dev_dbg(dev, "max batch size: %u\n", idxd->max_batch_size);
 239        if (idxd->hw.gen_cap.config_en)
 240                set_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags);
 241
 242        /* reading group capabilities */
 243        idxd->hw.group_cap.bits =
 244                ioread64(idxd->reg_base + IDXD_GRPCAP_OFFSET);
 245        dev_dbg(dev, "group_cap: %#llx\n", idxd->hw.group_cap.bits);
 246        idxd->max_groups = idxd->hw.group_cap.num_groups;
 247        dev_dbg(dev, "max groups: %u\n", idxd->max_groups);
 248        idxd->max_tokens = idxd->hw.group_cap.total_tokens;
 249        dev_dbg(dev, "max tokens: %u\n", idxd->max_tokens);
 250        idxd->nr_tokens = idxd->max_tokens;
 251
 252        /* read engine capabilities */
 253        idxd->hw.engine_cap.bits =
 254                ioread64(idxd->reg_base + IDXD_ENGCAP_OFFSET);
 255        dev_dbg(dev, "engine_cap: %#llx\n", idxd->hw.engine_cap.bits);
 256        idxd->max_engines = idxd->hw.engine_cap.num_engines;
 257        dev_dbg(dev, "max engines: %u\n", idxd->max_engines);
 258
 259        /* read workqueue capabilities */
 260        idxd->hw.wq_cap.bits = ioread64(idxd->reg_base + IDXD_WQCAP_OFFSET);
 261        dev_dbg(dev, "wq_cap: %#llx\n", idxd->hw.wq_cap.bits);
 262        idxd->max_wq_size = idxd->hw.wq_cap.total_wq_size;
 263        dev_dbg(dev, "total workqueue size: %u\n", idxd->max_wq_size);
 264        idxd->max_wqs = idxd->hw.wq_cap.num_wqs;
 265        dev_dbg(dev, "max workqueues: %u\n", idxd->max_wqs);
 266
 267        /* reading operation capabilities */
 268        for (i = 0; i < 4; i++) {
 269                idxd->hw.opcap.bits[i] = ioread64(idxd->reg_base +
 270                                IDXD_OPCAP_OFFSET + i * sizeof(u64));
 271                dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]);
 272        }
 273}
 274
 275static struct idxd_device *idxd_alloc(struct pci_dev *pdev,
 276                                      void __iomem * const *iomap)
 277{
 278        struct device *dev = &pdev->dev;
 279        struct idxd_device *idxd;
 280
 281        idxd = devm_kzalloc(dev, sizeof(struct idxd_device), GFP_KERNEL);
 282        if (!idxd)
 283                return NULL;
 284
 285        idxd->pdev = pdev;
 286        idxd->reg_base = iomap[IDXD_MMIO_BAR];
 287        spin_lock_init(&idxd->dev_lock);
 288
 289        return idxd;
 290}
 291
 292static int idxd_probe(struct idxd_device *idxd)
 293{
 294        struct pci_dev *pdev = idxd->pdev;
 295        struct device *dev = &pdev->dev;
 296        int rc;
 297
 298        dev_dbg(dev, "%s entered and resetting device\n", __func__);
 299        rc = idxd_device_reset(idxd);
 300        if (rc < 0)
 301                return rc;
 302        dev_dbg(dev, "IDXD reset complete\n");
 303
 304        idxd_read_caps(idxd);
 305        idxd_read_table_offsets(idxd);
 306
 307        rc = idxd_setup_internals(idxd);
 308        if (rc)
 309                goto err_setup;
 310
 311        rc = idxd_setup_interrupts(idxd);
 312        if (rc)
 313                goto err_setup;
 314
 315        dev_dbg(dev, "IDXD interrupt setup complete.\n");
 316
 317        mutex_lock(&idxd_idr_lock);
 318        idxd->id = idr_alloc(&idxd_idrs[idxd->type], idxd, 0, 0, GFP_KERNEL);
 319        mutex_unlock(&idxd_idr_lock);
 320        if (idxd->id < 0) {
 321                rc = -ENOMEM;
 322                goto err_idr_fail;
 323        }
 324
 325        idxd->major = idxd_cdev_get_major(idxd);
 326
 327        dev_dbg(dev, "IDXD device %d probed successfully\n", idxd->id);
 328        return 0;
 329
 330 err_idr_fail:
 331        idxd_mask_error_interrupts(idxd);
 332        idxd_mask_msix_vectors(idxd);
 333 err_setup:
 334        return rc;
 335}
 336
 337static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 338{
 339        void __iomem * const *iomap;
 340        struct device *dev = &pdev->dev;
 341        struct idxd_device *idxd;
 342        int rc;
 343        unsigned int mask;
 344
 345        rc = pcim_enable_device(pdev);
 346        if (rc)
 347                return rc;
 348
 349        dev_dbg(dev, "Mapping BARs\n");
 350        mask = (1 << IDXD_MMIO_BAR);
 351        rc = pcim_iomap_regions(pdev, mask, DRV_NAME);
 352        if (rc)
 353                return rc;
 354
 355        iomap = pcim_iomap_table(pdev);
 356        if (!iomap)
 357                return -ENOMEM;
 358
 359        dev_dbg(dev, "Set DMA masks\n");
 360        rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 361        if (rc)
 362                rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 363        if (rc)
 364                return rc;
 365
 366        rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 367        if (rc)
 368                rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 369        if (rc)
 370                return rc;
 371
 372        dev_dbg(dev, "Alloc IDXD context\n");
 373        idxd = idxd_alloc(pdev, iomap);
 374        if (!idxd)
 375                return -ENOMEM;
 376
 377        idxd_set_type(idxd);
 378
 379        dev_dbg(dev, "Set PCI master\n");
 380        pci_set_master(pdev);
 381        pci_set_drvdata(pdev, idxd);
 382
 383        idxd->hw.version = ioread32(idxd->reg_base + IDXD_VER_OFFSET);
 384        rc = idxd_probe(idxd);
 385        if (rc) {
 386                dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n");
 387                return -ENODEV;
 388        }
 389
 390        rc = idxd_setup_sysfs(idxd);
 391        if (rc) {
 392                dev_err(dev, "IDXD sysfs setup failed\n");
 393                return -ENODEV;
 394        }
 395
 396        idxd->state = IDXD_DEV_CONF_READY;
 397
 398        dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
 399                 idxd->hw.version);
 400
 401        return 0;
 402}
 403
 404static void idxd_flush_pending_llist(struct idxd_irq_entry *ie)
 405{
 406        struct idxd_desc *desc, *itr;
 407        struct llist_node *head;
 408
 409        head = llist_del_all(&ie->pending_llist);
 410        if (!head)
 411                return;
 412
 413        llist_for_each_entry_safe(desc, itr, head, llnode) {
 414                idxd_dma_complete_txd(desc, IDXD_COMPLETE_ABORT);
 415                idxd_free_desc(desc->wq, desc);
 416        }
 417}
 418
 419static void idxd_flush_work_list(struct idxd_irq_entry *ie)
 420{
 421        struct idxd_desc *desc, *iter;
 422
 423        list_for_each_entry_safe(desc, iter, &ie->work_list, list) {
 424                list_del(&desc->list);
 425                idxd_dma_complete_txd(desc, IDXD_COMPLETE_ABORT);
 426                idxd_free_desc(desc->wq, desc);
 427        }
 428}
 429
 430static void idxd_shutdown(struct pci_dev *pdev)
 431{
 432        struct idxd_device *idxd = pci_get_drvdata(pdev);
 433        int rc, i;
 434        struct idxd_irq_entry *irq_entry;
 435        int msixcnt = pci_msix_vec_count(pdev);
 436        unsigned long flags;
 437
 438        spin_lock_irqsave(&idxd->dev_lock, flags);
 439        rc = idxd_device_disable(idxd);
 440        spin_unlock_irqrestore(&idxd->dev_lock, flags);
 441        if (rc)
 442                dev_err(&pdev->dev, "Disabling device failed\n");
 443
 444        dev_dbg(&pdev->dev, "%s called\n", __func__);
 445        idxd_mask_msix_vectors(idxd);
 446        idxd_mask_error_interrupts(idxd);
 447
 448        for (i = 0; i < msixcnt; i++) {
 449                irq_entry = &idxd->irq_entries[i];
 450                synchronize_irq(idxd->msix_entries[i].vector);
 451                if (i == 0)
 452                        continue;
 453                idxd_flush_pending_llist(irq_entry);
 454                idxd_flush_work_list(irq_entry);
 455        }
 456}
 457
 458static void idxd_remove(struct pci_dev *pdev)
 459{
 460        struct idxd_device *idxd = pci_get_drvdata(pdev);
 461
 462        dev_dbg(&pdev->dev, "%s called\n", __func__);
 463        idxd_cleanup_sysfs(idxd);
 464        idxd_shutdown(pdev);
 465        idxd_wqs_free_lock(idxd);
 466        mutex_lock(&idxd_idr_lock);
 467        idr_remove(&idxd_idrs[idxd->type], idxd->id);
 468        mutex_unlock(&idxd_idr_lock);
 469}
 470
 471static struct pci_driver idxd_pci_driver = {
 472        .name           = DRV_NAME,
 473        .id_table       = idxd_pci_tbl,
 474        .probe          = idxd_pci_probe,
 475        .remove         = idxd_remove,
 476        .shutdown       = idxd_shutdown,
 477};
 478
 479static int __init idxd_init_module(void)
 480{
 481        int err, i;
 482
 483        /*
 484         * If the CPU does not support write512, there's no point in
 485         * enumerating the device. We can not utilize it.
 486         */
 487        if (!boot_cpu_has(X86_FEATURE_MOVDIR64B)) {
 488                pr_warn("idxd driver failed to load without MOVDIR64B.\n");
 489                return -ENODEV;
 490        }
 491
 492        pr_info("%s: Intel(R) Accelerator Devices Driver %s\n",
 493                DRV_NAME, IDXD_DRIVER_VERSION);
 494
 495        mutex_init(&idxd_idr_lock);
 496        for (i = 0; i < IDXD_TYPE_MAX; i++)
 497                idr_init(&idxd_idrs[i]);
 498
 499        err = idxd_register_bus_type();
 500        if (err < 0)
 501                return err;
 502
 503        err = idxd_register_driver();
 504        if (err < 0)
 505                goto err_idxd_driver_register;
 506
 507        err = idxd_cdev_register();
 508        if (err)
 509                goto err_cdev_register;
 510
 511        err = pci_register_driver(&idxd_pci_driver);
 512        if (err)
 513                goto err_pci_register;
 514
 515        return 0;
 516
 517err_pci_register:
 518        idxd_cdev_remove();
 519err_cdev_register:
 520        idxd_unregister_driver();
 521err_idxd_driver_register:
 522        idxd_unregister_bus_type();
 523        return err;
 524}
 525module_init(idxd_init_module);
 526
 527static void __exit idxd_exit_module(void)
 528{
 529        pci_unregister_driver(&idxd_pci_driver);
 530        idxd_cdev_remove();
 531        idxd_unregister_bus_type();
 532}
 533module_exit(idxd_exit_module);
 534