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 <james.r.harris@intel.com>
Change-Id: Ie3c0ef54a3e34153bd0850ecfb2be4fcb92455b1

Reviewed-on: https://review.gerrithub.io/410071
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2018-05-04 03:14:23 -07:00 committed by Daniel Verkamp
parent 08daa4477e
commit 4d8c6a8440

View File

@ -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
/*
* The vaddr was valid but returned 0. Touch the page
* to ensure a backing page gets assigned, then call
* rte_mem_virt2phy() again.
* 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 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;
}