From: David Marchand <david.marchand@6wind.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 3/7] pci: remove virtio-uio workaround
Date: Fri, 9 May 2014 15:15:55 +0200 [thread overview]
Message-ID: <1399641359-11267-4-git-send-email-david.marchand@6wind.com> (raw)
In-Reply-To: <1399641359-11267-1-git-send-email-david.marchand@6wind.com>
virtio-uio does not need eal to map bars from uio device, so remove flag
RTE_PCI_DRV_NEED_IGB_UIO.
Then, move virtio-uio workaround out of generic eal_pci.c for linux
implementation.
Signed-off-by: David Marchand <david.marchand@6wind.com>
---
lib/librte_eal/bsdapp/eal/eal_pci.c | 9 +--
lib/librte_eal/linuxapp/eal/eal_pci.c | 30 +-------
lib/librte_pmd_virtio/virtio_ethdev.c | 133 ++++++++++++++++++++++++++++++++-
3 files changed, 134 insertions(+), 38 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 5d8bcbd..a8945e4 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -221,8 +221,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
dev->intr_handle.fd = -1;
/* secondary processes - use already recorded details */
- if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
- (dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return (pci_uio_map_secondary(dev));
rte_snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
@@ -234,12 +233,6 @@ pci_uio_map_resource(struct rte_pci_device *dev)
return -1;
}
- if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
- /* I/O port address already assigned */
- /* rte_virtio_pmd does not need any other bar even if available */
- return (0);
- }
-
/* allocate the mapping details for secondary processes*/
if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
RTE_LOG(ERR, EAL,
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 99e07d2..c006cf5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -584,11 +584,9 @@ pci_uio_map_resource(struct rte_pci_device *dev)
{
int i, j;
char dirname[PATH_MAX];
- char filename[PATH_MAX];
char devname[PATH_MAX]; /* contains the /dev/uioX */
void *mapaddr;
int uio_num;
- unsigned long start,size;
uint64_t phaddr;
uint64_t offset;
uint64_t pagesz;
@@ -600,8 +598,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
dev->intr_handle.fd = -1;
/* secondary processes - use already recorded details */
- if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
- (dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return (pci_uio_map_secondary(dev));
/* find uio resource */
@@ -612,31 +609,6 @@ pci_uio_map_resource(struct rte_pci_device *dev)
return -1;
}
- if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
- /* get portio size */
- rte_snprintf(filename, sizeof(filename),
- "%s/portio/port0/size", dirname);
- if (eal_parse_sysfs_value(filename, &size) < 0) {
- RTE_LOG(ERR, EAL, "%s(): cannot parse size\n",
- __func__);
- return -1;
- }
-
- /* get portio start */
- rte_snprintf(filename, sizeof(filename),
- "%s/portio/port0/start", dirname);
- if (eal_parse_sysfs_value(filename, &start) < 0) {
- RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
- __func__);
- return -1;
- }
- dev->mem_resource[0].addr = (void *)(uintptr_t)start;
- dev->mem_resource[0].len = (uint64_t)size;
- RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx with size=0x%lx\n", start, size);
- /* rte_virtio_pmd does not need any other bar even if available */
- return (0);
- }
-
/* allocate the mapping details for secondary processes*/
if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
RTE_LOG(ERR, EAL,
diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c b/lib/librte_pmd_virtio/virtio_ethdev.c
index f107161..c6a1df5 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.c
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c
@@ -36,6 +36,9 @@
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
+#ifdef RTE_EXEC_ENV_LINUXAPP
+#include <dirent.h>
+#endif
#include <rte_ethdev.h>
#include <rte_memcpy.h>
@@ -392,6 +395,103 @@ virtio_negotiate_features(struct virtio_hw *hw)
hw->guest_features = vtpci_negotiate_features(hw, guest_features);
}
+#ifdef RTE_EXEC_ENV_LINUXAPP
+static int
+parse_sysfs_value(const char *filename, unsigned long *val)
+{
+ FILE *f;
+ char buf[BUFSIZ];
+ char *end = NULL;
+
+ if ((f = fopen(filename, "r")) == NULL) {
+ PMD_INIT_LOG(ERR, "%s(): cannot open sysfs value %s\n",
+ __func__, filename);
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ PMD_INIT_LOG(ERR, "%s(): cannot read sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ *val = strtoul(buf, &end, 0);
+ if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+ PMD_INIT_LOG(ERR, "%s(): cannot parse sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+ return 0;
+}
+
+static int get_uio_dev(struct rte_pci_addr *loc, char *buf, unsigned int buflen)
+{
+ unsigned int uio_num;
+ struct dirent *e;
+ DIR *dir;
+ char dirname[PATH_MAX];
+
+ /* depending on kernel version, uio can be located in uio/uioX
+ * or uio:uioX */
+ rte_snprintf(dirname, sizeof(dirname),
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
+ loc->domain, loc->bus, loc->devid, loc->function);
+ dir = opendir(dirname);
+ if (dir == NULL) {
+ /* retry with the parent directory */
+ rte_snprintf(dirname, sizeof(dirname),
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
+ loc->domain, loc->bus, loc->devid, loc->function);
+ dir = opendir(dirname);
+
+ if (dir == NULL) {
+ PMD_INIT_LOG(ERR, "Cannot opendir %s\n", dirname);
+ return -1;
+ }
+ }
+
+ /* take the first file starting with "uio" */
+ while ((e = readdir(dir)) != NULL) {
+ /* format could be uio%d ...*/
+ int shortprefix_len = sizeof("uio") - 1;
+ /* ... or uio:uio%d */
+ int longprefix_len = sizeof("uio:uio") - 1;
+ char *endptr;
+
+ if (strncmp(e->d_name, "uio", 3) != 0)
+ continue;
+
+ /* first try uio%d */
+ errno = 0;
+ uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+ if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+ rte_snprintf(buf, buflen, "%s/uio%u", dirname, uio_num);
+ break;
+ }
+
+ /* then try uio:uio%d */
+ errno = 0;
+ uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+ if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+ rte_snprintf(buf, buflen, "%s/uio:uio%u", dirname,
+ uio_num);
+ break;
+ }
+ }
+ closedir(dir);
+
+ /* No uio resource found */
+ if (e == NULL) {
+ PMD_INIT_LOG(ERR, "Could not find uio resource\n");
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
/*
* This function is based on probe() function in virtio_pci.c
* It returns 0 on success.
@@ -426,6 +526,38 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
hw->device_id = pci_dev->id.device_id;
hw->vendor_id = pci_dev->id.vendor_id;
+#ifdef RTE_EXEC_ENV_LINUXAPP
+ {
+ char dirname[PATH_MAX];
+ char filename[PATH_MAX];
+ unsigned long start,size;
+
+ if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname)) < 0)
+ return -1;
+
+ /* get portio size */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/size", dirname);
+ if (parse_sysfs_value(filename, &size) < 0) {
+ PMD_INIT_LOG(ERR, "%s(): cannot parse size\n",
+ __func__);
+ return -1;
+ }
+
+ /* get portio start */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/start", dirname);
+ if (parse_sysfs_value(filename, &start) < 0) {
+ PMD_INIT_LOG(ERR, "%s(): cannot parse portio start\n",
+ __func__);
+ return -1;
+ }
+ pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
+ pci_dev->mem_resource[0].len = (uint64_t)size;
+ PMD_INIT_LOG(DEBUG, "PCI Port IO found start=0x%lx with "
+ "size=0x%lx\n", start, size);
+ }
+#endif
hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
hw->max_rx_queues = VIRTIO_MAX_RX_QUEUES;
@@ -474,7 +606,6 @@ static struct eth_driver rte_virtio_pmd = {
{
.name = "rte_virtio_pmd",
.id_table = pci_id_virtio_map,
- .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
},
.eth_dev_init = eth_virtio_dev_init,
.dev_private_size = sizeof(struct virtio_adapter),
--
1.7.10.4
next prev parent reply other threads:[~2014-05-09 13:16 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-09 13:15 [dpdk-dev] [PATCH v2 0/7] pci cleanup David Marchand
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 1/7] pci: fix potential mem leaks David Marchand
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 2/7] pci: align bsd implementation on linux David Marchand
2014-05-09 13:15 ` David Marchand [this message]
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 4/7] pci: rework interrupt fd init and fix fd leak David Marchand
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 5/7] pci: pci_switch_module cleanup David Marchand
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 6/7] pci: move RTE_PCI_DRV_FORCE_UNBIND handling out of #ifdef David Marchand
2014-05-09 13:15 ` [dpdk-dev] [PATCH v2 7/7] pci: remove deprecated RTE_EAL_UNBIND_PORTS option David Marchand
2014-05-13 14:29 ` [dpdk-dev] [PATCH v2 0/7] pci cleanup Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1399641359-11267-4-git-send-email-david.marchand@6wind.com \
--to=david.marchand@6wind.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).