From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-it0-f49.google.com (mail-it0-f49.google.com [209.85.214.49]) by dpdk.org (Postfix) with ESMTP id 7CBD4FABC for ; Mon, 19 Dec 2016 23:00:08 +0100 (CET) Received: by mail-it0-f49.google.com with SMTP id x2so6492032itf.1 for ; Mon, 19 Dec 2016 14:00:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nYfgQZNpenugLirj5egAuuGla72CUa8RMnoaGdNPFkQ=; b=z54DGmWot8N2STK76aKJbC7HuAutKJJMOLRZ5aPqZvrOb3VtAk3EAaeFi8UMNIj5QE AevAoa3LEN3ykuaUGBp9DWor8Lel6BMhz+/4LgsgraRSW8N/Fos8RW1KsJbfIIcDLw6e 6ttfJJgp2Zl/tTHzEWCdqua89/tjDgHXoARnXm3XLAal32CWsQq2nTGqYVlZ57yLPi0J VN0S2+16MVTaYR7fLhqvyYUjG1QFEpdlwXTcv4dcTGYhqimMyjFsv8xHhYDmBTCMJ94j +6BlAsgFqueYU+059Si0pghhUNT3V2g+NWRntDjdfGgdtptjsUgdSOteuWOde3vKW/EQ Ie7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nYfgQZNpenugLirj5egAuuGla72CUa8RMnoaGdNPFkQ=; b=uI/ukq5GYaDMYgl3HtEIMOT3n7ZKdTM25UOQ+0ctb3JQfvFHo3xJ7qCQJc/QNxvymM IlaruMmlWWwtyaJLpRc/UUy3lKaDxJ8fAjVT8WjSMj2c+tx6ooZkbRV7yQ6qxtY2IgNx 8HEYRkE2Q1GJzDaVaNZX2QQhEElXjY6rWIk8u1nOVblDuCE88MCFXNx0yAMzyER7lg5H 2GRipX6ZEQaxcpOMhXBS90ZWIr1pYDkyH3MbIptN8LU6NuJfrVBNciDdEPaeOn45/HMz G5F/mQRd2kGhb3bLuv1XkAHatudoPicfahRuCJ0IiRPeShOJCSdZIyalfgZm7xirxHnC mnqQ== X-Gm-Message-State: AKaTC01bNFDoD+4Y23PfwxTaYypL+nqWHh5OQHdEQrfXW8jUS1jnN7oPwclOsFrFPg7kEg== X-Received: by 10.36.13.82 with SMTP id 79mr18508850itx.66.1482184806388; Mon, 19 Dec 2016 14:00:06 -0800 (PST) Received: from xeon-e3.wavecable.com (204-195-18-65.wavecable.com. [204.195.18.65]) by smtp.gmail.com with ESMTPSA id p20sm8270581itc.2.2016.12.19.14.00.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Dec 2016 14:00:05 -0800 (PST) From: Stephen Hemminger X-Google-Original-From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Date: Mon, 19 Dec 2016 13:59:44 -0800 Message-Id: <20161219215944.17226-14-sthemmin@microsoft.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20161219215944.17226-1-sthemmin@microsoft.com> References: <20161219215944.17226-1-sthemmin@microsoft.com> Subject: [dpdk-dev] [PATCH 13/13] hyperv: VMBUS support infrastucture X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Dec 2016 22:00:09 -0000 Generalize existing bus support to handle VMBUS in Hyper-V. Most of the code is based of existing model for PCI, the difference is how bus is represented in sysfs and how addressing works. This is based on earlier code contributed by Brocade. Signed-off-by: Stephen Hemminger --- lib/librte_eal/common/Makefile | 2 +- lib/librte_eal/common/eal_common_devargs.c | 7 +++ lib/librte_eal/common/eal_common_options.c | 38 ++++++++++++ lib/librte_eal/common/eal_internal_cfg.h | 3 +- lib/librte_eal/common/eal_options.h | 6 ++ lib/librte_eal/common/eal_private.h | 5 ++ lib/librte_eal/common/include/rte_devargs.h | 8 +++ lib/librte_eal/linuxapp/eal/Makefile | 6 ++ lib/librte_eal/linuxapp/eal/eal.c | 11 ++++ lib/librte_ether/rte_ethdev.c | 90 +++++++++++++++++++++++++++++ lib/librte_ether/rte_ethdev.h | 22 ++++++- mk/rte.app.mk | 1 + 12 files changed, 196 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index a92c984b..9254bae4 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_per_lcore.h rte_random.h INC += 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_devargs.c b/lib/librte_eal/common/eal_common_devargs.c index e403717b..934ca840 100644 --- a/lib/librte_eal/common/eal_common_devargs.c +++ b/lib/librte_eal/common/eal_common_devargs.c @@ -113,6 +113,13 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str) goto fail; break; + case RTE_DEVTYPE_WHITELISTED_VMBUS: + case RTE_DEVTYPE_BLACKLISTED_VMBUS: +#ifdef RTE_LIBRTE_HV_PMD + if (uuid_parse(buf, devargs->uuid) == 0) + break; +#endif + goto fail; } free(buf); diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c index 6ca8af17..6aea87d9 100644 --- a/lib/librte_eal/common/eal_common_options.c +++ b/lib/librte_eal/common/eal_common_options.c @@ -95,6 +95,11 @@ eal_long_options[] = { {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, {OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM }, {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM }, +#ifdef RTE_LIBRTE_HV_PMD + {OPT_NO_VMBUS, 0, NULL, OPT_NO_VMBUS_NUM }, + {OPT_VMBUS_BLACKLIST, 1, NULL, OPT_VMBUS_BLACKLIST_NUM }, + {OPT_VMBUS_WHITELIST, 1, NULL, OPT_VMBUS_WHITELIST_NUM }, +#endif {0, 0, NULL, 0 } }; @@ -855,6 +860,21 @@ eal_parse_common_option(int opt, const char *optarg, conf->no_pci = 1; break; +#ifdef RTE_LIBRTE_HV_PMD + case OPT_NO_VMBUS_NUM: + conf->no_vmbus = 1; + break; + case OPT_VMBUS_BLACKLIST_NUM: + if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_VMBUS, + optarg) < 0) + return -1; + break; + case OPT_VMBUS_WHITELIST_NUM: + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_VMBUS, + optarg) < 0) + return -1; + break; +#endif case OPT_NO_HPET_NUM: conf->no_hpet = 1; break; @@ -987,6 +1007,14 @@ eal_check_common_options(struct internal_config *internal_cfg) return -1; } +#ifdef RTE_LIBRTE_HV_PMD + if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_VMBUS) != 0 && + rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_VMBUS) != 0) { + RTE_LOG(ERR, EAL, "Options vmbus blacklist and whitelist " + "cannot be used at the same time\n"); + return -1; + } +#endif return 0; } @@ -1036,5 +1064,15 @@ eal_common_usage(void) " --"OPT_NO_PCI" Disable PCI\n" " --"OPT_NO_HPET" Disable HPET\n" " --"OPT_NO_SHCONF" No shared config (mmap'd files)\n" +#ifdef RTE_LIBRTE_HV_PMD + " --"OPT_NO_VMBUS" Disable VMBUS\n" + " --"OPT_VMBUS_BLACKLIST" Add a VMBUS device to black list.\n" + " Prevent EAL from using this PCI device. The argument\n" + " format is device UUID.\n" + " --"OPT_VMBUS_WHITELIST" Add a VMBUS device to white list.\n" + " Only use the specified VMBUS devices. The argument format\n" + " is device UUID This option can be present\n" + " several times (once per device).\n" +#endif "\n", RTE_MAX_LCORE); } diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h index 5f1367eb..18271943 100644 --- a/lib/librte_eal/common/eal_internal_cfg.h +++ b/lib/librte_eal/common/eal_internal_cfg.h @@ -69,7 +69,8 @@ struct internal_config { volatile unsigned no_pci; /**< true to disable PCI */ volatile unsigned no_hpet; /**< true to disable HPET */ volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping - * instead of native TSC */ + * instead of native TSC */ + volatile unsigned no_vmbus; /**< true to disable VMBUS */ volatile unsigned no_shconf; /**< true if there is no shared config */ volatile unsigned create_uio_dev; /**< true to create /dev/uioX devices */ volatile enum rte_proc_type_t process_type; /**< multi-process proc type */ diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h index a881c62e..156727e7 100644 --- a/lib/librte_eal/common/eal_options.h +++ b/lib/librte_eal/common/eal_options.h @@ -83,6 +83,12 @@ enum { OPT_VMWARE_TSC_MAP_NUM, #define OPT_XEN_DOM0 "xen-dom0" OPT_XEN_DOM0_NUM, +#define OPT_NO_VMBUS "no-vmbus" + OPT_NO_VMBUS_NUM, +#define OPT_VMBUS_BLACKLIST "vmbus-blacklist" + OPT_VMBUS_BLACKLIST_NUM, +#define OPT_VMBUS_WHITELIST "vmbus-whitelist" + OPT_VMBUS_WHITELIST_NUM, OPT_LONG_MAX_NUM }; diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 9e7d8f6b..c856c63e 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -210,6 +210,11 @@ int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx, struct mapped_pci_resource *uio_res, int map_idx); /** + * VMBUS related functions and structures + */ +int rte_eal_vmbus_init(void); + +/** * 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/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h index 88120a1c..c079d289 100644 --- a/lib/librte_eal/common/include/rte_devargs.h +++ b/lib/librte_eal/common/include/rte_devargs.h @@ -51,6 +51,9 @@ extern "C" { #include #include #include +#ifdef RTE_LIBRTE_HV_PMD +#include +#endif /** * Type of generic device @@ -59,6 +62,8 @@ enum rte_devtype { RTE_DEVTYPE_WHITELISTED_PCI, RTE_DEVTYPE_BLACKLISTED_PCI, RTE_DEVTYPE_VIRTUAL, + RTE_DEVTYPE_WHITELISTED_VMBUS, + RTE_DEVTYPE_BLACKLISTED_VMBUS, }; /** @@ -88,6 +93,9 @@ struct rte_devargs { /** Driver name. */ char drv_name[32]; } virt; +#ifdef RTE_LIBRTE_HV_PMD + uuid_t uuid; +#endif }; /** Arguments string as given by user or "" for no argument. */ char *args; diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index 4e206f09..f6ca3848 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -71,6 +71,11 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c +ifeq ($(CONFIG_RTE_LIBRTE_HV_PMD),y) +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vmbus.c +LDLIBS += -luuid +endif + # from common dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c @@ -114,6 +119,7 @@ CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE CFLAGS_eal_pci.o := -D_GNU_SOURCE CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE +CFLAGS_eal_vmbux.o := -D_GNU_SOURCE CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE CFLAGS_eal_common_options.o := -D_GNU_SOURCE CFLAGS_eal_common_thread.o := -D_GNU_SOURCE diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 2075282e..71083ec5 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 @@ -830,6 +831,11 @@ rte_eal_init(int argc, char **argv) eal_check_mem_on_local_socket(); +#ifdef RTE_LIBRTE_HV_PMD + if (rte_eal_vmbus_init() < 0) + RTE_LOG(ERR, EAL, "Cannot init VMBUS\n"); +#endif + if (eal_plugins_init() < 0) rte_panic("Cannot init plugins\n"); @@ -887,6 +893,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 + rte_eal_mcfg_complete(); return fctret; diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 3f7dc79e..e0585d7b 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -3294,3 +3294,93 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id, -ENOTSUP); return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en); } + + +#ifdef RTE_LIBRTE_HV_PMD +int +rte_eth_dev_vmbus_probe(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 ustr[UUID_BUF_SZ]; + int diag; + + uuid_unparse(vmbus_dev->device_id, ustr); + + eth_dev = rte_eth_dev_allocate(ustr); + 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->device = &vmbus_dev->device; + 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; + + RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n", + vmbus_drv->driver.name, ustr); + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + rte_free(eth_dev->data->dev_private); + + return diag; +} + +int +rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev) +{ + const struct eth_driver *eth_drv; + struct rte_eth_dev *eth_dev; + char ustr[UUID_BUF_SZ]; + int ret; + + if (vmbus_dev == NULL) + return -EINVAL; + + uuid_unparse(vmbus_dev->device_id, ustr); + eth_dev = rte_eth_dev_allocated(ustr); + 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->device = NULL; + eth_dev->driver = NULL; + eth_dev->data = NULL; + + return 0; +} +#endif diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index f7e156eb..00a70964 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -180,6 +180,7 @@ extern "C" { #include #include #include +#include #include #include #include "rte_ether.h" @@ -1866,7 +1867,11 @@ 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 PCI driver. */ + struct rte_vmbus_driver vmbus_drv;/**< The PMD VMBUS drv. */ + }; + 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. */ @@ -4383,6 +4388,21 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv, */ int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev); +/** + * @internal + * Wrapper for use by vmbus drivers as a .probe function to attach to a ethdev + * interface. + */ +int rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv, + struct rte_vmbus_device *vmbus_dev); + +/** + * @internal + * Wrapper for use by vmbus drivers as a .remove function to detach a ethdev + * interface. + */ +int rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev); + #ifdef __cplusplus } #endif diff --git a/mk/rte.app.mk b/mk/rte.app.mk index f75f0e24..6b304084 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -130,6 +130,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost endif # $(CONFIG_RTE_LIBRTE_VHOST) _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio +_LDLIBS-$(CONFIG_RTE_LIBRTE_HV_PMD) += -luuid ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb -- 2.11.0