X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fraw%2Fioat%2Fidxd_pci.c;h=13515dbc6c9407fb31f0f8ad7295ffd58a61f98a;hb=07d4bde1c0e811ae60144ae74337237e6fb47e29;hp=b173c5ae383e7d11065b51cbfb37b55ee58bab5f;hpb=69c4162643e5b4e06c5de12bc02d0f20ce27ffca;p=dpdk.git diff --git a/drivers/raw/ioat/idxd_pci.c b/drivers/raw/ioat/idxd_pci.c index b173c5ae38..13515dbc6c 100644 --- a/drivers/raw/ioat/idxd_pci.c +++ b/drivers/raw/ioat/idxd_pci.c @@ -4,6 +4,7 @@ #include #include +#include #include "ioat_private.h" #include "ioat_spec.h" @@ -44,25 +45,87 @@ idxd_pci_dev_command(struct idxd_rawdev *idxd, enum rte_idxd_cmds command) return err_code & CMDSTATUS_ERR_MASK; } +static uint32_t * +idxd_get_wq_cfg(struct idxd_pci_common *pci, uint8_t wq_idx) +{ + return RTE_PTR_ADD(pci->wq_regs_base, + (uintptr_t)wq_idx << (5 + pci->wq_cfg_sz)); +} + static int idxd_is_wq_enabled(struct idxd_rawdev *idxd) { - uint32_t state = idxd->u.pci->wq_regs[idxd->qid].wqcfg[WQ_STATE_IDX]; + uint32_t state = idxd_get_wq_cfg(idxd->u.pci, idxd->qid)[WQ_STATE_IDX]; return ((state >> WQ_STATE_SHIFT) & WQ_STATE_MASK) == 0x1; } +static void +idxd_pci_dev_stop(struct rte_rawdev *dev) +{ + struct idxd_rawdev *idxd = dev->dev_private; + uint8_t err_code; + + if (!idxd_is_wq_enabled(idxd)) { + IOAT_PMD_ERR("Work queue %d already disabled", idxd->qid); + return; + } + + err_code = idxd_pci_dev_command(idxd, idxd_disable_wq); + if (err_code || idxd_is_wq_enabled(idxd)) { + IOAT_PMD_ERR("Failed disabling work queue %d, error code: %#x", + idxd->qid, err_code); + return; + } + IOAT_PMD_DEBUG("Work queue %d disabled OK", idxd->qid); +} + +static int +idxd_pci_dev_start(struct rte_rawdev *dev) +{ + struct idxd_rawdev *idxd = dev->dev_private; + uint8_t err_code; + + if (idxd_is_wq_enabled(idxd)) { + IOAT_PMD_WARN("WQ %d already enabled", idxd->qid); + return 0; + } + + if (idxd->public.desc_ring == NULL) { + IOAT_PMD_ERR("WQ %d has not been fully configured", idxd->qid); + return -EINVAL; + } + + err_code = idxd_pci_dev_command(idxd, idxd_enable_wq); + if (err_code || !idxd_is_wq_enabled(idxd)) { + IOAT_PMD_ERR("Failed enabling work queue %d, error code: %#x", + idxd->qid, err_code); + return err_code == 0 ? -1 : err_code; + } + + IOAT_PMD_DEBUG("Work queue %d enabled OK", idxd->qid); + + return 0; +} + static const struct rte_rawdev_ops idxd_pci_ops = { .dev_close = idxd_rawdev_close, - .dev_selftest = idxd_rawdev_test, + .dev_selftest = ioat_rawdev_test, .dump = idxd_dev_dump, .dev_configure = idxd_dev_configure, + .dev_start = idxd_pci_dev_start, + .dev_stop = idxd_pci_dev_stop, + .dev_info_get = idxd_dev_info_get, + .xstats_get = ioat_xstats_get, + .xstats_get_names = ioat_xstats_get_names, + .xstats_reset = ioat_xstats_reset, }; /* each portal uses 4 x 4k pages */ #define IDXD_PORTAL_SIZE (4096 * 4) static int -init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) +init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd, + unsigned int max_queues) { struct idxd_pci_common *pci; uint8_t nb_groups, nb_engines, nb_wqs; @@ -83,8 +146,9 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) grp_offset = (uint16_t)pci->regs->offsets[0]; pci->grp_regs = RTE_PTR_ADD(pci->regs, grp_offset * 0x100); wq_offset = (uint16_t)(pci->regs->offsets[0] >> 16); - pci->wq_regs = RTE_PTR_ADD(pci->regs, wq_offset * 0x100); + pci->wq_regs_base = RTE_PTR_ADD(pci->regs, wq_offset * 0x100); pci->portals = dev->mem_resource[2].addr; + pci->wq_cfg_sz = (pci->regs->wqcap >> 24) & 0x0F; /* sanity check device status */ if (pci->regs->gensts & GENSTS_DEV_STATE_MASK) { @@ -115,7 +179,17 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) pci->grp_regs[i].grpwqcfg[0] = 0; } for (i = 0; i < nb_wqs; i++) - pci->wq_regs[i].wqcfg[0] = 0; + idxd_get_wq_cfg(pci, i)[0] = 0; + + /* limit queues if necessary */ + if (max_queues != 0 && nb_wqs > max_queues) { + nb_wqs = max_queues; + if (nb_engines > max_queues) + nb_engines = max_queues; + if (nb_groups > max_queues) + nb_engines = max_queues; + IOAT_PMD_DEBUG("Limiting queues to %u", nb_wqs); + } /* put each engine into a separate group to avoid reordering */ if (nb_groups > nb_engines) @@ -140,10 +214,10 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) i, i % nb_groups); pci->grp_regs[i % nb_groups].grpwqcfg[0] |= (1ULL << i); /* now configure it, in terms of size, max batch, mode */ - pci->wq_regs[i].wqcfg[WQ_SIZE_IDX] = wq_size; - pci->wq_regs[i].wqcfg[WQ_MODE_IDX] = (1 << WQ_PRIORITY_SHIFT) | + idxd_get_wq_cfg(pci, i)[WQ_SIZE_IDX] = wq_size; + idxd_get_wq_cfg(pci, i)[WQ_MODE_IDX] = (1 << WQ_PRIORITY_SHIFT) | WQ_MODE_DEDICATED; - pci->wq_regs[i].wqcfg[WQ_SIZES_IDX] = lg2_max_copy_size | + idxd_get_wq_cfg(pci, i)[WQ_SIZES_IDX] = lg2_max_copy_size | (lg2_max_batch << WQ_BATCH_SZ_SHIFT); } @@ -180,12 +254,23 @@ idxd_rawdev_probe_pci(struct rte_pci_driver *drv, struct rte_pci_device *dev) uint8_t nb_wqs; int qid, ret = 0; char name[PCI_PRI_STR_SIZE]; + unsigned int max_queues = 0; rte_pci_device_name(&dev->addr, name, sizeof(name)); IOAT_PMD_INFO("Init %s on NUMA node %d", name, dev->device.numa_node); dev->device.driver = &drv->driver; - ret = init_pci_device(dev, &idxd); + if (dev->device.devargs && dev->device.devargs->args[0] != '\0') { + /* if the number of devargs grows beyond just 1, use rte_kvargs */ + if (sscanf(dev->device.devargs->args, + "max_queues=%u", &max_queues) != 1) { + IOAT_PMD_ERR("Invalid device parameter: '%s'", + dev->device.devargs->args); + return -1; + } + } + + ret = init_pci_device(dev, &idxd, max_queues); if (ret < 0) { IOAT_PMD_ERR("Error initializing PCI hardware"); return ret; @@ -236,6 +321,10 @@ idxd_rawdev_destroy(const char *name) } idxd = rdev->dev_private; + if (!idxd) { + IOAT_PMD_ERR("Error getting dev_private"); + return -EINVAL; + } /* disable the device */ err_code = idxd_pci_dev_command(idxd, idxd_disable_dev); @@ -246,13 +335,12 @@ idxd_rawdev_destroy(const char *name) IOAT_PMD_DEBUG("IDXD Device disabled OK"); /* free device memory */ - if (rdev->dev_private != NULL) { - IOAT_PMD_DEBUG("Freeing device driver memory"); - rdev->dev_private = NULL; - rte_free(idxd->public.batch_ring); - rte_free(idxd->public.hdl_ring); - rte_memzone_free(idxd->mz); - } + IOAT_PMD_DEBUG("Freeing device driver memory"); + rdev->dev_private = NULL; + rte_free(idxd->public.batch_idx_ring); + rte_free(idxd->public.desc_ring); + rte_free(idxd->public.hdl_ring); + rte_memzone_free(idxd->mz); /* rte_rawdev_close is called by pmd_release */ ret = rte_rawdev_pmd_release(rdev); @@ -289,3 +377,4 @@ RTE_PMD_REGISTER_PCI(IDXD_PMD_RAWDEV_NAME_PCI, idxd_pmd_drv_pci); RTE_PMD_REGISTER_PCI_TABLE(IDXD_PMD_RAWDEV_NAME_PCI, pci_id_idxd_map); RTE_PMD_REGISTER_KMOD_DEP(IDXD_PMD_RAWDEV_NAME_PCI, "* igb_uio | uio_pci_generic | vfio-pci"); +RTE_PMD_REGISTER_PARAM_STRING(rawdev_idxd_pci, "max_queues=0");