From: Stephen Hemminger <stephen@networkplumber.org>
To: alexmay@microsoft.com
Cc: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 3/7] hv: add basic vmbus support
Date: Mon, 20 Apr 2015 14:54:10 -0700 [thread overview]
Message-ID: <1429566854-17490-4-git-send-email-stephen@networkplumber.org> (raw)
In-Reply-To: <1429566854-17490-1-git-send-email-stephen@networkplumber.org>
The hyper-v device driver forces the base EAL code to change
to support multiple bus types. This is done changing the pci_device
in ether driver to a generic union.
As much as possible this is done in a backwards source compatiable
way. It will break ABI for device drivers.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_options.c | 5 ++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 +
lib/librte_eal/common/eal_private.h | 10 +++
lib/librte_eal/linuxapp/eal/Makefile | 3 +
lib/librte_eal/linuxapp/eal/eal.c | 11 +++
lib/librte_ether/rte_ethdev.c | 128 +++++++++++++++++++++++++++--
lib/librte_ether/rte_ethdev.h | 15 +++-
9 files changed, 168 insertions(+), 9 deletions(-)
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 3ea3bbf..202485e 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h rte_vmbus.h
INC += rte_pci_dev_ids.h rte_per_lcore.h rte_random.h
INC += rte_rwlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 8fcb1ab..76a3394 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -80,6 +80,7 @@ eal_long_options[] = {
{OPT_NO_HPET, 0, NULL, OPT_NO_HPET_NUM },
{OPT_NO_HUGE, 0, NULL, OPT_NO_HUGE_NUM },
{OPT_NO_PCI, 0, NULL, OPT_NO_PCI_NUM },
+ {OPT_NO_VMBUS, 0, NULL, OPT_NO_VMBUS_NUM },
{OPT_NO_SHCONF, 0, NULL, OPT_NO_SHCONF_NUM },
{OPT_PCI_BLACKLIST, 1, NULL, OPT_PCI_BLACKLIST_NUM },
{OPT_PCI_WHITELIST, 1, NULL, OPT_PCI_WHITELIST_NUM },
@@ -726,6 +727,10 @@ eal_parse_common_option(int opt, const char *optarg,
conf->no_pci = 1;
break;
+ case OPT_NO_VMBUS_NUM:
+ conf->no_vmbus = 1;
+ break;
+
case OPT_NO_HPET_NUM:
conf->no_hpet = 1;
break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index e2ecb0d..0e7de34 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -66,6 +66,7 @@ struct internal_config {
volatile unsigned no_hugetlbfs; /**< true to disable hugetlbfs */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
+ volatile unsigned no_vmbus; /**< true to disable VMBUS */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index f6714d9..54f03dc 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -67,6 +67,8 @@ enum {
OPT_NO_HUGE_NUM,
#define OPT_NO_PCI "no-pci"
OPT_NO_PCI_NUM,
+#define OPT_NO_VMBUS "no-vmbus"
+ OPT_NO_VMBUS_NUM,
#define OPT_NO_SHCONF "no-shconf"
OPT_NO_SHCONF_NUM,
#define OPT_SOCKET_MEM "socket-mem"
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 4acf5a0..039e9f3 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -180,6 +180,16 @@ int rte_eal_pci_close_one_driver(struct rte_pci_driver *dr,
struct rte_pci_device *dev);
/**
+ * VMBUS related functions and structures
+ */
+int rte_eal_vmbus_init(void);
+
+struct rte_vmbus_driver;
+struct rte_vmbus_device;
+
+int rte_eal_vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
+ struct rte_vmbus_device *dev);
+/**
* Init tail queues for non-EAL library structures. This is to allow
* the rings, mempools, etc. lists to be shared among multiple processes
*
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 01f7b70..acd5127 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -74,6 +74,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_alarm.c
ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y)
SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_ivshmem.c
endif
+ifeq ($(CONFIG_RTE_LIBRTE_HV_PMD),y)
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_vmbus.c
+endif
# from common dir
SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_memzone.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index bd770cf..86d0e31 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_vmbus.h>
#include <rte_devargs.h>
#include <rte_common.h>
#include <rte_version.h>
@@ -796,6 +797,11 @@ rte_eal_init(int argc, char **argv)
rte_eal_mcfg_complete();
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_init() < 0)
+ RTE_LOG(ERR, EAL, "Cannot init VMBUS\n");
+#endif
+
TAILQ_FOREACH(solib, &solib_list, next) {
RTE_LOG(INFO, EAL, "open shared lib %s\n", solib->name);
solib->lib_handle = dlopen(solib->name, RTLD_NOW);
@@ -845,6 +851,11 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_probe() < 0)
+ rte_panic("Cannot probe VMBUS\n");
+#endif
+
return fctret;
}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9577d17..9093966 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -379,6 +379,98 @@ rte_eth_dev_uninit(struct rte_pci_device *pci_dev)
return 0;
}
+#ifdef RTE_LIBRTE_HV_PMD
+static int
+rte_vmbus_dev_init(struct rte_vmbus_driver *vmbus_drv,
+ struct rte_vmbus_device *vmbus_dev)
+{
+ struct eth_driver *eth_drv = (struct eth_driver *)vmbus_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+ int diag;
+
+ snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%u_%u",
+ vmbus_dev->id.device_id, vmbus_dev->id.sysfs_num);
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name, RTE_ETH_DEV_PCI);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
+ eth_drv->dev_private_size,
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private port data\n");
+ }
+ eth_dev->vmbus_dev = vmbus_dev;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ /*
+ * Set the default maximum frame size.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = (*eth_drv->eth_dev_init)(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ PMD_DEBUG_TRACE("driver %s: eth_dev_init(device_id=0x%x)"
+ " failed\n", vmbus_drv->name,
+ (unsigned) vmbus_dev->id.device_id);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ nb_ports--;
+ return diag;
+}
+
+
+static int
+rte_vmbus_dev_uninit(struct rte_vmbus_device *vmbus_dev)
+{
+ const struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+ int ret;
+
+ if (vmbus_dev == NULL)
+ return -EINVAL;
+
+ snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%u_%u",
+ vmbus_dev->id.device_id, vmbus_dev->id.sysfs_num);
+
+ eth_dev = rte_eth_dev_allocated(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENODEV;
+
+ eth_drv = (const struct eth_driver *)vmbus_dev->driver;
+
+ /* Invoke PMD device uninit function */
+ if (*eth_drv->eth_dev_uninit) {
+ ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+ if (ret)
+ return ret;
+ }
+
+ /* free ether device */
+ rte_eth_dev_release_port(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ eth_dev->pci_dev = NULL;
+ eth_dev->driver = NULL;
+ eth_dev->data = NULL;
+
+ return 0;
+}
+#endif
+
/**
* Register an Ethernet [Poll Mode] driver.
*
@@ -396,9 +488,22 @@ rte_eth_dev_uninit(struct rte_pci_device *pci_dev)
void
rte_eth_driver_register(struct eth_driver *eth_drv)
{
- eth_drv->pci_drv.devinit = rte_eth_dev_init;
- eth_drv->pci_drv.devuninit = rte_eth_dev_uninit;
- rte_eal_pci_register(ð_drv->pci_drv);
+ switch (eth_drv->bus_type) {
+ case RTE_BUS_PCI:
+ eth_drv->pci_drv.devinit = rte_eth_dev_init;
+ eth_drv->pci_drv.devuninit = rte_eth_dev_uninit;
+ rte_eal_pci_register(ð_drv->pci_drv);
+ break;
+#ifdef RTE_LIBRTE_HV_PMD
+ case RTE_BUS_VMBUS:
+ eth_drv->vmbus_drv.devinit = rte_vmbus_dev_init;
+ eth_drv->vmbus_drv.devuninit = rte_vmbus_dev_uninit;
+ rte_eal_vmbus_register(ð_drv->vmbus_drv);
+ break;
+#endif
+ default:
+ rte_panic("unknown bus type %u\n", eth_drv->bus_type);
+ }
}
static int
@@ -1351,6 +1456,9 @@ rte_eth_has_link_state(uint8_t port_id)
}
dev = &rte_eth_devices[port_id];
+ if (dev->driver->bus_type != RTE_BUS_PCI)
+ return 0;
+
return (dev->pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC) != 0;
}
@@ -1901,9 +2009,17 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
- dev_info->pci_dev = dev->pci_dev;
- if (dev->driver)
- dev_info->driver_name = dev->driver->pci_drv.name;
+
+ if (dev->driver) {
+ switch (dev->driver->bus_type) {
+ case RTE_BUS_PCI:
+ dev_info->driver_name = dev->driver->pci_drv.name;
+ dev_info->pci_dev = dev->pci_dev;
+ break;
+ case RTE_BUS_VMBUS:
+ dev_info->driver_name = dev->driver->vmbus_drv.name;
+ }
+ }
}
void
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 991023b..9e08f3e 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -178,6 +178,7 @@ extern "C" {
#include <rte_log.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_vmbus.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_mbuf.h>
@@ -1477,7 +1478,10 @@ struct rte_eth_dev {
struct rte_eth_dev_data *data; /**< Pointer to device data */
const struct eth_driver *driver;/**< Driver for this device */
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
- struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+ union {
+ struct rte_pci_device *pci_dev; /**< PCI info. supplied by probig */
+ struct rte_vmbus_device *vmbus_dev; /**< VMBUS info. supplied by probing */
+ };
/** User application callbacks for NIC interrupts */
struct rte_eth_dev_cb_list link_intr_cbs;
/**
@@ -1696,7 +1700,14 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
* - The size of the private data to allocate for each matching device.
*/
struct eth_driver {
- struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ union {
+ struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ struct rte_vmbus_driver vmbus_drv;/**< The PMD is also a VMBUS drv. */
+ };
+ enum {
+ RTE_BUS_PCI=0,
+ RTE_BUS_VMBUS
+ } bus_type; /**< Device bus type. */
eth_dev_init_t eth_dev_init; /**< Device init function. */
eth_dev_uninit_t eth_dev_uninit; /**< Device uninit function. */
unsigned int dev_private_size; /**< Size of device private data. */
--
2.1.4
next prev parent reply other threads:[~2015-04-20 21:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-20 21:54 [dpdk-dev] [PATCH 0/7] Hyper-V Poll Mode Driver Stephen Hemminger
2015-04-20 21:54 ` [dpdk-dev] [PATCH 1/7] ether: add function to query for link state interrupt Stephen Hemminger
2015-04-20 21:54 ` [dpdk-dev] [PATCH 2/7] pmd: change drivers initialization for pci Stephen Hemminger
2015-04-20 21:54 ` Stephen Hemminger [this message]
2015-04-21 12:23 ` [dpdk-dev] [PATCH 3/7] hv: add basic vmbus support Neil Horman
2015-04-20 21:54 ` [dpdk-dev] [PATCH 4/7] hv: uio driver Stephen Hemminger
2015-04-20 21:54 ` [dpdk-dev] [PATCH 5/7] hv: poll mode driver Stephen Hemminger
2015-04-20 21:54 ` [dpdk-dev] [PATCH 6/7] hv: enable driver in common config Stephen Hemminger
2015-04-20 21:54 ` [dpdk-dev] [PATCH 7/7] hv: add kernel patch Stephen Hemminger
-- strict thread matches above, loose matches on Subject: below --
2015-02-05 1:13 [dpdk-dev] [PATCH 0/7] Hyper-v driver and infrastructure Stephen Hemminger
2015-02-05 1:13 ` [dpdk-dev] [PATCH 3/7] hv: add basic vmbus support Stephen Hemminger
2015-02-05 1:50 ` Neil Horman
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=1429566854-17490-4-git-send-email-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=alexmay@microsoft.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).