From patchwork Tue Nov 25 14:11:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cunming Liang X-Patchwork-Id: 1546 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id D0921590F; Tue, 25 Nov 2014 15:01:43 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 24E00590F for ; Tue, 25 Nov 2014 15:01:39 +0100 (CET) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 25 Nov 2014 06:09:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,455,1413270000"; d="scan'208";a="613751396" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 25 Nov 2014 06:11:59 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id sAPEBv2D024012; Tue, 25 Nov 2014 22:11:57 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id sAPEBtNs024242; Tue, 25 Nov 2014 22:11:57 +0800 Received: (from cliang18@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id sAPEBtXU024238; Tue, 25 Nov 2014 22:11:55 +0800 From: Cunming Liang To: dev@dpdk.org Date: Tue, 25 Nov 2014 22:11:20 +0800 Message-Id: <1416924682-24170-5-git-send-email-cunming.liang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1416924682-24170-1-git-send-email-cunming.liang@intel.com> References: <1416924682-24170-1-git-send-email-cunming.liang@intel.com> Subject: [dpdk-dev] [RFC PATCH 4/6] bifurc: add driver to scan bifurcated netdev 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Cunming Liang --- config/common_linuxapp | 5 + lib/Makefile | 1 + lib/librte_bifurc/Makefile | 58 +++++++++ lib/librte_bifurc/rte_bifurc.c | 284 +++++++++++++++++++++++++++++++++++++++++ lib/librte_bifurc/rte_bifurc.h | 90 +++++++++++++ mk/rte.app.mk | 6 + 6 files changed, 444 insertions(+) create mode 100644 lib/librte_bifurc/Makefile create mode 100644 lib/librte_bifurc/rte_bifurc.c create mode 100644 lib/librte_bifurc/rte_bifurc.h diff --git a/config/common_linuxapp b/config/common_linuxapp index 86a0d15..72fe0b1 100644 --- a/config/common_linuxapp +++ b/config/common_linuxapp @@ -163,6 +163,11 @@ CONFIG_RTE_LIBRTE_IEEE1588=n CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16 # +# Compile bifurcate driver backed by AF_PACKET sockets (Linux only) +# +CONFIG_RTE_LIBRTE_BIFURC=y + +# # Support NIC bypass logic # CONFIG_RTE_NIC_BYPASS=n diff --git a/lib/Makefile b/lib/Makefile index 204ef11..c59ae5b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -69,6 +69,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += librte_ivshmem +DIRS-$(CONFIG_RTE_LIBRTE_BIFURC) += librte_bifurc endif include $(RTE_SDK)/mk/rte.sharelib.mk diff --git a/lib/librte_bifurc/Makefile b/lib/librte_bifurc/Makefile new file mode 100644 index 0000000..c5c1894 --- /dev/null +++ b/lib/librte_bifurc/Makefile @@ -0,0 +1,58 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_bifurc.a + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# +# all source are stored in SRCS-y +# +SRCS-$(CONFIG_RTE_LIBRTE_BIFURC) += rte_bifurc.c + +# +# Export include files +# +SYMLINK-$(CONFIG_RTE_LIBRTE_BIFURC)-include += rte_bifurc.h + + +# this lib depends upon: +DEPDIRS-$(CONFIG_RTE_LIBRTE_BIFURC) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_BIFURC) += lib/librte_ether +DEPDIRS-$(CONFIG_RTE_LIBRTE_BIFURC) += lib/librte_kvargs + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_bifurc/rte_bifurc.c b/lib/librte_bifurc/rte_bifurc.c new file mode 100644 index 0000000..8cb29e3 --- /dev/null +++ b/lib/librte_bifurc/rte_bifurc.c @@ -0,0 +1,284 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rte_bifurc.h" + +void +rte_bifurc_ethdev_get_info(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) +{ + struct bifurc_device *bif_dev = (struct bifurc_device *)dev->pci_dev; + + dev_info->if_index = bif_dev->if_index; + dev_info->max_mac_addrs = 1; + dev_info->max_rx_pktlen = (uint32_t)bif_dev->mtu; + dev_info->max_rx_queues = (uint32_t)bif_dev->nb_queues; + dev_info->max_tx_queues = (uint32_t)bif_dev->nb_queues; + dev_info->min_rx_bufsize = 0; + dev_info->pci_dev = NULL; +} + +static const char *valid_arguments[] = { + RTE_BIFURC_IFACE_ARG, + RTE_BIFURC_NUM_QPAIRS_ARG, + NULL, +}; + +static int +bif_get_ifname(const char *key __rte_unused, + const char *iface, + void *extra_args) +{ + char *ifname = (char *)extra_args; + uint16_t ifnamelen; + + ifnamelen = strlen(iface); + if (ifnamelen >= IFNAMSIZ) { + RTE_LOG(ERR, EAL, + "I/F name too long (%s)\n", iface); + return -1; + } + + /* request for ifindex */ + memcpy(ifname, iface, ifnamelen); + ifname[ifnamelen] = '\0'; + + return 0; +} + +static int +bif_get_qp(const char *key __rte_unused, + const char *value, + void *extra_args) +{ + uint32_t qpairs = RTE_BIFURC_PMD_MAX_QPAIRS; + uint32_t *nb_qp = (uint32_t *)extra_args; + + qpairs = atoi(value); + if (qpairs < 1 || + qpairs > RTE_BIFURC_PMD_MAX_QPAIRS) { + RTE_LOG(ERR, EAL, "invalid qpairs value\n"); + return -1; + } + + *nb_qp = qpairs; + + return 0; +} + +static struct bifurc_device * +rte_bifurc_alloc_dev(char *iface, struct rte_devargs *devargs) +{ + struct bifurc_device *dev = NULL; + uint16_t ifnamelen; + int sockfd = -1; + + if (iface == NULL || devargs == NULL) + goto error; + + if (rte_eal_bifurc_open(&sockfd)) + goto error; + + ifnamelen = strlen(iface); + if (ifnamelen >= IFNAMSIZ) { + RTE_LOG(ERR, EAL, + "I/F name too long (%s)\n", iface); + goto error; + } + + /* alloc dev and bind to af_packet socket */ + dev = calloc(sizeof(*dev), 1); + if (dev == NULL) + goto error; + + memcpy(dev->iface_name, iface, ifnamelen); + dev->iface_name[ifnamelen] = '\0'; + + if (rte_eal_bifurc_get_ifinfo(sockfd, dev->iface_name, &dev->if_index, + dev->hwaddr, &dev->mtu) != 0) + goto error; + + if (rte_eal_bifurc_bind(sockfd, dev->if_index) != 0) + goto error; + + /* update dev after bind success */ + dev->fd = sockfd; + + if (rte_eal_bifurc_set_pci(sockfd, &dev->pci_dev) != 0) + goto error; + + /* use iface name as pci_dev name */ + snprintf(dev->pci_dev.name, RTE_PCI_DEV_NAME_SIZE, "%s", + dev->iface_name); + + dev->pci_dev.devargs = devargs; + + TAILQ_INSERT_TAIL(&pci_device_list, &dev->pci_dev, next); + + return dev; + +error: + if (sockfd >= 0) + close(sockfd); + if (dev) + free(dev); + + return NULL; +} + +static void +rte_bifurc_free_dev(struct bifurc_device *dev) +{ + struct rte_pci_device *pci_dev = NULL; + + if (!dev) + return; + + pci_dev = &dev->pci_dev; + + /* unmap the mapped device memory */ + rte_eal_bifurc_unmap(dev->fd, pci_dev->mem_resource[0].addr); + + /* return queues to kernel driver */ + rte_eal_bifurc_retire(dev->fd, dev->nb_queues, dev->qp_lower); + + /* free the rest */ + if (pci_dev->devargs != NULL) + free(pci_dev->devargs); + + close(dev->fd); + free(dev); +} + +void +rte_bifurc_ethdev_free(struct rte_eth_dev *dev) +{ + rte_bifurc_free_dev((struct bifurc_device *)dev->pci_dev); +} + +static int +rte_bifurc_dev_init(const char *name, const char *params) +{ + struct rte_devargs *devargs = NULL; + struct rte_kvargs *kvlist; + struct bifurc_device *dev = NULL; + unsigned nb_qp; + int ret = 0; + char iface[IFNAMSIZ]; + + RTE_LOG(INFO, PMD, "Initializing %s vdev\n", name); + + kvlist = rte_kvargs_parse(params, valid_arguments); + if (kvlist == NULL) + return -1; + + /* + * If iface argument is passed we open the NICs and use them for + * reading / writing + */ + /* prepare dev info from kvlist */ + if (rte_kvargs_count(kvlist, RTE_BIFURC_NUM_QPAIRS_ARG)) + ret |= rte_kvargs_process(kvlist, + RTE_BIFURC_NUM_QPAIRS_ARG, + &bif_get_qp, &nb_qp); + + if (rte_kvargs_count(kvlist, RTE_BIFURC_IFACE_ARG)) + ret |= rte_kvargs_process(kvlist, RTE_BIFURC_IFACE_ARG, + &bif_get_ifname, &iface); + if (ret) + goto exit; + + devargs = rte_eal_bifurc_get_devargs(name, params); + if (devargs == NULL) { + ret = -1; + goto exit; + } + + dev = rte_bifurc_alloc_dev(iface, devargs); + if (dev == NULL) { + printf("no dev attach\n"); + ret = -1; + goto exit; + } + + dev->nb_queues = nb_qp; + ret = rte_eal_bifurc_split(dev->fd, &dev->nb_queues, &dev->qp_lower); + if (ret != 0) + goto exit; + + if (rte_eal_bifurc_map(dev->fd, + &(dev->pci_dev.mem_resource[0].addr), + (uint32_t *) + &(dev->pci_dev.mem_resource[0].len))) + goto exit; + + return 0; +exit: + if (devargs) + rte_eal_bifurc_put_devargs(devargs); + + if (dev) + rte_bifurc_free_dev(dev); + + rte_kvargs_free(kvlist); + return ret; +} + +static struct rte_driver bifurc_bus_drv = { + .name = RTE_BIFURC_DRV_NAME, + .type = PMD_VDEV, + .init = rte_bifurc_dev_init, +}; + +PMD_REGISTER_DRIVER(bifurc_bus_drv); diff --git a/lib/librte_bifurc/rte_bifurc.h b/lib/librte_bifurc/rte_bifurc.h new file mode 100644 index 0000000..c0951a5 --- /dev/null +++ b/lib/librte_bifurc/rte_bifurc.h @@ -0,0 +1,90 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_BIFURC_H_ +#define _RTE_BIFURC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define RTE_BIFURC_DRV_NAME "rte_bifurc" +#define RTE_BIFURC_IFACE_ARG "iface" +#define RTE_BIFURC_NUM_QPAIRS_ARG "qpairs" +#define RTE_BIFURC_PMD_MAX_QPAIRS 2 + +#define RTE_BIFURC_IFNAMESIZ 16 +#define RTE_BIFURC_HWADDR_LEN 6 + +struct bifurc_device { + struct rte_pci_device pci_dev; + char iface_name[RTE_BIFURC_IFNAMESIZ]; + int fd; + int if_index; + uint8_t hwaddr[RTE_BIFURC_HWADDR_LEN]; + int mtu; + unsigned qp_lower; + unsigned nb_queues; +}; + +void +rte_bifurc_ethdev_get_info(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); + +void +rte_bifurc_ethdev_free(struct rte_eth_dev *dev); + +static inline uint32_t +rte_bifurc_qp_base(struct rte_eth_dev *dev) +{ + struct bifurc_device *bif_dev = + (struct bifurc_device *)dev->pci_dev; + return bif_dev->qp_lower; +} + +static inline void +rte_bifurc_mac_addr(struct rte_eth_dev *dev, struct ether_addr *mac_addr) +{ + struct bifurc_device *bif_dev = + (struct bifurc_device *)dev->pci_dev; + ether_addr_copy((struct ether_addr *)bif_dev->hwaddr, mac_addr); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_BIFURC_H_ */ diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 59468b0..ea074ab 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -219,6 +219,12 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_AF_PACKET),y) LDLIBS += -lrte_pmd_af_packet endif +ifeq ($(CONFIG_RTE_LIBRTE_BIFURC),y) +ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) +LDLIBS += -lrte_bifurc +endif +endif + endif # plugins LDLIBS += $(EXECENV_LDLIBS)