Sorry, missed send this mail. Ignore it pls.
> -Original Message-
> From: Mo, YufengX
> Sent: Tuesday, June 18, 2019 10:38 AM
> To: Mo, YufengX ; dev@dpdk.org
> Cc: d...@ibm.com; prad...@us.ibm.com; Takeshi Yoshimura
> Subject: [dpdk-dev] [PATCH] vfio: fix expanding DMA area in ppc64le
>
> From: Takeshi Yoshimura
>
> In ppc64le, expanding DMA areas always fail because we cannot remove
> a DMA window. As a result, we cannot allocate more than one memseg in
> ppc64le. This is because vfio_spapr_dma_mem_map() doesn't unmap all
> the mapped DMA before removing the window. This patch fixes this
> incorrect behavior.
>
> I added a global variable to track current window size since we do
> not have better ways to get exact size of it than doing so. sPAPR
> IOMMU seems not to provide any ways to get window size with ioctl
> interfaces. rte_memseg_walk*() is currently used to calculate window
> size, but it walks memsegs that are marked as used, not mapped. So,
> we need to determine if a given memseg is mapped or not, otherwise
> the ioctl reports errors due to attempting to unregister memory
> addresses that are not registered. The global variable is excluded
> in non-ppc64le binaries.
>
> Similar problems happen in user maps. We need to avoid attempting to
> unmap the address that is given as the function's parameter. The
> compaction of user maps prevents us from passing correct length for
> unmapping DMA at the window recreation. So, I removed it in ppc64le.
>
> I also fixed the order of ioctl for unregister and unmap. The ioctl
> for unregister sometimes report device busy errors due to the
> existence of mapped area.
>
> Signed-off-by: Takeshi Yoshimura
> ---
> lib/librte_eal/linux/eal/eal_vfio.c | 154 +++-
> 1 file changed, 103 insertions(+), 51 deletions(-)
>
> diff --git a/lib/librte_eal/linux/eal/eal_vfio.c
> b/lib/librte_eal/linux/eal/eal_vfio.c
> index f16c5c3c0..c1b275b56 100644
> --- a/lib/librte_eal/linux/eal/eal_vfio.c
> +++ b/lib/librte_eal/linux/eal/eal_vfio.c
> @@ -93,6 +93,7 @@ is_null_map(const struct user_mem_map *map)
> return map->addr == 0 && map->iova == 0 && map->len == 0;
> }
>
> +#ifndef RTE_ARCH_PPC_64
> /* we may need to merge user mem maps together in case of user
> mapping/unmapping
> * chunks of memory, so we'll need a comparator function to sort segments.
> */
> @@ -126,6 +127,7 @@ user_mem_map_cmp(const void *a, const void *b)
>
> return 0;
> }
> +#endif
>
> /* adjust user map entry. this may result in shortening of existing map, or
> in
> * splitting existing map in two pieces.
> @@ -162,6 +164,7 @@ adjust_map(struct user_mem_map *src, struct user_mem_map
> *end,
> }
> }
>
> +#ifndef RTE_ARCH_PPC_64
> /* try merging two maps into one, return 1 if succeeded */
> static int
> merge_map(struct user_mem_map *left, struct user_mem_map *right)
> @@ -177,6 +180,7 @@ merge_map(struct user_mem_map *left, struct user_mem_map
> *right)
>
> return 1;
> }
> +#endif
>
> static struct user_mem_map *
> find_user_mem_map(struct user_mem_maps *user_mem_maps, uint64_t addr,
> @@ -211,6 +215,16 @@ find_user_mem_map(struct user_mem_maps *user_mem_maps,
> uint64_t addr,
> return NULL;
> }
>
> +#ifdef RTE_ARCH_PPC_64
> +/* Recreation of DMA window requires unregistering DMA memory.
> + * Compaction confuses the logic and causes false reports in the recreation.
> + * For now, we do not compact user maps in ppc64le.
> + */
> +static void
> +compact_user_maps(__rte_unused struct user_mem_maps *user_mem_maps)
> +{
> +}
> +#else
> /* this will sort all user maps, and merge/compact any adjacent maps */
> static void
> compact_user_maps(struct user_mem_maps *user_mem_maps)
> @@ -256,6 +270,7 @@ compact_user_maps(struct user_mem_maps *user_mem_maps)
> user_mem_maps->n_maps = cur_idx;
> }
> }
> +#endif
>
> static int
> vfio_open_group_fd(int iommu_group_num)
> @@ -1306,6 +1321,7 @@ vfio_type1_dma_map(int vfio_container_fd)
> return rte_memseg_walk(type1_map, &vfio_container_fd);
> }
>
> +#ifdef RTE_ARCH_PPC_64
> static int
> vfio_spapr_dma_do_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova,
> uint64_t len, int do_map)
> @@ -1357,14 +1373,6 @@ vfio_spapr_dma_do_map(int vfio_container_fd, uint64_t
> vaddr, uint64_t iova,
> }
>
> } else {
> - ret = ioctl(vfio_container_fd,
> - VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY, ®);
> - if (ret) {
> - RTE_LOG