[v4,2/6] vfio: don't fail to DMA map if memory is already mapped

Message ID f451a92975d42538f63a2b5e50bdd1a39a40f527.1552206210.git.shahafs@mellanox.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series introduce DMA memory mapping for external memory |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Shahaf Shuler March 10, 2019, 8:27 a.m. UTC
  Currently vfio DMA map function will fail in case the same memory
segment is mapped twice.

This is too strict, as this is not an error to map the same memory
twice.

Instead, use the kernel return value to detect such state and have the
DMA function to return as successful.

For type1 mapping the kernel driver returns EEXISTS.
For spapr mapping EBUSY is returned since kernel 4.10.

Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_vfio.c | 32 +++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 9adbda8bb7..d0a0f9c16f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -1264,9 +1264,21 @@  vfio_type1_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova,
 
 		ret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
 		if (ret) {
-			RTE_LOG(ERR, EAL, "  cannot set up DMA remapping, error %i (%s)\n",
-				errno, strerror(errno));
+			/**
+			 * In case the mapping was already done EEXIST will be
+			 * returned from kernel.
+			 */
+			if (errno == EEXIST) {
+				RTE_LOG(DEBUG, EAL,
+					" Memory segment is allready mapped,"
+					" skipping");
+			} else {
+				RTE_LOG(ERR, EAL,
+					"  cannot set up DMA remapping,"
+					" error %i (%s)\n",
+					errno, strerror(errno));
 				return -1;
+			}
 		}
 	} else {
 		memset(&dma_unmap, 0, sizeof(dma_unmap));
@@ -1325,9 +1337,21 @@  vfio_spapr_dma_do_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova,
 
 		ret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
 		if (ret) {
-			RTE_LOG(ERR, EAL, "  cannot set up DMA remapping, error %i (%s)\n",
-				errno, strerror(errno));
+			/**
+			 * In case the mapping was already done EBUSY will be
+			 * returned from kernel.
+			 */
+			if (errno == EBUSY) {
+				RTE_LOG(DEBUG, EAL,
+					" Memory segment is allready mapped,"
+					" skipping");
+			} else {
+				RTE_LOG(ERR, EAL,
+					"  cannot set up DMA remapping,"
+					" error %i (%s)\n", errno,
+					strerror(errno));
 				return -1;
+			}
 		}
 
 	} else {