From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id B7976A04B5; Sat, 19 Dec 2020 07:44:20 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D7A44CB46; Sat, 19 Dec 2020 07:43:23 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 82531CB43 for ; Sat, 19 Dec 2020 07:43:21 +0100 (CET) IronPort-SDR: 2mpW8u5yFLcbS/HKtgdOxFDmXc3PkfipDOTwnY+jVF649RFYoNTHW9Hx/pk7M//EAcBu9ykuxc 6U7qleJYc4fg== X-IronPort-AV: E=McAfee;i="6000,8403,9839"; a="163285189" X-IronPort-AV: E=Sophos;i="5.78,432,1599548400"; d="scan'208";a="163285189" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Dec 2020 22:43:21 -0800 IronPort-SDR: T9g7uPbkxLZ45ZKjkJzf7a8YRZm7fWmEZwyje++yJ3pUIWhq57a18Rkp3NQHmEzTvQCJRz6QQB AiEajVhgtYoQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,432,1599548400"; d="scan'208";a="454449606" Received: from npg-dpdk-virtio-xiachenbo-nw.sh.intel.com ([10.67.119.123]) by fmsmga001.fm.intel.com with ESMTP; 18 Dec 2020 22:43:18 -0800 From: Chenbo Xia To: dev@dpdk.org, thomas@monjalon.net, david.marchand@redhat.com Cc: stephen@networkplumber.org, cunming.liang@intel.com, xiuchun.lu@intel.com, miao.li@intel.com, jingjing.wu@intel.com Date: Sat, 19 Dec 2020 14:28:01 +0800 Message-Id: <20201219062806.56477-4-chenbo.xia@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201219062806.56477-1-chenbo.xia@intel.com> References: <20201218074736.93999-1-chenbo.xia@intel.com> <20201219062806.56477-1-chenbo.xia@intel.com> Subject: [dpdk-dev] [PATCH v2 3/8] emu: introduce emulated iavf driver 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch introduces emulated iavf driver. It is a vdev driver emulating all iavf device behavior except data path handling. Signed-off-by: Chenbo Xia Signed-off-by: Xiuchun Lu --- MAINTAINERS | 7 + drivers/emu/iavf/iavf_emu.c | 29 ++++ drivers/emu/iavf/iavf_emu_internal.h | 49 +++++++ drivers/emu/iavf/iavf_emudev.c | 207 +++++++++++++++++++++++++++ drivers/emu/iavf/meson.build | 8 ++ drivers/emu/iavf/rte_iavf_emu.h | 43 ++++++ drivers/emu/iavf/version.map | 3 + drivers/emu/meson.build | 6 + drivers/meson.build | 1 + 9 files changed, 353 insertions(+) create mode 100644 drivers/emu/iavf/iavf_emu.c create mode 100644 drivers/emu/iavf/iavf_emu_internal.h create mode 100644 drivers/emu/iavf/iavf_emudev.c create mode 100644 drivers/emu/iavf/meson.build create mode 100644 drivers/emu/iavf/rte_iavf_emu.h create mode 100644 drivers/emu/iavf/version.map create mode 100644 drivers/emu/meson.build diff --git a/MAINTAINERS b/MAINTAINERS index 1b395e181d..bca206ba8f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1275,6 +1275,13 @@ F: doc/guides/rawdevs/ntb.rst F: examples/ntb/ F: doc/guides/sample_app_ug/ntb.rst +Emudev Drivers +-------------- + +Intel iavf +M: Chenbo Xia +M: Xiuchun Lu +F: drivers/emulation/iavf/ Packet processing ----------------- diff --git a/drivers/emu/iavf/iavf_emu.c b/drivers/emu/iavf/iavf_emu.c new file mode 100644 index 0000000000..68d2c440e3 --- /dev/null +++ b/drivers/emu/iavf/iavf_emu.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#include "iavf_emu_internal.h" + +static int iavf_emu_dev_close(struct rte_emudev *dev) +{ + struct iavf_emudev *iavf; + + /* For now, we don't support device close when data + * path driver is attached + */ + if (dev->backend_priv) { + EMU_IAVF_LOG(ERR, "Close failed because of " + "data path attached\n"); + return -EPERM; + } + + iavf = (struct iavf_emudev *)dev->priv_data; + iavf_emu_uninit_device(iavf); + dev->priv_data = NULL; + + return 0; +} + +struct rte_emudev_ops emu_iavf_ops = { + .dev_close = iavf_emu_dev_close, +}; diff --git a/drivers/emu/iavf/iavf_emu_internal.h b/drivers/emu/iavf/iavf_emu_internal.h new file mode 100644 index 0000000000..a726bfe577 --- /dev/null +++ b/drivers/emu/iavf/iavf_emu_internal.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#ifndef _IAVF_EMU_ITNL_H +#define _IAVF_EMU_ITNL_H + +#include + +#include + +#include "rte_iavf_emu.h" + +extern struct rte_emudev_ops emu_iavf_ops; + +extern int emu_iavf_logtype; +#define EMU_IAVF_LOG(level, ...) \ + rte_log(RTE_LOG_ ## level, emu_iavf_logtype, "EMU_IAVF: " __VA_ARGS__) + +struct iavf_emu_intr_info { + int enable; + int fd; +}; + +struct iavf_emu_intr { + uint32_t intr_num; + struct iavf_emu_intr_info info[RTE_IAVF_EMU_MAX_INTR]; +}; + +struct iavf_emu_lanQ { + uint16_t db_size; + void *doorbell; +}; + +struct iavf_emudev { + struct rte_emudev *edev; + /* Maximum LANQ queue pair that this emulated iavf has */ + uint16_t max_lanqp; + /* Maximum LANQ queue pair number that back-end driver can use */ + uint16_t max_be_lanqp; + unsigned int numa_node; + char *sock_addr; + struct rte_iavf_emu_mem *mem; + struct iavf_emu_intr *intr; + struct iavf_emu_lanQ *lanq; +}; + +void iavf_emu_uninit_device(struct iavf_emudev *dev); +#endif diff --git a/drivers/emu/iavf/iavf_emudev.c b/drivers/emu/iavf/iavf_emudev.c new file mode 100644 index 0000000000..a4cd2deb06 --- /dev/null +++ b/drivers/emu/iavf/iavf_emudev.c @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#include +#include +#include + +#include "iavf_emu_internal.h" + +#define EMU_IAVF_SOCK_ARG "sock" +#define EMU_IAVF_QUEUES_ARG "queues" + +static const char * const emu_iavf_valid_arg[] = { + EMU_IAVF_SOCK_ARG, + EMU_IAVF_QUEUES_ARG, + NULL +}; + +static inline int +save_sockaddr(const char *key __rte_unused, const char *value, + void *extra_args) +{ + const char **sock_addr = extra_args; + + if (value == NULL) + return -1; + + *sock_addr = value; + + return 0; +} + +static inline int +save_int(const char *key __rte_unused, const char *value, void *extra_args) +{ + uint16_t *n = extra_args; + + if (value == NULL || extra_args == NULL) + return -EINVAL; + + *n = (uint16_t)strtoul(value, NULL, 0); + if (*n == USHRT_MAX && errno == ERANGE) + return -1; + + return 0; +} + +static int iavf_emu_init_device(struct iavf_emudev *dev, + char *sock_addr, uint16_t queues, unsigned int numa_node) +{ + dev->sock_addr = rte_malloc_socket("sock_addr", + strlen(sock_addr) + 1, 0, numa_node); + if (!dev->sock_addr) { + EMU_IAVF_LOG(ERR, "Failed to alloc sock addr\n"); + goto exit; + } + strcpy(dev->sock_addr, sock_addr); + + dev->mem = rte_zmalloc_socket("iavf_emu_mem", + sizeof(struct rte_iavf_emu_mem), + 0, numa_node); + if (!dev->mem) { + EMU_IAVF_LOG(ERR, "Unable to alloc iavf_emu_mem.\n"); + goto err_mem; + } + + dev->intr = rte_zmalloc_socket("iavf_emu_intr", + sizeof(struct iavf_emu_intr), + 0, numa_node); + if (!dev->intr) { + EMU_IAVF_LOG(ERR, "Unable to alloc iavf_emu_intr.\n"); + goto err_intr; + } + + dev->lanq = rte_zmalloc_socket("iavf_emu_lanQ", + sizeof(struct iavf_emu_lanQ) * queues * 2, + 0, numa_node); + if (!dev->lanq) { + EMU_IAVF_LOG(ERR, "Unable to alloc iavf_emu_lanQ.\n"); + goto err_lanq; + } + + dev->numa_node = numa_node; + + return 0; + +err_lanq: + rte_free(dev->lanq); +err_intr: + rte_free(dev->intr); +err_mem: + rte_free(dev->sock_addr); +exit: + return -1; +} + +void iavf_emu_uninit_device(struct iavf_emudev *dev) +{ + rte_free(dev->sock_addr); + rte_free(dev->mem); + rte_free(dev->intr); + rte_free(dev->lanq); +} + +static int +rte_emu_iavf_probe(struct rte_vdev_device *dev) +{ + struct rte_kvargs *kvlist = NULL; + struct rte_emudev *edev; + struct iavf_emudev *iavf; + char *sock_addr; + uint16_t queues; + int ret = 0; + + kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), + emu_iavf_valid_arg); + if (kvlist == NULL) + return -1; + + if (rte_kvargs_count(kvlist, EMU_IAVF_SOCK_ARG) == 1) { + ret = rte_kvargs_process(kvlist, EMU_IAVF_SOCK_ARG, + &save_sockaddr, &sock_addr); + if (ret < 0) + goto err; + } else { + ret = -1; + goto err; + } + + if (rte_kvargs_count(kvlist, EMU_IAVF_QUEUES_ARG) == 1) { + ret = rte_kvargs_process(kvlist, EMU_IAVF_QUEUES_ARG, + &save_int, &queues); + if (ret < 0 || queues > RTE_MAX_QUEUES_PER_PORT || + queues > RTE_IAVF_EMU_MAX_QP_NUM) + goto err; + + } else + queues = 1; + + if (dev->device.numa_node == SOCKET_ID_ANY) + dev->device.numa_node = rte_socket_id(); + + edev = rte_emu_vdev_allocate(dev, sizeof(*iavf)); + if (!edev) { + EMU_IAVF_LOG(ERR, "Failed to allocate emu_vdev\n"); + ret = -1; + goto err; + } + edev->dev_ops = &emu_iavf_ops; + edev->dev_info.region_num = RTE_IAVF_EMU_MAPPABLE_REG_NUM; + edev->dev_info.max_qp_num = queues + RTE_IAVF_EMU_ADMINQ_NUM / 2; + + strcpy(edev->dev_info.dev_type, RTE_IAVF_EMUDEV_TYPE); + + iavf = (struct iavf_emudev *)edev->priv_data; + ret = iavf_emu_init_device(iavf, sock_addr, queues, + dev->device.numa_node); + if (ret) { + EMU_IAVF_LOG(ERR, "Failed to init new iavf device\n"); + ret = -1; + goto err_ndev; + } + + iavf->edev = edev; + /* If not configured, we assume back-end driver + * can use all queues of emulated iavf + */ + iavf->max_be_lanqp = queues; + iavf->max_lanqp = queues; + edev->priv_data = (void *)iavf; + + edev->started = 1; + rte_kvargs_free(kvlist); + return 0; + +err_ndev: + rte_emudev_release(edev); +err: + rte_kvargs_free(kvlist); + return ret; +} + +static int +rte_emu_iavf_remove(struct rte_vdev_device *dev) +{ + struct rte_emudev *emu_dev; + + /* Find the emudev entry */ + emu_dev = rte_emudev_allocated(rte_vdev_device_name(dev)); + if (!emu_dev) + return 0; + + return rte_emudev_close(emu_dev->dev_id); +} + +static struct rte_vdev_driver emu_iavf_drv = { + .probe = rte_emu_iavf_probe, + .remove = rte_emu_iavf_remove, +}; + +RTE_PMD_REGISTER_VDEV(emu_iavf, emu_iavf_drv); +RTE_PMD_REGISTER_PARAM_STRING(emu_iavf, + "sock= " + "queues= "); + +RTE_LOG_REGISTER(emu_iavf_logtype, emu.iavf, INFO); diff --git a/drivers/emu/iavf/meson.build b/drivers/emu/iavf/meson.build new file mode 100644 index 0000000000..58c2a90383 --- /dev/null +++ b/drivers/emu/iavf/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2020 Intel Corporation + +sources = files('iavf_emu.c', 'iavf_emudev.c') + +deps += ['bus_vdev', 'emudev'] + +headers = files('rte_iavf_emu.h') diff --git a/drivers/emu/iavf/rte_iavf_emu.h b/drivers/emu/iavf/rte_iavf_emu.h new file mode 100644 index 0000000000..623c3c5d99 --- /dev/null +++ b/drivers/emu/iavf/rte_iavf_emu.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#ifndef _IAVF_EMU_H +#define _IAVF_EMU_H + +#include + +#include + +#define RTE_IAVF_EMUDEV_TYPE "iavf" +#define RTE_IAVF_EMU_MAX_MEM_REGIONS 256 +#define RTE_IAVF_EMU_MAX_QP_NUM 256 +#define RTE_IAVF_EMU_MAX_INTR 32 + +enum { + RTE_IAVF_EMU_ADMINQ_TXQ = 0, + RTE_IAVF_EMU_ADMINQ_RXQ = 1, + RTE_IAVF_EMU_ADMINQ_NUM = 2, +}; + +enum { + RTE_IAVF_EMU_MAPPABLE_REG_BAR0 = 0, + RTE_IAVF_EMU_MAPPABLE_REG_BAR3 = 1, + RTE_IAVF_EMU_MAPPABLE_REG_NUM = 2, +}; + +struct rte_iavf_emu_mem_reg { + uint64_t guest_phys_addr; + uint64_t host_user_addr; + uint64_t size; + void *mmap_addr; + uint64_t mmap_size; + int fd; +}; + +struct rte_iavf_emu_mem { + uint32_t region_num; + struct rte_iavf_emu_mem_reg regions[RTE_IAVF_EMU_MAX_MEM_REGIONS]; +}; + +#endif diff --git a/drivers/emu/iavf/version.map b/drivers/emu/iavf/version.map new file mode 100644 index 0000000000..4a76d1d52d --- /dev/null +++ b/drivers/emu/iavf/version.map @@ -0,0 +1,3 @@ +DPDK_21 { + local: *; +}; diff --git a/drivers/emu/meson.build b/drivers/emu/meson.build new file mode 100644 index 0000000000..acc8c395ef --- /dev/null +++ b/drivers/emu/meson.build @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2020 Intel Corporation + +drivers = ['iavf'] +std_deps = ['emudev'] +config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_EMUDEV' diff --git a/drivers/meson.build b/drivers/meson.build index f9febc579e..64c34d2f9f 100644 --- a/drivers/meson.build +++ b/drivers/meson.build @@ -8,6 +8,7 @@ subdirs = [ 'common/mlx5', # depends on bus. 'common/qat', # depends on bus. 'mempool', # depends on common and bus. + 'emu', # depends on common and bus. 'net', # depends on common, bus, mempool 'raw', # depends on common, bus and net. 'crypto', # depends on common, bus and mempool (net in future). -- 2.17.1