From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com [209.85.220.54]) by dpdk.org (Postfix) with ESMTP id DEB995A55 for ; Mon, 20 Apr 2015 23:54:13 +0200 (CEST) Received: by pabsx10 with SMTP id sx10so219435880pab.3 for ; Mon, 20 Apr 2015 14:54:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zy5NUT/WQ2ah7jEiWywaRkqjXjgkxlBAqpDBqDm1h6c=; b=AqCoJFbhCgpZqHMnY0pp2KzwkpMzb+mSRqpjK1SvrglvuFHo1PtCpwIdHQEuFYHK6i E6e/s5hQvXRM+yLeKhwAsH8ECRpIgcU339G2YJeQHVQSEzViJpXvzr9vVOxOttV/aJex vs4O9L0h5oTiiex60W2e4w4roOF/HAEbK1qlcJjAt74XfCVwVYUls1Eh0q0zUH2y1q6N QwsKlrbH/QadsfJ3civDOaWv8gCQ3Ylm/ngnswgiwxkOmp6fkFXiZ2DcyBc9jXyr0pB7 ufVrJDqg9Q4hOLaF7odQGDfCd3LtbJIvDljlK18EmWJbbaUvXasDdV2xiXOMHRecmiz1 sKHg== X-Gm-Message-State: ALoCoQnOYuATE60qZgbi8jmoT8YL2HHNLILWiG5porp+KII3ahUW9ixt56Gu3O9QzYEEWtqqfFbk X-Received: by 10.66.102.99 with SMTP id fn3mr31786903pab.118.1429566853295; Mon, 20 Apr 2015 14:54:13 -0700 (PDT) Received: from urahara.home.lan (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by mx.google.com with ESMTPSA id kr9sm278619pab.30.2015.04.20.14.54.12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 20 Apr 2015 14:54:12 -0700 (PDT) From: Stephen Hemminger To: alexmay@microsoft.com Date: Mon, 20 Apr 2015 14:54:10 -0700 Message-Id: <1429566854-17490-4-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1429566854-17490-1-git-send-email-stephen@networkplumber.org> References: <1429566854-17490-1-git-send-email-stephen@networkplumber.org> Cc: dev@dpdk.org Subject: [dpdk-dev] [PATCH 3/7] hv: add basic vmbus support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Apr 2015 21:54:14 -0000 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 --- 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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