From patchwork Sat May 27 08:22:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Dai X-Patchwork-Id: 24741 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 6EE49377A; Sat, 27 May 2017 10:31:23 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id E30C22BA3 for ; Sat, 27 May 2017 10:31:18 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2017 01:31:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.38,400,1491289200"; d="scan'208"; a="1135329739" Received: from dpdk6.bj.intel.com ([172.16.182.81]) by orsmga001.jf.intel.com with ESMTP; 27 May 2017 01:31:17 -0700 From: Wei Dai To: wenzhuo.lu@intel.com, konstantin.ananyev@intel.com, helin.zhang@intel.com, jingjing.wu@intel.com Cc: dev@dpdk.org, Wei Dai Date: Sat, 27 May 2017 16:22:03 +0800 Message-Id: <1495873329-43303-2-git-send-email-wei.dai@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1495873329-43303-1-git-send-email-wei.dai@intel.com> References: <1495873329-43303-1-git-send-email-wei.dai@intel.com> Subject: [dpdk-dev] [PATCH 1/7] ethdev: add support of NIC restoration 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" The steps of NIC restoration process include following items in order: dev_stop, dev_uninit, dev_init, dev_configure with stored configuration, setup each Rx and Tx queue with previous configurations and dev_start. Signed-off-by: Wei Dai --- lib/librte_ether/rte_ethdev.c | 102 ++++++++++++++++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 36 ++++++++++++ lib/librte_ether/rte_ether_version.map | 6 ++ 3 files changed, 142 insertions(+), 2 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 83898a8..a5a9519 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -795,17 +795,39 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, /* * Setup new number of RX/TX queues and reconfigure device. */ + if (dev->data->rxq_conf == NULL) { + dev->data->rxq_conf = rte_zmalloc("ethdev->rxq_conf", + sizeof(struct rte_eth_rx_queue_conf) * nb_rx_q, + RTE_CACHE_LINE_SIZE); + if (dev->data->rxq_conf == NULL) + return -ENOMEM; + } + diag = rte_eth_dev_rx_queue_config(dev, nb_rx_q); if (diag != 0) { RTE_PMD_DEBUG_TRACE("port%d rte_eth_dev_rx_queue_config = %d\n", port_id, diag); + rte_free(dev->data->rxq_conf); return diag; } + if (dev->data->txq_conf == NULL) { + dev->data->txq_conf = rte_zmalloc("ethdev->txq_conf", + sizeof(struct rte_eth_tx_queue_conf) * nb_tx_q, + RTE_CACHE_LINE_SIZE); + if (dev->data->txq_conf == NULL) { + rte_free(dev->data->rxq_conf); + rte_eth_dev_rx_queue_config(dev, 0); + return -ENOMEM; + } + } + diag = rte_eth_dev_tx_queue_config(dev, nb_tx_q); if (diag != 0) { RTE_PMD_DEBUG_TRACE("port%d rte_eth_dev_tx_queue_config = %d\n", port_id, diag); + rte_free(dev->data->rxq_conf); + rte_free(dev->data->txq_conf); rte_eth_dev_rx_queue_config(dev, 0); return diag; } @@ -814,6 +836,8 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, if (diag != 0) { RTE_PMD_DEBUG_TRACE("port%d dev_configure = %d\n", port_id, diag); + rte_free(dev->data->rxq_conf); + rte_free(dev->data->txq_conf); rte_eth_dev_rx_queue_config(dev, 0); rte_eth_dev_tx_queue_config(dev, 0); return diag; @@ -1005,6 +1029,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id, struct rte_eth_dev *dev; struct rte_eth_dev_info dev_info; void **rxq; + struct rte_eth_rx_queue_conf *rxq_conf; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); @@ -1080,6 +1105,12 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id, if (!dev->data->min_rx_buf_size || dev->data->min_rx_buf_size > mbp_buf_size) dev->data->min_rx_buf_size = mbp_buf_size; + + rxq_conf = &dev->data->rxq_conf[rx_queue_id]; + rxq_conf->nb_rx_desc = nb_rx_desc; + rxq_conf->socket_id = socket_id; + rxq_conf->rx_conf = *rx_conf; + rxq_conf->mp = mp; } return ret; @@ -1093,6 +1124,8 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id, struct rte_eth_dev *dev; struct rte_eth_dev_info dev_info; void **txq; + int ret; + struct rte_eth_tx_queue_conf *txq_conf; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); @@ -1136,8 +1169,16 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id, if (tx_conf == NULL) tx_conf = &dev_info.default_txconf; - return (*dev->dev_ops->tx_queue_setup)(dev, tx_queue_id, nb_tx_desc, - socket_id, tx_conf); + ret = (*dev->dev_ops->tx_queue_setup)(dev, tx_queue_id, nb_tx_desc, + socket_id, tx_conf); + if (!ret) { + txq_conf = &dev->data->txq_conf[tx_queue_id]; + txq_conf->nb_tx_desc = nb_tx_desc; + txq_conf->socket_id = socket_id; + txq_conf->tx_conf = *tx_conf; + } + + return ret; } void @@ -3472,3 +3513,60 @@ 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); } + +int +rte_eth_dev_restore(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int ret; + uint16_t q; + struct rte_eth_rx_queue_conf *rxq_conf; + struct rte_eth_tx_queue_conf *txq_conf; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_uninit, -ENOTSUP); + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_init, -ENOTSUP); + + rte_eth_dev_stop(port_id); + + ret = dev->dev_ops->dev_uninit(dev); + if (ret) + return ret; + + ret = dev->dev_ops->dev_init(dev); + if (ret) + return ret; + + ret = rte_eth_dev_configure(port_id, dev->data->nb_rx_queues, + dev->data->nb_tx_queues, &dev->data->dev_conf); + if (ret) + return ret; + + for (q = 0; q < dev->data->nb_rx_queues; q++) { + rxq_conf = &dev->data->rxq_conf[q]; + ret = rte_eth_rx_queue_setup(port_id, q, rxq_conf->nb_rx_desc, + rxq_conf->socket_id, + &rxq_conf->rx_conf, + rxq_conf->mp); + if (!ret) + return ret; + } + + for (q = 0; q < dev->data->nb_tx_queues; q++) { + txq_conf = &dev->data->txq_conf[q]; + ret = rte_eth_tx_queue_setup(port_id, q, txq_conf->nb_tx_desc, + txq_conf->socket_id, + &txq_conf->tx_conf); + if (!ret) + return ret; + } + + ret = rte_eth_dev_start(port_id); + + if (dev->dev_ops->dev_restore) + ret = dev->dev_ops->dev_restore(dev); + + return ret; +} diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 0f38b45..0298a1f 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -1085,6 +1085,15 @@ typedef int (*eth_dev_set_link_down_t)(struct rte_eth_dev *dev); typedef void (*eth_dev_close_t)(struct rte_eth_dev *dev); /**< @internal Function used to close a configured Ethernet device. */ +typedef int (*eth_dev_init_t)(struct rte_eth_dev *dev); +/** < @internal Function used to initialize a configured Ethernet device. */ + +typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *dev); +/** < @internal Function used to uninit a configured Ethernet device. */ + +typedef int (*eth_dev_restore_t)(struct rte_eth_dev *dev); +/**< @internal Function used to restore a configured Ethernet device. */ + typedef void (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev); /**< @internal Function used to enable the RX promiscuous mode of an Ethernet device. */ @@ -1455,6 +1464,9 @@ struct eth_dev_ops { eth_dev_set_link_up_t dev_set_link_up; /**< Device link up. */ eth_dev_set_link_down_t dev_set_link_down; /**< Device link down. */ eth_dev_close_t dev_close; /**< Close device. */ + eth_dev_init_t dev_init; /**< Initialize device */ + eth_dev_uninit_t dev_uninit; /**< Uninit device */ + eth_dev_restore_t dev_restore; /**< Restore device */ eth_link_update_t link_update; /**< Get device link state. */ eth_promiscuous_enable_t promiscuous_enable; /**< Promiscuous ON. */ @@ -1689,6 +1701,19 @@ struct rte_eth_dev_sriov { #define RTE_ETH_NAME_MAX_LEN (32) +struct rte_eth_rx_queue_conf { + uint16_t nb_rx_desc; + unsigned int socket_id; + struct rte_eth_rxconf rx_conf; + struct rte_mempool *mp; +}; + +struct rte_eth_tx_queue_conf { + uint16_t nb_tx_desc; + unsigned int socket_id; + struct rte_eth_txconf tx_conf; +}; + /** * @internal * The data part, with no function pointers, associated with each ethernet device. @@ -1738,6 +1763,9 @@ struct rte_eth_dev_data { enum rte_kernel_driver kdrv; /**< Kernel driver passthrough */ int numa_node; /**< NUMA node connection */ const char *drv_name; /**< Driver name */ + + struct rte_eth_rx_queue_conf *rxq_conf; + struct rte_eth_tx_queue_conf *txq_conf; }; /** Device supports hotplug detach */ @@ -2168,6 +2196,14 @@ int rte_eth_dev_set_link_down(uint8_t port_id); void rte_eth_dev_close(uint8_t port_id); /** + * Resotre a Ethernet device. + * + * @param port_id + * The port identifier of the Ethernet device. + */ +int rte_eth_dev_restore(uint8_t port_id); + +/** * Enable receipt in promiscuous mode for an Ethernet device. * * @param port_id diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map index d6726bb..b867c4c 100644 --- a/lib/librte_ether/rte_ether_version.map +++ b/lib/librte_ether/rte_ether_version.map @@ -156,3 +156,9 @@ DPDK_17.05 { rte_eth_xstats_get_names_by_id; } DPDK_17.02; + +DPDK_17.08 { + global: + + rte_eth_dev_restore; +} DPDK_17.05;