From 4d8c6a84407b977ee535dafbaa5c122e599dbb01 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Fri, 4 May 2018 03:14:23 -0700 Subject: [PATCH] env_dpdk: handle RTE_BAD_IOVA correctly in vtophys_get_paddr_pagemap We've had cases (especially with vhost) in the past where we have a valid vaddr but the backing page was not assigned yet. DPDK used to return 0 as the phys addr in these cases but now it returns RTE_BAD_IOVA. Unfortunately we don't have any tests currently in the test pool that hit this condition, but at least one user has an environment which hits it and this patch fixes their problem. Make sure we still work with older versions of DPDK as well. Fixes issue #260. Signed-off-by: Jim Harris Change-Id: Ie3c0ef54a3e34153bd0850ecfb2be4fcb92455b1 Reviewed-on: https://review.gerrithub.io/410071 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Dariusz Stojaczyk Reviewed-by: Daniel Verkamp --- lib/env_dpdk/vtophys.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/env_dpdk/vtophys.c b/lib/env_dpdk/vtophys.c index 254997c0a..a314a016a 100644 --- a/lib/env_dpdk/vtophys.c +++ b/lib/env_dpdk/vtophys.c @@ -250,21 +250,38 @@ vtophys_get_paddr_pagemap(uint64_t vaddr) { uintptr_t paddr; - paddr = rte_mem_virt2phy((void *)vaddr); - if (paddr == 0) { +#if RTE_VERSION >= RTE_VERSION_NUM(17, 11, 0, 3) +#define BAD_ADDR RTE_BAD_IOVA +#define VTOPHYS rte_mem_virt2iova +#else +#define BAD_ADDR RTE_BAD_PHYS_ADDR +#define VTOPHYS rte_mem_virt2phy +#endif + + /* + * Note: the virt2phy/virt2iova functions have changed over time, such + * that older versions may return 0 while recent versions will never + * return 0 but RTE_BAD_PHYS_ADDR/IOVA instead. To support older and + * newer versions, check for both return values. + */ + paddr = VTOPHYS((void *)vaddr); + if (paddr == 0 || paddr == BAD_ADDR) { /* - * The vaddr was valid but returned 0. Touch the page - * to ensure a backing page gets assigned, then call - * rte_mem_virt2phy() again. + * The vaddr may be valid but doesn't have a backing page + * assigned yet. Touch the page to ensure a backing page + * gets assigned, then try to translate again. */ rte_atomic64_read((rte_atomic64_t *)vaddr); - paddr = rte_mem_virt2phy((void *)vaddr); + paddr = VTOPHYS((void *)vaddr); } - if (paddr == RTE_BAD_PHYS_ADDR) { + if (paddr == 0 || paddr == BAD_ADDR) { /* Unable to get to the physical address. */ return SPDK_VTOPHYS_ERROR; } +#undef BAD_ADDR +#undef VTOPHYS + return paddr; }