[dpdk-dev] [PATCH] vfio: retry creating sPAPR DMA window

Takeshi Yoshimura tyos at jp.ibm.com
Fri Jun 7 04:28:29 CEST 2019


sPAPR allows only page_shift from VFIO_IOMMU_SPAPR_TCE_GET_INFO ioctl.
However, Linux 4.17 or before returns incorrect page_shift for Power9.
I added the code for retrying creation of sPAPR DMA window.

Signed-off-by: Takeshi Yoshimura <tyos at jp.ibm.com>
---
 lib/librte_eal/linux/eal/eal_vfio.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/linux/eal/eal_vfio.c b/lib/librte_eal/linux/eal/eal_vfio.c
index 6892a2c14..f16c5c3c0 100644
--- a/lib/librte_eal/linux/eal/eal_vfio.c
+++ b/lib/librte_eal/linux/eal/eal_vfio.c
@@ -1448,9 +1448,29 @@ vfio_spapr_create_new_dma_window(int vfio_container_fd,
 	/* create new DMA window */
 	ret = ioctl(vfio_container_fd, VFIO_IOMMU_SPAPR_TCE_CREATE, create);
 	if (ret) {
-		RTE_LOG(ERR, EAL, "  cannot create new DMA window, "
-				"error %i (%s)\n", errno, strerror(errno));
-		return -1;
+		/* try possible page_shift and levels for workaround */
+		uint32_t levels;
+
+		for (levels = 1; levels <= info.ddw.levels; levels++) {
+			uint32_t pgsizes = info.ddw.pgsizes;
+
+			while (pgsizes != 0) {
+				create->page_shift = 31 - __builtin_clz(pgsizes);
+				create->levels = levels;
+				ret = ioctl(vfio_container_fd,
+					VFIO_IOMMU_SPAPR_TCE_CREATE, create);
+				if (!ret)
+					break;
+				pgsizes &= ~(1 << create->page_shift);
+			}
+			if (!ret)
+				break;
+		}
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  cannot create new DMA window, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
 	}
 
 	if (create->start_addr != 0) {
-- 
2.17.1



More information about the dev mailing list