dpdk/0059-net-hns3-add-runtime-config-to-select-IO-burst-funct.patch
speech_white 3a8995b1ad Update DPDK baseline version
Update DPDK version from 19.11 to 20.11 and also support
hns3 PMD for Kunpeng 920 and Kunpeng 930.

Signed-off-by: speech_white <humin29@huawei.com>
2021-06-28 00:52:34 +00:00

342 lines
12 KiB
Diff

From 20570791fbb46112707b5ddb21da9446da8a938d Mon Sep 17 00:00:00 2001
From: Chengwen Feng <fengchengwen@huawei.com>
Date: Tue, 23 Mar 2021 19:21:00 +0800
Subject: [PATCH 059/189] net/hns3: add runtime config to select IO burst
function
Currently, the driver support multiple IO burst function and auto
selection of the most appropriate function based on offload
configuration.
Most applications such as l2fwd/l3fwd don't provide the means to
change offload configuration, so it will use the auto selection's io
burst function.
This patch support runtime config to select io burst function, which
add two config: rx_func_hint and tx_func_hint, both could assign
vec/sve/simple/common.
The driver will use the following rules to select io burst func:
a. if hint equal vec and meet the vec Rx/Tx usage condition then use the
neon function.
b. if hint equal sve and meet the sve Rx/Tx usage condition then use the
sve function.
c. if hint equal simple and meet the simple Rx/Tx usage condition then
use the simple function.
d. if hint equal common then use the common function.
e. if hint not set then:
e.1. if meet the vec Rx/Tx usage condition then use the neon function.
e.2. if meet the simple Rx/Tx usage condition then use the simple
function.
e.3. else use the common function.
Note: the sve Rx/Tx usage condition based on the vec Rx/Tx usage
condition and runtime environment (which must support SVE).
In the previous versions, driver will preferred use the sve function
when meet the sve Rx/Tx usage condition, but in this case driver could
get better performance if use the neon function.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
doc/guides/nics/hns3.rst | 37 +++++++++++++++++++
drivers/net/hns3/hns3_ethdev.c | 77 +++++++++++++++++++++++++++++++++++++++
drivers/net/hns3/hns3_ethdev.h | 15 ++++++++
drivers/net/hns3/hns3_ethdev_vf.c | 4 ++
drivers/net/hns3/hns3_rxtx.c | 54 ++++++++++++++++++++-------
5 files changed, 173 insertions(+), 14 deletions(-)
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 8db8867..e8abd07 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -46,6 +46,43 @@ Prerequisites
- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+Runtime Config Options
+----------------------
+
+- ``rx_func_hint`` (default ``none``)
+
+ Used to select Rx burst function, supported value are ``vec``, ``sve``,
+ ``simple``, ``common``.
+ ``vec``, if supported use the ``vec`` Rx function which indicates the
+ default vector algorithm, neon for Kunpeng Arm platform.
+ ``sve``, if supported use the ``sve`` Rx function which indicates the
+ sve algorithm.
+ ``simple``, if supported use the ``simple`` Rx function which indicates
+ the scalar algorithm.
+ ``common``, if supported use the ``common`` Rx function which indicates
+ the scalar scattered algorithm.
+
+ When provided parameter is not supported, ``vec`` usage condition will
+ be first checked, if meets, use the ``vec``. Then, ``simple``, at last
+ ``common``.
+
+- ``tx_func_hint`` (default ``none``)
+
+ Used to select Tx burst function, supported value are ``vec``, ``sve``,
+ ``simple``, ``common``.
+ ``vec``, if supported use the ``vec`` Tx function which indicates the
+ default vector algorithm, neon for Kunpeng Arm platform.
+ ``sve``, if supported use the ``sve`` Tx function which indicates the
+ sve algorithm.
+ ``simple``, if supported use the ``simple`` Tx function which indicates
+ the scalar simple algorithm.
+ ``common``, if supported use the ``common`` Tx function which indicates
+ the scalar algorithm.
+
+ When provided parameter is not supported, ``vec`` usage condition will
+ be first checked, if meets, use the ``vec``. Then, ``simple``, at last
+ ``common``.
+
Driver compilation and testing
------------------------------
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 80f91a7..f6ec8ac 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -6,6 +6,7 @@
#include <rte_bus_pci.h>
#include <rte_ethdev_pci.h>
#include <rte_pci.h>
+#include <rte_kvargs.h>
#include "hns3_ethdev.h"
#include "hns3_logs.h"
@@ -6505,6 +6506,78 @@ hns3_get_module_info(struct rte_eth_dev *dev,
return 0;
}
+static int
+hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args)
+{
+ uint32_t hint = HNS3_IO_FUNC_HINT_NONE;
+
+ RTE_SET_USED(key);
+
+ if (strcmp(value, "vec") == 0)
+ hint = HNS3_IO_FUNC_HINT_VEC;
+ else if (strcmp(value, "sve") == 0)
+ hint = HNS3_IO_FUNC_HINT_SVE;
+ else if (strcmp(value, "simple") == 0)
+ hint = HNS3_IO_FUNC_HINT_SIMPLE;
+ else if (strcmp(value, "common") == 0)
+ hint = HNS3_IO_FUNC_HINT_COMMON;
+
+ /* If the hint is valid then update output parameters */
+ if (hint != HNS3_IO_FUNC_HINT_NONE)
+ *(uint32_t *)extra_args = hint;
+
+ return 0;
+}
+
+static const char *
+hns3_get_io_hint_func_name(uint32_t hint)
+{
+ switch (hint) {
+ case HNS3_IO_FUNC_HINT_VEC:
+ return "vec";
+ case HNS3_IO_FUNC_HINT_SVE:
+ return "sve";
+ case HNS3_IO_FUNC_HINT_SIMPLE:
+ return "simple";
+ case HNS3_IO_FUNC_HINT_COMMON:
+ return "common";
+ default:
+ return "none";
+ }
+}
+
+void
+hns3_parse_devargs(struct rte_eth_dev *dev)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE;
+ uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE;
+ struct hns3_hw *hw = &hns->hw;
+ struct rte_kvargs *kvlist;
+
+ if (dev->device->devargs == NULL)
+ return;
+
+ kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL);
+ if (!kvlist)
+ return;
+
+ rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT,
+ &hns3_parse_io_hint_func, &rx_func_hint);
+ rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT,
+ &hns3_parse_io_hint_func, &tx_func_hint);
+ rte_kvargs_free(kvlist);
+
+ if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE)
+ hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_RX_FUNC_HINT,
+ hns3_get_io_hint_func_name(rx_func_hint));
+ hns->rx_func_hint = rx_func_hint;
+ if (tx_func_hint != HNS3_IO_FUNC_HINT_NONE)
+ hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT,
+ hns3_get_io_hint_func_name(tx_func_hint));
+ hns->tx_func_hint = tx_func_hint;
+}
+
static const struct eth_dev_ops hns3_eth_dev_ops = {
.dev_configure = hns3_dev_configure,
.dev_start = hns3_dev_start,
@@ -6625,6 +6698,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
hw->adapter_state = HNS3_NIC_UNINITIALIZED;
hns->is_vf = false;
hw->data = eth_dev->data;
+ hns3_parse_devargs(eth_dev);
/*
* Set default max packet size according to the mtu
@@ -6758,5 +6832,8 @@ static struct rte_pci_driver rte_hns3_pmd = {
RTE_PMD_REGISTER_PCI(net_hns3, rte_hns3_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map);
RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_hns3,
+ HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common "
+ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common ");
RTE_LOG_REGISTER(hns3_logtype_init, pmd.net.hns3.init, NOTICE);
RTE_LOG_REGISTER(hns3_logtype_driver, pmd.net.hns3.driver, NOTICE);
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 52e6c49..67a69ba 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -772,9 +772,23 @@ struct hns3_adapter {
bool tx_simple_allowed;
bool tx_vec_allowed;
+ uint32_t rx_func_hint;
+ uint32_t tx_func_hint;
+
struct hns3_ptype_table ptype_tbl __rte_cache_min_aligned;
};
+enum {
+ HNS3_IO_FUNC_HINT_NONE = 0,
+ HNS3_IO_FUNC_HINT_VEC,
+ HNS3_IO_FUNC_HINT_SVE,
+ HNS3_IO_FUNC_HINT_SIMPLE,
+ HNS3_IO_FUNC_HINT_COMMON
+};
+
+#define HNS3_DEVARG_RX_FUNC_HINT "rx_func_hint"
+#define HNS3_DEVARG_TX_FUNC_HINT "tx_func_hint"
+
#define HNS3_DEV_SUPPORT_DCB_B 0x0
#define HNS3_DEV_SUPPORT_COPPER_B 0x1
#define HNS3_DEV_SUPPORT_UDP_GSO_B 0x2
@@ -975,6 +989,7 @@ int hns3_dev_infos_get(struct rte_eth_dev *eth_dev,
struct rte_eth_dev_info *info);
void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
uint32_t link_speed, uint8_t link_duplex);
+void hns3_parse_devargs(struct rte_eth_dev *dev);
static inline bool
is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 12af105..a4fd8ca 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -2834,6 +2834,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev)
hw->adapter_state = HNS3_NIC_UNINITIALIZED;
hns->is_vf = true;
hw->data = eth_dev->data;
+ hns3_parse_devargs(eth_dev);
ret = hns3_reset_init(hw);
if (ret)
@@ -2962,3 +2963,6 @@ static struct rte_pci_driver rte_hns3vf_pmd = {
RTE_PMD_REGISTER_PCI(net_hns3_vf, rte_hns3vf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_hns3_vf, pci_id_hns3vf_map);
RTE_PMD_REGISTER_KMOD_DEP(net_hns3_vf, "* igb_uio | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_hns3_vf,
+ HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common "
+ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common ");
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 09b38d4..8e927f1 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2689,13 +2689,26 @@ hns3_get_rx_function(struct rte_eth_dev *dev)
{
struct hns3_adapter *hns = dev->data->dev_private;
uint64_t offloads = dev->data->dev_conf.rxmode.offloads;
+ bool vec_allowed, sve_allowed, simple_allowed;
+
+ vec_allowed = hns->rx_vec_allowed &&
+ hns3_rx_check_vec_support(dev) == 0;
+ sve_allowed = vec_allowed && hns3_check_sve_support();
+ simple_allowed = hns->rx_simple_allowed && !dev->data->scattered_rx &&
+ (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0;
+
+ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed)
+ return hns3_recv_pkts_vec;
+ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SVE && sve_allowed)
+ return hns3_recv_pkts_vec_sve;
+ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed)
+ return hns3_recv_pkts;
+ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_COMMON)
+ return hns3_recv_scattered_pkts;
- if (hns->rx_vec_allowed && hns3_rx_check_vec_support(dev) == 0)
- return hns3_check_sve_support() ? hns3_recv_pkts_vec_sve :
- hns3_recv_pkts_vec;
-
- if (hns->rx_simple_allowed && !dev->data->scattered_rx &&
- (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0)
+ if (vec_allowed)
+ return hns3_recv_pkts_vec;
+ if (simple_allowed)
return hns3_recv_pkts;
return hns3_recv_scattered_pkts;
@@ -3930,19 +3943,32 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep)
{
uint64_t offloads = dev->data->dev_conf.txmode.offloads;
struct hns3_adapter *hns = dev->data->dev_private;
+ bool vec_allowed, sve_allowed, simple_allowed;
- if (hns->tx_vec_allowed && hns3_tx_check_vec_support(dev) == 0) {
- *prep = NULL;
- return hns3_check_sve_support() ? hns3_xmit_pkts_vec_sve :
- hns3_xmit_pkts_vec;
- }
+ vec_allowed = hns->tx_vec_allowed &&
+ hns3_tx_check_vec_support(dev) == 0;
+ sve_allowed = vec_allowed && hns3_check_sve_support();
+ simple_allowed = hns->tx_simple_allowed &&
+ offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
- if (hns->tx_simple_allowed &&
- offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE)) {
- *prep = NULL;
+ *prep = NULL;
+
+ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed)
+ return hns3_xmit_pkts_vec;
+ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SVE && sve_allowed)
+ return hns3_xmit_pkts_vec_sve;
+ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed)
return hns3_xmit_pkts_simple;
+ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON) {
+ *prep = hns3_prep_pkts;
+ return hns3_xmit_pkts;
}
+ if (vec_allowed)
+ return hns3_xmit_pkts_vec;
+ if (simple_allowed)
+ return hns3_xmit_pkts_simple;
+
*prep = hns3_prep_pkts;
return hns3_xmit_pkts;
}
--
2.7.4