env_dpdk: track PCI devices internally for vtophys

Replace the use of the private rte_pci_bus list with our own internal
list of PCI devices inside SPDK.  This fixes linking against the shared
library version of DPDK.

Change-Id: Ia69555e4e7caa1a40974b7969d48773e36ae0fd7
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/405937
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Daniel Verkamp 2018-03-30 16:51:26 -07:00 committed by Jim Harris
parent 75ed184a79
commit 8e56cd4131
3 changed files with 67 additions and 13 deletions

View File

@ -88,15 +88,17 @@ int spdk_mem_map_init(void);
int spdk_vtophys_init(void);
/**
* Increase the refcount of active DMA-capable devices managed by SPDK.
* Report a DMA-capable PCI device to the vtophys translation code.
* Increases the refcount of active DMA-capable devices managed by SPDK.
* This must be called after a `rte_pci_device` is created.
*/
void spdk_vtophys_get_ref(void);
void spdk_vtophys_pci_device_added(struct rte_pci_device *pci_device);
/**
* Decrease the refcount of active DMA-capable devices managed by SPDK.
* Report the removal of a DMA-capable PCI device to the vtophys translation code.
* Decreases the refcount of active DMA-capable devices managed by SPDK.
* This must be called before a `rte_pci_device` is destroyed.
*/
void spdk_vtophys_put_ref(void);
void spdk_vtophys_pci_device_removed(struct rte_pci_device *pci_device);
#endif

View File

@ -72,14 +72,14 @@ spdk_pci_device_init(struct rte_pci_driver *driver,
return rc;
}
spdk_vtophys_get_ref();
spdk_vtophys_pci_device_added(device);
return 0;
}
int
spdk_pci_device_fini(struct rte_pci_device *device)
{
spdk_vtophys_put_ref();
spdk_vtophys_pci_device_removed(device);
return 0;
}

View File

@ -99,6 +99,16 @@ static struct vfio_cfg g_vfio = {
#define DEBUG_PRINT(...)
#endif
struct spdk_vtophys_pci_device {
struct rte_pci_device *pci_device;
TAILQ_ENTRY(spdk_vtophys_pci_device) tailq;
uint64_t ref;
};
static pthread_mutex_t g_vtophys_pci_devices_mutex = PTHREAD_MUTEX_INITIALIZER;
static TAILQ_HEAD(, spdk_vtophys_pci_device) g_vtophys_pci_devices =
TAILQ_HEAD_INITIALIZER(g_vtophys_pci_devices);
static struct spdk_mem_map *g_vtophys_map;
#if SPDK_VFIO_ENABLED
@ -262,16 +272,16 @@ vtophys_get_paddr_pagemap(uint64_t vaddr)
static uint64_t
vtophys_get_paddr_pci(uint64_t vaddr)
{
struct spdk_vtophys_pci_device *vtophys_dev;
uintptr_t paddr;
struct rte_pci_device *dev;
struct rte_mem_resource *res;
unsigned r;
#if RTE_VERSION >= RTE_VERSION_NUM(17, 05, 0, 2)
FOREACH_DEVICE_ON_PCIBUS(dev) {
#else
TAILQ_FOREACH(dev, &pci_device_list, next) {
#endif
pthread_mutex_lock(&g_vtophys_pci_devices_mutex);
TAILQ_FOREACH(vtophys_dev, &g_vtophys_pci_devices, tailq) {
dev = vtophys_dev->pci_device;
for (r = 0; r < PCI_MAX_RESOURCE; r++) {
res = &dev->mem_resource[r];
if (res->phys_addr && vaddr >= (uint64_t)res->addr &&
@ -279,10 +289,13 @@ vtophys_get_paddr_pci(uint64_t vaddr)
paddr = res->phys_addr + (vaddr - (uint64_t)res->addr);
DEBUG_PRINT("%s: %p -> %p\n", __func__, (void *)vaddr,
(void *)paddr);
pthread_mutex_unlock(&g_vtophys_pci_devices_mutex);
return paddr;
}
}
}
pthread_mutex_unlock(&g_vtophys_pci_devices_mutex);
return SPDK_VTOPHYS_ERROR;
}
@ -443,8 +456,32 @@ spdk_vtophys_iommu_init(void)
#endif
void
spdk_vtophys_get_ref(void)
spdk_vtophys_pci_device_added(struct rte_pci_device *pci_device)
{
struct spdk_vtophys_pci_device *vtophys_dev;
bool found = false;
pthread_mutex_lock(&g_vtophys_pci_devices_mutex);
TAILQ_FOREACH(vtophys_dev, &g_vtophys_pci_devices, tailq) {
if (vtophys_dev->pci_device == pci_device) {
vtophys_dev->ref++;
found = true;
break;
}
}
if (!found) {
vtophys_dev = calloc(1, sizeof(*vtophys_dev));
if (vtophys_dev) {
vtophys_dev->pci_device = pci_device;
vtophys_dev->ref = 1;
TAILQ_INSERT_TAIL(&g_vtophys_pci_devices, vtophys_dev, tailq);
} else {
DEBUG_PRINT("Memory allocation error\n");
}
}
pthread_mutex_unlock(&g_vtophys_pci_devices_mutex);
#if SPDK_VFIO_ENABLED
struct spdk_vfio_dma_map *dma_map;
int ret;
@ -476,8 +513,23 @@ spdk_vtophys_get_ref(void)
}
void
spdk_vtophys_put_ref(void)
spdk_vtophys_pci_device_removed(struct rte_pci_device *pci_device)
{
struct spdk_vtophys_pci_device *vtophys_dev;
pthread_mutex_lock(&g_vtophys_pci_devices_mutex);
TAILQ_FOREACH(vtophys_dev, &g_vtophys_pci_devices, tailq) {
if (vtophys_dev->pci_device == pci_device) {
assert(vtophys_dev->ref > 0);
if (--vtophys_dev->ref == 0) {
TAILQ_REMOVE(&g_vtophys_pci_devices, vtophys_dev, tailq);
free(vtophys_dev);
}
break;
}
}
pthread_mutex_unlock(&g_vtophys_pci_devices_mutex);
#if SPDK_VFIO_ENABLED
struct spdk_vfio_dma_map *dma_map;
int ret;