[dpdk-dev] [PATCH v4 66/70] bus/fslmc: enable support for mem event callbacks for vfio
Shreyansh Jain
shreyansh.jain at nxp.com
Mon Apr 9 12:01:28 CEST 2018
Hi Anatoly,
On Monday 09 April 2018 01:48 AM, Anatoly Burakov wrote:
> VFIO needs to map and unmap segments for DMA whenever they
> become available or unavailable, so register a callback for
> memory events, and provide map/unmap functions.
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
> ---
> drivers/bus/fslmc/fslmc_vfio.c | 150 +++++++++++++++++++++++++++++++++++++----
> 1 file changed, 136 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
> index db3eb61..dfdd2bc 100644
> --- a/drivers/bus/fslmc/fslmc_vfio.c
> +++ b/drivers/bus/fslmc/fslmc_vfio.c
> @@ -30,6 +30,7 @@
> #include <rte_kvargs.h>
> #include <rte_dev.h>
> #include <rte_bus.h>
> +#include <rte_eal_memconfig.h>
>
> #include "rte_fslmc.h"
> #include "fslmc_vfio.h"
> @@ -188,11 +189,57 @@ static int vfio_map_irq_region(struct fslmc_vfio_group *group)
> return -errno;
> }
>
> +static int fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
> +static int fslmc_unmap_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
> +
> +static void
> +fslmc_memevent_cb(enum rte_mem_event type, const void *addr, size_t len)
> +{
> + struct rte_memseg_list *msl;
> + struct rte_memseg *ms;
> + size_t cur_len = 0, map_len = 0;
> + uint64_t virt_addr;
> + rte_iova_t iova_addr;
> + int ret;
> +
> + msl = rte_mem_virt2memseg_list(addr);
> +
> + while (cur_len < len) {
> + const void *va = RTE_PTR_ADD(addr, cur_len);
> +
> + ms = rte_mem_virt2memseg(va, msl);
> + iova_addr = ms->iova;
> + virt_addr = ms->addr_64;
> + map_len = ms->len;
> +
> + DPAA2_BUS_DEBUG("Calling with type=%d, va=%p, virt_addr=0x%" PRIx64 ", iova=0x%" PRIx64 ", map_len=%zu\n",
I would like to correct this message (80char + rewording) - What do you
suggest? Should I send a new patch to you or just convey what should be
changed?
> + type, va, virt_addr, iova_addr, map_len);
> +
> + if (type == RTE_MEM_EVENT_ALLOC)
> + ret = fslmc_map_dma(virt_addr, iova_addr, map_len);
> + else
> + ret = fslmc_unmap_dma(virt_addr, iova_addr, map_len);
> +
> + if (ret != 0) {
> + DPAA2_BUS_ERR("DMA Mapping/Unmapping failed. Map=%d, addr=%p, len=%zu, err:(%d)",
> + type, va, map_len, ret);
Same as above. 80 Char issue.
> + return;
> + }
> +
> + cur_len += map_len;
> + }
> +
> + if (type == RTE_MEM_EVENT_ALLOC)
> + DPAA2_BUS_DEBUG("Total Mapped: addr=%p, len=%zu\n",
> + addr, len);
> + else
> + DPAA2_BUS_DEBUG("Total Unmapped: addr=%p, len=%zu\n",
> + addr, len);
> +}
> +
> static int
> -fslmc_vfio_map(const struct rte_memseg_list *msl __rte_unused,
> - const struct rte_memseg *ms, void *arg)
> +fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr __rte_unused, size_t len)
> {
> - int *n_segs = arg;
> struct fslmc_vfio_group *group;
> struct vfio_iommu_type1_dma_map dma_map = {
> .argsz = sizeof(struct vfio_iommu_type1_dma_map),
> @@ -200,10 +247,11 @@ fslmc_vfio_map(const struct rte_memseg_list *msl __rte_unused,
> };
> int ret;
>
> - dma_map.size = ms->len;
> - dma_map.vaddr = ms->addr_64;
> + dma_map.size = len;
> + dma_map.vaddr = vaddr;
> +
> #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
> - dma_map.iova = ms->iova;
> + dma_map.iova = iovaddr;
> #else
> dma_map.iova = dma_map.vaddr;
> #endif
> @@ -216,30 +264,99 @@ fslmc_vfio_map(const struct rte_memseg_list *msl __rte_unused,
> return -1;
> }
>
> - DPAA2_BUS_DEBUG("-->Initial SHM Virtual ADDR %llX",
> - dma_map.vaddr);
> - DPAA2_BUS_DEBUG("-----> DMA size 0x%llX", dma_map.size);
> - ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA,
> - &dma_map);
> + DPAA2_BUS_DEBUG("--> Map address: %llX, size: 0x%llX\n",
> + dma_map.vaddr, dma_map.size);
> + ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map);
> if (ret) {
> DPAA2_BUS_ERR("VFIO_IOMMU_MAP_DMA API(errno = %d)",
> errno);
> return -1;
> }
> - (*n_segs)++;
> +
> return 0;
> }
>
> +static int
> +fslmc_unmap_dma(uint64_t vaddr, uint64_t iovaddr __rte_unused, size_t len)
> +{
> + struct fslmc_vfio_group *group;
> + struct vfio_iommu_type1_dma_unmap dma_unmap = {
> + .argsz = sizeof(struct vfio_iommu_type1_dma_unmap),
> + .flags = 0,
> + };
> + int ret;
> +
> + dma_unmap.size = len;
> + dma_unmap.iova = vaddr;
> +
> + /* SET DMA MAP for IOMMU */
> + group = &vfio_group;
> +
> + if (!group->container) {
> + DPAA2_BUS_ERR("Container is not connected ");
> + return -1;
> + }
> +
> + DPAA2_BUS_DEBUG("--> Unmap address: %llX, size: 0x%llX\n",
> + dma_unmap.iova, dma_unmap.size);
> + ret = ioctl(group->container->fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
> + if (ret) {
> + DPAA2_BUS_ERR("VFIO_IOMMU_UNMAP_DMA API(errno = %d)",
> + errno);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +fslmc_dmamap_seg(const struct rte_memseg_list *msl __rte_unused,
> + const struct rte_memseg *ms, void *arg)
> +{
> + int *n_segs = arg;
> + int ret;
> +
> + ret = fslmc_map_dma(ms->addr_64, ms->iova, ms->len);
> + if (ret)
> + DPAA2_BUS_ERR("Unable to VFIO map (addr=%p, len=%zu)\n",
> + ms->addr, ms->len);
> + else
> + (*n_segs)++;
> +
> + return ret;
> +}
> +
> int rte_fslmc_vfio_dmamap(void)
> {
> - int i = 0;
> + int i = 0, ret;
> + struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
> + rte_rwlock_t *mem_lock = &mcfg->memory_hotplug_lock;
> +
> + /* Lock before parsing and registering callback to memory subsystem */
> + rte_rwlock_read_lock(mem_lock);
>
> - if (rte_memseg_walk(fslmc_vfio_map, &i) < 0)
> + if (rte_memseg_walk(fslmc_dmamap_seg, &i) < 0) {
> + rte_rwlock_read_unlock(mem_lock);
> return -1;
> + }
> +
> + ret = rte_mem_event_callback_register("fslmc_memevent_clb",
> + fslmc_memevent_cb);
> + if (ret && rte_errno == ENOTSUP)
> + DPAA2_BUS_DEBUG("Memory event callbacks not supported");
> + else if (ret)
> + DPAA2_BUS_DEBUG("Unable to install memory handler");
> + else
> + DPAA2_BUS_DEBUG("Installed memory callback handler");
>
> /* Verifying that at least single segment is available */
> if (i <= 0) {
> + /* TODO: Is this verification required any more? What would
> + * happen to non-legacy case where nothing was preallocated
> + * thus causing i==0?
> + */
And this as well - if call backs are not going to appear in case of
legacy, this needs to be removed.
let me know how do you want to take these changes.
> DPAA2_BUS_ERR("No Segments found for VFIO Mapping");
> + rte_rwlock_read_unlock(mem_lock);
> return -1;
> }
> DPAA2_BUS_DEBUG("Total %d segments found.", i);
> @@ -250,6 +367,11 @@ int rte_fslmc_vfio_dmamap(void)
> */
> vfio_map_irq_region(&vfio_group);
>
> + /* Existing segments have been mapped and memory callback for hotplug
> + * has been installed.
> + */
> + rte_rwlock_read_unlock(mem_lock);
> +
> return 0;
> }
>
>
More information about the dev
mailing list