From 229a6d2096fd1066172855becca12aa46773b848 Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Wed, 15 Feb 2023 14:02:44 +0800 Subject: [PATCH 01/10] sync some RSS bugfix for hns3 PMD And patchs are as follows: - net/hns3: fix log about indirection table size - net/hns3: extract common function to query device - net/hns3: refactor set RSS hash algorithm and key interface - net/hns3: fix RSS key size compatibility - net/hns3: fix clearing RSS configuration - net/hns3: use RSS filter list to check duplicated rule - net/hns3: remove useless code when destroy valid RSS rule - net/hns3: fix warning on flush or destroy rule - net/hns3: fix config struct used for conversion - net/hns3: fix duplicate RSS rule check --- ...fix-log-about-indirection-table-size.patch | 53 ++++ ...ract-common-function-to-query-device.patch | 291 ++++++++++++++++++ ...r-set-RSS-hash-algorithm-and-key-int.patch | 149 +++++++++ ...-hns3-fix-RSS-key-size-compatibility.patch | 209 +++++++++++++ ...-hns3-fix-clearing-RSS-configuration.patch | 42 +++ ...-filter-list-to-check-duplicated-rul.patch | 89 ++++++ ...useless-code-when-destroy-valid-RSS-.patch | 91 ++++++ ...fix-warning-on-flush-or-destroy-rule.patch | 66 ++++ ...ix-config-struct-used-for-conversion.patch | 133 ++++++++ ...et-hns3-fix-duplicate-RSS-rule-check.patch | 108 +++++++ dpdk.spec | 25 +- 11 files changed, 1255 insertions(+), 1 deletion(-) create mode 100644 0221-net-hns3-fix-log-about-indirection-table-size.patch create mode 100644 0222-net-hns3-extract-common-function-to-query-device.patch create mode 100644 0223-net-hns3-refactor-set-RSS-hash-algorithm-and-key-int.patch create mode 100644 0224-net-hns3-fix-RSS-key-size-compatibility.patch create mode 100644 0225-net-hns3-fix-clearing-RSS-configuration.patch create mode 100644 0226-net-hns3-use-RSS-filter-list-to-check-duplicated-rul.patch create mode 100644 0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch create mode 100644 0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch create mode 100644 0229-net-hns3-fix-config-struct-used-for-conversion.patch create mode 100644 0230-net-hns3-fix-duplicate-RSS-rule-check.patch diff --git a/0221-net-hns3-fix-log-about-indirection-table-size.patch b/0221-net-hns3-fix-log-about-indirection-table-size.patch new file mode 100644 index 0000000..613aaf4 --- /dev/null +++ b/0221-net-hns3-fix-log-about-indirection-table-size.patch @@ -0,0 +1,53 @@ +From 55cc3ba793a896aeac7abb05a247b3b32d2adc75 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:51 +0800 +Subject: net/hns3: fix log about indirection table size + +[ upstream commit b55516a94246364f272db802f5dfb9aeb8d3a2f2 ] + +The error log about indirection table size during initialization phase +of PF and VF is unreasonable. + +In addition, VF driver should use error level to print this log. + +Fixes: 0fce2c46dc16 ("net/hns3: fix RSS indirection table size") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + drivers/net/hns3/hns3_ethdev_vf.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 25f9c9fab1..ed273b5b69 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2679,7 +2679,7 @@ hns3_check_dev_specifications(struct hns3_hw *hw) + { + if (hw->rss_ind_tbl_size == 0 || + hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { +- hns3_err(hw, "the size of hash lookup table configured (%u) exceeds the maximum(%u)", ++ hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", + hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); + return -EINVAL; + } +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index de44b07691..8a3a3cc657 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -718,8 +718,8 @@ hns3vf_check_dev_specifications(struct hns3_hw *hw) + { + if (hw->rss_ind_tbl_size == 0 || + hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { +- hns3_warn(hw, "the size of hash lookup table configured (%u) exceeds the maximum(%u)", +- hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); ++ hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", ++ hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); + return -EINVAL; + } + +-- +2.23.0 + diff --git a/0222-net-hns3-extract-common-function-to-query-device.patch b/0222-net-hns3-extract-common-function-to-query-device.patch new file mode 100644 index 0000000..99e65ff --- /dev/null +++ b/0222-net-hns3-extract-common-function-to-query-device.patch @@ -0,0 +1,291 @@ +From 6fb8330396b77c4a4acc73ff895a8d2b62a5ab93 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:52 +0800 +Subject: net/hns3: extract common function to query device + +[ upstream commit 52a4e960b49c526dd1ad7c1e91ebcfa664a38e6d ] + +Extract common function to query device specifications used by VF and +PF. + +Fixes: 9c740336f024 ("net/hns3: get device specifications from firmware") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_common.c | 75 +++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_common.h | 2 + + drivers/net/hns3/hns3_ethdev.c | 63 -------------------------- + drivers/net/hns3/hns3_ethdev_vf.c | 65 +-------------------------- + 4 files changed, 79 insertions(+), 126 deletions(-) + +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 2ebcf5695b..212b35d842 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -10,6 +10,7 @@ + #include "hns3_logs.h" + #include "hns3_regs.h" + #include "hns3_rxtx.h" ++#include "hns3_dcb.h" + #include "hns3_common.h" + + int +@@ -843,3 +844,77 @@ hns3_get_pci_revision_id(struct hns3_hw *hw, uint8_t *revision_id) + + return 0; + } ++ ++void ++hns3_set_default_dev_specifications(struct hns3_hw *hw) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ ++ hw->max_non_tso_bd_num = HNS3_MAX_NON_TSO_BD_PER_PKT; ++ hw->rss_ind_tbl_size = HNS3_RSS_IND_TBL_SIZE; ++ hw->rss_key_size = HNS3_RSS_KEY_SIZE; ++ hw->intr.int_ql_max = HNS3_INTR_QL_NONE; ++ ++ if (hns->is_vf) ++ return; ++ ++ hw->max_tm_rate = HNS3_ETHER_MAX_RATE; ++} ++ ++static void ++hns3_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ struct hns3_dev_specs_0_cmd *req0; ++ struct hns3_dev_specs_1_cmd *req1; ++ ++ req0 = (struct hns3_dev_specs_0_cmd *)desc[0].data; ++ req1 = (struct hns3_dev_specs_1_cmd *)desc[1].data; ++ ++ hw->max_non_tso_bd_num = req0->max_non_tso_bd_num; ++ hw->rss_ind_tbl_size = rte_le_to_cpu_16(req0->rss_ind_tbl_size); ++ hw->rss_key_size = rte_le_to_cpu_16(req0->rss_key_size); ++ hw->intr.int_ql_max = rte_le_to_cpu_16(req0->intr_ql_max); ++ hw->min_tx_pkt_len = req1->min_tx_pkt_len; ++ ++ if (hns->is_vf) ++ return; ++ ++ hw->max_tm_rate = rte_le_to_cpu_32(req0->max_tm_rate); ++} ++ ++static int ++hns3_check_dev_specifications(struct hns3_hw *hw) ++{ ++ if (hw->rss_ind_tbl_size == 0 || ++ hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { ++ hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", ++ hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int ++hns3_query_dev_specifications(struct hns3_hw *hw) ++{ ++ struct hns3_cmd_desc desc[HNS3_QUERY_DEV_SPECS_BD_NUM]; ++ int ret; ++ int i; ++ ++ for (i = 0; i < HNS3_QUERY_DEV_SPECS_BD_NUM - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, ++ true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, true); ++ ++ ret = hns3_cmd_send(hw, desc, HNS3_QUERY_DEV_SPECS_BD_NUM); ++ if (ret) ++ return ret; ++ ++ hns3_parse_dev_specifications(hw, desc); ++ ++ return hns3_check_dev_specifications(hw); ++} +diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h +index 5aa001f0cc..8eaeda26e7 100644 +--- a/drivers/net/hns3/hns3_common.h ++++ b/drivers/net/hns3/hns3_common.h +@@ -60,5 +60,7 @@ void hns3_unmap_rx_interrupt(struct rte_eth_dev *dev); + int hns3_restore_rx_interrupt(struct hns3_hw *hw); + + int hns3_get_pci_revision_id(struct hns3_hw *hw, uint8_t *revision_id); ++void hns3_set_default_dev_specifications(struct hns3_hw *hw); ++int hns3_query_dev_specifications(struct hns3_hw *hw); + + #endif /* HNS3_COMMON_H */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index ed273b5b69..8fa12d91bb 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2647,69 +2647,6 @@ hns3_parse_speed(int speed_cmd, uint32_t *speed) + return 0; + } + +-static void +-hns3_set_default_dev_specifications(struct hns3_hw *hw) +-{ +- hw->max_non_tso_bd_num = HNS3_MAX_NON_TSO_BD_PER_PKT; +- hw->rss_ind_tbl_size = HNS3_RSS_IND_TBL_SIZE; +- hw->rss_key_size = HNS3_RSS_KEY_SIZE; +- hw->max_tm_rate = HNS3_ETHER_MAX_RATE; +- hw->intr.int_ql_max = HNS3_INTR_QL_NONE; +-} +- +-static void +-hns3_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc) +-{ +- struct hns3_dev_specs_0_cmd *req0; +- struct hns3_dev_specs_1_cmd *req1; +- +- req0 = (struct hns3_dev_specs_0_cmd *)desc[0].data; +- req1 = (struct hns3_dev_specs_1_cmd *)desc[1].data; +- +- hw->max_non_tso_bd_num = req0->max_non_tso_bd_num; +- hw->rss_ind_tbl_size = rte_le_to_cpu_16(req0->rss_ind_tbl_size); +- hw->rss_key_size = rte_le_to_cpu_16(req0->rss_key_size); +- hw->max_tm_rate = rte_le_to_cpu_32(req0->max_tm_rate); +- hw->intr.int_ql_max = rte_le_to_cpu_16(req0->intr_ql_max); +- hw->min_tx_pkt_len = req1->min_tx_pkt_len; +-} +- +-static int +-hns3_check_dev_specifications(struct hns3_hw *hw) +-{ +- if (hw->rss_ind_tbl_size == 0 || +- hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { +- hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", +- hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int +-hns3_query_dev_specifications(struct hns3_hw *hw) +-{ +- struct hns3_cmd_desc desc[HNS3_QUERY_DEV_SPECS_BD_NUM]; +- int ret; +- int i; +- +- for (i = 0; i < HNS3_QUERY_DEV_SPECS_BD_NUM - 1; i++) { +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, +- true); +- desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- } +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, true); +- +- ret = hns3_cmd_send(hw, desc, HNS3_QUERY_DEV_SPECS_BD_NUM); +- if (ret) +- return ret; +- +- hns3_parse_dev_specifications(hw, desc); +- +- return hns3_check_dev_specifications(hw); +-} +- + static int + hns3_get_capability(struct hns3_hw *hw) + { +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 8a3a3cc657..a3a1b71a63 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -688,67 +688,6 @@ hns3vf_interrupt_handler(void *param) + hns3vf_enable_irq0(hw); + } + +-static void +-hns3vf_set_default_dev_specifications(struct hns3_hw *hw) +-{ +- hw->max_non_tso_bd_num = HNS3_MAX_NON_TSO_BD_PER_PKT; +- hw->rss_ind_tbl_size = HNS3_RSS_IND_TBL_SIZE; +- hw->rss_key_size = HNS3_RSS_KEY_SIZE; +- hw->intr.int_ql_max = HNS3_INTR_QL_NONE; +-} +- +-static void +-hns3vf_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc) +-{ +- struct hns3_dev_specs_0_cmd *req0; +- struct hns3_dev_specs_1_cmd *req1; +- +- req0 = (struct hns3_dev_specs_0_cmd *)desc[0].data; +- req1 = (struct hns3_dev_specs_1_cmd *)desc[1].data; +- +- hw->max_non_tso_bd_num = req0->max_non_tso_bd_num; +- hw->rss_ind_tbl_size = rte_le_to_cpu_16(req0->rss_ind_tbl_size); +- hw->rss_key_size = rte_le_to_cpu_16(req0->rss_key_size); +- hw->intr.int_ql_max = rte_le_to_cpu_16(req0->intr_ql_max); +- hw->min_tx_pkt_len = req1->min_tx_pkt_len; +-} +- +-static int +-hns3vf_check_dev_specifications(struct hns3_hw *hw) +-{ +- if (hw->rss_ind_tbl_size == 0 || +- hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { +- hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", +- hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int +-hns3vf_query_dev_specifications(struct hns3_hw *hw) +-{ +- struct hns3_cmd_desc desc[HNS3_QUERY_DEV_SPECS_BD_NUM]; +- int ret; +- int i; +- +- for (i = 0; i < HNS3_QUERY_DEV_SPECS_BD_NUM - 1; i++) { +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, +- true); +- desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- } +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_QUERY_DEV_SPECS, true); +- +- ret = hns3_cmd_send(hw, desc, HNS3_QUERY_DEV_SPECS_BD_NUM); +- if (ret) +- return ret; +- +- hns3vf_parse_dev_specifications(hw, desc); +- +- return hns3vf_check_dev_specifications(hw); +-} +- + void + hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported) + { +@@ -826,7 +765,7 @@ hns3vf_get_capability(struct hns3_hw *hw) + return ret; + + if (hw->revision < PCI_REVISION_ID_HIP09_A) { +- hns3vf_set_default_dev_specifications(hw); ++ hns3_set_default_dev_specifications(hw); + hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE; + hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US; + hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM; +@@ -837,7 +776,7 @@ hns3vf_get_capability(struct hns3_hw *hw) + return 0; + } + +- ret = hns3vf_query_dev_specifications(hw); ++ ret = hns3_query_dev_specifications(hw); + if (ret) { + PMD_INIT_LOG(ERR, + "failed to query dev specifications, ret = %d", +-- +2.23.0 + diff --git a/0223-net-hns3-refactor-set-RSS-hash-algorithm-and-key-int.patch b/0223-net-hns3-refactor-set-RSS-hash-algorithm-and-key-int.patch new file mode 100644 index 0000000..7d48ce2 --- /dev/null +++ b/0223-net-hns3-refactor-set-RSS-hash-algorithm-and-key-int.patch @@ -0,0 +1,149 @@ +From d0c9a7b130290b2079dfaeaf301b95982480912c Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:53 +0800 +Subject: net/hns3: refactor set RSS hash algorithm and key interface + +[ upstream commit 88347111eb53bc54c598dde81715a06ca1dbd132 ] + +The hns3_rss_set_algo_key() is used to set RSS hash algorithm and key to +hardware. +The maximum execution time of the command sent to the firmware is +proportional to the length of the key. +However, now this times is fixed, which isn't good for key expansion. + +In addition, hash algorithm comes from rss_info::hash_algo maintained in +the driver, which also isn't good for the usage of this function. + +Interface is updated to get hash algorithm and key length as input +parameters. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 3 ++- + drivers/net/hns3/hns3_rss.c | 48 ++++++++++++++++-------------------- + drivers/net/hns3/hns3_rss.h | 4 ++- + 3 files changed, 26 insertions(+), 29 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index a2c1589c39..95609f8483 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1494,7 +1494,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + if (ret) + return ret; + +- ret = hns3_rss_set_algo_key(hw, rss_config->key); ++ ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, ++ rss_config->key, HNS3_RSS_KEY_SIZE); + if (ret) + return ret; + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index ca5a129234..3db7bf0445 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -277,45 +277,37 @@ static const struct { + + /* + * rss_generic_config command function, opcode:0x0D01. +- * Used to set algorithm, key_offset and hash key of rss. ++ * Used to set algorithm and hash key of RSS. + */ + int +-hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key) ++hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, ++ const uint8_t *key, uint8_t key_len) + { +-#define HNS3_KEY_OFFSET_MAX 3 +-#define HNS3_SET_HASH_KEY_BYTE_FOUR 2 +- + struct hns3_rss_generic_config_cmd *req; + struct hns3_cmd_desc desc; +- uint32_t key_offset, key_size; +- const uint8_t *key_cur; +- uint8_t cur_offset; ++ const uint8_t *cur_key; ++ uint16_t cur_key_size; ++ uint16_t max_bd_num; ++ uint16_t idx; + int ret; + + req = (struct hns3_rss_generic_config_cmd *)desc.data; + +- /* +- * key_offset=0, hash key byte0~15 is set to hardware. +- * key_offset=1, hash key byte16~31 is set to hardware. +- * key_offset=2, hash key byte32~39 is set to hardware. +- */ +- for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) { ++ max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); ++ for (idx = 0; idx < max_bd_num; idx++) { + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, + false); + +- req->hash_config |= +- (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); +- req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); ++ req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK); ++ req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); + +- if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) +- key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM * +- HNS3_SET_HASH_KEY_BYTE_FOUR; ++ if (idx == max_bd_num - 1) ++ cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; + else +- key_size = HNS3_RSS_HASH_KEY_NUM; ++ cur_key_size = HNS3_RSS_HASH_KEY_NUM; + +- cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM; +- key_cur = key + cur_offset; +- memcpy(req->hash_key, key_cur, key_size); ++ cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; ++ memcpy(req->hash_key, cur_key, cur_key_size); + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { +@@ -518,7 +510,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + goto set_tuple_fail; + + if (key) { +- ret = hns3_rss_set_algo_key(hw, key); ++ ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, ++ key, HNS3_RSS_KEY_SIZE); + if (ret) + goto set_algo_key_fail; + } +@@ -795,8 +788,9 @@ hns3_config_rss(struct hns3_adapter *hns) + break; + } + +- /* Configure RSS hash algorithm and hash key offset */ +- ret = hns3_rss_set_algo_key(hw, hash_key); ++ /* Configure RSS hash algorithm and hash key */ ++ ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, hash_key, ++ HNS3_RSS_KEY_SIZE); + if (ret) + return ret; + +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 8e8b056f4e..b7f62ca1ee 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -109,6 +109,8 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw); + int hns3_config_rss(struct hns3_adapter *hns); + void hns3_rss_uninit(struct hns3_adapter *hns); + int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); +-int hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key); ++int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, ++ const uint8_t *key, uint8_t key_len); ++ + + #endif /* HNS3_RSS_H */ +-- +2.23.0 + diff --git a/0224-net-hns3-fix-RSS-key-size-compatibility.patch b/0224-net-hns3-fix-RSS-key-size-compatibility.patch new file mode 100644 index 0000000..ed823ec --- /dev/null +++ b/0224-net-hns3-fix-RSS-key-size-compatibility.patch @@ -0,0 +1,209 @@ +From 7d81fd5ed42af46c6e5eef15b4dce7172a2e571d Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:54 +0800 +Subject: net/hns3: fix RSS key size compatibility + +[ upstream commit 5172f9c464aa315a9d45b9177af71b4f99d55cdb ] + +For better compatibility, the RSS key size of PF and VF are obtained +from firmware. However, the outdated HNS3_RSS_KEY_SIZE macro is still +utilized in many locations as the key size. + +Fixes: 9c740336f024 ("net/hns3: get device specifications from firmware") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_common.c | 12 +++++++++++- + drivers/net/hns3/hns3_flow.c | 26 ++++++++++++-------------- + drivers/net/hns3/hns3_rss.c | 23 +++++++++++------------ + drivers/net/hns3/hns3_rss.h | 3 ++- + 4 files changed, 36 insertions(+), 28 deletions(-) + +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 212b35d842..9bfbe1161f 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -129,7 +129,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + }; + + info->reta_size = hw->rss_ind_tbl_size; +- info->hash_key_size = HNS3_RSS_KEY_SIZE; ++ info->hash_key_size = hw->rss_key_size; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; + + info->default_rxportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; +@@ -893,6 +893,16 @@ hns3_check_dev_specifications(struct hns3_hw *hw) + return -EINVAL; + } + ++ if (hw->rss_key_size == 0 || hw->rss_key_size > HNS3_RSS_KEY_SIZE_MAX) { ++ hns3_err(hw, "the RSS key size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", ++ hw->rss_key_size, HNS3_RSS_KEY_SIZE_MAX); ++ return -EINVAL; ++ } ++ ++ if (hw->rss_key_size > HNS3_RSS_KEY_SIZE) ++ hns3_warn(hw, "the RSS key size obtained (%u) is greater than the default key size (%u)", ++ hw->rss_key_size, HNS3_RSS_KEY_SIZE); ++ + return 0; + } + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 95609f8483..a18ec7650d 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1406,10 +1406,10 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, + "a nonzero RSS encapsulation level is not supported"); +- if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key)) ++ if (rss->key_len && rss->key_len != hw->rss_key_size) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "RSS hash key must be exactly 40 bytes"); ++ "invalid RSS key length"); + + if (!hns3_rss_input_tuple_supported(hw, rss)) + return rte_flow_error_set(error, EINVAL, +@@ -1443,16 +1443,6 @@ hns3_disable_rss(struct hns3_hw *hw) + return 0; + } + +-static void +-hns3_adjust_rss_key(struct hns3_hw *hw, struct rte_flow_action_rss *rss_conf) +-{ +- if (rss_conf->key == NULL || rss_conf->key_len < HNS3_RSS_KEY_SIZE) { +- hns3_warn(hw, "Default RSS hash key to be set"); +- rss_conf->key = hns3_hash_key; +- rss_conf->key_len = HNS3_RSS_KEY_SIZE; +- } +-} +- + static int + hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, + uint8_t *hash_algo) +@@ -1485,9 +1475,16 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, + static int + hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + { ++ uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; ++ bool use_default_key = false; + int ret; + +- hns3_adjust_rss_key(hw, rss_config); ++ if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) { ++ hns3_warn(hw, "Default RSS hash key to be set"); ++ memcpy(rss_key, hns3_hash_key, ++ RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); ++ use_default_key = true; ++ } + + ret = hns3_parse_rss_algorithm(hw, &rss_config->func, + &hw->rss_info.hash_algo); +@@ -1495,7 +1492,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + return ret; + + ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, +- rss_config->key, HNS3_RSS_KEY_SIZE); ++ use_default_key ? rss_key : rss_config->key, ++ hw->rss_key_size); + if (ret) + return ret; + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 3db7bf0445..d6e0754273 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -316,7 +316,7 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + } + } + /* Update the shadow RSS key with user specified */ +- memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE); ++ memcpy(hw->rss_info.key, key, hw->rss_key_size); + return 0; + } + +@@ -498,9 +498,9 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + uint8_t *key = rss_conf->rss_key; + int ret; + +- if (key && key_len != HNS3_RSS_KEY_SIZE) { ++ if (key && key_len != hw->rss_key_size) { + hns3_err(hw, "the hash key len(%u) is invalid, must be %u", +- key_len, HNS3_RSS_KEY_SIZE); ++ key_len, hw->rss_key_size); + return -EINVAL; + } + +@@ -511,7 +511,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + + if (key) { + ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, +- key, HNS3_RSS_KEY_SIZE); ++ key, hw->rss_key_size); + if (ret) + goto set_algo_key_fail; + } +@@ -547,9 +547,9 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, + rss_conf->rss_hf = rss_cfg->conf.types; + + /* Get the RSS Key required by the user */ +- if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { +- memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); +- rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; ++ if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) { ++ memcpy(rss_conf->rss_key, rss_cfg->key, hw->rss_key_size); ++ rss_conf->rss_key_len = hw->rss_key_size; + } + rte_spinlock_unlock(&hw->lock); + +@@ -754,8 +754,8 @@ hns3_rss_set_default_args(struct hns3_hw *hw) + /* Default hash algorithm */ + rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; + +- /* Default RSS key */ +- memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); ++ memcpy(rss_cfg->key, hns3_hash_key, ++ RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); + + /* Initialize RSS indirection table */ + for (i = 0; i < hw->rss_ind_tbl_size; i++) +@@ -788,9 +788,8 @@ hns3_config_rss(struct hns3_adapter *hns) + break; + } + +- /* Configure RSS hash algorithm and hash key */ +- ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, hash_key, +- HNS3_RSS_KEY_SIZE); ++ ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo, ++ hash_key, hw->rss_key_size); + if (ret) + return ret; + +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index b7f62ca1ee..d6f81996f4 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -29,6 +29,7 @@ + #define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */ + #define HNS3_RSS_IND_TBL_SIZE_MAX 2048 + #define HNS3_RSS_KEY_SIZE 40 ++#define HNS3_RSS_KEY_SIZE_MAX 128 + #define HNS3_RSS_SET_BITMAP_MSK 0xffff + + #define HNS3_RSS_HASH_ALGO_TOEPLITZ 0 +@@ -41,7 +42,7 @@ struct hns3_rss_conf { + /* RSS parameters :algorithm, flow_types, key, queue */ + struct rte_flow_action_rss conf; + uint8_t hash_algo; /* hash function type defined by hardware */ +- uint8_t key[HNS3_RSS_KEY_SIZE]; /* Hash key */ ++ uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ + uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; + uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ + bool valid; /* check if RSS rule is valid */ +-- +2.23.0 + diff --git a/0225-net-hns3-fix-clearing-RSS-configuration.patch b/0225-net-hns3-fix-clearing-RSS-configuration.patch new file mode 100644 index 0000000..2a850e2 --- /dev/null +++ b/0225-net-hns3-fix-clearing-RSS-configuration.patch @@ -0,0 +1,42 @@ +From b81a2f05658192464916c0d4f5cc1349d9d3aca4 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:55 +0800 +Subject: net/hns3: fix clearing RSS configuration + +[ upstream commit 1aa5222454725001939ff571e685225f6cf85653 ] + +When a RSS rule has an unsupported action, the RSS configuration is +cleared by mistake. + +Remove clearing RSS configuration in this case. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index a18ec7650d..c338eab049 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1421,12 +1421,10 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + + /* Check if the next not void action is END */ + NEXT_ITEM_OF_ACTION(act, actions, act_index); +- if (act->type != RTE_FLOW_ACTION_TYPE_END) { +- memset(rss_conf, 0, sizeof(struct hns3_rss_conf)); ++ if (act->type != RTE_FLOW_ACTION_TYPE_END) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, "Not supported action."); +- } + + return 0; + } +-- +2.23.0 + diff --git a/0226-net-hns3-use-RSS-filter-list-to-check-duplicated-rul.patch b/0226-net-hns3-use-RSS-filter-list-to-check-duplicated-rul.patch new file mode 100644 index 0000000..4f30996 --- /dev/null +++ b/0226-net-hns3-use-RSS-filter-list-to-check-duplicated-rul.patch @@ -0,0 +1,89 @@ +From dd5efbef75ed9511f497e2da05131e902dc4f277 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:56 +0800 +Subject: net/hns3: use RSS filter list to check duplicated rule + +[ upstream commit 6afde23d843ecf67453eaf69924bd79873f6f207 ] + +All rules from user are saved in RSS filter list, so use RSS +filter list to check duplicated rule. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 35 +++++++++++++++++++++-------------- + 1 file changed, 21 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index c338eab049..303275ae93 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1300,7 +1300,7 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, + !memcmp(comp->key, with->key, with->key_len); + + return (func_is_same && rss_key_is_same && +- comp->types == (with->types & HNS3_ETH_RSS_SUPPORT) && ++ comp->types == with->types && + comp->level == with->level && + comp->queue_num == with->queue_num && + !memcmp(comp->queue, with->queue, +@@ -1596,15 +1596,7 @@ hns3_config_rss_filter(struct hns3_hw *hw, + } + + /* Set hash algorithm and flow types by the user's config */ +- ret = hns3_hw_rss_hash_set(hw, &rss_flow_conf); +- if (ret) +- return ret; +- +- ret = hns3_rss_conf_copy(rss_info, &rss_flow_conf); +- if (ret) +- hns3_err(hw, "RSS config init fail(%d)", ret); +- +- return ret; ++ return hns3_hw_rss_hash_set(hw, &rss_flow_conf); + } + + static int +@@ -1676,17 +1668,32 @@ hns3_restore_filter(struct hns3_adapter *hns) + return hns3_restore_rss_filter(hw); + } + ++static bool ++hns3_rss_action_is_dup(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *act) ++{ ++ struct hns3_rss_conf_ele *filter; ++ ++ TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { ++ if (!filter->filter_info.valid) ++ continue; ++ ++ if (hns3_action_rss_same(&filter->filter_info.conf, act)) ++ return true; ++ } ++ ++ return false; ++} ++ + static int + hns3_flow_parse_rss(struct rte_eth_dev *dev, + const struct hns3_rss_conf *conf, bool add) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- bool ret; + +- ret = hns3_action_rss_same(&hw->rss_info.conf, &conf->conf); +- if (ret) { +- hns3_err(hw, "Enter duplicate RSS configuration : %d", ret); ++ if (hns3_rss_action_is_dup(hw, &conf->conf)) { ++ hns3_err(hw, "duplicate RSS configuration"); + return -EINVAL; + } + +-- +2.23.0 + diff --git a/0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch b/0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch new file mode 100644 index 0000000..082bc02 --- /dev/null +++ b/0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch @@ -0,0 +1,91 @@ +From 1f32e5059ee95c4433d1c37034e02f8c4a722418 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:57 +0800 +Subject: net/hns3: remove useless code when destroy valid RSS rule + +[ upstream commit 546031ba551485c3e3aa57c3698975c2852cbef1 ] + +When all rules are flushed the hw::rss_info::conf::func set to +RTE_ETH_HASH_FUNCTION_MAX and hw::rss_info::conf::queue set to NULL +which indicates no flow rules is issued. +See: commit eb158fc756a5 ("net/hns3: fix config when creating RSS rule +after flush"). + +Actually, the way determining whether there are rules has been changed +by walking the flow RSS list. +See: commit 705a50800334 ("net/hns3: fix RSS filter restore"). + +In addition, the rte_flow_action_rss from user isn't saved to 'conf' in +hw->rss_info now. So this code can be removed. + +Fixes: eb158fc756a5 ("net/hns3: fix config when creating RSS rule after flush") +Fixes: 705a50800334 ("net/hns3: fix RSS filter restore") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 26 ++------------------------ + 1 file changed, 2 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 303275ae93..7adde16cbc 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1279,19 +1279,8 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, + bool rss_key_is_same; + bool func_is_same; + +- /* +- * When user flush all RSS rule, RSS func is set invalid with +- * RTE_ETH_HASH_FUNCTION_MAX. Then the user create a flow after +- * flushed, any validate RSS func is different with it before +- * flushed. Others, when user create an action RSS with RSS func +- * specified RTE_ETH_HASH_FUNCTION_DEFAULT, the func is the same +- * between continuous RSS flow. +- */ +- if (comp->func == RTE_ETH_HASH_FUNCTION_MAX) +- func_is_same = false; +- else +- func_is_same = (with->func != RTE_ETH_HASH_FUNCTION_DEFAULT) ? +- (comp->func == with->func) : true; ++ func_is_same = (with->func != RTE_ETH_HASH_FUNCTION_DEFAULT) ? ++ (comp->func == with->func) : true; + + if (with->key_len == 0 || with->key == NULL) + rss_key_is_same = 1; +@@ -1533,7 +1522,6 @@ static int + hns3_config_rss_filter(struct hns3_hw *hw, + const struct hns3_rss_conf *conf, bool add) + { +- struct hns3_rss_conf *rss_info; + uint64_t flow_types; + uint16_t num; + int ret; +@@ -1560,7 +1548,6 @@ hns3_config_rss_filter(struct hns3_hw *hw, + /* Update the useful flow types */ + rss_flow_conf.types = flow_types; + +- rss_info = &hw->rss_info; + if (!add) { + if (!conf->valid) + return 0; +@@ -1571,15 +1558,6 @@ hns3_config_rss_filter(struct hns3_hw *hw, + return ret; + } + +- if (rss_flow_conf.queue_num) { +- /* +- * Due the content of queue pointer have been reset to +- * 0, the rss_info->conf.queue should be set to NULL +- */ +- rss_info->conf.queue = NULL; +- rss_info->conf.queue_num = 0; +- } +- + return 0; + } + +-- +2.23.0 + diff --git a/0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch b/0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch new file mode 100644 index 0000000..5a7fecf --- /dev/null +++ b/0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch @@ -0,0 +1,66 @@ +From 21b43c2f2d66de594ed174a0ba18da03a6fe5296 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:58 +0800 +Subject: net/hns3: fix warning on flush or destroy rule + +[ upstream commit a7bf2789168c8d49ca4dec5bb7bb0b3f765fc1bd ] + +Although flow rules will no longer be used when user flush all rules +or destroy a rule a warning is generated like: +"modified RSS types based on hardware support, requested:0x137f83fffc +configured:0x3ffc". + +Prevent warning for flush or destroy rule case. + +Fixes: ec674cb742e5 ("net/hns3: fix flushing RSS rule") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 7adde16cbc..fbc38dd3d4 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1537,17 +1537,6 @@ hns3_config_rss_filter(struct hns3_hw *hw, + .queue = conf->conf.queue, + }; + +- /* Filter the unsupported flow types */ +- flow_types = conf->conf.types ? +- rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT : +- hw->rss_info.conf.types; +- if (flow_types != rss_flow_conf.types) +- hns3_warn(hw, "modified RSS types based on hardware support, " +- "requested:0x%" PRIx64 " configured:0x%" PRIx64, +- rss_flow_conf.types, flow_types); +- /* Update the useful flow types */ +- rss_flow_conf.types = flow_types; +- + if (!add) { + if (!conf->valid) + return 0; +@@ -1573,6 +1562,17 @@ hns3_config_rss_filter(struct hns3_hw *hw, + return ret; + } + ++ /* Filter the unsupported flow types */ ++ flow_types = conf->conf.types ? ++ rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT : ++ hw->rss_info.conf.types; ++ if (flow_types != rss_flow_conf.types) ++ hns3_warn(hw, "modified RSS types based on hardware support," ++ " requested:0x%" PRIx64 " configured:0x%" PRIx64, ++ rss_flow_conf.types, flow_types); ++ /* Update the useful flow types */ ++ rss_flow_conf.types = flow_types; ++ + /* Set hash algorithm and flow types by the user's config */ + return hns3_hw_rss_hash_set(hw, &rss_flow_conf); + } +-- +2.23.0 + diff --git a/0229-net-hns3-fix-config-struct-used-for-conversion.patch b/0229-net-hns3-fix-config-struct-used-for-conversion.patch new file mode 100644 index 0000000..9706fe1 --- /dev/null +++ b/0229-net-hns3-fix-config-struct-used-for-conversion.patch @@ -0,0 +1,133 @@ +From e59403adf4cc2485d10fba148bf935b037170fb7 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:02:59 +0800 +Subject: net/hns3: fix config struct used for conversion + +[ upstream commit 815c7db53167f7ee1573dca18fa7f889e44764d4 ] + +When the type in 'struct rte_flow_action' is RTE_FLOW_ACTION_TYPE_RSS, +the 'conf' pointer references the 'struct rte_flow_action_rss' instead +of the 'struct hns3_rss_conf' in driver. But driver uses 'struct +hns3_rss_conf' to convert this 'conf' pointer to get RSS action +configuration. + +In addition, RSS filter configuration is directly cloned to RSS filter +node instead of coping it after successfully setting to hardware. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 59 ++++++++++++++---------------------- + 1 file changed, 22 insertions(+), 37 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index fbc38dd3d4..a30b19cfdb 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -95,8 +95,8 @@ static const struct rte_flow_action * + hns3_find_rss_general_action(const struct rte_flow_item pattern[], + const struct rte_flow_action actions[]) + { ++ const struct rte_flow_action_rss *rss_act; + const struct rte_flow_action *act = NULL; +- const struct hns3_rss_conf *rss; + bool have_eth = false; + + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { +@@ -115,8 +115,8 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[], + } + } + +- rss = act->conf; +- if (have_eth && rss->conf.queue_num) { ++ rss_act = act->conf; ++ if (have_eth && rss_act->queue_num) { + /* + * Pattern have ETH and action's queue_num > 0, indicate this is + * queue region configuration. +@@ -1296,30 +1296,6 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, + sizeof(*with->queue) * with->queue_num)); + } + +-static int +-hns3_rss_conf_copy(struct hns3_rss_conf *out, +- const struct rte_flow_action_rss *in) +-{ +- if (in->key_len > RTE_DIM(out->key) || +- in->queue_num > RTE_DIM(out->queue)) +- return -EINVAL; +- if (in->key == NULL && in->key_len) +- return -EINVAL; +- out->conf = (struct rte_flow_action_rss) { +- .func = in->func, +- .level = in->level, +- .types = in->types, +- .key_len = in->key_len, +- .queue_num = in->queue_num, +- }; +- out->conf.queue = memcpy(out->queue, in->queue, +- sizeof(*in->queue) * in->queue_num); +- if (in->key) +- out->conf.key = memcpy(out->key, in->key, in->key_len); +- +- return 0; +-} +- + static bool + hns3_rss_input_tuple_supported(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss) +@@ -1733,9 +1709,10 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + struct rte_flow *flow) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ const struct rte_flow_action_rss *rss_act; + struct hns3_rss_conf_ele *rss_filter_ptr; + struct hns3_rss_conf_ele *filter_ptr; +- const struct hns3_rss_conf *rss_conf; ++ struct hns3_rss_conf *new_conf; + int ret; + + rss_filter_ptr = rte_zmalloc("hns3 rss filter", +@@ -1745,19 +1722,27 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + return -ENOMEM; + } + +- /* +- * After all the preceding tasks are successfully configured, configure +- * rules to the hardware to simplify the rollback of rules in the +- * hardware. +- */ +- rss_conf = (const struct hns3_rss_conf *)act->conf; +- ret = hns3_flow_parse_rss(dev, rss_conf, true); ++ rss_act = (const struct rte_flow_action_rss *)act->conf; ++ new_conf = &rss_filter_ptr->filter_info; ++ memcpy(&new_conf->conf, rss_act, sizeof(*rss_act)); ++ if (rss_act->queue_num > 0) { ++ memcpy(new_conf->queue, rss_act->queue, ++ rss_act->queue_num * sizeof(new_conf->queue[0])); ++ new_conf->conf.queue = new_conf->queue; ++ } ++ if (rss_act->key_len > 0) { ++ if (rss_act->key != NULL) { ++ memcpy(new_conf->key, rss_act->key, ++ rss_act->key_len * sizeof(new_conf->key[0])); ++ new_conf->conf.key = new_conf->key; ++ } ++ } ++ ++ ret = hns3_flow_parse_rss(dev, new_conf, true); + if (ret != 0) { + rte_free(rss_filter_ptr); + return ret; + } +- +- hns3_rss_conf_copy(&rss_filter_ptr->filter_info, &rss_conf->conf); + rss_filter_ptr->filter_info.valid = true; + + /* +-- +2.23.0 + diff --git a/0230-net-hns3-fix-duplicate-RSS-rule-check.patch b/0230-net-hns3-fix-duplicate-RSS-rule-check.patch new file mode 100644 index 0000000..02518e8 --- /dev/null +++ b/0230-net-hns3-fix-duplicate-RSS-rule-check.patch @@ -0,0 +1,108 @@ +From 4aa7369a34a576a630beb0680b55b7c3c8b982f5 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 31 Jan 2023 21:03:00 +0800 +Subject: net/hns3: fix duplicate RSS rule check + +[ upstream commit 150fd8f839e332d68aa7b60646c2033084544cb7 ] + +Currently, the interface for verifying duplicate RSS rules has +some problems: +1) If the value of 'func' in configuring RSS rule is default + value, this rule is mistakenly considered as a duplicate rule. +2) If key length is zero or 'key' is NULL in configuring RSS rule + this rule is also mistakenly considered as a duplicate rule. +3) If 'key' or 'queue' in struct rte_flow_action_rss being NULL + is used to memcpy, which may cause segment fault. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 63 +++++++++++++++++++++++++++--------- + 1 file changed, 47 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index a30b19cfdb..e80ec0f053 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1272,28 +1272,59 @@ hns3_filterlist_flush(struct rte_eth_dev *dev) + } + } + ++static bool ++hns3_flow_rule_key_same(const struct rte_flow_action_rss *comp, ++ const struct rte_flow_action_rss *with) ++{ ++ if (comp->key_len != with->key_len) ++ return false; ++ ++ if (with->key_len == 0) ++ return true; ++ ++ if (comp->key == NULL && with->key == NULL) ++ return true; ++ ++ if (!(comp->key != NULL && with->key != NULL)) ++ return false; ++ ++ return !memcmp(comp->key, with->key, with->key_len); ++} ++ ++static bool ++hns3_flow_rule_queues_same(const struct rte_flow_action_rss *comp, ++ const struct rte_flow_action_rss *with) ++{ ++ if (comp->queue_num != with->queue_num) ++ return false; ++ ++ if (with->queue_num == 0) ++ return true; ++ ++ if (comp->queue == NULL && with->queue == NULL) ++ return true; ++ ++ if (!(comp->queue != NULL && with->queue != NULL)) ++ return false; ++ ++ return !memcmp(comp->queue, with->queue, with->queue_num); ++} ++ + static bool + hns3_action_rss_same(const struct rte_flow_action_rss *comp, + const struct rte_flow_action_rss *with) + { +- bool rss_key_is_same; +- bool func_is_same; ++ bool same_level; ++ bool same_types; ++ bool same_func; + +- func_is_same = (with->func != RTE_ETH_HASH_FUNCTION_DEFAULT) ? +- (comp->func == with->func) : true; ++ same_level = (comp->level == with->level); ++ same_types = (comp->types == with->types); ++ same_func = (comp->func == with->func); + +- if (with->key_len == 0 || with->key == NULL) +- rss_key_is_same = 1; +- else +- rss_key_is_same = comp->key_len == with->key_len && +- !memcmp(comp->key, with->key, with->key_len); +- +- return (func_is_same && rss_key_is_same && +- comp->types == with->types && +- comp->level == with->level && +- comp->queue_num == with->queue_num && +- !memcmp(comp->queue, with->queue, +- sizeof(*with->queue) * with->queue_num)); ++ return same_level && same_types && same_func && ++ hns3_flow_rule_key_same(comp, with) && ++ hns3_flow_rule_queues_same(comp, with); + } + + static bool +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index 1c673eb..f8b0ffa 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 31 +Release: 32 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -238,6 +238,16 @@ Patch9217: 0217-kni-use-dedicated-function-to-set-MAC-address.patch Patch9218: 0218-linux-igb_uio-fix-build-for-switch-fall-through.patch Patch9219: 0219-linux-igb_uio-fix-build-with-kernel-5.18.patch Patch9220: 0220-net-hns3-fix-inaccurate-RTC-time-to-read.patch +Patch9221: 0221-net-hns3-fix-log-about-indirection-table-size.patch +Patch9222: 0222-net-hns3-extract-common-function-to-query-device.patch +Patch9223: 0223-net-hns3-refactor-set-RSS-hash-algorithm-and-key-int.patch +Patch9224: 0224-net-hns3-fix-RSS-key-size-compatibility.patch +Patch9225: 0225-net-hns3-fix-clearing-RSS-configuration.patch +Patch9226: 0226-net-hns3-use-RSS-filter-list-to-check-duplicated-rul.patch +Patch9227: 0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch +Patch9228: 0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch +Patch9229: 0229-net-hns3-fix-config-struct-used-for-conversion.patch +Patch9230: 0230-net-hns3-fix-duplicate-RSS-rule-check.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -380,6 +390,19 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Wed Feb 15 2023 chenjiji - 21.11-32 + Sync some RSS bugfix for hns3 PMD. And patchs are as follows: + - net/hns3: fix log about indirection table size + - net/hns3: extract common function to query device + - net/hns3: refactor set RSS hash algorithm and key interface + - net/hns3: fix RSS key size compatibility + - net/hns3: fix clearing RSS configuration + - net/hns3: use RSS filter list to check duplicated rule + - net/hns3: remove useless code when destroy valid RSS rule + - net/hns3: fix warning on flush or destroy rule + - net/hns3: fix config struct used for conversion + - net/hns3: fix duplicate RSS rule check + * Mon Feb 06 2023 jiangheng - 21.11-31 - linux/igb_uio: fix build with kernel 5.18+ -- Gitee From e04e5db223545fe84fe587c41fe1513565ebc660 Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Tue, 21 Feb 2023 17:37:58 +0800 Subject: [PATCH 02/10] refactor Rx/Tx function of hns3 PMD And patchs are as follows: - net/hns3: fix burst mode query with dummy function - net/hns3: add debug info for Rx/Tx dummy function - net/hns3: remove debug condition for Tx prepare - net/hns3: separate Tx prepare from getting Tx function - net/hns3: make getting Tx function static - net/hns3: extract common functions to set Rx/Tx (cherry picked from commit 571fd9635317255990d8d0a9e2ef97c7ab8524fd) --- ...burst-mode-query-with-dummy-function.patch | 82 ++++++++ ...-debug-info-for-Rx-Tx-dummy-function.patch | 41 ++++ ...emove-debug-condition-for-Tx-prepare.patch | 46 ++++ ...e-Tx-prepare-from-getting-Tx-functio.patch | 130 ++++++++++++ ...hns3-make-getting-Tx-function-static.patch | 49 +++++ ...xtract-common-functions-to-set-Rx-Tx.patch | 196 ++++++++++++++++++ dpdk.spec | 18 +- 7 files changed, 561 insertions(+), 1 deletion(-) create mode 100644 0231-net-hns3-fix-burst-mode-query-with-dummy-function.patch create mode 100644 0232-net-hns3-add-debug-info-for-Rx-Tx-dummy-function.patch create mode 100644 0233-net-hns3-remove-debug-condition-for-Tx-prepare.patch create mode 100644 0234-net-hns3-separate-Tx-prepare-from-getting-Tx-functio.patch create mode 100644 0235-net-hns3-make-getting-Tx-function-static.patch create mode 100644 0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch diff --git a/0231-net-hns3-fix-burst-mode-query-with-dummy-function.patch b/0231-net-hns3-fix-burst-mode-query-with-dummy-function.patch new file mode 100644 index 0000000..e49dbef --- /dev/null +++ b/0231-net-hns3-fix-burst-mode-query-with-dummy-function.patch @@ -0,0 +1,82 @@ +From 6a7c7c31b57bb4dadaf3750a3fc36e3ec0761f3f Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:25 +0800 +Subject: net/hns3: fix burst mode query with dummy function + +[ upstream commit 10f91af5a5b370df922f888826a4387abebe1cde ] + +The rte_eth_rx/tx_burst_mode_get API will fail when Rx/Tx +function is dummy. + +Fixes: 7ef933908f04 ("net/hns3: add simple Tx path") +Fixes: 521ab3e93361 ("net/hns3: add simple Rx path") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rxtx.c | 38 ++++++++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 9a597e032e..c69fb38402 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2786,6 +2786,7 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + { hns3_recv_scattered_pkts, "Scalar Scattered" }, + { hns3_recv_pkts_vec, "Vector Neon" }, + { hns3_recv_pkts_vec_sve, "Vector Sve" }, ++ { rte_eth_pkt_burst_dummy, "Dummy" }, + }; + + eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; +@@ -4272,24 +4273,31 @@ int + hns3_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + struct rte_eth_burst_mode *mode) + { ++ static const struct { ++ eth_tx_burst_t pkt_burst; ++ const char *info; ++ } burst_infos[] = { ++ { hns3_xmit_pkts_simple, "Scalar Simple" }, ++ { hns3_xmit_pkts, "Scalar" }, ++ { hns3_xmit_pkts_vec, "Vector Neon" }, ++ { hns3_xmit_pkts_vec_sve, "Vector Sve" }, ++ { rte_eth_pkt_burst_dummy, "Dummy" }, ++ }; ++ + eth_tx_burst_t pkt_burst = dev->tx_pkt_burst; +- const char *info = NULL; +- +- if (pkt_burst == hns3_xmit_pkts_simple) +- info = "Scalar Simple"; +- else if (pkt_burst == hns3_xmit_pkts) +- info = "Scalar"; +- else if (pkt_burst == hns3_xmit_pkts_vec) +- info = "Vector Neon"; +- else if (pkt_burst == hns3_xmit_pkts_vec_sve) +- info = "Vector Sve"; +- +- if (info == NULL) +- return -EINVAL; ++ int ret = -EINVAL; ++ unsigned int i; + +- snprintf(mode->info, sizeof(mode->info), "%s", info); ++ for (i = 0; i < RTE_DIM(burst_infos); i++) { ++ if (pkt_burst == burst_infos[i].pkt_burst) { ++ snprintf(mode->info, sizeof(mode->info), "%s", ++ burst_infos[i].info); ++ ret = 0; ++ break; ++ } ++ } + +- return 0; ++ return ret; + } + + static bool +-- +2.23.0 + diff --git a/0232-net-hns3-add-debug-info-for-Rx-Tx-dummy-function.patch b/0232-net-hns3-add-debug-info-for-Rx-Tx-dummy-function.patch new file mode 100644 index 0000000..a3fb1ee --- /dev/null +++ b/0232-net-hns3-add-debug-info-for-Rx-Tx-dummy-function.patch @@ -0,0 +1,41 @@ +From cd3db5d9c5aea3efa6b0bbaefecb7fb8367a7719 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:26 +0800 +Subject: net/hns3: add debug info for Rx/Tx dummy function + +[ upstream commit a8f52a5cf13715c61dfe224815c7f4e4858be82f ] + +Now dummy function can be report by rte_eth_rx/tx_burst_mode_get. +So this patch adds debug info for Rx/Tx dummy function. + +Fixes: 7feb2aee0e2c ("net/hns3: log selected datapath") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rxtx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index c69fb38402..52393b1f6f 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4420,13 +4420,13 @@ hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + hns3_get_tx_function(eth_dev, &prep); + eth_dev->tx_pkt_prepare = prep; + eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status; +- hns3_trace_rxtx_function(eth_dev); + } else { + eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; + eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; + eth_dev->tx_pkt_prepare = NULL; + } + ++ hns3_trace_rxtx_function(eth_dev); + hns3_eth_dev_fp_ops_config(eth_dev); + } + +-- +2.23.0 + diff --git a/0233-net-hns3-remove-debug-condition-for-Tx-prepare.patch b/0233-net-hns3-remove-debug-condition-for-Tx-prepare.patch new file mode 100644 index 0000000..8c3973e --- /dev/null +++ b/0233-net-hns3-remove-debug-condition-for-Tx-prepare.patch @@ -0,0 +1,46 @@ +From 25a54df88c36a76f4914287ba393d2251f4492ec Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:27 +0800 +Subject: net/hns3: remove debug condition for Tx prepare + +[ upstream commit a8d240786e1af129fdf789391d574bf4a7fe60e6 ] + +The Tx prepare in driver is always needed if RTE_LIBRTE_ETHDEV_DEBUG +is defined. But it doesn't matter with this macro. Let's remove it. + +Fixes: d7ec2c076579 ("net/hns3: select Tx prepare based on Tx offload") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rxtx.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 52393b1f6f..9fc54d50f1 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4311,11 +4311,6 @@ hns3_tx_check_simple_support(struct rte_eth_dev *dev) + static bool + hns3_get_tx_prep_needed(struct rte_eth_dev *dev) + { +-#ifdef RTE_LIBRTE_ETHDEV_DEBUG +- RTE_SET_USED(dev); +- /* always perform tx_prepare when debug */ +- return true; +-#else + #define HNS3_DEV_TX_CSKUM_TSO_OFFLOAD_MASK (\ + RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \ + RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \ +@@ -4333,7 +4328,6 @@ hns3_get_tx_prep_needed(struct rte_eth_dev *dev) + return true; + + return false; +-#endif + } + + eth_tx_burst_t +-- +2.23.0 + diff --git a/0234-net-hns3-separate-Tx-prepare-from-getting-Tx-functio.patch b/0234-net-hns3-separate-Tx-prepare-from-getting-Tx-functio.patch new file mode 100644 index 0000000..0aaa9a7 --- /dev/null +++ b/0234-net-hns3-separate-Tx-prepare-from-getting-Tx-functio.patch @@ -0,0 +1,130 @@ +From 9e0cd6d469351131e473edc8a9dbbcd70890519f Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:28 +0800 +Subject: net/hns3: separate Tx prepare from getting Tx function + +[ upstream commit 6a934ba4c6c48691b119a878981a4e3748766518 ] + +Separate getting tx prepare from hns3_get_tx_function by extracting +an independent function. + +Fixes: d7ec2c076579 ("net/hns3: select Tx prepare based on Tx offload") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rxtx.c | 32 ++++++++++++++------------------ + drivers/net/hns3/hns3_rxtx.h | 3 +-- + 2 files changed, 15 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 9fc54d50f1..2dba4d8120 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4324,26 +4324,30 @@ hns3_get_tx_prep_needed(struct rte_eth_dev *dev) + RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO) + + uint64_t tx_offload = dev->data->dev_conf.txmode.offloads; ++ + if (tx_offload & HNS3_DEV_TX_CSKUM_TSO_OFFLOAD_MASK) + return true; + + return false; + } + ++static eth_tx_prep_t ++hns3_get_tx_prepare(struct rte_eth_dev *dev) ++{ ++ return hns3_get_tx_prep_needed(dev) ? hns3_prep_pkts : NULL; ++} ++ + eth_tx_burst_t +-hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) ++hns3_get_tx_function(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; + bool vec_allowed, sve_allowed, simple_allowed; +- bool vec_support, tx_prepare_needed; ++ bool vec_support; + + vec_support = hns3_tx_check_vec_support(dev) == 0; + vec_allowed = vec_support && hns3_get_default_vec_support(); + sve_allowed = vec_support && hns3_get_sve_support(); + simple_allowed = hns3_tx_check_simple_support(dev); +- tx_prepare_needed = hns3_get_tx_prep_needed(dev); +- +- *prep = NULL; + + if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed) + return hns3_xmit_pkts_vec; +@@ -4351,19 +4355,14 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + 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) { +- if (tx_prepare_needed) +- *prep = hns3_prep_pkts; ++ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON) + return hns3_xmit_pkts; +- } + + if (vec_allowed) + return hns3_xmit_pkts_vec; + if (simple_allowed) + return hns3_xmit_pkts_simple; + +- if (tx_prepare_needed) +- *prep = hns3_prep_pkts; + return hns3_xmit_pkts; + } + +@@ -4403,7 +4402,6 @@ hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + struct hns3_adapter *hns = eth_dev->data->dev_private; +- eth_tx_prep_t prep = NULL; + + if (hns->hw.adapter_state == HNS3_NIC_STARTED && + __atomic_load_n(&hns->hw.reset.resetting, __ATOMIC_RELAXED) == 0) { +@@ -4411,8 +4409,8 @@ hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + eth_dev->rx_descriptor_status = hns3_dev_rx_descriptor_status; + eth_dev->tx_pkt_burst = hw->set_link_down ? + rte_eth_pkt_burst_dummy : +- hns3_get_tx_function(eth_dev, &prep); +- eth_dev->tx_pkt_prepare = prep; ++ hns3_get_tx_function(eth_dev); ++ eth_dev->tx_pkt_prepare = hns3_get_tx_prepare(eth_dev); + eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status; + } else { + eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; +@@ -4758,10 +4756,8 @@ hns3_stop_tx_datapath(struct rte_eth_dev *dev) + void + hns3_start_tx_datapath(struct rte_eth_dev *dev) + { +- eth_tx_prep_t prep = NULL; +- +- dev->tx_pkt_burst = hns3_get_tx_function(dev, &prep); +- dev->tx_pkt_prepare = prep; ++ dev->tx_pkt_burst = hns3_get_tx_function(dev); ++ dev->tx_pkt_prepare = hns3_get_tx_prepare(dev); + hns3_eth_dev_fp_ops_config(dev); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index ea1a805491..38c3581312 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -740,8 +740,7 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev, + const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev); + void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev); + void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev); +-eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev, +- eth_tx_prep_t *prep); ++eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev); + + uint32_t hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id); + void hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, +-- +2.23.0 + diff --git a/0235-net-hns3-make-getting-Tx-function-static.patch b/0235-net-hns3-make-getting-Tx-function-static.patch new file mode 100644 index 0000000..b2793aa --- /dev/null +++ b/0235-net-hns3-make-getting-Tx-function-static.patch @@ -0,0 +1,49 @@ +From 4efa4ab6f451ebc5ef8439eedda3b3982e9465ca Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:29 +0800 +Subject: net/hns3: make getting Tx function static + +[ upstream commit 2aec7beaba05cd82cd951f0c6bbaecb82d533ce0 ] + +The hns3_get_tx_function() is an intrinsic function now and should +not be open to other files. + +Fixes: 96c33cfb06cf ("net/hns3: fix Rx/Tx functions update") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rxtx.c | 2 +- + drivers/net/hns3/hns3_rxtx.h | 2 -- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 2dba4d8120..b5e7ba7325 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4337,7 +4337,7 @@ hns3_get_tx_prepare(struct rte_eth_dev *dev) + return hns3_get_tx_prep_needed(dev) ? hns3_prep_pkts : NULL; + } + +-eth_tx_burst_t ++static eth_tx_burst_t + hns3_get_tx_function(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 38c3581312..1bdc124b7b 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -740,8 +740,6 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev, + const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev); + void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev); + void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev); +-eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev); +- + uint32_t hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id); + void hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, + uint8_t gl_idx, uint16_t gl_value); +-- +2.23.0 + diff --git a/0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch b/0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch new file mode 100644 index 0000000..ecb2c65 --- /dev/null +++ b/0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch @@ -0,0 +1,196 @@ +From a83eecfe38a20bbfa51a108f62d55d6189e943d7 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 11 Feb 2023 17:18:30 +0800 +Subject: net/hns3: extract common functions to set Rx/Tx + +[ upstream commit 4ba28c957a16bbfe5b2a8d49dfda1c85387d7602 ] + +Extract two common functions to set Rx/Tx function in order to +reduce duplicate codes. + +Fixes: 23d4b61fee5d ("net/hns3: support multiple process") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_ethdev.c | 20 ++++---------------- + drivers/net/hns3/hns3_ethdev_vf.c | 19 ++++--------------- + drivers/net/hns3/hns3_mp.c | 4 ++-- + drivers/net/hns3/hns3_rxtx.c | 28 ++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 2 ++ + 5 files changed, 40 insertions(+), 33 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 8fa12d91bb..1c67ff2c99 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5052,8 +5052,7 @@ hns3_dev_start(struct rte_eth_dev *dev) + rte_spinlock_unlock(&hw->lock); + + hns3_rx_scattered_calc(dev); +- hns3_set_rxtx_function(dev); +- hns3_mp_req_start_rxtx(dev); ++ hns3_start_rxtx_datapath(dev); + + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); +@@ -5131,12 +5130,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) + dev->data->dev_started = 0; + + hw->adapter_state = HNS3_NIC_STOPPING; +- hns3_set_rxtx_function(dev); +- rte_wmb(); +- /* Disable datapath on secondary process. */ +- hns3_mp_req_stop_rxtx(dev); +- /* Prevent crashes when queues are still in use. */ +- rte_delay_ms(hw->cfg_max_queues); ++ hns3_stop_rxtx_datapath(dev); + + rte_spinlock_lock(&hw->lock); + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { +@@ -5752,12 +5746,7 @@ hns3_stop_service(struct hns3_adapter *hns) + rte_eal_alarm_cancel(hns3_service_handler, eth_dev); + hns3_update_linkstatus_and_event(hw, false); + } +- +- hns3_set_rxtx_function(eth_dev); +- rte_wmb(); +- /* Disable datapath on secondary process. */ +- hns3_mp_req_stop_rxtx(eth_dev); +- rte_delay_ms(hw->cfg_max_queues); ++ hns3_stop_rxtx_datapath(eth_dev); + + rte_spinlock_lock(&hw->lock); + if (hns->hw.adapter_state == HNS3_NIC_STARTED || +@@ -5790,8 +5779,7 @@ hns3_start_service(struct hns3_adapter *hns) + hw->reset.level == HNS3_GLOBAL_RESET) + hns3_set_rst_done(hw); + eth_dev = &rte_eth_devices[hw->data->port_id]; +- hns3_set_rxtx_function(eth_dev); +- hns3_mp_req_start_rxtx(eth_dev); ++ hns3_start_rxtx_datapath(eth_dev); + if (hw->adapter_state == HNS3_NIC_STARTED) { + /* + * This API parent function already hold the hns3_hw.lock, the +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index a3a1b71a63..3a93987409 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1572,12 +1572,7 @@ hns3vf_dev_stop(struct rte_eth_dev *dev) + dev->data->dev_started = 0; + + hw->adapter_state = HNS3_NIC_STOPPING; +- hns3_set_rxtx_function(dev); +- rte_wmb(); +- /* Disable datapath on secondary process. */ +- hns3_mp_req_stop_rxtx(dev); +- /* Prevent crashes when queues are still in use. */ +- rte_delay_ms(hw->cfg_max_queues); ++ hns3_stop_rxtx_datapath(dev); + + rte_spinlock_lock(&hw->lock); + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { +@@ -1731,8 +1726,7 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + rte_spinlock_unlock(&hw->lock); + + hns3_rx_scattered_calc(dev); +- hns3_set_rxtx_function(dev); +- hns3_mp_req_start_rxtx(dev); ++ hns3_start_rxtx_datapath(dev); + + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); +@@ -1902,11 +1896,7 @@ hns3vf_stop_service(struct hns3_adapter *hns) + } + hw->mac.link_status = RTE_ETH_LINK_DOWN; + +- hns3_set_rxtx_function(eth_dev); +- rte_wmb(); +- /* Disable datapath on secondary process. */ +- hns3_mp_req_stop_rxtx(eth_dev); +- rte_delay_ms(hw->cfg_max_queues); ++ hns3_stop_rxtx_datapath(eth_dev); + + rte_spinlock_lock(&hw->lock); + if (hw->adapter_state == HNS3_NIC_STARTED || +@@ -1938,8 +1928,7 @@ hns3vf_start_service(struct hns3_adapter *hns) + struct rte_eth_dev *eth_dev; + + eth_dev = &rte_eth_devices[hw->data->port_id]; +- hns3_set_rxtx_function(eth_dev); +- hns3_mp_req_start_rxtx(eth_dev); ++ hns3_start_rxtx_datapath(eth_dev); + + rte_eal_alarm_set(HNS3VF_KEEP_ALIVE_INTERVAL, hns3vf_keep_alive_handler, + eth_dev); +diff --git a/drivers/net/hns3/hns3_mp.c b/drivers/net/hns3/hns3_mp.c +index e74ddea195..c3005b943f 100644 +--- a/drivers/net/hns3/hns3_mp.c ++++ b/drivers/net/hns3/hns3_mp.c +@@ -87,12 +87,12 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + case HNS3_MP_REQ_START_RXTX: + PMD_INIT_LOG(INFO, "port %u starting datapath", + dev->data->port_id); +- hns3_set_rxtx_function(dev); ++ hns3_start_rxtx_datapath(dev); + break; + case HNS3_MP_REQ_STOP_RXTX: + PMD_INIT_LOG(INFO, "port %u stopping datapath", + dev->data->port_id); +- hns3_set_rxtx_function(dev); ++ hns3_stop_rxtx_datapath(dev); + break; + case HNS3_MP_REQ_START_TX: + PMD_INIT_LOG(INFO, "port %u starting Tx datapath", +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index b5e7ba7325..1f44c0345f 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4765,3 +4765,31 @@ hns3_start_tx_datapath(struct rte_eth_dev *dev) + + hns3_mp_req_start_tx(dev); + } ++ ++void ++hns3_stop_rxtx_datapath(struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ ++ hns3_set_rxtx_function(dev); ++ ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY) ++ return; ++ ++ rte_wmb(); ++ /* Disable datapath on secondary process. */ ++ hns3_mp_req_stop_rxtx(dev); ++ /* Prevent crashes when queues are still in use. */ ++ rte_delay_ms(hw->cfg_max_queues); ++} ++ ++void ++hns3_start_rxtx_datapath(struct rte_eth_dev *dev) ++{ ++ hns3_set_rxtx_function(dev); ++ ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY) ++ return; ++ ++ hns3_mp_req_start_rxtx(dev); ++} +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 1bdc124b7b..fa39f6481a 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -773,5 +773,7 @@ int hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset); + void hns3_tx_push_init(struct rte_eth_dev *dev); + void hns3_stop_tx_datapath(struct rte_eth_dev *dev); + void hns3_start_tx_datapath(struct rte_eth_dev *dev); ++void hns3_stop_rxtx_datapath(struct rte_eth_dev *dev); ++void hns3_start_rxtx_datapath(struct rte_eth_dev *dev); + + #endif /* HNS3_RXTX_H */ +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index f8b0ffa..b32ab2a 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 32 +Release: 33 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -248,6 +248,12 @@ Patch9227: 0227-net-hns3-remove-useless-code-when-destroy-valid-RSS-.patch Patch9228: 0228-net-hns3-fix-warning-on-flush-or-destroy-rule.patch Patch9229: 0229-net-hns3-fix-config-struct-used-for-conversion.patch Patch9230: 0230-net-hns3-fix-duplicate-RSS-rule-check.patch +Patch9231: 0231-net-hns3-fix-burst-mode-query-with-dummy-function.patch +Patch9232: 0232-net-hns3-add-debug-info-for-Rx-Tx-dummy-function.patch +Patch9233: 0233-net-hns3-remove-debug-condition-for-Tx-prepare.patch +Patch9234: 0234-net-hns3-separate-Tx-prepare-from-getting-Tx-functio.patch +Patch9235: 0235-net-hns3-make-getting-Tx-function-static.patch +Patch9236: 0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -390,6 +396,16 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Tue Feb 21 2023 chenjiji - 21.11-33 + refactor Rc/Tx function of hns3 PMD + And patchs are as follows: + - net/hns3: fix burst mode query with dummy function + - net/hns3: add debug info for Rx/Tx dummy function + - net/hns3: remove debug condition for Tx prepare + - net/hns3: separate Tx prepare from getting Tx function + - net/hns3: make getting Tx function static + - net/hns3: extract common functions to set Rx/Tx + * Wed Feb 15 2023 chenjiji - 21.11-32 Sync some RSS bugfix for hns3 PMD. And patchs are as follows: - net/hns3: fix log about indirection table size -- Gitee From afdfdf1ce084d8bbe2d6415afd07a3442949fac3 Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Thu, 2 Mar 2023 20:05:03 +0800 Subject: [PATCH 03/10] Support flow rule keeping capability for hns3 PMD and testpmd. Patchs are as follow: - net/hns3: declare flow rule keeping capability - app/testpmd: add --disable-flow-flush option (cherry picked from commit f8c9d4f3cb51c95bef01fa1737110eabd99c7c60) --- ...declare-flow-rule-keeping-capability.patch | 45 ++++++++ ...estpmd-add-disable-flow-flush-option.patch | 106 ++++++++++++++++++ dpdk.spec | 10 +- 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 0237-net-hns3-declare-flow-rule-keeping-capability.patch create mode 100644 0238-app-testpmd-add-disable-flow-flush-option.patch diff --git a/0237-net-hns3-declare-flow-rule-keeping-capability.patch b/0237-net-hns3-declare-flow-rule-keeping-capability.patch new file mode 100644 index 0000000..7e0426e --- /dev/null +++ b/0237-net-hns3-declare-flow-rule-keeping-capability.patch @@ -0,0 +1,45 @@ +From 1ee0d9b0270d2a6954c6276aa08f437232707f18 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Dec 2022 01:41:41 +0000 +Subject: net/hns3: declare flow rule keeping capability + +[ upstream commit 27fd46521517cae0f456dad850a04f18de0690f8 ] + +The driver supports create flow rules when device is stopped, and +re-setup flow rules when restarting, so declare support +RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP. + +The driver also supports to create indirect actions when device is +stopped, and keeps the indirect actions when restarting, so declare +support RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP. + +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Acked-by: Dongdong Liu +--- + drivers/net/hns3/hns3_common.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 9bfbe1161f..3c5e07f1bd 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -91,10 +91,11 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + if (hns3_dev_get_support(hw, OUTER_UDP_CKSUM)) + info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM; + ++ info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP | ++ RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP; + if (hns3_dev_get_support(hw, INDEP_TXRX)) +- info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | +- RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; +- info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; ++ info->dev_capa |= RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | ++ RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + + if (hns3_dev_get_support(hw, PTP)) + info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP; +-- +2.23.0 + diff --git a/0238-app-testpmd-add-disable-flow-flush-option.patch b/0238-app-testpmd-add-disable-flow-flush-option.patch new file mode 100644 index 0000000..ee3c2ab --- /dev/null +++ b/0238-app-testpmd-add-disable-flow-flush-option.patch @@ -0,0 +1,106 @@ +From c4daf6ffbb78fb4cb2ec3b6d632364d5e077cf10 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Dec 2022 01:41:42 +0000 +Subject: app/testpmd: add --disable-flow-flush option + +[ upstream commit 543df472bced6a9bf0e45c290c3af852486b474a ] + +This patch adds "--disable-flow-flush" parameter, which could used to +disable port flow flush when stop port. It allows testing keep flow +rules or shared flow objects across restart. + +Signed-off-by: Chengwen Feng +Acked-by: Ori Kam +Acked-by: Aman Singh +--- + app/test-pmd/parameters.c | 4 ++++ + app/test-pmd/testpmd.c | 7 ++++++- + app/test-pmd/testpmd.h | 1 + + doc/guides/testpmd_app_ug/run_app.rst | 5 +++++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c +index 435687fa6d..e147be28b3 100644 +--- a/app/test-pmd/parameters.c ++++ b/app/test-pmd/parameters.c +@@ -184,6 +184,7 @@ usage(char* progname) + "disable print of designated event or all of them.\n"); + printf(" --flow-isolate-all: " + "requests flow API isolated mode on all ports at initialization time.\n"); ++ printf(" --disable-flow-flush: disable port flow flush when stop port.\n"); + printf(" --tx-offloads=0xXXXXXXXX: hexadecimal bitmask of TX queue offloads\n"); + printf(" --rx-offloads=0xXXXXXXXX: hexadecimal bitmask of RX queue offloads\n"); + printf(" --hot-plug: enable hot plug for device.\n"); +@@ -674,6 +675,7 @@ launch_args_parse(int argc, char** argv) + { "rxfreet", 1, 0, 0 }, + { "no-flush-rx", 0, 0, 0 }, + { "flow-isolate-all", 0, 0, 0 }, ++ { "disable-flow-flush", 0, 0, 0 }, + { "rxoffs", 1, 0, 0 }, + { "rxpkts", 1, 0, 0 }, + { "txpkts", 1, 0, 0 }, +@@ -1381,6 +1383,8 @@ launch_args_parse(int argc, char** argv) + rmv_interrupt = 0; + if (!strcmp(lgopts[opt_idx].name, "flow-isolate-all")) + flow_isolate_all = 1; ++ if (!strcmp(lgopts[opt_idx].name, "disable-flow-flush")) ++ no_flow_flush = 1; + if (!strcmp(lgopts[opt_idx].name, "tx-offloads")) { + char *end = NULL; + n = strtoull(optarg, &end, 16); +diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c +index 32098d4701..20134c5234 100644 +--- a/app/test-pmd/testpmd.c ++++ b/app/test-pmd/testpmd.c +@@ -371,6 +371,11 @@ uint8_t no_flush_rx = 0; /* flush by default */ + */ + uint8_t flow_isolate_all; + ++/* ++ * Disable port flow flush when stop port. ++ */ ++uint8_t no_flow_flush = 0; /* do flow flush by default */ ++ + /* + * Avoids to check link status when starting/stopping a port. + */ +@@ -3173,7 +3178,7 @@ stop_port(portid_t pid) + } + } + +- if (port->flow_list) ++ if (port->flow_list && !no_flow_flush) + port_flow_flush(pi); + + if (eth_dev_stop_mp(pi) != 0) +diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h +index 480dc3fa34..be7454ab44 100644 +--- a/app/test-pmd/testpmd.h ++++ b/app/test-pmd/testpmd.h +@@ -398,6 +398,7 @@ extern uint8_t numa_support; /**< set by "--numa" parameter */ + extern uint16_t port_topology; /**< set by "--port-topology" parameter */ + extern uint8_t no_flush_rx; /** - 21.11-34 + Support flow rule keeping capability for hns3 PMD and + testpmd. Patchs are as follow: + - net/hns3: declare flow rule keeping capability + - app/testpmd: add --disable-flow-flush option + * Tue Feb 21 2023 chenjiji - 21.11-33 refactor Rc/Tx function of hns3 PMD And patchs are as follows: -- Gitee From 23b4d048985c8cd7105778fc70810f78e99d4054 Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Wed, 15 Mar 2023 15:57:49 +0800 Subject: [PATCH 04/10] Fix some RSS bugs and reimplement hash flow function for hns3. 1. fix some RSS bugs and optimize RSS codes for hns3 2. reimplement hash flow function for hns3 to satisfy the mainstream usage of rte flow hash in the community (cherry picked from commit 651fc55df087a9855b899eea5e5fda45a1316893) --- ...sible-truncation-of-hash-key-when-co.patch | 37 + ...sible-truncation-of-redirection-tabl.patch | 59 + ...e-hardware-config-to-report-hash-key.patch | 114 ++ ...hardware-config-to-report-hash-types.patch | 490 +++++ ...dware-config-to-report-redirection-t.patch | 133 ++ ...hns3-separate-setting-hash-algorithm.patch | 186 ++ 0245-net-hns3-separate-setting-hash-key.patch | 49 + ...3-separate-setting-redirection-table.patch | 98 + ...-net-hns3-separate-setting-RSS-types.patch | 131 ++ ...parate-setting-and-clearing-RSS-rule.patch | 126 ++ ...e-new-RSS-rule-to-configure-hardware.patch | 121 ++ ...ve-hash-algo-to-RSS-filter-list-node.patch | 96 + ...w-adding-queue-buffer-size-hash-rule.patch | 37 + ...parate-flow-RSS-config-from-RSS-conf.patch | 169 ++ ...-hns3-reimplement-hash-flow-function.patch | 1697 +++++++++++++++++ ...t-hns3-add-verification-of-RSS-types.patch | 199 ++ dpdk.spec | 24 +- 17 files changed, 3765 insertions(+), 1 deletion(-) create mode 100644 0239-net-hns3-fix-possible-truncation-of-hash-key-when-co.patch create mode 100644 0240-net-hns3-fix-possible-truncation-of-redirection-tabl.patch create mode 100644 0241-net-hns3-use-hardware-config-to-report-hash-key.patch create mode 100644 0242-net-hns3-use-hardware-config-to-report-hash-types.patch create mode 100644 0243-net-hns3-use-hardware-config-to-report-redirection-t.patch create mode 100644 0244-net-hns3-separate-setting-hash-algorithm.patch create mode 100644 0245-net-hns3-separate-setting-hash-key.patch create mode 100644 0246-net-hns3-separate-setting-redirection-table.patch create mode 100644 0247-net-hns3-separate-setting-RSS-types.patch create mode 100644 0248-net-hns3-separate-setting-and-clearing-RSS-rule.patch create mode 100644 0249-net-hns3-use-new-RSS-rule-to-configure-hardware.patch create mode 100644 0250-net-hns3-save-hash-algo-to-RSS-filter-list-node.patch create mode 100644 0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch create mode 100644 0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch create mode 100644 0253-net-hns3-reimplement-hash-flow-function.patch create mode 100644 0254-net-hns3-add-verification-of-RSS-types.patch diff --git a/0239-net-hns3-fix-possible-truncation-of-hash-key-when-co.patch b/0239-net-hns3-fix-possible-truncation-of-hash-key-when-co.patch new file mode 100644 index 0000000..cf636b6 --- /dev/null +++ b/0239-net-hns3-fix-possible-truncation-of-hash-key-when-co.patch @@ -0,0 +1,37 @@ +From eeeacb6170dabebbfb5fcbcb3fa240db11cdd362 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:03 +0800 +Subject: net/hns3: fix possible truncation of hash key when config + +[ upstream commit bb38316e738ad6009b3f20b3abfaf27ea8cb0202 ] + +The hash key length of hns3 driver is obtained from firmware. If the +length is a multiple of HNS3_RSS_HASH_KEY_NUM (16), the last part +of hash key will be truncated. + +Fixes: 88347111eb53 ("net/hns3: refactor set RSS hash algorithm and key interface") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index d6e0754273..2011c18b9b 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -301,7 +301,8 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK); + req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); + +- if (idx == max_bd_num - 1) ++ if (idx == max_bd_num - 1 && ++ (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) + cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; + else + cur_key_size = HNS3_RSS_HASH_KEY_NUM; +-- +2.23.0 + diff --git a/0240-net-hns3-fix-possible-truncation-of-redirection-tabl.patch b/0240-net-hns3-fix-possible-truncation-of-redirection-tabl.patch new file mode 100644 index 0000000..01b8996 --- /dev/null +++ b/0240-net-hns3-fix-possible-truncation-of-redirection-tabl.patch @@ -0,0 +1,59 @@ +From 81cda32ef08ef6b179a36fcfe5b04b0a702dfa33 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:04 +0800 +Subject: net/hns3: fix possible truncation of redirection table + +[ upstream commit 4729376e555b58a739e6e231d403ca3b029ad92c ] + +The size of the redirection table is obtained from firmware. If the size +isn't a multiple of HNS3_RSS_CFG_TBL_SIZE, the redirection table from +user will be truncated. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 2011c18b9b..ed397587b5 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -329,6 +329,7 @@ int + hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) + { + struct hns3_rss_indirection_table_cmd *req; ++ uint16_t max_bd_num, cfg_tbl_size; + struct hns3_cmd_desc desc; + uint8_t qid_msb_off; + uint8_t qid_msb_val; +@@ -337,14 +338,20 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) + int ret; + + req = (struct hns3_rss_indirection_table_cmd *)desc.data; +- +- for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { ++ max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); ++ for (i = 0; i < max_bd_num; i++) { + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, + false); + req->start_table_index = + rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); + req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); +- for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { ++ ++ if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) ++ cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; ++ else ++ cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; ++ ++ for (j = 0; j < cfg_tbl_size; j++) { + q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; + req->rss_result_l[j] = q_id & 0xff; + +-- +2.23.0 + diff --git a/0241-net-hns3-use-hardware-config-to-report-hash-key.patch b/0241-net-hns3-use-hardware-config-to-report-hash-key.patch new file mode 100644 index 0000000..0175113 --- /dev/null +++ b/0241-net-hns3-use-hardware-config-to-report-hash-key.patch @@ -0,0 +1,114 @@ +From da66262ce661cba4454a7e00971822791a5e1305 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:05 +0800 +Subject: net/hns3: use hardware config to report hash key + +[ upstream commit 7da415d27d8872a45a2d0cf9b5e66a8027c8f53c ] + +Currently, hns3_dev_rss_hash_conf_get() interface reports RSS key from +the key maintained by driver. It's better to report the key from +hardware, which is more realistic. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.c | 53 ++++++++++++++++++++++++++++++++++++- + drivers/net/hns3/hns3_rss.h | 3 ++- + 2 files changed, 54 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index ed397587b5..a8ea5150ab 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -321,6 +321,48 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + return 0; + } + ++int ++hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, ++ uint8_t *key, uint8_t key_len) ++{ ++ struct hns3_rss_generic_config_cmd *req; ++ struct hns3_cmd_desc desc; ++ uint16_t cur_key_size; ++ uint16_t max_bd_num; ++ uint8_t *cur_key; ++ uint16_t idx; ++ int ret; ++ ++ req = (struct hns3_rss_generic_config_cmd *)desc.data; ++ max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); ++ for (idx = 0; idx < max_bd_num; idx++) { ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, ++ true); ++ ++ req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ if (idx == 0) ++ *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK; ++ ++ if (idx == max_bd_num - 1 && ++ (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) ++ cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; ++ else ++ cur_key_size = HNS3_RSS_HASH_KEY_NUM; ++ ++ cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; ++ memcpy(cur_key, req->hash_key, cur_key_size); ++ } ++ ++ return 0; ++} ++ + /* + * rss_indirection_table command function, opcode:0x0D07. + * Used to configure the indirection table of rss. +@@ -550,13 +592,22 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + struct hns3_rss_conf *rss_cfg = &hw->rss_info; ++ uint8_t hash_algo; ++ int ret; + + rte_spinlock_lock(&hw->lock); + rss_conf->rss_hf = rss_cfg->conf.types; + + /* Get the RSS Key required by the user */ + if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) { +- memcpy(rss_conf->rss_key, rss_cfg->key, hw->rss_key_size); ++ ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_conf->rss_key, ++ hw->rss_key_size); ++ if (ret != 0) { ++ rte_spinlock_unlock(&hw->lock); ++ hns3_err(hw, "obtain hash algo and key failed, ret = %d", ++ ret); ++ return ret; ++ } + rss_conf->rss_key_len = hw->rss_key_size; + } + rte_spinlock_unlock(&hw->lock); +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index d6f81996f4..be0141f602 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -112,6 +112,7 @@ void hns3_rss_uninit(struct hns3_adapter *hns); + int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); + int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len); +- ++int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, ++ uint8_t *key, uint8_t key_len); + + #endif /* HNS3_RSS_H */ +-- +2.23.0 + diff --git a/0242-net-hns3-use-hardware-config-to-report-hash-types.patch b/0242-net-hns3-use-hardware-config-to-report-hash-types.patch new file mode 100644 index 0000000..ef63558 --- /dev/null +++ b/0242-net-hns3-use-hardware-config-to-report-hash-types.patch @@ -0,0 +1,490 @@ +From b36d99962a7ef0c2ae408e4edbabb95f00554d58 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:06 +0800 +Subject: net/hns3: use hardware config to report hash types + +[ upstream commit 406b25c7ffd2d84b1e09665872f69755c75e7d89 ] + +Use the configuration in hardware to report hash types instead +of data maintained in software. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.c | 260 ++++++++++++++++++++++++++++-------- + drivers/net/hns3/hns3_rss.h | 1 + + 2 files changed, 208 insertions(+), 53 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index a8ea5150ab..9addc00a67 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -70,6 +70,17 @@ enum hns3_tuple_field { + HNS3_RSS_FIELD_IPV6_FRAG_IP_S + }; + ++#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0) ++#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8) ++#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16) ++#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24) ++#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26) ++#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32) ++#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40) ++#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48) ++#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56) ++#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58) ++ + enum hns3_rss_tuple_type { + HNS3_RSS_IP_TUPLE, + HNS3_RSS_IP_L4_TUPLE, +@@ -79,200 +90,249 @@ static const struct { + uint64_t rss_types; + uint16_t tuple_type; + uint64_t rss_field; ++ uint64_t tuple_mask; + } hns3_set_tuple_table[] = { + /* IPV4-FRAG */ + { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV4_FLAG_M }, + { RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_FLAG_M }, + { RTE_ETH_RSS_FRAG_IPV4, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_FLAG_M }, + + /* IPV4 */ + { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + { RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + { RTE_ETH_RSS_IPV4, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + + /* IPV4-OTHER */ + { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_OTHER, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV4_NONF_M }, + + /* IPV4-TCP */ + { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV4_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV4_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S), ++ HNS3_RSS_TUPLE_IPV4_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), ++ HNS3_RSS_TUPLE_IPV4_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_TCP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), ++ HNS3_RSS_TUPLE_IPV4_TCP_M }, + + /* IPV4-UDP */ + { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV4_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV4_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S), ++ HNS3_RSS_TUPLE_IPV4_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), ++ HNS3_RSS_TUPLE_IPV4_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_UDP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), ++ HNS3_RSS_TUPLE_IPV4_UDP_M }, + + /* IPV4-SCTP */ + { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV4_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV4_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S), ++ HNS3_RSS_TUPLE_IPV4_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D), ++ HNS3_RSS_TUPLE_IPV4_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV4_SCTP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | +- BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER), ++ HNS3_RSS_TUPLE_IPV4_SCTP_M }, + + /* IPV6-FRAG */ + { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV6_FLAG_M }, + { RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_FLAG_M }, + { RTE_ETH_RSS_FRAG_IPV6, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_FLAG_M }, + + /* IPV6 */ + { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + { RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + { RTE_ETH_RSS_IPV6, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + + /* IPV6-OTHER */ + { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_OTHER, + HNS3_RSS_IP_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), ++ HNS3_RSS_TUPLE_IPV6_NONF_M }, + + /* IPV6-TCP */ + { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV6_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV6_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S), ++ HNS3_RSS_TUPLE_IPV6_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), ++ HNS3_RSS_TUPLE_IPV6_TCP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_TCP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), ++ HNS3_RSS_TUPLE_IPV6_TCP_M }, + + /* IPV6-UDP */ + { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV6_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV6_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S), ++ HNS3_RSS_TUPLE_IPV6_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), ++ HNS3_RSS_TUPLE_IPV6_UDP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_UDP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), ++ HNS3_RSS_TUPLE_IPV6_UDP_M }, + + /* IPV6-SCTP */ + { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S), ++ HNS3_RSS_TUPLE_IPV6_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L3_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D), ++ HNS3_RSS_TUPLE_IPV6_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_SRC_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S), ++ HNS3_RSS_TUPLE_IPV6_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_L4_DST_ONLY, + HNS3_RSS_IP_L4_TUPLE, +- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D), ++ HNS3_RSS_TUPLE_IPV6_SCTP_M }, + { RTE_ETH_RSS_NONFRAG_IPV6_SCTP, + HNS3_RSS_IP_L4_TUPLE, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) | +- BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) }, ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER), ++ HNS3_RSS_TUPLE_IPV6_SCTP_M }, + }; + + /* +@@ -576,6 +636,96 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + return ret; + } + ++int ++hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields) ++{ ++ struct hns3_rss_input_tuple_cmd *req; ++ struct hns3_cmd_desc desc; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true); ++ req = (struct hns3_rss_input_tuple_cmd *)desc.data; ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret != 0) { ++ hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ *tuple_fields = rte_le_to_cpu_64(req->tuple_field); ++ ++ return 0; ++} ++ ++static uint64_t ++hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields) ++{ ++ uint64_t ipv6_sctp_l4_mask = ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | ++ BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S); ++ uint64_t rss_hf = 0; ++ uint64_t tuple_mask; ++ uint32_t i; ++ ++ for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { ++ tuple_mask = hns3_set_tuple_table[i].tuple_mask; ++ /* ++ * The RSS hash of the packet type is disabled if its tuples is ++ * zero. ++ */ ++ if ((tuple_fields & tuple_mask) == 0) ++ continue; ++ ++ /* ++ * Some hardware don't support to use src/dst port fields to ++ * hash for IPV6-SCTP packet. ++ */ ++ if ((hns3_set_tuple_table[i].rss_types & ++ RTE_ETH_RSS_NONFRAG_IPV6_SCTP) && ++ !hw->rss_info.ipv6_sctp_offload_supported) ++ tuple_mask &= ~ipv6_sctp_l4_mask; ++ ++ /* ++ * The framework (ethdev ops) or driver (rte flow API) ensure ++ * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set ++ * to driver at the same time. But if user doesn't specify ++ * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields. ++ * In this case, driver should not report L3/L4_SRC/DST_ONLY. ++ */ ++ if ((tuple_fields & tuple_mask) == tuple_mask) { ++ /* Skip the item enabled part tuples. */ ++ if ((tuple_fields & hns3_set_tuple_table[i].rss_field) != ++ tuple_mask) ++ continue; ++ ++ rss_hf |= hns3_set_tuple_table[i].rss_types; ++ continue; ++ } ++ ++ /* Match the item enabled part tuples.*/ ++ if ((tuple_fields & hns3_set_tuple_table[i].rss_field) == ++ hns3_set_tuple_table[i].rss_field) ++ rss_hf |= hns3_set_tuple_table[i].rss_types; ++ } ++ ++ return rss_hf; ++} ++ ++static int ++hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf) ++{ ++ uint64_t tuple_fields; ++ int ret; ++ ++ ret = hns3_get_rss_tuple_field(hw, &tuple_fields); ++ if (ret != 0) ++ return ret; ++ ++ *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields); ++ ++ return 0; ++} ++ + /* + * Get rss key and rss_hf types set of RSS hash configuration. + * @param dev +@@ -591,28 +741,32 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rss_conf *rss_cfg = &hw->rss_info; + uint8_t hash_algo; + int ret; + + rte_spinlock_lock(&hw->lock); +- rss_conf->rss_hf = rss_cfg->conf.types; ++ ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf); ++ if (ret != 0) { ++ hns3_err(hw, "obtain hash tuples failed, ret = %d", ret); ++ goto out; ++ } + + /* Get the RSS Key required by the user */ + if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) { + ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_conf->rss_key, + hw->rss_key_size); + if (ret != 0) { +- rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "obtain hash algo and key failed, ret = %d", + ret); +- return ret; ++ goto out; + } + rss_conf->rss_key_len = hw->rss_key_size; + } ++ ++out: + rte_spinlock_unlock(&hw->lock); + +- return 0; ++ return ret; + } + + /* +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index be0141f602..17473e70e2 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -110,6 +110,7 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw); + int hns3_config_rss(struct hns3_adapter *hns); + void hns3_rss_uninit(struct hns3_adapter *hns); + int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); ++int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields); + int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len); + int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, +-- +2.23.0 + diff --git a/0243-net-hns3-use-hardware-config-to-report-redirection-t.patch b/0243-net-hns3-use-hardware-config-to-report-redirection-t.patch new file mode 100644 index 0000000..df64168 --- /dev/null +++ b/0243-net-hns3-use-hardware-config-to-report-redirection-t.patch @@ -0,0 +1,133 @@ +From 866a61065fb67ec7e8cf34f5919ca93633d09cf7 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:07 +0800 +Subject: net/hns3: use hardware config to report redirection table + +[ upstream commit d1e37d1c6916858314a2c67e6317b0bb6c691b36 ] + +Currently, reta_query() API reports the redirection table from software. +This patch uses the one in hardware to report. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_cmd.h | 1 + + drivers/net/hns3/hns3_rss.c | 65 ++++++++++++++++++++++++++++++++++--- + 2 files changed, 62 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 994dfc48cc..eb394c9dec 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -606,6 +606,7 @@ struct hns3_rss_input_tuple_cmd { + #define HNS3_RSS_CFG_TBL_SIZE_H 4 + #define HNS3_RSS_CFG_TBL_BW_H 2 + #define HNS3_RSS_CFG_TBL_BW_L 8 ++#define HNS3_RSS_CFG_TBL_BW_H_M 0x3 + + /* Configure the indirection table, opcode:0x0D07 */ + struct hns3_rss_indirection_table_cmd { +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 9addc00a67..7dc4e03d83 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -481,6 +481,54 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) + return 0; + } + ++static int ++hns3_get_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) ++{ ++ struct hns3_rss_indirection_table_cmd *req; ++ uint16_t max_bd_num, cfg_tbl_size; ++ uint8_t qid_msb_off, qid_msb_idx; ++ struct hns3_cmd_desc desc; ++ uint16_t q_id, q_hi, q_lo; ++ uint8_t rss_result_h; ++ uint16_t i, j; ++ int ret; ++ ++ req = (struct hns3_rss_indirection_table_cmd *)desc.data; ++ max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); ++ for (i = 0; i < max_bd_num; i++) { ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, ++ true); ++ req->start_table_index = ++ rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) ++ cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; ++ else ++ cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; ++ ++ for (j = 0; j < cfg_tbl_size; j++) { ++ qid_msb_idx = ++ j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; ++ rss_result_h = req->rss_result_h[qid_msb_idx]; ++ qid_msb_off = ++ j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE; ++ q_hi = (rss_result_h >> qid_msb_off) & ++ HNS3_RSS_CFG_TBL_BW_H_M; ++ q_lo = req->rss_result_l[j]; ++ q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo; ++ indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id; ++ } ++ } ++ ++ return 0; ++} ++ + int + hns3_rss_reset_indir_table(struct hns3_hw *hw) + { +@@ -842,10 +890,11 @@ hns3_dev_rss_reta_query(struct rte_eth_dev *dev, + uint16_t reta_size) + { + struct hns3_adapter *hns = dev->data->dev_private; ++ uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX]; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rss_conf *rss_cfg = &hw->rss_info; + uint16_t idx, shift; + uint16_t i; ++ int ret; + + if (reta_size != hw->rss_ind_tbl_size) { + hns3_err(hw, "The size of hash lookup table configured (%u)" +@@ -854,14 +903,22 @@ hns3_dev_rss_reta_query(struct rte_eth_dev *dev, + return -EINVAL; + } + rte_spinlock_lock(&hw->lock); ++ ret = hns3_get_rss_indir_table(hw, reta_table, reta_size); ++ if (ret != 0) { ++ rte_spinlock_unlock(&hw->lock); ++ hns3_err(hw, "query RSS redirection table failed, ret = %d.", ++ ret); ++ return ret; ++ } ++ rte_spinlock_unlock(&hw->lock); ++ + for (i = 0; i < reta_size; i++) { + idx = i / RTE_ETH_RETA_GROUP_SIZE; + shift = i % RTE_ETH_RETA_GROUP_SIZE; + if (reta_conf[idx].mask & (1ULL << shift)) +- reta_conf[idx].reta[shift] = +- rss_cfg->rss_indirection_tbl[i]; ++ reta_conf[idx].reta[shift] = reta_table[i]; + } +- rte_spinlock_unlock(&hw->lock); ++ + return 0; + } + +-- +2.23.0 + diff --git a/0244-net-hns3-separate-setting-hash-algorithm.patch b/0244-net-hns3-separate-setting-hash-algorithm.patch new file mode 100644 index 0000000..0526a23 --- /dev/null +++ b/0244-net-hns3-separate-setting-hash-algorithm.patch @@ -0,0 +1,186 @@ +From e9ff78f09278b62f184277357777ebec6b7ac0f2 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:08 +0800 +Subject: net/hns3: separate setting hash algorithm + +[ upstream commit 1fcbef5ccb993b6028a3f8a68a7b01f9b8c67413 ] + +Currently, the setting of hash algorithm comes from the +default configuration in driver and the rte_flow interface. +The hash algorithm that is set to hardware in both ways is +saved in hw->rss_info.conf.func. + +But the 'func' in struct rte_flow_action_rss is usually used +in rte flow interface. And the ethdev ops interface may also +set hash algorithm in the future. It is not appropriate and +is a little messy for ethdev ops interface and driver default +configuration to use struct rte_flow_action_rss. So we have +to separate the RSS configuration from ethdev ops and rte +flow interface to make codes more easier to maintain. + +This patch separates hash algorithm by following ways: +1) 'hash_algo' in struct hns3_rss_conf is used for ethdev ops + interface or default configuration in driver. +2) Add a 'rte_flow_hash_algo' field in struct hns3_rss_conf + to save algorithm from rte flow interface. The main reasons + are as follows: + Currently, only the last rule is used to restore the rte + flow rule. If 'func' in RSS action is 'DEFAULT', it means + that this rule doesn't modify algorithm and driver need to + save current algorithm for restoring algorithm during reset + phase. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 60 +++++++++++++++++++++--------------- + drivers/net/hns3/hns3_rss.c | 14 +-------- + drivers/net/hns3/hns3_rss.h | 1 + + 3 files changed, 37 insertions(+), 38 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index e80ec0f053..0cb6914982 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1438,30 +1438,40 @@ hns3_disable_rss(struct hns3_hw *hw) + } + + static int +-hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, ++hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func, + uint8_t *hash_algo) + { +- enum rte_eth_hash_function algo_func = *func; +- switch (algo_func) { +- case RTE_ETH_HASH_FUNCTION_DEFAULT: +- /* Keep *hash_algo as what it used to be */ +- algo_func = hw->rss_info.conf.func; +- break; +- case RTE_ETH_HASH_FUNCTION_TOEPLITZ: +- *hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; +- break; +- case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: +- *hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; +- break; +- case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: +- *hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; +- break; +- default: +- hns3_err(hw, "Invalid RSS algorithm configuration(%d)", +- algo_func); +- return -EINVAL; ++ const uint8_t hash_func_map[] = { ++ [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ, ++ [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ, ++ [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE, ++ [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP, ++ }; ++ uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0}; ++ int ret; ++ ++ if (func == RTE_ETH_HASH_FUNCTION_DEFAULT) { ++ ret = hns3_rss_get_algo_key(hw, hash_algo, key, ++ hw->rss_key_size); ++ if (ret != 0) { ++ hns3_err(hw, "fail to get current RSS hash algorithm, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ /* ++ * During the phase of reset recovery, the hash algorithm ++ * obtained from hardware may not be the one used(saved in ++ * rte_flow_hash_algo) when this rule is delivered. ++ */ ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) && ++ *hash_algo != hw->rss_info.rte_flow_hash_algo) ++ *hash_algo = hw->rss_info.rte_flow_hash_algo; ++ ++ return 0; + } +- *func = algo_func; ++ ++ *hash_algo = hash_func_map[func]; + + return 0; + } +@@ -1471,6 +1481,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + { + uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; + bool use_default_key = false; ++ uint8_t hash_algo; + int ret; + + if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) { +@@ -1480,18 +1491,17 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + use_default_key = true; + } + +- ret = hns3_parse_rss_algorithm(hw, &rss_config->func, +- &hw->rss_info.hash_algo); ++ ret = hns3_parse_rss_algorithm(hw, rss_config->func, &hash_algo); + if (ret) + return ret; + +- ret = hns3_rss_set_algo_key(hw, hw->rss_info.hash_algo, ++ ret = hns3_rss_set_algo_key(hw, hash_algo, + use_default_key ? rss_key : rss_config->key, + hw->rss_key_size); + if (ret) + return ret; + +- hw->rss_info.conf.func = rss_config->func; ++ hw->rss_info.rte_flow_hash_algo = hash_algo; + + ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_config->types); + if (ret) +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 7dc4e03d83..dcd42b554a 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -1022,7 +1022,7 @@ hns3_rss_set_default_args(struct hns3_hw *hw) + uint16_t i; + + /* Default hash algorithm */ +- rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; ++ rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; + + memcpy(rss_cfg->key, hns3_hash_key, + RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); +@@ -1046,18 +1046,6 @@ hns3_config_rss(struct hns3_adapter *hns) + + enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; + +- switch (hw->rss_info.conf.func) { +- case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: +- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; +- break; +- case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: +- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; +- break; +- default: +- hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; +- break; +- } +- + ret = hns3_rss_set_algo_key(hw, rss_cfg->hash_algo, + hash_key, hw->rss_key_size); + if (ret) +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 17473e70e2..6e679b709b 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -42,6 +42,7 @@ struct hns3_rss_conf { + /* RSS parameters :algorithm, flow_types, key, queue */ + struct rte_flow_action_rss conf; + uint8_t hash_algo; /* hash function type defined by hardware */ ++ uint8_t rte_flow_hash_algo; + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ + uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; + uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ +-- +2.23.0 + diff --git a/0245-net-hns3-separate-setting-hash-key.patch b/0245-net-hns3-separate-setting-hash-key.patch new file mode 100644 index 0000000..85b75f4 --- /dev/null +++ b/0245-net-hns3-separate-setting-hash-key.patch @@ -0,0 +1,49 @@ +From 8ca08cd0671207b57d934b439d7b245966fbbfe8 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:09 +0800 +Subject: net/hns3: separate setting hash key + +[ upstream commit fe9cc8b88babd0911d91dc194b35c7c352e2bf7b ] + +The settings of hash key comes from the ethdev ops (like, dev_configure +and rss_hash_update) and rte_flow API. For the ethdev ops, driver has +to save it to rss_info::key in hns3_hw structure so as to it can be +restored when reset is triggered. While rte_flow API no need to use +this field to save, they has a global flow_rss_list to maintain all +rules which save hash key. And hash key can be restored by this rule +information during the reset phase. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index dcd42b554a..401e3adfdf 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -376,8 +376,7 @@ hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + return ret; + } + } +- /* Update the shadow RSS key with user specified */ +- memcpy(hw->rss_info.key, key, hw->rss_key_size); ++ + return 0; + } + +@@ -672,6 +671,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + key, hw->rss_key_size); + if (ret) + goto set_algo_key_fail; ++ /* Update the shadow RSS key with user specified */ ++ memcpy(hw->rss_info.key, key, hw->rss_key_size); + } + rte_spinlock_unlock(&hw->lock); + +-- +2.23.0 + diff --git a/0246-net-hns3-separate-setting-redirection-table.patch b/0246-net-hns3-separate-setting-redirection-table.patch new file mode 100644 index 0000000..4e71a61 --- /dev/null +++ b/0246-net-hns3-separate-setting-redirection-table.patch @@ -0,0 +1,98 @@ +From 5a9f2de85e9f9185165c7fe82247ef6125ef4115 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:10 +0800 +Subject: net/hns3: separate setting redirection table + +[ upstream commit a421cb93462932717f23c5d8342381726e547ba6 ] + +The settings of redirection table comes from the ethdev ops (like, +dev_configure and rss_hash_update) and rte_flow API. For the ethdev +ops, driver has to save it to rss_info::rss_indirection_tbl in hns3_hw +structure so as to it can be restored when reset is triggered. +While rte_flow API no need to use this field to save, they has a global +RSS flow list to maintain all rules which can be used to restore the +table during the reset phase. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 2 -- + drivers/net/hns3/hns3_rss.c | 21 +++++++++++++-------- + 2 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 0cb6914982..875c0eec11 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1519,8 +1519,6 @@ hns3_update_indir_table(struct hns3_hw *hw, + uint32_t i; + + /* Fill in redirection table */ +- memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl, +- sizeof(hw->rss_info.rss_indirection_tbl)); + for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) { + j %= num; + if (conf->queue[j] >= hw->alloc_rss_size) { +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 401e3adfdf..751033d98f 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -473,10 +473,6 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) + } + } + +- /* Update redirection table of hw */ +- memcpy(hw->rss_info.rss_indirection_tbl, indir, +- sizeof(uint16_t) * size); +- + return 0; + } + +@@ -542,8 +538,11 @@ hns3_rss_reset_indir_table(struct hns3_hw *hw) + } + + ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); +- if (ret) +- hns3_err(hw, "RSS uninit indir table failed: %d", ret); ++ if (ret != 0) ++ hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret); ++ else ++ memcpy(hw->rss_info.rss_indirection_tbl, lut, ++ sizeof(uint16_t) * hw->rss_ind_tbl_size); + rte_free(lut); + + return ret; +@@ -855,12 +854,12 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, + idx = i / RTE_ETH_RETA_GROUP_SIZE; + shift = i % RTE_ETH_RETA_GROUP_SIZE; + if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) { +- rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "queue id(%u) set to redirection table " + "exceeds queue number(%u) allocated to a TC", + reta_conf[idx].reta[shift], + hw->alloc_rss_size); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + + if (reta_conf[idx].mask & (1ULL << shift)) +@@ -869,7 +868,13 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, + + ret = hns3_set_rss_indir_table(hw, indirection_tbl, + hw->rss_ind_tbl_size); ++ if (ret != 0) ++ goto out; + ++ memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl, ++ sizeof(uint16_t) * hw->rss_ind_tbl_size); ++ ++out: + rte_spinlock_unlock(&hw->lock); + return ret; + } +-- +2.23.0 + diff --git a/0247-net-hns3-separate-setting-RSS-types.patch b/0247-net-hns3-separate-setting-RSS-types.patch new file mode 100644 index 0000000..457d326 --- /dev/null +++ b/0247-net-hns3-separate-setting-RSS-types.patch @@ -0,0 +1,131 @@ +From b99379a51ab920cbd8d4ee51122efff2f1af57db Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:11 +0800 +Subject: net/hns3: separate setting RSS types + +[ upstream commit 791e56935e488b8154a83daaf3952e1901ed7552 ] + +The settings of RSS types comes from the ethdev ops (like, dev_configure +and rss_hash_update) and rte_flow API. For the ethdev ops, driver has to +save it so as to it can be restored when reset is triggered. +While rte_flow API no need to maintain this field, it can be restored by +the saved rule. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 3 ++- + drivers/net/hns3/hns3_rss.c | 22 ++++++++++++++-------- + drivers/net/hns3/hns3_rss.h | 1 + + 3 files changed, 17 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 875c0eec11..9e51891bd9 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1433,6 +1433,7 @@ hns3_disable_rss(struct hns3_hw *hw) + ret = hns3_set_rss_tuple_by_rss_hf(hw, 0); + if (ret) + return ret; ++ hw->rss_info.rss_hf = 0; + + return 0; + } +@@ -1580,7 +1581,7 @@ hns3_config_rss_filter(struct hns3_hw *hw, + /* Filter the unsupported flow types */ + flow_types = conf->conf.types ? + rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT : +- hw->rss_info.conf.types; ++ hw->rss_info.rss_hf; + if (flow_types != rss_flow_conf.types) + hns3_warn(hw, "modified RSS types based on hardware support," + " requested:0x%" PRIx64 " configured:0x%" PRIx64, +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 751033d98f..f51d70a8e5 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -628,9 +628,6 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) + return ret; + } + +- /* Update supported flow types when set tuple success */ +- hw->rss_info.conf.types = rss_hf; +- + return 0; + } + +@@ -648,7 +645,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- uint64_t rss_hf_bk = hw->rss_info.conf.types; ++ uint64_t rss_hf_bk = hw->rss_info.rss_hf; + uint8_t key_len = rss_conf->rss_key_len; + uint64_t rss_hf = rss_conf->rss_hf; + uint8_t *key = rss_conf->rss_key; +@@ -673,6 +670,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + /* Update the shadow RSS key with user specified */ + memcpy(hw->rss_info.key, key, hw->rss_key_size); + } ++ hw->rss_info.rss_hf = rss_hf; + rte_spinlock_unlock(&hw->lock); + + return 0; +@@ -1030,6 +1028,7 @@ hns3_rss_set_default_args(struct hns3_hw *hw) + /* Default hash algorithm */ + rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; + ++ hw->rss_info.rss_hf = 0; + memcpy(rss_cfg->key, hns3_hash_key, + RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); + +@@ -1067,15 +1066,22 @@ hns3_config_rss(struct hns3_adapter *hns) + return ret; + + /* +- * When muli-queue RSS mode flag is not set or unsupported tuples are ++ * When multi-queue RSS mode flag is not set or unsupported tuples are + * set, disable all tuples. + */ +- rss_hf = hw->rss_info.conf.types; ++ rss_hf = hw->rss_info.rss_hf; + if (!((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) || + !(rss_hf & HNS3_ETH_RSS_SUPPORT)) + rss_hf = 0; + +- return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); ++ ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); ++ if (ret != 0) { ++ hns3_err(hw, "set RSS tuples failed, ret = %d.", ret); ++ return ret; ++ } ++ hw->rss_info.rss_hf = rss_hf; ++ ++ return 0; + } + + /* +@@ -1093,5 +1099,5 @@ hns3_rss_uninit(struct hns3_adapter *hns) + return; + + /* Disable RSS */ +- hw->rss_info.conf.types = 0; ++ hw->rss_info.rss_hf = 0; + } +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 6e679b709b..21b90789d0 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -41,6 +41,7 @@ + struct hns3_rss_conf { + /* RSS parameters :algorithm, flow_types, key, queue */ + struct rte_flow_action_rss conf; ++ uint64_t rss_hf; + uint8_t hash_algo; /* hash function type defined by hardware */ + uint8_t rte_flow_hash_algo; + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ +-- +2.23.0 + diff --git a/0248-net-hns3-separate-setting-and-clearing-RSS-rule.patch b/0248-net-hns3-separate-setting-and-clearing-RSS-rule.patch new file mode 100644 index 0000000..85d77c6 --- /dev/null +++ b/0248-net-hns3-separate-setting-and-clearing-RSS-rule.patch @@ -0,0 +1,126 @@ +From 0667045e83f2ed2769e1e71947ce6530108739ed Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:12 +0800 +Subject: net/hns3: separate setting and clearing RSS rule + +[ upstream commit 1c3aeb2be4b8ef8b18846883ebbb9320f62cf097 ] + +Separate the setting and clearing of RSS rule. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 46 +++++++++++++++++------------------- + 1 file changed, 22 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 9e51891bd9..80dda63afe 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1535,8 +1535,22 @@ hns3_update_indir_table(struct hns3_hw *hw, + } + + static int +-hns3_config_rss_filter(struct hns3_hw *hw, +- const struct hns3_rss_conf *conf, bool add) ++hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) ++{ ++ int ret; ++ ++ if (!conf->valid) ++ return 0; ++ ++ ret = hns3_disable_rss(hw); ++ if (ret) ++ hns3_err(hw, "RSS disable failed(%d)", ret); ++ ++ return ret; ++} ++ ++static int ++hns3_config_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) + { + uint64_t flow_types; + uint16_t num; +@@ -1553,19 +1567,6 @@ hns3_config_rss_filter(struct hns3_hw *hw, + .queue = conf->conf.queue, + }; + +- if (!add) { +- if (!conf->valid) +- return 0; +- +- ret = hns3_disable_rss(hw); +- if (ret) { +- hns3_err(hw, "RSS disable failed(%d)", ret); +- return ret; +- } +- +- return 0; +- } +- + /* Set rx queues to use */ + num = RTE_MIN(hw->data->nb_rx_queues, rss_flow_conf.queue_num); + if (rss_flow_conf.queue_num > num) +@@ -1606,8 +1607,7 @@ hns3_clear_rss_filter(struct rte_eth_dev *dev) + rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); + while (rss_filter_ptr) { + TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); +- ret = hns3_config_rss_filter(hw, &rss_filter_ptr->filter_info, +- false); ++ ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info); + if (ret) + rss_rule_fail_cnt++; + else +@@ -1636,7 +1636,7 @@ hns3_restore_rss_filter(struct hns3_hw *hw) + if (!filter->filter_info.valid) + continue; + +- ret = hns3_config_rss_filter(hw, &filter->filter_info, true); ++ ret = hns3_config_rss_filter(hw, &filter->filter_info); + if (ret != 0) { + hns3_err(hw, "restore RSS filter failed, ret=%d", ret); + goto out; +@@ -1680,8 +1680,7 @@ hns3_rss_action_is_dup(struct hns3_hw *hw, + } + + static int +-hns3_flow_parse_rss(struct rte_eth_dev *dev, +- const struct hns3_rss_conf *conf, bool add) ++hns3_flow_parse_rss(struct rte_eth_dev *dev, const struct hns3_rss_conf *conf) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +@@ -1691,7 +1690,7 @@ hns3_flow_parse_rss(struct rte_eth_dev *dev, + return -EINVAL; + } + +- return hns3_config_rss_filter(hw, conf, add); ++ return hns3_config_rss_filter(hw, conf); + } + + static int +@@ -1778,7 +1777,7 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + } + } + +- ret = hns3_flow_parse_rss(dev, new_conf, true); ++ ret = hns3_flow_parse_rss(dev, new_conf); + if (ret != 0) { + rte_free(rss_filter_ptr); + return ret; +@@ -1961,8 +1960,7 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + break; + case RTE_ETH_FILTER_HASH: + rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule; +- ret = hns3_config_rss_filter(hw, &rss_filter_ptr->filter_info, +- false); ++ ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info); + if (ret) + return rte_flow_error_set(error, EIO, + RTE_FLOW_ERROR_TYPE_HANDLE, +-- +2.23.0 + diff --git a/0249-net-hns3-use-new-RSS-rule-to-configure-hardware.patch b/0249-net-hns3-use-new-RSS-rule-to-configure-hardware.patch new file mode 100644 index 0000000..82de7a0 --- /dev/null +++ b/0249-net-hns3-use-new-RSS-rule-to-configure-hardware.patch @@ -0,0 +1,121 @@ +From 08730d02d9f5cb532ea3953c2ae1920aaa123358 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:13 +0800 +Subject: net/hns3: use new RSS rule to configure hardware + +[ upstream commit 218a119a08e01f203f92b46334b6b2f03ff9765d ] + +Remove redundant assignment and directly use new RSS rule to configure +hardware. Additionally, considering that the new rule configuration may +need to be modified, the 'const' of input parameter about it is removed. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 52 ++++++++++++++---------------------- + 1 file changed, 20 insertions(+), 32 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 80dda63afe..3ac5279538 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1482,6 +1482,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + { + uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; + bool use_default_key = false; ++ uint64_t flow_types; + uint8_t hash_algo; + int ret; + +@@ -1501,10 +1502,18 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + hw->rss_key_size); + if (ret) + return ret; +- + hw->rss_info.rte_flow_hash_algo = hash_algo; + +- ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_config->types); ++ /* Filter the unsupported flow types */ ++ flow_types = rss_config->types ? ++ rss_config->types & HNS3_ETH_RSS_SUPPORT : ++ hw->rss_info.rss_hf; ++ if (flow_types != rss_config->types) ++ hns3_warn(hw, "modified RSS types based on hardware support," ++ " requested:0x%" PRIx64 " configured:0x%" PRIx64, ++ rss_config->types, flow_types); ++ ++ ret = hns3_set_rss_tuple_by_rss_hf(hw, flow_types); + if (ret) + hns3_err(hw, "Update RSS tuples by rss hf failed %d", ret); + +@@ -1550,48 +1559,27 @@ hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) + } + + static int +-hns3_config_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) ++hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf) + { +- uint64_t flow_types; ++ struct rte_flow_action_rss *rss_act; + uint16_t num; + int ret; + +- struct rte_flow_action_rss rss_flow_conf = { +- .func = conf->conf.func, +- .level = conf->conf.level, +- .types = conf->conf.types, +- .key_len = conf->conf.key_len, +- .queue_num = conf->conf.queue_num, +- .key = conf->conf.key_len ? +- (void *)(uintptr_t)conf->conf.key : NULL, +- .queue = conf->conf.queue, +- }; +- ++ rss_act = &conf->conf; + /* Set rx queues to use */ +- num = RTE_MIN(hw->data->nb_rx_queues, rss_flow_conf.queue_num); +- if (rss_flow_conf.queue_num > num) ++ num = RTE_MIN(hw->data->nb_rx_queues, rss_act->queue_num); ++ if (rss_act->queue_num > num) + hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated", +- rss_flow_conf.queue_num); ++ rss_act->queue_num); + hns3_info(hw, "Max of contiguous %u PF queues are configured", num); + if (num) { +- ret = hns3_update_indir_table(hw, &rss_flow_conf, num); ++ ret = hns3_update_indir_table(hw, rss_act, num); + if (ret) + return ret; + } + +- /* Filter the unsupported flow types */ +- flow_types = conf->conf.types ? +- rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT : +- hw->rss_info.rss_hf; +- if (flow_types != rss_flow_conf.types) +- hns3_warn(hw, "modified RSS types based on hardware support," +- " requested:0x%" PRIx64 " configured:0x%" PRIx64, +- rss_flow_conf.types, flow_types); +- /* Update the useful flow types */ +- rss_flow_conf.types = flow_types; +- + /* Set hash algorithm and flow types by the user's config */ +- return hns3_hw_rss_hash_set(hw, &rss_flow_conf); ++ return hns3_hw_rss_hash_set(hw, rss_act); + } + + static int +@@ -1680,7 +1668,7 @@ hns3_rss_action_is_dup(struct hns3_hw *hw, + } + + static int +-hns3_flow_parse_rss(struct rte_eth_dev *dev, const struct hns3_rss_conf *conf) ++hns3_flow_parse_rss(struct rte_eth_dev *dev, struct hns3_rss_conf *conf) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +-- +2.23.0 + diff --git a/0250-net-hns3-save-hash-algo-to-RSS-filter-list-node.patch b/0250-net-hns3-save-hash-algo-to-RSS-filter-list-node.patch new file mode 100644 index 0000000..77d24d8 --- /dev/null +++ b/0250-net-hns3-save-hash-algo-to-RSS-filter-list-node.patch @@ -0,0 +1,96 @@ +From e439b6f69b496ab010cff1b87f7a8cd83e258faf Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:14 +0800 +Subject: net/hns3: save hash algo to RSS filter list node + +[ upstream commit 9d34b8a181bf022fe3a3a3ae8511f3d921fc5c67 ] + +Save hash algo from rte flow RSS rule to RSS filter list node +instead of struct hns3_rss_conf. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 3ac5279538..f073adebb6 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1439,7 +1439,7 @@ hns3_disable_rss(struct hns3_hw *hw) + } + + static int +-hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func, ++hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf, + uint8_t *hash_algo) + { + const uint8_t hash_func_map[] = { +@@ -1451,7 +1451,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func, + uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0}; + int ret; + +- if (func == RTE_ETH_HASH_FUNCTION_DEFAULT) { ++ if (rss_conf->conf.func == RTE_ETH_HASH_FUNCTION_DEFAULT) { + ret = hns3_rss_get_algo_key(hw, hash_algo, key, + hw->rss_key_size); + if (ret != 0) { +@@ -1466,20 +1466,21 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function func, + * rte_flow_hash_algo) when this rule is delivered. + */ + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) && +- *hash_algo != hw->rss_info.rte_flow_hash_algo) +- *hash_algo = hw->rss_info.rte_flow_hash_algo; ++ *hash_algo != rss_conf->rte_flow_hash_algo) ++ *hash_algo = rss_conf->rte_flow_hash_algo; + + return 0; + } + +- *hash_algo = hash_func_map[func]; ++ *hash_algo = hash_func_map[rss_conf->conf.func]; + + return 0; + } + + static int +-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) ++hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf) + { ++ struct rte_flow_action_rss *rss_config = &conf->conf; + uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; + bool use_default_key = false; + uint64_t flow_types; +@@ -1493,7 +1494,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + use_default_key = true; + } + +- ret = hns3_parse_rss_algorithm(hw, rss_config->func, &hash_algo); ++ ret = hns3_parse_rss_algorithm(hw, conf, &hash_algo); + if (ret) + return ret; + +@@ -1502,7 +1503,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + hw->rss_key_size); + if (ret) + return ret; +- hw->rss_info.rte_flow_hash_algo = hash_algo; ++ conf->rte_flow_hash_algo = hash_algo; + + /* Filter the unsupported flow types */ + flow_types = rss_config->types ? +@@ -1579,7 +1580,7 @@ hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf) + } + + /* Set hash algorithm and flow types by the user's config */ +- return hns3_hw_rss_hash_set(hw, rss_act); ++ return hns3_hw_rss_hash_set(hw, conf); + } + + static int +-- +2.23.0 + diff --git a/0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch b/0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch new file mode 100644 index 0000000..31542c5 --- /dev/null +++ b/0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch @@ -0,0 +1,37 @@ +From 9810ccb9266f09bef6f0d8cfcab6ac0d203d8e23 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:15 +0800 +Subject: net/hns3: allow adding queue buffer size hash rule + +[ upstream commit 8095bf3e6d8ca7349e0a15f95407acd2063e7be0 ] + +The maximum queue number from RSS flow rule allowed depends on +the maximum queue number (512) under one TC instead of the one +of Rx/Tx queue so as to eliminate restrictions on user usage. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_rss.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 21b90789d0..cc0bb8431d 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -37,7 +37,8 @@ + #define HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP 2 + #define HNS3_RSS_HASH_ALGO_MASK 0xf + +-#define HNS3_RSS_QUEUES_BUFFER_NUM 64 /* Same as the Max rx/tx queue num */ ++/* Same as the Max queue num under TC */ ++#define HNS3_RSS_QUEUES_BUFFER_NUM 512 + struct hns3_rss_conf { + /* RSS parameters :algorithm, flow_types, key, queue */ + struct rte_flow_action_rss conf; +-- +2.23.0 + diff --git a/0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch b/0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch new file mode 100644 index 0000000..22b7646 --- /dev/null +++ b/0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch @@ -0,0 +1,169 @@ +From bfbcc4acf9a007f4774e54febda3eac275b9c747 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:16 +0800 +Subject: net/hns3: separate flow RSS config from RSS conf + +[ upstream commit b93ad0cc7677881911e5fc3baa89e0a0bbd73c48 ] + +Some RSS fields in struct hns3_rss_conf (e.g. conf, queue, +valid) are only used when create RSS flow rule, which is +unnecessary for RSS configuration information from ethdev +ops. This patch removes these fields from hns3_rss_conf +and add a new struct hns3_flow_rss_conf as rte flow +RSS filter list node element. + +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 23 ++++++++++++----------- + drivers/net/hns3/hns3_flow.h | 10 +++++++++- + drivers/net/hns3/hns3_rss.h | 5 ----- + 3 files changed, 21 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index f073adebb6..b1189455ec 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1359,7 +1359,6 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rss_conf *rss_conf = &hw->rss_info; + const struct rte_flow_action_rss *rss; + const struct rte_flow_action *act; + uint32_t act_index = 0; +@@ -1374,7 +1373,7 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + act, "no valid queues"); + } + +- if (rss->queue_num > RTE_DIM(rss_conf->queue)) ++ if (rss->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, + "queue number configured exceeds " +@@ -1439,7 +1438,7 @@ hns3_disable_rss(struct hns3_hw *hw) + } + + static int +-hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf, ++hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_flow_rss_conf *rss_conf, + uint8_t *hash_algo) + { + const uint8_t hash_func_map[] = { +@@ -1466,8 +1465,8 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf, + * rte_flow_hash_algo) when this rule is delivered. + */ + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) && +- *hash_algo != rss_conf->rte_flow_hash_algo) +- *hash_algo = rss_conf->rte_flow_hash_algo; ++ *hash_algo != rss_conf->hash_algo) ++ *hash_algo = rss_conf->hash_algo; + + return 0; + } +@@ -1478,7 +1477,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_rss_conf *rss_conf, + } + + static int +-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf) ++hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf) + { + struct rte_flow_action_rss *rss_config = &conf->conf; + uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; +@@ -1503,7 +1502,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_rss_conf *conf) + hw->rss_key_size); + if (ret) + return ret; +- conf->rte_flow_hash_algo = hash_algo; ++ conf->hash_algo = hash_algo; + + /* Filter the unsupported flow types */ + flow_types = rss_config->types ? +@@ -1545,7 +1544,8 @@ hns3_update_indir_table(struct hns3_hw *hw, + } + + static int +-hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) ++hns3_reset_rss_filter(struct hns3_hw *hw, ++ const struct hns3_flow_rss_conf *conf) + { + int ret; + +@@ -1560,7 +1560,7 @@ hns3_reset_rss_filter(struct hns3_hw *hw, const struct hns3_rss_conf *conf) + } + + static int +-hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_rss_conf *conf) ++hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf) + { + struct rte_flow_action_rss *rss_act; + uint16_t num; +@@ -1669,7 +1669,8 @@ hns3_rss_action_is_dup(struct hns3_hw *hw, + } + + static int +-hns3_flow_parse_rss(struct rte_eth_dev *dev, struct hns3_rss_conf *conf) ++hns3_flow_parse_rss(struct rte_eth_dev *dev, ++ struct hns3_flow_rss_conf *conf) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +@@ -1739,8 +1740,8 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + const struct rte_flow_action_rss *rss_act; + struct hns3_rss_conf_ele *rss_filter_ptr; ++ struct hns3_flow_rss_conf *new_conf; + struct hns3_rss_conf_ele *filter_ptr; +- struct hns3_rss_conf *new_conf; + int ret; + + rss_filter_ptr = rte_zmalloc("hns3 rss filter", +diff --git a/drivers/net/hns3/hns3_flow.h b/drivers/net/hns3/hns3_flow.h +index e4b2fdf2e6..90126f2b6e 100644 +--- a/drivers/net/hns3/hns3_flow.h ++++ b/drivers/net/hns3/hns3_flow.h +@@ -24,10 +24,18 @@ struct rte_flow { + uint32_t counter_id; + }; + ++struct hns3_flow_rss_conf { ++ struct rte_flow_action_rss conf; ++ uint8_t hash_algo; ++ uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ ++ uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ ++ bool valid; /* check if RSS rule is valid */ ++}; ++ + /* rss filter list structure */ + struct hns3_rss_conf_ele { + TAILQ_ENTRY(hns3_rss_conf_ele) entries; +- struct hns3_rss_conf filter_info; ++ struct hns3_flow_rss_conf filter_info; + }; + + /* hns3_flow memory list structure */ +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index cc0bb8431d..d19730c69c 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -40,15 +40,10 @@ + /* Same as the Max queue num under TC */ + #define HNS3_RSS_QUEUES_BUFFER_NUM 512 + struct hns3_rss_conf { +- /* RSS parameters :algorithm, flow_types, key, queue */ +- struct rte_flow_action_rss conf; + uint64_t rss_hf; + uint8_t hash_algo; /* hash function type defined by hardware */ +- uint8_t rte_flow_hash_algo; + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ + uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; +- uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ +- bool valid; /* check if RSS rule is valid */ + /* + * For IPv6 SCTP packets type, check whether the NIC hardware support + * RSS hash using the src/dst port as the input tuple. For Kunpeng920 +-- +2.23.0 + diff --git a/0253-net-hns3-reimplement-hash-flow-function.patch b/0253-net-hns3-reimplement-hash-flow-function.patch new file mode 100644 index 0000000..ea37f42 --- /dev/null +++ b/0253-net-hns3-reimplement-hash-flow-function.patch @@ -0,0 +1,1697 @@ +From d5ee6b81de99a8699a6d4adb620ecc88103eb6e2 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:17 +0800 +Subject: net/hns3: reimplement hash flow function + +[ upstream commit e3069658da9ffb6f83a0d972ff2776c405eb6a8f ] + +Currently, hns3 driver supports setting multiple rte flow RSS rule, +but only the last is valid. This implementation is different from +the mainstream usage of rte flow hash in the community. Please see +the discussion threads [1] and [2]. + +This patch sets RSS hash feature completely based on the request of +the flow rule so that multiple hash rules can take effect at the same +time. Please notice that: +1. For hns3, 'func' has only one hardware. 'key' and 'queue' have only + one entry in hardware. +2. the overlapping part of the old rule will be overridden if the + configuration items of a new rule overlap with those of an old rule. + +The hns3_flow_validate() verifies and parses RSS or Fdir rules from +user, and saves them to a local variable at the same time. The local +variable is directly used to create RSS or Fdir rules. In this way, +we save one parsing and saving process. + +[1] https://lore.kernel.org/all/DM5PR12MB46648085D7CABF1AFF2D75CDD60A9@DM5PR12MB4664.namprd12.prod.outlook.com/ +[2] https://lore.kernel.org/all/f7de4db4-1b88-622f-4e03-acd3eee8a72c@oktetlabs.ru/ + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_ethdev.h | 9 - + drivers/net/hns3/hns3_flow.c | 966 +++++++++++++++++++++++---------- + drivers/net/hns3/hns3_flow.h | 15 +- + drivers/net/hns3/hns3_rss.c | 144 ++--- + drivers/net/hns3/hns3_rss.h | 117 +++- + 5 files changed, 855 insertions(+), 396 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 2457754b3d..9acc5a3d7e 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -996,15 +996,6 @@ static inline uint32_t hns3_read_reg(void *base, uint32_t reg) + #define hns3_read_dev(a, reg) \ + hns3_read_reg((a)->io_base, (reg)) + +-#define NEXT_ITEM_OF_ACTION(act, actions, index) \ +- do { \ +- (act) = (actions) + (index); \ +- while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \ +- (index)++; \ +- (act) = (actions) + (index); \ +- } \ +- } while (0) +- + static inline uint64_t + hns3_atomic_test_bit(unsigned int nr, volatile uint64_t *addr) + { +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index b1189455ec..c38bd9dd8b 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -10,6 +10,125 @@ + #include "hns3_logs.h" + #include "hns3_flow.h" + ++#define NEXT_ITEM_OF_ACTION(act, actions, index) \ ++ do { \ ++ (act) = (actions) + (index); \ ++ while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \ ++ (index)++; \ ++ (act) = (actions) + (index); \ ++ } \ ++ } while (0) ++ ++#define NEXT_ITEM_OF_PATTERN(item, pattern, index) \ ++ do { \ ++ (item) = (pattern) + (index); \ ++ while ((item)->type == RTE_FLOW_ITEM_TYPE_VOID) { \ ++ (index)++; \ ++ (item) = (pattern) + (index); \ ++ } \ ++ } while (0) ++ ++#define HNS3_HASH_HDR_ETH RTE_BIT64(0) ++#define HNS3_HASH_HDR_IPV4 RTE_BIT64(1) ++#define HNS3_HASH_HDR_IPV6 RTE_BIT64(2) ++#define HNS3_HASH_HDR_TCP RTE_BIT64(3) ++#define HNS3_HASH_HDR_UDP RTE_BIT64(4) ++#define HNS3_HASH_HDR_SCTP RTE_BIT64(5) ++ ++#define HNS3_HASH_VOID_NEXT_ALLOW BIT_ULL(RTE_FLOW_ITEM_TYPE_ETH) ++ ++#define HNS3_HASH_ETH_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \ ++ BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6)) ++ ++#define HNS3_HASH_IP_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_TCP) | \ ++ BIT_ULL(RTE_FLOW_ITEM_TYPE_UDP) | \ ++ BIT_ULL(RTE_FLOW_ITEM_TYPE_SCTP)) ++ ++static const uint64_t hash_pattern_next_allow_items[] = { ++ [RTE_FLOW_ITEM_TYPE_VOID] = HNS3_HASH_VOID_NEXT_ALLOW, ++ [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_ETH_NEXT_ALLOW, ++ [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_IP_NEXT_ALLOW, ++ [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_IP_NEXT_ALLOW, ++}; ++ ++static const uint64_t hash_pattern_item_header[] = { ++ [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_HDR_ETH, ++ [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_HDR_IPV4, ++ [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_HDR_IPV6, ++ [RTE_FLOW_ITEM_TYPE_TCP] = HNS3_HASH_HDR_TCP, ++ [RTE_FLOW_ITEM_TYPE_UDP] = HNS3_HASH_HDR_UDP, ++ [RTE_FLOW_ITEM_TYPE_SCTP] = HNS3_HASH_HDR_SCTP, ++}; ++ ++#define HNS3_HASH_IPV4 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV4) ++#define HNS3_HASH_IPV4_TCP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV4 | \ ++ HNS3_HASH_HDR_TCP) ++#define HNS3_HASH_IPV4_UDP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV4 | \ ++ HNS3_HASH_HDR_UDP) ++#define HNS3_HASH_IPV4_SCTP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV4 | \ ++ HNS3_HASH_HDR_SCTP) ++#define HNS3_HASH_IPV6 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV6) ++#define HNS3_HASH_IPV6_TCP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV6 | \ ++ HNS3_HASH_HDR_TCP) ++#define HNS3_HASH_IPV6_UDP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV6 | \ ++ HNS3_HASH_HDR_UDP) ++#define HNS3_HASH_IPV6_SCTP (HNS3_HASH_HDR_ETH | \ ++ HNS3_HASH_HDR_IPV6 | \ ++ HNS3_HASH_HDR_SCTP) ++ ++static const struct hns3_hash_map_info { ++ /* flow type specified, zero means action works for all flow types. */ ++ uint64_t pattern_type; ++ uint64_t rss_pctype; /* packet type with prefix RTE_ETH_RSS_xxx */ ++ uint64_t l3l4_types; /* Supported L3/L4 RSS types for this packet type */ ++ uint64_t hw_pctype; /* packet type in driver */ ++ uint64_t tuple_mask; /* full tuples of the hw_pctype */ ++} hash_map_table[] = { ++ /* IPV4 */ ++ { HNS3_HASH_IPV4, ++ RTE_ETH_RSS_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M }, ++ { HNS3_HASH_IPV4, ++ RTE_ETH_RSS_NONFRAG_IPV4_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M }, ++ { HNS3_HASH_IPV4, ++ RTE_ETH_RSS_FRAG_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV4_FLAG, HNS3_RSS_TUPLE_IPV4_FLAG_M }, ++ { HNS3_HASH_IPV4_TCP, ++ RTE_ETH_RSS_NONFRAG_IPV4_TCP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV4_TCP, HNS3_RSS_TUPLE_IPV4_TCP_M }, ++ { HNS3_HASH_IPV4_UDP, ++ RTE_ETH_RSS_NONFRAG_IPV4_UDP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV4_UDP, HNS3_RSS_TUPLE_IPV4_UDP_M }, ++ { HNS3_HASH_IPV4_SCTP, ++ RTE_ETH_RSS_NONFRAG_IPV4_SCTP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV4_SCTP, HNS3_RSS_TUPLE_IPV4_SCTP_M }, ++ /* IPV6 */ ++ { HNS3_HASH_IPV6, ++ RTE_ETH_RSS_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M }, ++ { HNS3_HASH_IPV6, ++ RTE_ETH_RSS_NONFRAG_IPV6_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M }, ++ { HNS3_HASH_IPV6, ++ RTE_ETH_RSS_FRAG_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST, ++ HNS3_RSS_PCTYPE_IPV6_FLAG, HNS3_RSS_TUPLE_IPV6_FLAG_M }, ++ { HNS3_HASH_IPV6_TCP, ++ RTE_ETH_RSS_NONFRAG_IPV6_TCP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV6_TCP, HNS3_RSS_TUPLE_IPV6_TCP_M }, ++ { HNS3_HASH_IPV6_UDP, ++ RTE_ETH_RSS_NONFRAG_IPV6_UDP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV6_UDP, HNS3_RSS_TUPLE_IPV6_UDP_M }, ++ { HNS3_HASH_IPV6_SCTP, ++ RTE_ETH_RSS_NONFRAG_IPV6_SCTP, HNS3_RSS_SUPPORT_L3L4, ++ HNS3_RSS_PCTYPE_IPV6_SCTP, HNS3_RSS_TUPLE_IPV6_SCTP_M }, ++}; ++ + static const uint8_t full_mask[VNI_OR_TNI_LEN] = { 0xFF, 0xFF, 0xFF }; + static const uint8_t zero_mask[VNI_OR_TNI_LEN] = { 0x00, 0x00, 0x00 }; + +@@ -79,7 +198,7 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len) + } + + /* +- * This function is used to find rss general action. ++ * This function is used to parse filter type. + * 1. As we know RSS is used to spread packets among several queues, the flow + * API provide the struct rte_flow_action_rss, user could config its field + * sush as: func/level/types/key/queue to control RSS function. +@@ -87,16 +206,18 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len) + * implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule + * which action is RSS queues region. + * 3. When action is RSS, we use the following rule to distinguish: +- * Case 1: pattern have ETH and action's queue_num > 0, indicate it is queue +- * region configuration. ++ * Case 1: pattern has ETH and all fields in RSS action except 'queues' are ++ * zero or default, indicate it is queue region configuration. + * Case other: an rss general action. + */ +-static const struct rte_flow_action * +-hns3_find_rss_general_action(const struct rte_flow_item pattern[], +- const struct rte_flow_action actions[]) ++static void ++hns3_parse_filter_type(const struct rte_flow_item pattern[], ++ const struct rte_flow_action actions[], ++ struct hns3_filter_info *filter_info) + { + const struct rte_flow_action_rss *rss_act; + const struct rte_flow_action *act = NULL; ++ bool only_has_queues = false; + bool have_eth = false; + + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { +@@ -105,8 +226,10 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[], + break; + } + } +- if (!act) +- return NULL; ++ if (act == NULL) { ++ filter_info->type = RTE_ETH_FILTER_FDIR; ++ return; ++ } + + for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { + if (pattern->type == RTE_FLOW_ITEM_TYPE_ETH) { +@@ -116,18 +239,20 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[], + } + + rss_act = act->conf; +- if (have_eth && rss_act->queue_num) { ++ only_has_queues = (rss_act->queue_num > 0) && ++ (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT && ++ rss_act->types == 0 && rss_act->key_len == 0); ++ if (have_eth && only_has_queues) { + /* +- * Pattern have ETH and action's queue_num > 0, indicate this is +- * queue region configuration. +- * Because queue region is implemented by FDIR + RSS in hns3 +- * hardware, it needs to enter FDIR process, so here return NULL +- * to avoid enter RSS process. ++ * Pattern has ETH and all fields in RSS action except 'queues' ++ * are zero or default, which indicates this is queue region ++ * configuration. + */ +- return NULL; ++ filter_info->type = RTE_ETH_FILTER_FDIR; ++ return; + } + +- return act; ++ filter_info->type = RTE_ETH_FILTER_HASH; + } + + static inline struct hns3_flow_counter * +@@ -1246,7 +1371,6 @@ hns3_filterlist_flush(struct rte_eth_dev *dev) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_fdir_rule_ele *fdir_rule_ptr; +- struct hns3_rss_conf_ele *rss_filter_ptr; + struct hns3_flow_mem *flow_node; + + fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list); +@@ -1256,13 +1380,6 @@ hns3_filterlist_flush(struct rte_eth_dev *dev) + fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list); + } + +- rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); +- while (rss_filter_ptr) { +- TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); +- rte_free(rss_filter_ptr); +- rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); +- } +- + flow_node = TAILQ_FIRST(&hw->flow_list); + while (flow_node) { + TAILQ_REMOVE(&hw->flow_list, flow_node, entries); +@@ -1328,196 +1445,422 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, + } + + static bool +-hns3_rss_input_tuple_supported(struct hns3_hw *hw, +- const struct rte_flow_action_rss *rss) ++hns3_valid_ipv6_sctp_rss_types(struct hns3_hw *hw, uint64_t types) + { + /* +- * For IP packet, it is not supported to use src/dst port fields to RSS +- * hash for the following packet types. +- * - IPV4 FRAG | IPV4 NONFRAG | IPV6 FRAG | IPV6 NONFRAG +- * Besides, for Kunpeng920, the NIC HW is not supported to use src/dst +- * port fields to RSS hash for IPV6 SCTP packet type. However, the +- * Kunpeng930 and future kunpeng series support to use src/dst port +- * fields to RSS hash for IPv6 SCTP packet type. ++ * Some hardware don't support to use src/dst port fields to hash ++ * for IPV6 SCTP packet type. + */ +- if (rss->types & (RTE_ETH_RSS_L4_DST_ONLY | RTE_ETH_RSS_L4_SRC_ONLY) && +- (rss->types & RTE_ETH_RSS_IP || +- (!hw->rss_info.ipv6_sctp_offload_supported && +- rss->types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP))) ++ if (types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP && ++ types & HNS3_RSS_SUPPORT_L4_SRC_DST && ++ !hw->rss_info.ipv6_sctp_offload_supported) + return false; + + return true; + } + +-/* +- * This function is used to parse rss action validation. +- */ + static int +-hns3_parse_rss_filter(struct rte_eth_dev *dev, +- const struct rte_flow_action *actions, +- struct rte_flow_error *error) ++hns3_flow_parse_hash_func(const struct rte_flow_action_rss *rss_act, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) + { +- struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; +- const struct rte_flow_action_rss *rss; +- const struct rte_flow_action *act; +- uint32_t act_index = 0; +- uint16_t n; ++ if (rss_act->func >= RTE_ETH_HASH_FUNCTION_MAX) ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, "RSS hash func are not supported"); + +- NEXT_ITEM_OF_ACTION(act, actions, act_index); +- rss = act->conf; ++ rss_conf->conf.func = rss_act->func; ++ return 0; ++} + +- if (rss == NULL) { ++static int ++hns3_flow_parse_hash_key(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss_act, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ if (rss_act->key_len != hw->rss_key_size) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, +- act, "no valid queues"); +- } ++ NULL, "invalid RSS key length"); ++ ++ if (rss_act->key != NULL) ++ memcpy(rss_conf->key, rss_act->key, rss_act->key_len); ++ else ++ memcpy(rss_conf->key, hns3_hash_key, ++ RTE_MIN(sizeof(hns3_hash_key), rss_act->key_len)); ++ /* Need to record if user sets hash key. */ ++ rss_conf->conf.key = rss_act->key; ++ rss_conf->conf.key_len = rss_act->key_len; + +- if (rss->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM) ++ return 0; ++} ++ ++static int ++hns3_flow_parse_queues(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss_act, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ uint16_t i; ++ ++ if (rss_act->queue_num > hw->rss_ind_tbl_size) + return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "queue number configured exceeds " +- "queue buffer size driver supported"); ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, ++ "queue number can not exceed RSS indirection table."); + +- for (n = 0; n < rss->queue_num; n++) { +- if (rss->queue[n] < hw->alloc_rss_size) +- continue; +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "queue id must be less than queue number allocated to a TC"); ++ if (rss_act->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM) ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, ++ "queue number configured exceeds queue buffer size driver supported"); ++ ++ for (i = 0; i < rss_act->queue_num; i++) { ++ if (rss_act->queue[i] >= hw->alloc_rss_size) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, ++ "queue id must be less than queue number allocated to a TC"); + } + +- if (!(rss->types & HNS3_ETH_RSS_SUPPORT) && rss->types) ++ memcpy(rss_conf->queue, rss_act->queue, ++ rss_act->queue_num * sizeof(rss_conf->queue[0])); ++ rss_conf->conf.queue = rss_conf->queue; ++ rss_conf->conf.queue_num = rss_act->queue_num; ++ ++ return 0; ++} ++ ++static int ++hns3_flow_get_hw_pctype(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss_act, ++ const struct hns3_hash_map_info *map, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ uint64_t l3l4_src_dst, l3l4_refine, left_types; ++ ++ if (rss_act->types == 0) { ++ /* Disable RSS hash of this packet type if types is zero. */ ++ rss_conf->hw_pctypes |= map->hw_pctype; ++ return 0; ++ } ++ ++ /* ++ * Can not have extra types except rss_pctype and l3l4_type in this map. ++ */ ++ left_types = ~map->rss_pctype & rss_act->types; ++ if (left_types & ~map->l3l4_types) + return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, +- act, +- "Flow types is unsupported by " +- "hns3's RSS"); +- if (rss->func >= RTE_ETH_HASH_FUNCTION_MAX) +- return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "RSS hash func are not supported"); +- if (rss->level) ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, ++ "cannot set extra types."); ++ ++ l3l4_src_dst = left_types; ++ /* L3/L4 SRC and DST shouldn't be specified at the same time. */ ++ l3l4_refine = rte_eth_rss_hf_refine(l3l4_src_dst); ++ if (l3l4_refine != l3l4_src_dst) + return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "a nonzero RSS encapsulation level is not supported"); +- if (rss->key_len && rss->key_len != hw->rss_key_size) ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, ++ "cannot specify L3_SRC/DST_ONLY or L4_SRC/DST_ONLY at the same."); ++ ++ if (!hns3_valid_ipv6_sctp_rss_types(hw, rss_act->types)) + return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, +- "invalid RSS key length"); ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, ++ "hardware doesn't support to use L4 src/dst to hash for IPV6-SCTP."); + +- if (!hns3_rss_input_tuple_supported(hw, rss)) +- return rte_flow_error_set(error, EINVAL, ++ rss_conf->hw_pctypes |= map->hw_pctype; ++ ++ return 0; ++} ++ ++static int ++hns3_flow_parse_rss_types_by_ptype(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss_act, ++ uint64_t pattern_type, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ const struct hns3_hash_map_info *map; ++ bool matched = false; ++ uint16_t i; ++ int ret; ++ ++ for (i = 0; i < RTE_DIM(hash_map_table); i++) { ++ map = &hash_map_table[i]; ++ if (map->pattern_type != pattern_type) { ++ /* ++ * If the target pattern type is already matched with ++ * the one before this pattern in the hash map table, ++ * no need to continue walk. ++ */ ++ if (matched) ++ break; ++ continue; ++ } ++ matched = true; ++ ++ /* ++ * If pattern type is matched and the 'types' is zero, all packet flow ++ * types related to this pattern type disable RSS hash. ++ * Otherwise, RSS types must match the pattern type and cannot have no ++ * extra or unsupported types. ++ */ ++ if (rss_act->types != 0 && !(map->rss_pctype & rss_act->types)) ++ continue; ++ ++ ret = hns3_flow_get_hw_pctype(hw, rss_act, map, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ } ++ ++ if (rss_conf->hw_pctypes != 0) ++ return 0; ++ ++ if (matched) ++ return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, +- &rss->types, +- "input RSS types are not supported"); ++ NULL, "RSS types are unsupported"); + +- act_index++; ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, "Pattern specified is unsupported"); ++} + +- /* Check if the next not void action is END */ +- NEXT_ITEM_OF_ACTION(act, actions, act_index); +- if (act->type != RTE_FLOW_ACTION_TYPE_END) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION, +- act, "Not supported action."); ++static uint64_t ++hns3_flow_get_all_hw_pctypes(uint64_t types) ++{ ++ uint64_t hw_pctypes = 0; ++ uint16_t i; + +- return 0; ++ for (i = 0; i < RTE_DIM(hash_map_table); i++) { ++ if (types & hash_map_table[i].rss_pctype) ++ hw_pctypes |= hash_map_table[i].hw_pctype; ++ } ++ ++ return hw_pctypes; + } + + static int +-hns3_disable_rss(struct hns3_hw *hw) ++hns3_flow_parse_rss_types(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss_act, ++ uint64_t pattern_type, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ rss_conf->conf.types = rss_act->types; ++ ++ /* no pattern specified to set global RSS types. */ ++ if (pattern_type == 0) { ++ if (rss_act->types & ~HNS3_ETH_RSS_SUPPORT) ++ hns3_warn(hw, "some types in the requested RSS types (0x%" PRIx64 ") aren't supported, they are ignored.", ++ rss_act->types); ++ rss_conf->hw_pctypes = ++ hns3_flow_get_all_hw_pctypes(rss_act->types); ++ return 0; ++ } ++ ++ return hns3_flow_parse_rss_types_by_ptype(hw, rss_act, pattern_type, ++ rss_conf, error); ++} ++ ++static int ++hns3_flow_parse_hash_global_conf(struct rte_eth_dev *dev, ++ const struct rte_flow_action_rss *rss_act, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) + { ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + +- ret = hns3_set_rss_tuple_by_rss_hf(hw, 0); +- if (ret) ++ ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error); ++ if (ret != 0) + return ret; +- hw->rss_info.rss_hf = 0; + +- return 0; ++ if (rss_act->queue_num > 0) { ++ ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ } ++ ++ if (rss_act->key_len > 0) { ++ ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ } ++ ++ return hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type, ++ rss_conf, error); + } + + static int +-hns3_parse_rss_algorithm(struct hns3_hw *hw, struct hns3_flow_rss_conf *rss_conf, +- uint8_t *hash_algo) +-{ +- const uint8_t hash_func_map[] = { +- [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ, +- [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ, +- [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE, +- [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP, +- }; +- uint8_t key[HNS3_RSS_KEY_SIZE_MAX] = {0}; +- int ret; ++hns3_flow_parse_pattern_type(const struct rte_flow_item pattern[], ++ uint64_t *ptype, struct rte_flow_error *error) ++{ ++ enum rte_flow_item_type pre_type = RTE_FLOW_ITEM_TYPE_VOID; ++ const char *message = "Pattern specified isn't supported"; ++ uint64_t item_hdr, pattern_hdrs = 0; ++ enum rte_flow_item_type cur_type; + +- if (rss_conf->conf.func == RTE_ETH_HASH_FUNCTION_DEFAULT) { +- ret = hns3_rss_get_algo_key(hw, hash_algo, key, +- hw->rss_key_size); +- if (ret != 0) { +- hns3_err(hw, "fail to get current RSS hash algorithm, ret = %d", +- ret); +- return ret; ++ for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { ++ if (pattern->type == RTE_FLOW_ITEM_TYPE_VOID) ++ continue; ++ if (pattern->mask || pattern->spec || pattern->last) { ++ message = "Header info shouldn't be specified"; ++ goto unsup; + } + +- /* +- * During the phase of reset recovery, the hash algorithm +- * obtained from hardware may not be the one used(saved in +- * rte_flow_hash_algo) when this rule is delivered. +- */ +- if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) && +- *hash_algo != rss_conf->hash_algo) +- *hash_algo = rss_conf->hash_algo; ++ /* Check the sub-item allowed by the previous item . */ ++ if (pre_type >= RTE_DIM(hash_pattern_next_allow_items) || ++ !(hash_pattern_next_allow_items[pre_type] & ++ BIT_ULL(pattern->type))) ++ goto unsup; ++ ++ cur_type = pattern->type; ++ /* Unsupported for current type being greater than array size. */ ++ if (cur_type >= RTE_DIM(hash_pattern_item_header)) ++ goto unsup; ++ ++ /* The value is zero, which means unsupported current header. */ ++ item_hdr = hash_pattern_item_header[cur_type]; ++ if (item_hdr == 0) ++ goto unsup; ++ ++ /* Have duplicate pattern header. */ ++ if (item_hdr & pattern_hdrs) ++ goto unsup; ++ pre_type = cur_type; ++ pattern_hdrs |= item_hdr; ++ } + ++ if (pattern_hdrs != 0) { ++ *ptype = pattern_hdrs; + return 0; + } + +- *hash_algo = hash_func_map[rss_conf->conf.func]; ++unsup: ++ return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, ++ pattern, message); ++} ++ ++static int ++hns3_flow_parse_pattern_act(struct rte_eth_dev *dev, ++ const struct rte_flow_item pattern[], ++ const struct rte_flow_action_rss *rss_act, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ ++ if (rss_act->key_len > 0) { ++ ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ } ++ ++ if (rss_act->queue_num > 0) { ++ ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error); ++ if (ret != 0) ++ return ret; ++ } ++ ++ ret = hns3_flow_parse_pattern_type(pattern, &rss_conf->pattern_type, ++ error); ++ if (ret != 0) ++ return ret; ++ ++ ret = hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type, ++ rss_conf, error); ++ if (ret != 0) ++ return ret; ++ ++ if (rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT || ++ rss_act->key_len > 0 || rss_act->queue_num > 0) ++ hns3_warn(hw, "hash func, key and queues are global config, which work for all flow types. " ++ "Recommend: don't set them together with pattern."); + + return 0; + } + ++static bool ++hns3_rss_action_is_dup(struct hns3_hw *hw, ++ const struct hns3_flow_rss_conf *conf) ++{ ++ struct hns3_rss_conf_ele *filter; ++ ++ TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { ++ if (conf->pattern_type != filter->filter_info.pattern_type) ++ continue; ++ ++ if (hns3_action_rss_same(&filter->filter_info.conf, &conf->conf)) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* ++ * This function is used to parse rss action validation. ++ */ + static int +-hns3_hw_rss_hash_set(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf) ++hns3_parse_rss_filter(struct rte_eth_dev *dev, ++ const struct rte_flow_item pattern[], ++ const struct rte_flow_action *actions, ++ struct hns3_flow_rss_conf *rss_conf, ++ struct rte_flow_error *error) + { +- struct rte_flow_action_rss *rss_config = &conf->conf; +- uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; +- bool use_default_key = false; +- uint64_t flow_types; +- uint8_t hash_algo; ++ struct hns3_adapter *hns = dev->data->dev_private; ++ const struct rte_flow_action_rss *rss_act; ++ const struct rte_flow_action *act; ++ const struct rte_flow_item *pat; ++ struct hns3_hw *hw = &hns->hw; ++ uint32_t index = 0; + int ret; + +- if (rss_config->key == NULL || rss_config->key_len != hw->rss_key_size) { +- hns3_warn(hw, "Default RSS hash key to be set"); +- memcpy(rss_key, hns3_hash_key, +- RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); +- use_default_key = true; ++ NEXT_ITEM_OF_ACTION(act, actions, index); ++ if (actions[1].type != RTE_FLOW_ACTION_TYPE_END) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ &actions[1], ++ "Only support one action for RSS."); ++ ++ rss_act = (const struct rte_flow_action_rss *)act->conf; ++ if (rss_act == NULL) { ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ act, "lost RSS action configuration"); + } + +- ret = hns3_parse_rss_algorithm(hw, conf, &hash_algo); +- if (ret) ++ if (rss_act->level != 0) ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ act, ++ "RSS level is not supported"); ++ ++ index = 0; ++ NEXT_ITEM_OF_PATTERN(pat, pattern, index); ++ if (pat[0].type == RTE_FLOW_ITEM_TYPE_END) { ++ rss_conf->pattern_type = 0; ++ ret = hns3_flow_parse_hash_global_conf(dev, rss_act, ++ rss_conf, error); ++ } else { ++ ret = hns3_flow_parse_pattern_act(dev, pat, rss_act, ++ rss_conf, error); ++ } ++ if (ret != 0) + return ret; + +- ret = hns3_rss_set_algo_key(hw, hash_algo, +- use_default_key ? rss_key : rss_config->key, +- hw->rss_key_size); +- if (ret) +- return ret; +- conf->hash_algo = hash_algo; +- +- /* Filter the unsupported flow types */ +- flow_types = rss_config->types ? +- rss_config->types & HNS3_ETH_RSS_SUPPORT : +- hw->rss_info.rss_hf; +- if (flow_types != rss_config->types) +- hns3_warn(hw, "modified RSS types based on hardware support," +- " requested:0x%" PRIx64 " configured:0x%" PRIx64, +- rss_config->types, flow_types); +- +- ret = hns3_set_rss_tuple_by_rss_hf(hw, flow_types); +- if (ret) +- hns3_err(hw, "Update RSS tuples by rss hf failed %d", ret); ++ if (hns3_rss_action_is_dup(hw, rss_conf)) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ act, "duplicate RSS rule"); + +- return ret; ++ return 0; + } + + static int +@@ -1543,44 +1886,106 @@ hns3_update_indir_table(struct hns3_hw *hw, + return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size); + } + ++static uint64_t ++hns3_flow_get_pctype_tuple_mask(uint64_t hw_pctype) ++{ ++ uint64_t tuple_mask = 0; ++ uint16_t i; ++ ++ for (i = 0; i < RTE_DIM(hash_map_table); i++) { ++ if (hw_pctype == hash_map_table[i].hw_pctype) { ++ tuple_mask = hash_map_table[i].tuple_mask; ++ break; ++ } ++ } ++ ++ return tuple_mask; ++} ++ + static int +-hns3_reset_rss_filter(struct hns3_hw *hw, +- const struct hns3_flow_rss_conf *conf) ++hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw, ++ struct hns3_flow_rss_conf *rss_conf) + { ++ uint64_t old_tuple_fields, new_tuple_fields; ++ uint64_t hw_pctypes, tuples, tuple_mask = 0; ++ bool cfg_global_tuple; + int ret; + +- if (!conf->valid) +- return 0; ++ cfg_global_tuple = (rss_conf->pattern_type == 0); ++ if (!cfg_global_tuple) { ++ /* ++ * To ensure that different packets do not affect each other, ++ * we have to first read all tuple fields, and then only modify ++ * the tuples for the specified packet type. ++ */ ++ ret = hns3_get_rss_tuple_field(hw, &old_tuple_fields); ++ if (ret != 0) ++ return ret; + +- ret = hns3_disable_rss(hw); +- if (ret) +- hns3_err(hw, "RSS disable failed(%d)", ret); ++ new_tuple_fields = old_tuple_fields; ++ hw_pctypes = rss_conf->hw_pctypes; ++ while (hw_pctypes > 0) { ++ uint32_t idx = rte_bsf64(hw_pctypes); ++ uint64_t pctype = BIT_ULL(idx); ++ ++ tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype); ++ tuples = hns3_rss_calc_tuple_filed(hw, ++ rss_conf->conf.types); ++ new_tuple_fields &= ~tuple_mask; ++ new_tuple_fields |= tuples; ++ hw_pctypes &= ~pctype; ++ } ++ } else { ++ new_tuple_fields = ++ hns3_rss_calc_tuple_filed(hw, rss_conf->conf.types); ++ } + +- return ret; ++ ret = hns3_set_rss_tuple_field(hw, new_tuple_fields); ++ if (ret != 0) ++ return ret; ++ ++ hns3_info(hw, "RSS tuple fields changed from 0x%" PRIx64 " to 0x%" PRIx64, ++ old_tuple_fields, new_tuple_fields); ++ ++ return 0; + } + + static int +-hns3_config_rss_filter(struct hns3_hw *hw, struct hns3_flow_rss_conf *conf) ++hns3_config_rss_filter(struct hns3_hw *hw, ++ struct hns3_flow_rss_conf *rss_conf) + { + struct rte_flow_action_rss *rss_act; +- uint16_t num; + int ret; + +- rss_act = &conf->conf; +- /* Set rx queues to use */ +- num = RTE_MIN(hw->data->nb_rx_queues, rss_act->queue_num); +- if (rss_act->queue_num > num) +- hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated", +- rss_act->queue_num); +- hns3_info(hw, "Max of contiguous %u PF queues are configured", num); +- if (num) { +- ret = hns3_update_indir_table(hw, rss_act, num); +- if (ret) ++ rss_act = &rss_conf->conf; ++ if (rss_act->queue_num > 0) { ++ ret = hns3_update_indir_table(hw, rss_act, rss_act->queue_num); ++ if (ret) { ++ hns3_err(hw, "set queues action failed, ret = %d", ret); ++ return ret; ++ } ++ } ++ ++ if (rss_act->key_len > 0 || ++ rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT) { ++ ret = hns3_update_rss_algo_key(hw, rss_act->func, rss_conf->key, ++ rss_act->key_len); ++ if (ret != 0) { ++ hns3_err(hw, "set func or hash key action failed, ret = %d", ++ ret); + return ret; ++ } ++ } ++ ++ if (rss_conf->hw_pctypes > 0) { ++ ret = hns3_flow_set_rss_ptype_tuple(hw, rss_conf); ++ if (ret != 0) { ++ hns3_err(hw, "set types action failed, ret = %d", ret); ++ return ret; ++ } + } + +- /* Set hash algorithm and flow types by the user's config */ +- return hns3_hw_rss_hash_set(hw, conf); ++ return 0; + } + + static int +@@ -1589,50 +1994,44 @@ hns3_clear_rss_filter(struct rte_eth_dev *dev) + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_rss_conf_ele *rss_filter_ptr; + struct hns3_hw *hw = &hns->hw; +- int rss_rule_succ_cnt = 0; /* count for success of clearing RSS rules */ +- int rss_rule_fail_cnt = 0; /* count for failure of clearing RSS rules */ +- int ret = 0; + + rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); + while (rss_filter_ptr) { + TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); +- ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info); +- if (ret) +- rss_rule_fail_cnt++; +- else +- rss_rule_succ_cnt++; + rte_free(rss_filter_ptr); + rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); + } + +- if (rss_rule_fail_cnt) { +- hns3_err(hw, "fail to delete all RSS filters, success num = %d fail num = %d", +- rss_rule_succ_cnt, rss_rule_fail_cnt); +- ret = -EIO; +- } +- +- return ret; ++ return hns3_config_rss(hns); + } + + static int +-hns3_restore_rss_filter(struct hns3_hw *hw) ++hns3_reconfig_all_rss_filter(struct hns3_hw *hw) + { + struct hns3_rss_conf_ele *filter; +- int ret = 0; ++ uint32_t rule_no = 0; ++ int ret; + +- pthread_mutex_lock(&hw->flows_lock); + TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { +- if (!filter->filter_info.valid) +- continue; +- + ret = hns3_config_rss_filter(hw, &filter->filter_info); + if (ret != 0) { +- hns3_err(hw, "restore RSS filter failed, ret=%d", ret); +- goto out; ++ hns3_err(hw, "config %uth RSS filter failed, ret = %d", ++ rule_no, ret); ++ return ret; + } ++ rule_no++; + } + +-out: ++ return 0; ++} ++ ++static int ++hns3_restore_rss_filter(struct hns3_hw *hw) ++{ ++ int ret; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ ret = hns3_reconfig_all_rss_filter(hw); + pthread_mutex_unlock(&hw->flows_lock); + + return ret; +@@ -1651,38 +2050,6 @@ hns3_restore_filter(struct hns3_adapter *hns) + return hns3_restore_rss_filter(hw); + } + +-static bool +-hns3_rss_action_is_dup(struct hns3_hw *hw, +- const struct rte_flow_action_rss *act) +-{ +- struct hns3_rss_conf_ele *filter; +- +- TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { +- if (!filter->filter_info.valid) +- continue; +- +- if (hns3_action_rss_same(&filter->filter_info.conf, act)) +- return true; +- } +- +- return false; +-} +- +-static int +-hns3_flow_parse_rss(struct rte_eth_dev *dev, +- struct hns3_flow_rss_conf *conf) +-{ +- struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; +- +- if (hns3_rss_action_is_dup(hw, &conf->conf)) { +- hns3_err(hw, "duplicate RSS configuration"); +- return -EINVAL; +- } +- +- return hns3_config_rss_filter(hw, conf); +-} +- + static int + hns3_flow_args_check(const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], +@@ -1716,32 +2083,55 @@ static int + hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], +- struct rte_flow_error *error) ++ struct rte_flow_error *error, ++ struct hns3_filter_info *filter_info) + { +- struct hns3_fdir_rule fdir_rule; ++ union hns3_filter_conf *conf; + int ret; + + ret = hns3_flow_args_check(attr, pattern, actions, error); + if (ret) + return ret; + +- if (hns3_find_rss_general_action(pattern, actions)) +- return hns3_parse_rss_filter(dev, actions, error); ++ hns3_parse_filter_type(pattern, actions, filter_info); ++ conf = &filter_info->conf; ++ if (filter_info->type == RTE_ETH_FILTER_HASH) ++ return hns3_parse_rss_filter(dev, pattern, actions, ++ &conf->rss_conf, error); + +- memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule)); +- return hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error); ++ return hns3_parse_fdir_filter(dev, pattern, actions, ++ &conf->fdir_conf, error); ++} ++ ++static int ++hns3_flow_rebuild_all_rss_filter(struct hns3_adapter *hns) ++{ ++ struct hns3_hw *hw = &hns->hw; ++ int ret; ++ ++ ret = hns3_config_rss(hns); ++ if (ret != 0) { ++ hns3_err(hw, "restore original RSS configuration failed, ret = %d.", ++ ret); ++ return ret; ++ } ++ ret = hns3_reconfig_all_rss_filter(hw); ++ if (ret != 0) ++ hns3_err(hw, "rebuild all RSS filter failed, ret = %d.", ret); ++ ++ return ret; + } + + static int + hns3_flow_create_rss_rule(struct rte_eth_dev *dev, +- const struct rte_flow_action *act, ++ struct hns3_flow_rss_conf *rss_conf, + struct rte_flow *flow) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- const struct rte_flow_action_rss *rss_act; ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_rss_conf_ele *rss_filter_ptr; + struct hns3_flow_rss_conf *new_conf; +- struct hns3_rss_conf_ele *filter_ptr; ++ struct rte_flow_action_rss *rss_act; + int ret; + + rss_filter_ptr = rte_zmalloc("hns3 rss filter", +@@ -1751,35 +2141,28 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + return -ENOMEM; + } + +- rss_act = (const struct rte_flow_action_rss *)act->conf; + new_conf = &rss_filter_ptr->filter_info; +- memcpy(&new_conf->conf, rss_act, sizeof(*rss_act)); +- if (rss_act->queue_num > 0) { +- memcpy(new_conf->queue, rss_act->queue, +- rss_act->queue_num * sizeof(new_conf->queue[0])); ++ memcpy(new_conf, rss_conf, sizeof(*new_conf)); ++ rss_act = &new_conf->conf; ++ if (rss_act->queue_num > 0) + new_conf->conf.queue = new_conf->queue; +- } +- if (rss_act->key_len > 0) { +- if (rss_act->key != NULL) { +- memcpy(new_conf->key, rss_act->key, +- rss_act->key_len * sizeof(new_conf->key[0])); +- new_conf->conf.key = new_conf->key; +- } +- } ++ /* ++ * There are two ways to deliver hash key action: ++ * 1> 'key_len' is greater than zero and 'key' isn't NULL. ++ * 2> 'key_len' is greater than zero, but 'key' is NULL. ++ * For case 2, we need to keep 'key' of the new_conf is NULL so as to ++ * inherit the configuration from user in case of failing to verify ++ * duplicate rule later. ++ */ ++ if (rss_act->key_len > 0 && rss_act->key != NULL) ++ new_conf->conf.key = new_conf->key; + +- ret = hns3_flow_parse_rss(dev, new_conf); ++ ret = hns3_config_rss_filter(hw, new_conf); + if (ret != 0) { + rte_free(rss_filter_ptr); ++ (void)hns3_flow_rebuild_all_rss_filter(hns); + return ret; + } +- rss_filter_ptr->filter_info.valid = true; +- +- /* +- * When create a new RSS rule, the old rule will be overlaid and set +- * invalid. +- */ +- TAILQ_FOREACH(filter_ptr, &hw->flow_rss_list, entries) +- filter_ptr->filter_info.valid = false; + + TAILQ_INSERT_TAIL(&hw->flow_rss_list, rss_filter_ptr, entries); + flow->rule = rss_filter_ptr; +@@ -1790,31 +2173,24 @@ hns3_flow_create_rss_rule(struct rte_eth_dev *dev, + + static int + hns3_flow_create_fdir_rule(struct rte_eth_dev *dev, +- const struct rte_flow_item pattern[], +- const struct rte_flow_action actions[], ++ struct hns3_fdir_rule *fdir_rule, + struct rte_flow_error *error, + struct rte_flow *flow) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_fdir_rule_ele *fdir_rule_ptr; +- struct hns3_fdir_rule fdir_rule; + bool indir; + int ret; + +- memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule)); +- ret = hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error); +- if (ret != 0) +- return ret; +- +- indir = !!(fdir_rule.flags & HNS3_RULE_FLAG_COUNTER_INDIR); +- if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) { +- ret = hns3_counter_new(dev, indir, fdir_rule.act_cnt.id, ++ indir = !!(fdir_rule->flags & HNS3_RULE_FLAG_COUNTER_INDIR); ++ if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) { ++ ret = hns3_counter_new(dev, indir, fdir_rule->act_cnt.id, + error); + if (ret != 0) + return ret; + +- flow->counter_id = fdir_rule.act_cnt.id; ++ flow->counter_id = fdir_rule->act_cnt.id; + } + + fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", +@@ -1830,11 +2206,11 @@ hns3_flow_create_fdir_rule(struct rte_eth_dev *dev, + * rules to the hardware to simplify the rollback of rules in the + * hardware. + */ +- ret = hns3_fdir_filter_program(hns, &fdir_rule, false); ++ ret = hns3_fdir_filter_program(hns, fdir_rule, false); + if (ret != 0) + goto err_fdir_filter; + +- memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule, ++ memcpy(&fdir_rule_ptr->fdir_conf, fdir_rule, + sizeof(struct hns3_fdir_rule)); + TAILQ_INSERT_TAIL(&hw->flow_fdir_list, fdir_rule_ptr, entries); + flow->rule = fdir_rule_ptr; +@@ -1845,8 +2221,8 @@ hns3_flow_create_fdir_rule(struct rte_eth_dev *dev, + err_fdir_filter: + rte_free(fdir_rule_ptr); + err_malloc: +- if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) +- hns3_counter_release(dev, fdir_rule.act_cnt.id); ++ if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) ++ hns3_counter_release(dev, fdir_rule->act_cnt.id); + + return ret; + } +@@ -1864,13 +2240,15 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + struct rte_flow_error *error) + { + struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; ++ struct hns3_filter_info filter_info = {0}; + struct hns3_flow_mem *flow_node; +- const struct rte_flow_action *act; ++ struct hns3_hw *hw = &hns->hw; ++ union hns3_filter_conf *conf; + struct rte_flow *flow; + int ret; + +- ret = hns3_flow_validate(dev, attr, pattern, actions, error); ++ ret = hns3_flow_validate(dev, attr, pattern, actions, error, ++ &filter_info); + if (ret) + return NULL; + +@@ -1890,13 +2268,12 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + } + + flow_node->flow = flow; ++ conf = &filter_info.conf; + TAILQ_INSERT_TAIL(&hw->flow_list, flow_node, entries); +- +- act = hns3_find_rss_general_action(pattern, actions); +- if (act) +- ret = hns3_flow_create_rss_rule(dev, act, flow); ++ if (filter_info.type == RTE_ETH_FILTER_HASH) ++ ret = hns3_flow_create_rss_rule(dev, &conf->rss_conf, flow); + else +- ret = hns3_flow_create_fdir_rule(dev, pattern, actions, ++ ret = hns3_flow_create_fdir_rule(dev, &conf->fdir_conf, + error, flow); + if (ret == 0) + return flow; +@@ -1950,15 +2327,10 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + break; + case RTE_ETH_FILTER_HASH: + rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule; +- ret = hns3_reset_rss_filter(hw, &rss_filter_ptr->filter_info); +- if (ret) +- return rte_flow_error_set(error, EIO, +- RTE_FLOW_ERROR_TYPE_HANDLE, +- flow, +- "Destroy RSS fail.Try again"); + TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); + rte_free(rss_filter_ptr); + rss_filter_ptr = NULL; ++ (void)hns3_flow_rebuild_all_rss_filter(hns); + break; + default: + return rte_flow_error_set(error, EINVAL, +@@ -2064,10 +2436,12 @@ hns3_flow_validate_wrap(struct rte_eth_dev *dev, + struct rte_flow_error *error) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_filter_info filter_info = {0}; + int ret; + + pthread_mutex_lock(&hw->flows_lock); +- ret = hns3_flow_validate(dev, attr, pattern, actions, error); ++ ret = hns3_flow_validate(dev, attr, pattern, actions, error, ++ &filter_info); + pthread_mutex_unlock(&hw->flows_lock); + + return ret; +diff --git a/drivers/net/hns3/hns3_flow.h b/drivers/net/hns3/hns3_flow.h +index 90126f2b6e..1b49673f11 100644 +--- a/drivers/net/hns3/hns3_flow.h ++++ b/drivers/net/hns3/hns3_flow.h +@@ -9,6 +9,7 @@ + #include + + #include "hns3_rss.h" ++#include "hns3_fdir.h" + + struct hns3_flow_counter { + LIST_ENTRY(hns3_flow_counter) next; /* Pointer to the next counter. */ +@@ -26,10 +27,10 @@ struct rte_flow { + + struct hns3_flow_rss_conf { + struct rte_flow_action_rss conf; +- uint8_t hash_algo; + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ + uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ +- bool valid; /* check if RSS rule is valid */ ++ uint64_t pattern_type; ++ uint64_t hw_pctypes; /* packet types in driver */ + }; + + /* rss filter list structure */ +@@ -53,6 +54,16 @@ struct rte_flow_action_handle { + uint32_t counter_id; + }; + ++union hns3_filter_conf { ++ struct hns3_fdir_rule fdir_conf; ++ struct hns3_flow_rss_conf rss_conf; ++}; ++ ++struct hns3_filter_info { ++ enum rte_filter_type type; ++ union hns3_filter_conf conf; ++}; ++ + TAILQ_HEAD(hns3_rss_filter_list, hns3_rss_conf_ele); + TAILQ_HEAD(hns3_flow_mem_list, hns3_flow_mem); + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index f51d70a8e5..dfa2901ae3 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -18,69 +18,13 @@ const uint8_t hns3_hash_key[HNS3_RSS_KEY_SIZE] = { + 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA + }; + +-enum hns3_tuple_field { +- /* IPV4_TCP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, +- HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, +- HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, +- HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, +- +- /* IPV4_UDP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, +- HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, +- HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, +- HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, +- +- /* IPV4_SCTP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, +- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, +- HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, +- HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, +- HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, +- +- /* IPV4 ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, +- HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, +- HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, +- HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, +- +- /* IPV6_TCP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, +- HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, +- HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, +- HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, +- +- /* IPV6_UDP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, +- HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, +- HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, +- HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, +- +- /* IPV6_SCTP ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48, +- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S, +- HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D, +- HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, +- HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, +- +- /* IPV6 ENABLE FIELD */ +- HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, +- HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, +- HNS3_RSS_FIELD_IPV6_FRAG_IP_D, +- HNS3_RSS_FIELD_IPV6_FRAG_IP_S ++const uint8_t hns3_hash_func_map[] = { ++ [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ, ++ [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ, ++ [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE, ++ [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP, + }; + +-#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0) +-#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8) +-#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16) +-#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24) +-#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26) +-#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32) +-#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40) +-#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48) +-#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56) +-#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58) +- + enum hns3_rss_tuple_type { + HNS3_RSS_IP_TUPLE, + HNS3_RSS_IP_L4_TUPLE, +@@ -574,7 +518,7 @@ hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf) + hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored."); + } + +-static uint64_t ++uint64_t + hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) + { + uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY | +@@ -610,25 +554,35 @@ hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) + } + + int +-hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) ++hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields) + { + struct hns3_rss_input_tuple_cmd *req; + struct hns3_cmd_desc desc; +- uint64_t tuple_field; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); + req = (struct hns3_rss_input_tuple_cmd *)desc.data; +- +- tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf); +- req->tuple_field = rte_cpu_to_le_64(tuple_field); ++ req->tuple_field = rte_cpu_to_le_64(tuple_fields); + ret = hns3_cmd_send(hw, &desc, 1); +- if (ret) { +- hns3_err(hw, "Update RSS flow types tuples failed %d", ret); +- return ret; +- } ++ if (ret != 0) ++ hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret); + +- return 0; ++ return ret; ++} ++ ++int ++hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) ++{ ++ uint64_t tuple_fields; ++ int ret; ++ ++ tuple_fields = hns3_rss_calc_tuple_filed(hw, rss_hf); ++ ret = hns3_set_rss_tuple_field(hw, tuple_fields); ++ if (ret != 0) ++ hns3_err(hw, "Update RSS flow types tuples failed, ret = %d", ++ ret); ++ ++ return ret; + } + + /* +@@ -1000,6 +954,52 @@ hns3_set_rss_tc_mode(struct hns3_hw *hw) + return ret; + } + ++/* ++ * Note: the 'hash_algo' is defined by enum rte_eth_hash_function. ++ */ ++int ++hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func, ++ uint8_t *key, uint8_t key_len) ++{ ++ uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; ++ bool modify_key, modify_algo; ++ uint8_t hash_algo; ++ int ret; ++ ++ modify_key = (key != NULL && key_len > 0); ++ modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT; ++ if (!modify_key && !modify_algo) ++ return 0; ++ ++ if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) { ++ hns3_err(hw, "hash func (%u) is unsupported.", hash_func); ++ return -ENOTSUP; ++ } ++ if (modify_key && key_len != hw->rss_key_size) { ++ hns3_err(hw, "hash key length (%u) is invalid.", key_len); ++ return -EINVAL; ++ } ++ ++ ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size); ++ if (ret != 0) { ++ hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ if (modify_algo) ++ hash_algo = hns3_hash_func_map[hash_func]; ++ if (modify_key) ++ memcpy(rss_key, key, key_len); ++ ++ ret = hns3_rss_set_algo_key(hw, hash_algo, rss_key, hw->rss_key_size); ++ if (ret != 0) ++ hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d", ++ ret); ++ ++ return ret; ++} ++ + static void + hns3_rss_tuple_uninit(struct hns3_hw *hw) + { +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index d19730c69c..d672481a14 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -8,23 +8,102 @@ + #include + #include + +-#define HNS3_ETH_RSS_SUPPORT ( \ +- RTE_ETH_RSS_IPV4 | \ +- RTE_ETH_RSS_FRAG_IPV4 | \ +- RTE_ETH_RSS_NONFRAG_IPV4_TCP | \ +- RTE_ETH_RSS_NONFRAG_IPV4_UDP | \ +- RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \ +- RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \ +- RTE_ETH_RSS_IPV6 | \ +- RTE_ETH_RSS_FRAG_IPV6 | \ +- RTE_ETH_RSS_NONFRAG_IPV6_TCP | \ +- RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ +- RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \ +- RTE_ETH_RSS_NONFRAG_IPV6_OTHER | \ +- RTE_ETH_RSS_L3_SRC_ONLY | \ +- RTE_ETH_RSS_L3_DST_ONLY | \ +- RTE_ETH_RSS_L4_SRC_ONLY | \ +- RTE_ETH_RSS_L4_DST_ONLY) ++#define HNS3_RSS_SUPPORT_L3_SRC_DST (RTE_ETH_RSS_L3_SRC_ONLY | \ ++ RTE_ETH_RSS_L3_DST_ONLY) ++#define HNS3_RSS_SUPPORT_L4_SRC_DST (RTE_ETH_RSS_L4_SRC_ONLY | \ ++ RTE_ETH_RSS_L4_DST_ONLY) ++#define HNS3_RSS_SUPPORT_L3L4 (HNS3_RSS_SUPPORT_L3_SRC_DST | \ ++ HNS3_RSS_SUPPORT_L4_SRC_DST) ++ ++#define HNS3_RSS_SUPPORT_FLOW_TYPE (RTE_ETH_RSS_IPV4 | \ ++ RTE_ETH_RSS_FRAG_IPV4 | \ ++ RTE_ETH_RSS_NONFRAG_IPV4_TCP | \ ++ RTE_ETH_RSS_NONFRAG_IPV4_UDP | \ ++ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \ ++ RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \ ++ RTE_ETH_RSS_IPV6 | \ ++ RTE_ETH_RSS_FRAG_IPV6 | \ ++ RTE_ETH_RSS_NONFRAG_IPV6_TCP | \ ++ RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ ++ RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \ ++ RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ++ ++#define HNS3_ETH_RSS_SUPPORT (HNS3_RSS_SUPPORT_FLOW_TYPE | \ ++ HNS3_RSS_SUPPORT_L3L4) ++ ++enum hns3_tuple_field { ++ /* IPV4_TCP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, ++ HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, ++ HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, ++ ++ /* IPV4_UDP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, ++ HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, ++ HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, ++ ++ /* IPV4_SCTP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, ++ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, ++ HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, ++ HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, ++ ++ /* IPV4 ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, ++ HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, ++ HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, ++ HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, ++ ++ /* IPV6_TCP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, ++ HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, ++ HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, ++ ++ /* IPV6_UDP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, ++ HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, ++ HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, ++ ++ /* IPV6_SCTP ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48, ++ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S, ++ HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D, ++ HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, ++ HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, ++ ++ /* IPV6 ENABLE FIELD */ ++ HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, ++ HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, ++ HNS3_RSS_FIELD_IPV6_FRAG_IP_D, ++ HNS3_RSS_FIELD_IPV6_FRAG_IP_S ++}; ++ ++#define HNS3_RSS_PCTYPE_IPV4_TCP BIT_ULL(0) ++#define HNS3_RSS_PCTYPE_IPV4_UDP BIT_ULL(8) ++#define HNS3_RSS_PCTYPE_IPV4_SCTP BIT_ULL(16) ++#define HNS3_RSS_PCTYPE_IPV4_NONF BIT_ULL(24) ++#define HNS3_RSS_PCTYPE_IPV4_FLAG BIT_ULL(26) ++#define HNS3_RSS_PCTYPE_IPV6_TCP BIT_ULL(32) ++#define HNS3_RSS_PCTYPE_IPV6_UDP BIT_ULL(40) ++#define HNS3_RSS_PCTYPE_IPV6_SCTP BIT_ULL(48) ++#define HNS3_RSS_PCTYPE_IPV6_NONF BIT_ULL(56) ++#define HNS3_RSS_PCTYPE_IPV6_FLAG BIT_ULL(58) ++ ++#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0) ++#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8) ++#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16) ++#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24) ++#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26) ++#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32) ++#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40) ++#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48) ++#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56) ++#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58) + + #define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */ + #define HNS3_RSS_IND_TBL_SIZE_MAX 2048 +@@ -108,10 +187,14 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw); + int hns3_config_rss(struct hns3_adapter *hns); + void hns3_rss_uninit(struct hns3_adapter *hns); + int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); ++int hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields); + int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields); + int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len); + int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, + uint8_t *key, uint8_t key_len); ++uint64_t hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf); ++int hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, ++ uint8_t *key, uint8_t key_len); + + #endif /* HNS3_RSS_H */ +-- +2.23.0 + diff --git a/0254-net-hns3-add-verification-of-RSS-types.patch b/0254-net-hns3-add-verification-of-RSS-types.patch new file mode 100644 index 0000000..302bf4a --- /dev/null +++ b/0254-net-hns3-add-verification-of-RSS-types.patch @@ -0,0 +1,199 @@ +From 190de70e4c72d4abb356c8f8a24fec9ec17ce6c1 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 10 Mar 2023 17:35:18 +0800 +Subject: net/hns3: add verification of RSS types + +[ upstream commit eb3ef9e0d7eb54b47ab58d3d14f9f5fff3f4120b ] + +Add the verification of RSS types from ethdev ops and rte flow without +pattern attribute. The following cases are invalid: +1. types contains unsupported RSS type but hasn't type driver support. +2. types has L3 src/dst but hasn't supported packet type. +3. types has L4 src/dst but hasn't supported packet type and hasn't IP + packet type. + +Fixes: 13c3993240c8 ("net/hns3: add L3 and L4 RSS types") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +--- + drivers/net/hns3/hns3_flow.c | 12 +++--- + drivers/net/hns3/hns3_rss.c | 74 +++++++++++++++++++++++++----------- + drivers/net/hns3/hns3_rss.h | 3 +- + 3 files changed, 60 insertions(+), 29 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index c38bd9dd8b..c1f4f5cb0b 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1652,9 +1652,10 @@ hns3_flow_parse_rss_types(struct hns3_hw *hw, + + /* no pattern specified to set global RSS types. */ + if (pattern_type == 0) { +- if (rss_act->types & ~HNS3_ETH_RSS_SUPPORT) +- hns3_warn(hw, "some types in the requested RSS types (0x%" PRIx64 ") aren't supported, they are ignored.", +- rss_act->types); ++ if (!hns3_check_rss_types_valid(hw, rss_act->types)) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, "RSS types is invalid."); + rss_conf->hw_pctypes = + hns3_flow_get_all_hw_pctypes(rss_act->types); + return 0; +@@ -1929,15 +1930,14 @@ hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw, + uint64_t pctype = BIT_ULL(idx); + + tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype); +- tuples = hns3_rss_calc_tuple_filed(hw, +- rss_conf->conf.types); ++ tuples = hns3_rss_calc_tuple_filed(rss_conf->conf.types); + new_tuple_fields &= ~tuple_mask; + new_tuple_fields |= tuples; + hw_pctypes &= ~pctype; + } + } else { + new_tuple_fields = +- hns3_rss_calc_tuple_filed(hw, rss_conf->conf.types); ++ hns3_rss_calc_tuple_filed(rss_conf->conf.types); + } + + ret = hns3_set_rss_tuple_field(hw, new_tuple_fields); +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index dfa2901ae3..6126512bd7 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -492,34 +492,62 @@ hns3_rss_reset_indir_table(struct hns3_hw *hw) + return ret; + } + +-static void +-hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf) ++bool ++hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types) + { + uint64_t ip_mask = RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | + RTE_ETH_RSS_NONFRAG_IPV4_OTHER | + RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | + RTE_ETH_RSS_NONFRAG_IPV6_OTHER; +- uint64_t l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP | +- RTE_ETH_RSS_NONFRAG_IPV4_UDP | +- RTE_ETH_RSS_NONFRAG_IPV4_SCTP | +- RTE_ETH_RSS_NONFRAG_IPV6_TCP | +- RTE_ETH_RSS_NONFRAG_IPV6_UDP | +- RTE_ETH_RSS_NONFRAG_IPV6_SCTP; +- uint64_t l3_src_dst_mask = RTE_ETH_RSS_L3_SRC_ONLY | +- RTE_ETH_RSS_L3_DST_ONLY; +- uint64_t l4_src_dst_mask = RTE_ETH_RSS_L4_SRC_ONLY | +- RTE_ETH_RSS_L4_DST_ONLY; +- +- if (rss_hf & l3_src_dst_mask && +- !(rss_hf & ip_mask || rss_hf & l4_mask)) +- hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored."); +- +- if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask)) +- hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored."); ++ uint64_t ip_l4_mask = RTE_ETH_RSS_NONFRAG_IPV4_TCP | ++ RTE_ETH_RSS_NONFRAG_IPV4_UDP | ++ RTE_ETH_RSS_NONFRAG_IPV4_SCTP | ++ RTE_ETH_RSS_NONFRAG_IPV6_TCP | ++ RTE_ETH_RSS_NONFRAG_IPV6_UDP | ++ RTE_ETH_RSS_NONFRAG_IPV6_SCTP; ++ bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST); ++ bool has_ip_pkt = !!(types & ip_mask); ++ uint64_t final_types; ++ ++ if (types == 0) ++ return true; ++ ++ if ((types & HNS3_ETH_RSS_SUPPORT) == 0) { ++ hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.", ++ types); ++ return false; ++ } ++ ++ if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 && ++ (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) { ++ hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set."); ++ return false; ++ } ++ ++ if (has_l4_src_dst && (types & ip_l4_mask) == 0) { ++ if (!has_ip_pkt) { ++ hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set."); ++ return false; ++ } ++ /* ++ * For the case that the types has L4_SRC/DST_ONLY but hasn't ++ * IP-TCP/UDP/SCTP packet type, this types is considered valid ++ * if it also has IP packet type. ++ */ ++ hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet."); ++ } ++ ++ if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) { ++ final_types = types & HNS3_ETH_RSS_SUPPORT; ++ hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "", ++ types, final_types); ++ } ++ ++ return true; + } + + uint64_t +-hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) ++hns3_rss_calc_tuple_filed(uint64_t rss_hf) + { + uint64_t l3_only_mask = RTE_ETH_RSS_L3_SRC_ONLY | + RTE_ETH_RSS_L3_DST_ONLY; +@@ -548,7 +576,6 @@ hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) + !has_l3_l4_only) + tuple |= hns3_set_tuple_table[i].rss_field; + } +- hns3_rss_check_l3l4_types(hw, rss_hf); + + return tuple; + } +@@ -576,7 +603,7 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) + uint64_t tuple_fields; + int ret; + +- tuple_fields = hns3_rss_calc_tuple_filed(hw, rss_hf); ++ tuple_fields = hns3_rss_calc_tuple_filed(rss_hf); + ret = hns3_set_rss_tuple_field(hw, tuple_fields); + if (ret != 0) + hns3_err(hw, "Update RSS flow types tuples failed, ret = %d", +@@ -611,6 +638,9 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + return -EINVAL; + } + ++ if (!hns3_check_rss_types_valid(hw, rss_hf)) ++ return -EINVAL; ++ + rte_spinlock_lock(&hw->lock); + ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); + if (ret) +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index d672481a14..415430a399 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -186,6 +186,7 @@ int hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, + int hns3_rss_reset_indir_table(struct hns3_hw *hw); + int hns3_config_rss(struct hns3_adapter *hns); + void hns3_rss_uninit(struct hns3_adapter *hns); ++bool hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types); + int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); + int hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields); + int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields); +@@ -193,7 +194,7 @@ int hns3_rss_set_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len); + int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, + uint8_t *key, uint8_t key_len); +-uint64_t hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf); ++uint64_t hns3_rss_calc_tuple_filed(uint64_t rss_hf); + int hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + uint8_t *key, uint8_t key_len); + +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index 45664e0..7463b57 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 34 +Release: 35 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -256,6 +256,22 @@ Patch9235: 0235-net-hns3-make-getting-Tx-function-static.patch Patch9236: 0236-net-hns3-extract-common-functions-to-set-Rx-Tx.patch Patch9237: 0237-net-hns3-declare-flow-rule-keeping-capability.patch Patch9238: 0238-app-testpmd-add-disable-flow-flush-option.patch +Patch9239: 0239-net-hns3-fix-possible-truncation-of-hash-key-when-co.patch +Patch9240: 0240-net-hns3-fix-possible-truncation-of-redirection-tabl.patch +Patch9241: 0241-net-hns3-use-hardware-config-to-report-hash-key.patch +Patch9242: 0242-net-hns3-use-hardware-config-to-report-hash-types.patch +Patch9243: 0243-net-hns3-use-hardware-config-to-report-redirection-t.patch +Patch9244: 0244-net-hns3-separate-setting-hash-algorithm.patch +Patch9245: 0245-net-hns3-separate-setting-hash-key.patch +Patch9246: 0246-net-hns3-separate-setting-redirection-table.patch +Patch9247: 0247-net-hns3-separate-setting-RSS-types.patch +Patch9248: 0248-net-hns3-separate-setting-and-clearing-RSS-rule.patch +Patch9249: 0249-net-hns3-use-new-RSS-rule-to-configure-hardware.patch +Patch9250: 0250-net-hns3-save-hash-algo-to-RSS-filter-list-node.patch +Patch9251: 0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch +Patch9252: 0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch +Patch9253: 0253-net-hns3-reimplement-hash-flow-function.patch +Patch9254: 0254-net-hns3-add-verification-of-RSS-types.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -398,6 +414,12 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Wed Mar 15 2023 chenjiji - 21.11-35 + Fix some RSS bugs and reimplement hash flow function for hns3: + - fix some RSS bugs and optimize RSS codes for hns3 + - reimplement hash flow function for hns3 to satisfy the + mainstream usage of rte flow hash in the community + * Fri Mar 03 2023 chenjiji - 21.11-34 Support flow rule keeping capability for hns3 PMD and testpmd. Patchs are as follow: -- Gitee From a3293931e3f2078b0b47736388bf60fa384fbdeb Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Thu, 23 Mar 2023 16:48:08 +0800 Subject: [PATCH 05/10] Fix a m_buf pool was not freed bug for test and support CPPC cpufreq for l3fwd-power. Patchs are as follow: - test/mbuf: fix mbuf reset test - examples/l3fwd-power: support CPPC cpufreq (cherry picked from commit cf6fe7cb51e23e99db070af56b4a75bc041b9751) --- 0255-test-mbuf-fix-mbuf-reset-test.patch | 35 ++++++++++++ ...les-l3fwd-power-support-CPPC-cpufreq.patch | 53 +++++++++++++++++++ dpdk.spec | 10 +++- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 0255-test-mbuf-fix-mbuf-reset-test.patch create mode 100644 0256-examples-l3fwd-power-support-CPPC-cpufreq.patch diff --git a/0255-test-mbuf-fix-mbuf-reset-test.patch b/0255-test-mbuf-fix-mbuf-reset-test.patch new file mode 100644 index 0000000..b66b2a3 --- /dev/null +++ b/0255-test-mbuf-fix-mbuf-reset-test.patch @@ -0,0 +1,35 @@ +From b6f800b2897f8e2008d0897ceaa491a357eab1cf Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 31 Jan 2023 10:48:51 +0800 +Subject: test/mbuf: fix mbuf reset test + +[ upstream commit bf47fb83a61a4bc6bf45e1ec6e3ddd239a856190 ] + +Retest "mbuf_autotest" will fail because the mbuf pool was +not freed after previous test successful done. +This patch fixes it. + +Fixes: efc6f9104c80 ("mbuf: fix reset on mbuf free") +Cc: stable@dpdk.org + +Signed-off-by: Jie Hai +Reviewed-by: David Marchand +--- + app/test/test_mbuf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c +index f54d1d7c00..cd9f8fd8cf 100644 +--- a/app/test/test_mbuf.c ++++ b/app/test/test_mbuf.c +@@ -2769,6 +2769,7 @@ test_nb_segs_and_next_reset(void) + m2->nb_segs != 1 || m2->next != NULL) + GOTO_FAIL("nb_segs or next was not reset properly"); + ++ rte_mempool_free(pool); + return 0; + + fail: +-- +2.23.0 + diff --git a/0256-examples-l3fwd-power-support-CPPC-cpufreq.patch b/0256-examples-l3fwd-power-support-CPPC-cpufreq.patch new file mode 100644 index 0000000..8100126 --- /dev/null +++ b/0256-examples-l3fwd-power-support-CPPC-cpufreq.patch @@ -0,0 +1,53 @@ +From 9f45602b8df4c7a0eca4228ab94de824b1c5337b Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 31 Jan 2023 10:58:52 +0800 +Subject: examples/l3fwd-power: support CPPC cpufreq + +[ upstream commit bc6fe48468767df2b6a31c9de06796164981cbaf ] + +Currently the l3fwd-power only supports ACPI cpufreq and Pstate +cpufreq, This patch adds CPPC cpufreq. + +Signed-off-by: Jie Hai +Acked-by: David Hunt +Acked-by: Dongdong Liu +--- + examples/l3fwd-power/main.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c +index 20e5b59af9..a2eb35d6e2 100644 +--- a/examples/l3fwd-power/main.c ++++ b/examples/l3fwd-power/main.c +@@ -2290,9 +2290,10 @@ init_power_library(void) + /* we're not supporting the VM channel mode */ + env = rte_power_get_env(); + if (env != PM_ENV_ACPI_CPUFREQ && +- env != PM_ENV_PSTATE_CPUFREQ) { ++ env != PM_ENV_PSTATE_CPUFREQ && ++ env != PM_ENV_CPPC_CPUFREQ) { + RTE_LOG(ERR, POWER, +- "Only ACPI and PSTATE mode are supported\n"); ++ "Only ACPI, PSTATE and CPPC mode are supported\n"); + return -1; + } + } +@@ -2456,12 +2457,14 @@ autodetect_mode(void) + /* + * Empty poll and telemetry modes have to be specifically requested to + * be enabled, but we can auto-detect between interrupt mode with or +- * without frequency scaling. Both ACPI and pstate can be used. ++ * without frequency scaling. Any of ACPI, pstate and CPPC can be used. + */ + if (rte_power_check_env_supported(PM_ENV_ACPI_CPUFREQ)) + return APP_MODE_LEGACY; + if (rte_power_check_env_supported(PM_ENV_PSTATE_CPUFREQ)) + return APP_MODE_LEGACY; ++ if (rte_power_check_env_supported(PM_ENV_CPPC_CPUFREQ)) ++ return APP_MODE_LEGACY; + + RTE_LOG(NOTICE, L3FWD_POWER, "Frequency scaling not supported, selecting interrupt-only mode\n"); + +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index 7463b57..09d7e5f 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 35 +Release: 36 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -272,6 +272,8 @@ Patch9251: 0251-net-hns3-allow-adding-queue-buffer-size-hash-rule.patch Patch9252: 0252-net-hns3-separate-flow-RSS-config-from-RSS-conf.patch Patch9253: 0253-net-hns3-reimplement-hash-flow-function.patch Patch9254: 0254-net-hns3-add-verification-of-RSS-types.patch +Patch9255: 0255-test-mbuf-fix-mbuf-reset-test.patch +Patch9256: 0256-examples-l3fwd-power-support-CPPC-cpufreq.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -414,6 +416,12 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Thu Mar 23 2023 chenjiji - 21.11-36 + Fix a m_buf pool was not freed bugs for test and support + CPPC cpufreq for l3fwd-power. Patchs are as follow: + - test/mbuf: fix mbuf reset test + - examples/l3fwd-power: support CPPC cpufreq + * Wed Mar 15 2023 chenjiji - 21.11-35 Fix some RSS bugs and reimplement hash flow function for hns3: - fix some RSS bugs and optimize RSS codes for hns3 -- Gitee From 7928c9da9e674eb25c0751dcf0180e3daf557c51 Mon Sep 17 00:00:00 2001 From: jiangheng12 Date: Sat, 1 Apr 2023 21:46:52 +0800 Subject: [PATCH 06/10] hinic: free tx mbuf use rte_pktmbuf_free_seg (cherry picked from commit 5ab3035fb19abaace494a7e0948c05ee043545e2) --- ...c-free-mbuf-use-rte_pktmbuf_free_seg.patch | 107 ++++++++++++++++++ dpdk.spec | 6 +- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch diff --git a/0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch b/0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch new file mode 100644 index 0000000..9a8d751 --- /dev/null +++ b/0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch @@ -0,0 +1,107 @@ +From b5c93dae2b73115c46f2e66dc87be61a200e006b Mon Sep 17 00:00:00 2001 +From: jiangheng12 +Date: Sat, 1 Apr 2023 21:56:20 +0800 +Subject: [PATCH] hinic: free tx mbuf use rte_pktmbuf_free_seg + +--- + drivers/net/hinic/hinic_pmd_tx.c | 27 ++++++++++++++++++--------- + drivers/net/hinic/hinic_pmd_tx.h | 9 +++++++++ + 2 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/hinic/hinic_pmd_tx.c b/drivers/net/hinic/hinic_pmd_tx.c +index f09b1a6..8eab94d 100644 +--- a/drivers/net/hinic/hinic_pmd_tx.c ++++ b/drivers/net/hinic/hinic_pmd_tx.c +@@ -30,13 +30,6 @@ + #define TX_MSS_DEFAULT 0x3E00 + #define TX_MSS_MIN 0x50 + +-#define HINIC_NONTSO_PKT_MAX_SGE 17 /* non-tso max sge 17 */ +-#define HINIC_NONTSO_SEG_NUM_INVALID(num) \ +- ((num) > HINIC_NONTSO_PKT_MAX_SGE) +- +-#define HINIC_TSO_PKT_MAX_SGE 127 /* tso max sge 127 */ +-#define HINIC_TSO_SEG_NUM_INVALID(num) ((num) > HINIC_TSO_PKT_MAX_SGE) +- + /* sizeof(struct hinic_sq_bufdesc) == 16, shift 4 */ + #define HINIC_BUF_DESC_SIZE(nr_descs) (SIZE_8BYTES(((u32)nr_descs) << 4)) + +@@ -640,6 +633,7 @@ static inline void hinic_xmit_mbuf_cleanup(struct hinic_txq *txq) + if (likely(mbuf->nb_segs == 1)) { + m = rte_pktmbuf_prefree_seg(mbuf); + tx_info->mbuf = NULL; ++ tx_info->nb_segs = 0; + + if (unlikely(m == NULL)) + continue; +@@ -653,8 +647,11 @@ static inline void hinic_xmit_mbuf_cleanup(struct hinic_txq *txq) + mbuf_free[nb_free++] = m; + } + } else { +- rte_pktmbuf_free(mbuf); ++ for (int j = 0; j < tx_info->nb_segs; j++) { ++ rte_pktmbuf_free_seg(tx_info->mbufs[j]); ++ } + tx_info->mbuf = NULL; ++ tx_info->nb_segs = 0; + } + } + +@@ -1191,6 +1188,13 @@ u16 hinic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, u16 nb_pkts) + tx_info->mbuf = mbuf_pkt; + tx_info->wqebb_cnt = wqe_wqebb_cnt; + ++ tx_info->nb_segs = mbuf_pkt->nb_segs; ++ struct rte_mbuf *tmp = mbuf_pkt; ++ for (int j = 0; j < mbuf_pkt->nb_segs; j++) { ++ tx_info->mbufs[j] = tmp; ++ tmp = tmp->next; ++ } ++ + /* 7. fill sq wqe header section */ + hinic_fill_sq_wqe_header(&sq_wqe->ctrl, queue_info, + sqe_info.sge_cnt, sqe_info.owner); +@@ -1231,7 +1235,12 @@ void hinic_free_all_tx_mbufs(struct hinic_txq *txq) + tx_info->cpy_mbuf = NULL; + } + +- rte_pktmbuf_free(tx_info->mbuf); ++ for (int j = 0; j < tx_info->nb_segs; j++) { ++ rte_pktmbuf_free_seg(tx_info->mbufs[j]); ++ tx_info->mbufs[j] = NULL; ++ } ++ tx_info->nb_segs = 0; ++ + hinic_update_sq_local_ci(nic_dev->hwdev, txq->q_id, + tx_info->wqebb_cnt); + +diff --git a/drivers/net/hinic/hinic_pmd_tx.h b/drivers/net/hinic/hinic_pmd_tx.h +index a3ec629..70159bd 100644 +--- a/drivers/net/hinic/hinic_pmd_tx.h ++++ b/drivers/net/hinic/hinic_pmd_tx.h +@@ -20,6 +20,13 @@ + RTE_MBUF_F_TX_OUTER_IP_CKSUM | \ + RTE_MBUF_F_TX_TCP_SEG) + ++#define HINIC_NONTSO_PKT_MAX_SGE 17 /* non-tso max sge 17 */ ++#define HINIC_NONTSO_SEG_NUM_INVALID(num) \ ++ ((num) > HINIC_NONTSO_PKT_MAX_SGE) ++ ++#define HINIC_TSO_PKT_MAX_SGE 127 /* tso max sge 127 */ ++#define HINIC_TSO_SEG_NUM_INVALID(num) ((num) > HINIC_TSO_PKT_MAX_SGE) ++ + enum sq_wqe_type { + SQ_NORMAL_WQE = 0, + }; +@@ -98,6 +105,8 @@ struct hinic_txq_stats { + + struct hinic_tx_info { + struct rte_mbuf *mbuf; ++ struct rte_mbuf *mbufs[HINIC_TSO_PKT_MAX_SGE]; ++ int nb_segs; + int wqebb_cnt; + struct rte_mbuf *cpy_mbuf; + }; +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index 09d7e5f..216fde1 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 36 +Release: 37 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -274,6 +274,7 @@ Patch9253: 0253-net-hns3-reimplement-hash-flow-function.patch Patch9254: 0254-net-hns3-add-verification-of-RSS-types.patch Patch9255: 0255-test-mbuf-fix-mbuf-reset-test.patch Patch9256: 0256-examples-l3fwd-power-support-CPPC-cpufreq.patch +Patch9257: 0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -416,6 +417,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Sat Apr 01 2023 jiangheng - 21.11-37 +- hinic: free tx mbuf use rte_pktmbuf_free_seg + * Thu Mar 23 2023 chenjiji - 21.11-36 Fix a m_buf pool was not freed bugs for test and support CPPC cpufreq for l3fwd-power. Patchs are as follow: -- Gitee From 4fe1853deb5916bab64354fbb6ea9b7b4ec382e1 Mon Sep 17 00:00:00 2001 From: jiangheng12 Date: Sat, 1 Apr 2023 22:11:39 +0800 Subject: [PATCH 07/10] build as shared libraries to reduce the size of debug packet (cherry picked from commit b8e46952e0405c1c02124d027cf55b67d3396794) --- dpdk.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dpdk.spec b/dpdk.spec index 216fde1..0415192 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 37 +Release: 38 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -324,7 +324,7 @@ This package contains the pdump tool for capture the dpdk network packets. %build export CFLAGS="%{optflags}" -meson build -Dplatform=generic -Dexamples=l3fwd-power,ethtool,l3fwd,kni,dma,ptpclient +meson build -Dplatform=generic -Dexamples=l3fwd-power,ethtool,l3fwd,kni,dma,ptpclient --default-library=shared ninja -C build -v #build gazelle-pdump/gazell-proc-info @@ -346,6 +346,8 @@ chrpath -d ./build/examples/dpdk-ethtool chrpath -d ./build/examples/dpdk-kni chrpath -d ./build/examples/dpdk-dma chrpath -d ./build/examples/dpdk-ptpclient +chrpath -d ./build/app/dpdk-pdump.p/gazelle-pdump +chrpath -d ./build/app/dpdk-proc-info.p/gazelle-proc-info cp ./build/examples/dpdk-l3fwd $RPM_BUILD_ROOT/usr/local/bin cp ./build/examples/dpdk-l3fwd-power $RPM_BUILD_ROOT/usr/local/bin @@ -417,6 +419,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Sat Apr 01 2023 jiangheng - 21.11-38 +- build as shared libraries to reduce the size of debug packet + * Sat Apr 01 2023 jiangheng - 21.11-37 - hinic: free tx mbuf use rte_pktmbuf_free_seg -- Gitee From ae24aed1e0c0c4d06b4fb97bf48324d1cc976109 Mon Sep 17 00:00:00 2001 From: chenjiji09 Date: Tue, 4 Apr 2023 10:19:35 +0800 Subject: [PATCH 08/10] add private dump for bonding, virtio and vhost Sync some patchs from upstreaming branch and modifies are as follow: 1. Add private dump for bonding, virtio and vhost. 2. Support LACP info dump for bonding. 3. Display RSS hash key of flow rule in testpmd. --- ...nding-support-private-dump-operation.patch | 150 ++++++++++++++ 0259-net-bonding-add-LACP-info-dump.patch | 187 ++++++++++++++++++ 0260-net-virtio-support-private-dump.patch | 56 ++++++ 0261-net-vhost-support-private-dump.patch | 55 ++++++ ...stpmd-show-private-info-in-port-info.patch | 37 ++++ ...md-display-RSS-hash-key-of-flow-rule.patch | 48 +++++ dpdk.spec | 15 +- 7 files changed, 547 insertions(+), 1 deletion(-) create mode 100644 0258-net-bonding-support-private-dump-operation.patch create mode 100644 0259-net-bonding-add-LACP-info-dump.patch create mode 100644 0260-net-virtio-support-private-dump.patch create mode 100644 0261-net-vhost-support-private-dump.patch create mode 100644 0262-app-testpmd-show-private-info-in-port-info.patch create mode 100644 0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch diff --git a/0258-net-bonding-support-private-dump-operation.patch b/0258-net-bonding-support-private-dump-operation.patch new file mode 100644 index 0000000..88867d1 --- /dev/null +++ b/0258-net-bonding-support-private-dump-operation.patch @@ -0,0 +1,150 @@ +From fdbebc668c5df36d34a64ba627b6e373263c1fca Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 14 Dec 2022 06:13:23 +0000 +Subject: net/bonding: support private dump operation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ upstream commit 29e89fb1e30cf12937dec8a3f4f7ab86f0303d24 ] + +This patch implements eth_dev_priv_dump ops which could enhance the +debug capability. + +The dump output is similar to testpmd command +"show bonding config [port]". + +Signed-off-by: Chengwen Feng +Acked-by:Min Hu (Connor) +Acked-by: Huisong Li +Acked-by: Ferruh Yigit +--- + drivers/net/bonding/rte_eth_bond_pmd.c | 105 ++++++++++++++++++++++++- + 1 file changed, 104 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c +index 29871cf8a3..cf7d275bf5 100644 +--- a/drivers/net/bonding/rte_eth_bond_pmd.c ++++ b/drivers/net/bonding/rte_eth_bond_pmd.c +@@ -3297,6 +3297,108 @@ bond_ethdev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) + rte_spinlock_unlock(&internals->lock); + } + ++static const char * ++bond_mode_name(uint8_t mode) ++{ ++ switch (mode) { ++ case BONDING_MODE_ROUND_ROBIN: ++ return "ROUND_ROBIN"; ++ case BONDING_MODE_ACTIVE_BACKUP: ++ return "ACTIVE_BACKUP"; ++ case BONDING_MODE_BALANCE: ++ return "BALANCE"; ++ case BONDING_MODE_BROADCAST: ++ return "BROADCAST"; ++ case BONDING_MODE_8023AD: ++ return "8023AD"; ++ case BONDING_MODE_TLB: ++ return "TLB"; ++ case BONDING_MODE_ALB: ++ return "ALB"; ++ default: ++ return "Unknown"; ++ } ++} ++ ++static int ++bond_ethdev_priv_dump(struct rte_eth_dev *dev, FILE *f) ++{ ++ struct bond_dev_private instant_priv; ++ const struct bond_dev_private *internals = &instant_priv; ++ int mode, i; ++ ++ /* Obtain a instance of dev_private to prevent data from being modified. */ ++ memcpy(&instant_priv, dev->data->dev_private, sizeof(struct bond_dev_private)); ++ mode = internals->mode; ++ ++ fprintf(f, " - Dev basic:\n"); ++ fprintf(f, "\tBonding mode: %s(%d)\n", bond_mode_name(mode), mode); ++ ++ if (mode == BONDING_MODE_BALANCE || mode == BONDING_MODE_8023AD) { ++ fprintf(f, "\tBalance Xmit Policy: "); ++ switch (internals->balance_xmit_policy) { ++ case BALANCE_XMIT_POLICY_LAYER2: ++ fprintf(f, "BALANCE_XMIT_POLICY_LAYER2"); ++ break; ++ case BALANCE_XMIT_POLICY_LAYER23: ++ fprintf(f, "BALANCE_XMIT_POLICY_LAYER23"); ++ break; ++ case BALANCE_XMIT_POLICY_LAYER34: ++ fprintf(f, "BALANCE_XMIT_POLICY_LAYER34"); ++ break; ++ default: ++ fprintf(f, "Unknown"); ++ } ++ fprintf(f, "\n"); ++ } ++ ++ if (mode == BONDING_MODE_8023AD) { ++ fprintf(f, "\tIEEE802.3AD Aggregator Mode: "); ++ switch (internals->mode4.agg_selection) { ++ case AGG_BANDWIDTH: ++ fprintf(f, "bandwidth"); ++ break; ++ case AGG_STABLE: ++ fprintf(f, "stable"); ++ break; ++ case AGG_COUNT: ++ fprintf(f, "count"); ++ break; ++ default: ++ fprintf(f, "unknown"); ++ } ++ fprintf(f, "\n"); ++ } ++ ++ if (internals->slave_count > 0) { ++ fprintf(f, "\tSlaves (%u): [", internals->slave_count); ++ for (i = 0; i < internals->slave_count - 1; i++) ++ fprintf(f, "%u ", internals->slaves[i].port_id); ++ ++ fprintf(f, "%u]\n", internals->slaves[internals->slave_count - 1].port_id); ++ } else { ++ fprintf(f, "\tSlaves: []\n"); ++ } ++ ++ if (internals->active_slave_count > 0) { ++ fprintf(f, "\tActive Slaves (%u): [", internals->active_slave_count); ++ for (i = 0; i < internals->active_slave_count - 1; i++) ++ fprintf(f, "%u ", internals->active_slaves[i]); ++ ++ fprintf(f, "%u]\n", internals->active_slaves[internals->active_slave_count - 1]); ++ ++ } else { ++ fprintf(f, "\tActive Slaves: []\n"); ++ } ++ ++ if (internals->user_defined_primary_port) ++ fprintf(f, "\tUser Defined Primary: [%u]\n", internals->primary_port); ++ if (internals->slave_count > 0) ++ fprintf(f, "\tCurrent Primary: [%u]\n", internals->current_primary_port); ++ ++ return 0; ++} ++ + const struct eth_dev_ops default_dev_ops = { + .dev_start = bond_ethdev_start, + .dev_stop = bond_ethdev_stop, +@@ -3323,7 +3425,8 @@ const struct eth_dev_ops default_dev_ops = { + .mac_addr_set = bond_ethdev_mac_address_set, + .mac_addr_add = bond_ethdev_mac_addr_add, + .mac_addr_remove = bond_ethdev_mac_addr_remove, +- .flow_ops_get = bond_flow_ops_get ++ .flow_ops_get = bond_flow_ops_get, ++ .eth_dev_priv_dump = bond_ethdev_priv_dump, + }; + + static int +-- +2.23.0 + diff --git a/0259-net-bonding-add-LACP-info-dump.patch b/0259-net-bonding-add-LACP-info-dump.patch new file mode 100644 index 0000000..6839d34 --- /dev/null +++ b/0259-net-bonding-add-LACP-info-dump.patch @@ -0,0 +1,187 @@ +From a74801e4c1d59a8e40317c8ea9e4ba3a5472d633 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 14 Dec 2022 06:13:24 +0000 +Subject: net/bonding: add LACP info dump +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ upstream commit b00119fc03dc585213236ea7f550662befa68fbe ] + +This patch adds dump lacp info in eth_dev_priv_dump ops. + +The extra dump output is similar to testpmd command +"show bonding lacp info [port]". + +Signed-off-by: Chengwen Feng +Acked-by:Min Hu (Connor) +Acked-by: Huisong Li +Acked-by: Ferruh Yigit +--- + drivers/net/bonding/rte_eth_bond_pmd.c | 143 ++++++++++++++++++++++++- + 1 file changed, 141 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c +index cf7d275bf5..0f2b21a568 100644 +--- a/drivers/net/bonding/rte_eth_bond_pmd.c ++++ b/drivers/net/bonding/rte_eth_bond_pmd.c +@@ -3320,8 +3320,8 @@ bond_mode_name(uint8_t mode) + } + } + +-static int +-bond_ethdev_priv_dump(struct rte_eth_dev *dev, FILE *f) ++static void ++dump_basic(const struct rte_eth_dev *dev, FILE *f) + { + struct bond_dev_private instant_priv; + const struct bond_dev_private *internals = &instant_priv; +@@ -3395,6 +3395,145 @@ bond_ethdev_priv_dump(struct rte_eth_dev *dev, FILE *f) + fprintf(f, "\tUser Defined Primary: [%u]\n", internals->primary_port); + if (internals->slave_count > 0) + fprintf(f, "\tCurrent Primary: [%u]\n", internals->current_primary_port); ++} ++ ++static void ++dump_lacp_conf(const struct rte_eth_bond_8023ad_conf *conf, FILE *f) ++{ ++ fprintf(f, "\tfast period: %u ms\n", conf->fast_periodic_ms); ++ fprintf(f, "\tslow period: %u ms\n", conf->slow_periodic_ms); ++ fprintf(f, "\tshort timeout: %u ms\n", conf->short_timeout_ms); ++ fprintf(f, "\tlong timeout: %u ms\n", conf->long_timeout_ms); ++ fprintf(f, "\taggregate wait timeout: %u ms\n", ++ conf->aggregate_wait_timeout_ms); ++ fprintf(f, "\ttx period: %u ms\n", conf->tx_period_ms); ++ fprintf(f, "\trx marker period: %u ms\n", conf->rx_marker_period_ms); ++ fprintf(f, "\tupdate timeout: %u ms\n", conf->update_timeout_ms); ++ switch (conf->agg_selection) { ++ case AGG_BANDWIDTH: ++ fprintf(f, "\taggregation mode: bandwidth\n"); ++ break; ++ case AGG_STABLE: ++ fprintf(f, "\taggregation mode: stable\n"); ++ break; ++ case AGG_COUNT: ++ fprintf(f, "\taggregation mode: count\n"); ++ break; ++ default: ++ fprintf(f, "\taggregation mode: invalid\n"); ++ break; ++ } ++ fprintf(f, "\n"); ++} ++ ++static void ++dump_lacp_port_param(const struct port_params *params, FILE *f) ++{ ++ char buf[RTE_ETHER_ADDR_FMT_SIZE]; ++ fprintf(f, "\t\tsystem priority: %u\n", params->system_priority); ++ rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, ¶ms->system); ++ fprintf(f, "\t\tsystem mac address: %s\n", buf); ++ fprintf(f, "\t\tport key: %u\n", params->key); ++ fprintf(f, "\t\tport priority: %u\n", params->port_priority); ++ fprintf(f, "\t\tport number: %u\n", params->port_number); ++} ++ ++static void ++dump_lacp_slave(const struct rte_eth_bond_8023ad_slave_info *info, FILE *f) ++{ ++ char a_state[256] = { 0 }; ++ char p_state[256] = { 0 }; ++ int a_len = 0; ++ int p_len = 0; ++ uint32_t i; ++ ++ static const char * const state[] = { ++ "ACTIVE", ++ "TIMEOUT", ++ "AGGREGATION", ++ "SYNCHRONIZATION", ++ "COLLECTING", ++ "DISTRIBUTING", ++ "DEFAULTED", ++ "EXPIRED" ++ }; ++ static const char * const selection[] = { ++ "UNSELECTED", ++ "STANDBY", ++ "SELECTED" ++ }; ++ ++ for (i = 0; i < RTE_DIM(state); i++) { ++ if ((info->actor_state >> i) & 1) ++ a_len += snprintf(&a_state[a_len], ++ RTE_DIM(a_state) - a_len, "%s ", ++ state[i]); ++ ++ if ((info->partner_state >> i) & 1) ++ p_len += snprintf(&p_state[p_len], ++ RTE_DIM(p_state) - p_len, "%s ", ++ state[i]); ++ } ++ fprintf(f, "\tAggregator port id: %u\n", info->agg_port_id); ++ fprintf(f, "\tselection: %s\n", selection[info->selected]); ++ fprintf(f, "\tActor detail info:\n"); ++ dump_lacp_port_param(&info->actor, f); ++ fprintf(f, "\t\tport state: %s\n", a_state); ++ fprintf(f, "\tPartner detail info:\n"); ++ dump_lacp_port_param(&info->partner, f); ++ fprintf(f, "\t\tport state: %s\n", p_state); ++ fprintf(f, "\n"); ++} ++ ++static void ++dump_lacp(uint16_t port_id, FILE *f) ++{ ++ struct rte_eth_bond_8023ad_slave_info slave_info; ++ struct rte_eth_bond_8023ad_conf port_conf; ++ uint16_t slaves[RTE_MAX_ETHPORTS]; ++ int num_active_slaves; ++ int i, ret; ++ ++ fprintf(f, " - Lacp info:\n"); ++ ++ num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves, ++ RTE_MAX_ETHPORTS); ++ if (num_active_slaves < 0) { ++ fprintf(f, "\tFailed to get active slave list for port %u\n", ++ port_id); ++ return; ++ } ++ ++ fprintf(f, "\tIEEE802.3 port: %u\n", port_id); ++ ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf); ++ if (ret) { ++ fprintf(f, "\tGet bonded device %u 8023ad config failed\n", ++ port_id); ++ return; ++ } ++ dump_lacp_conf(&port_conf, f); ++ ++ for (i = 0; i < num_active_slaves; i++) { ++ ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i], ++ &slave_info); ++ if (ret) { ++ fprintf(f, "\tGet slave device %u 8023ad info failed\n", ++ slaves[i]); ++ return; ++ } ++ fprintf(f, "\tSlave Port: %u\n", slaves[i]); ++ dump_lacp_slave(&slave_info, f); ++ } ++} ++ ++static int ++bond_ethdev_priv_dump(struct rte_eth_dev *dev, FILE *f) ++{ ++ const struct bond_dev_private *internals = dev->data->dev_private; ++ ++ dump_basic(dev, f); ++ if (internals->mode == BONDING_MODE_8023AD) ++ dump_lacp(dev->data->port_id, f); + + return 0; + } +-- +2.23.0 + diff --git a/0260-net-virtio-support-private-dump.patch b/0260-net-virtio-support-private-dump.patch new file mode 100644 index 0000000..f2f6550 --- /dev/null +++ b/0260-net-virtio-support-private-dump.patch @@ -0,0 +1,56 @@ +From a247b89fe26e5bae41159dfa59475c04ae53e8e2 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 19 Jan 2023 12:30:55 +0000 +Subject: net/virtio: support private dump + +[ upstream commit 426858d6a9975a26539f0398037558dcb418947a ] + +This patch implements eth_dev_priv_dump callback which could use for +debugging. + +Signed-off-by: Chengwen Feng +Reviewed-by: Maxime Coquelin +--- + drivers/net/virtio/virtio_ethdev.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c +index b317649d7e..a38b15d01c 100644 +--- a/drivers/net/virtio/virtio_ethdev.c ++++ b/drivers/net/virtio/virtio_ethdev.c +@@ -1018,6 +1018,24 @@ virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) + return 0; + } + ++static int ++virtio_dev_priv_dump(struct rte_eth_dev *dev, FILE *f) ++{ ++ struct virtio_hw *hw = dev->data->dev_private; ++ ++ fprintf(f, "guest_features: 0x%" PRIx64 "\n", hw->guest_features); ++ fprintf(f, "vtnet_hdr_size: %u\n", hw->vtnet_hdr_size); ++ fprintf(f, "use_vec: rx-%u tx-%u\n", hw->use_vec_rx, hw->use_vec_tx); ++ fprintf(f, "use_inorder: rx-%u tx-%u\n", hw->use_inorder_rx, hw->use_inorder_tx); ++ fprintf(f, "intr_lsc: %u\n", hw->intr_lsc); ++ fprintf(f, "max_mtu: %u\n", hw->max_mtu); ++ fprintf(f, "max_rx_pkt_len: %zu\n", hw->max_rx_pkt_len); ++ fprintf(f, "max_queue_pairs: %u\n", hw->max_queue_pairs); ++ fprintf(f, "req_guest_features: 0x%" PRIx64 "\n", hw->req_guest_features); ++ ++ return 0; ++} ++ + /* + * dev_ops for virtio, bare necessities for basic operation + */ +@@ -1054,6 +1072,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = { + .mac_addr_remove = virtio_mac_addr_remove, + .mac_addr_set = virtio_mac_addr_set, + .get_monitor_addr = virtio_get_monitor_addr, ++ .eth_dev_priv_dump = virtio_dev_priv_dump, + }; + + /* +-- +2.23.0 + diff --git a/0261-net-vhost-support-private-dump.patch b/0261-net-vhost-support-private-dump.patch new file mode 100644 index 0000000..ec38d71 --- /dev/null +++ b/0261-net-vhost-support-private-dump.patch @@ -0,0 +1,55 @@ +From 423959cfe25c9dc231b80f3df59318585df3a023 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 19 Jan 2023 12:30:56 +0000 +Subject: net/vhost: support private dump + +[ upstream commit 47b9fb64c15d60e1c8c2c8f6e63824fd2cada428 ] + +This patch implements eth_dev_priv_dump callback which could use for +debugging. + +Signed-off-by: Chengwen Feng +Reviewed-by: Maxime Coquelin +--- + drivers/net/vhost/rte_eth_vhost.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c +index 070f0e6dfd..b120341d0c 100644 +--- a/drivers/net/vhost/rte_eth_vhost.c ++++ b/drivers/net/vhost/rte_eth_vhost.c +@@ -1429,6 +1429,23 @@ vhost_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond *pmc) + return 0; + } + ++static int ++vhost_dev_priv_dump(struct rte_eth_dev *dev, FILE *f) ++{ ++ struct pmd_internal *internal = dev->data->dev_private; ++ ++ fprintf(f, "iface_name: %s\n", internal->iface_name); ++ fprintf(f, "flags: 0x%" PRIx64 "\n", internal->flags); ++ fprintf(f, "disable_flags: 0x%" PRIx64 "\n", internal->disable_flags); ++ fprintf(f, "max_queues: %u\n", internal->max_queues); ++ fprintf(f, "vid: %d\n", internal->vid); ++ fprintf(f, "started: %d\n", rte_atomic32_read(&internal->started)); ++ fprintf(f, "dev_attached: %d\n", rte_atomic32_read(&internal->dev_attached)); ++ fprintf(f, "vlan_strip: %d\n", internal->vlan_strip); ++ ++ return 0; ++} ++ + static const struct eth_dev_ops ops = { + .dev_start = eth_dev_start, + .dev_stop = eth_dev_stop, +@@ -1449,6 +1466,7 @@ static const struct eth_dev_ops ops = { + .rx_queue_intr_enable = eth_rxq_intr_enable, + .rx_queue_intr_disable = eth_rxq_intr_disable, + .get_monitor_addr = vhost_get_monitor_addr, ++ .eth_dev_priv_dump = vhost_dev_priv_dump, + }; + + static int +-- +2.23.0 + diff --git a/0262-app-testpmd-show-private-info-in-port-info.patch b/0262-app-testpmd-show-private-info-in-port-info.patch new file mode 100644 index 0000000..3ba2887 --- /dev/null +++ b/0262-app-testpmd-show-private-info-in-port-info.patch @@ -0,0 +1,37 @@ +From 9f1acbbbe8050c3b8794d45a4af610f9e0774211 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 16 Mar 2023 09:32:16 +0000 +Subject: app/testpmd: show private info in port info + +[ upstream commit d0aa6cd7a43d737797ba139a7f18b879cc44dac3 ] + +This patch adds dump private info in 'show port info [port_id]' cmd. + +Signed-off-by: Chengwen Feng +Acked-by: Aman Singh +Acked-by: Ferruh Yigit +--- + app/test-pmd/config.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index 12386c4d82..873d1f1357 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -891,6 +891,13 @@ port_infos_display(portid_t port_id) + printf("Switch Rx domain: %u\n", + dev_info.switch_info.rx_domain); + } ++ printf("Device private info:\n"); ++ ret = rte_eth_dev_priv_dump(port_id, stdout); ++ if (ret == -ENOTSUP) ++ printf(" none\n"); ++ else if (ret < 0) ++ fprintf(stderr, " Failed to dump private info with error (%d): %s\n", ++ ret, strerror(-ret)); + } + + void +-- +2.23.0 + diff --git a/0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch b/0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch new file mode 100644 index 0000000..3dd36b7 --- /dev/null +++ b/0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch @@ -0,0 +1,48 @@ +From 491333ae684b8303e019536900bb931b9f64b1ce Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 16 Mar 2023 20:58:14 +0800 +Subject: app/testpmd: display RSS hash key of flow rule + +[ upstream commit f958bbe2210dcc888032e81ec1326c0df5e5c518 ] + +There are two ways to set RSS hash key with rte flow rule: +1. 'key_len' isn't zero and 'key' is NULL. +2. 'key_len' isn't zero and 'key' isn't NULL. +This patch adds displaying for the hash key of rte flow rule. + +Signed-off-by: Huisong Li +Signed-off-by: Dongdong Liu +Acked-by: Ferruh Yigit +--- + app/test-pmd/config.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index 873d1f1357..78af232a8a 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -1651,6 +1651,21 @@ rss_config_display(struct rte_flow_action_rss *rss_conf) + return; + } + ++ printf(" RSS key:\n"); ++ if (rss_conf->key_len == 0) { ++ printf(" none"); ++ } else { ++ printf(" key_len: %u\n", rss_conf->key_len); ++ printf(" key: "); ++ if (rss_conf->key == NULL) { ++ printf("none"); ++ } else { ++ for (i = 0; i < rss_conf->key_len; i++) ++ printf("%02X", rss_conf->key[i]); ++ } ++ } ++ printf("\n"); ++ + printf(" types:\n"); + if (rss_conf->types == 0) { + printf(" none\n"); +-- +2.23.0 + diff --git a/dpdk.spec b/dpdk.spec index 0415192..7c03abd 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 38 +Release: 39 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -275,6 +275,12 @@ Patch9254: 0254-net-hns3-add-verification-of-RSS-types.patch Patch9255: 0255-test-mbuf-fix-mbuf-reset-test.patch Patch9256: 0256-examples-l3fwd-power-support-CPPC-cpufreq.patch Patch9257: 0257-hinic-free-mbuf-use-rte_pktmbuf_free_seg.patch +Patch9258: 0258-net-bonding-support-private-dump-operation.patch +Patch9259: 0259-net-bonding-add-LACP-info-dump.patch +Patch9260: 0260-net-virtio-support-private-dump.patch +Patch9261: 0261-net-vhost-support-private-dump.patch +Patch9262: 0262-app-testpmd-show-private-info-in-port-info.patch +Patch9263: 0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -419,6 +425,13 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Tue Apr 04 2023 chenjiji - 21.11-39 + Sync some patchs from upstreaming branch and modifies + are as follow: + 1. Add private dump for bonding, virtio and vhost. + 2. Support LACP info dump for bonding. + 3. Display RSS hash key of flow rule in testpmd. + * Sat Apr 01 2023 jiangheng - 21.11-38 - build as shared libraries to reduce the size of debug packet -- Gitee From de1dccbac6844d23037ec63f4fa9b69bf3e0b2f9 Mon Sep 17 00:00:00 2001 From: yuelg Date: Tue, 11 Apr 2023 17:07:52 +0800 Subject: [PATCH 09/10] Create a softlink to dpdk default driver path Signed-off-by: yuelg --- dpdk.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dpdk.spec b/dpdk.spec index 7c03abd..f1363e0 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 39 +Release: 40 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -377,6 +377,8 @@ cd - cd $RPM_BUILD_ROOT/usr/lib64/dpdk/pmds-22.0/lib ln -fs ../../../*.so . cd - +mkdir -p $RPM_BUILD_ROOT/usr/local/lib64/dpdk +ln -fs /usr/lib64/dpdk/pmds-22.0 $RPM_BUILD_ROOT/usr/local/lib64/dpdk/pmds-22.0 strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/rte_kni.ko strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko @@ -390,6 +392,7 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /lib/modules/%{kern_devel_ver}/extra/dpdk/*.ko /usr/lib64/*.so* /usr/lib64/dpdk/* +/usr/local/lib64/dpdk/* %exclude /usr/lib64/dpdk/pmds-22.0/include/*.h %files devel @@ -425,6 +428,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Tue Apr 11 2023 bigclouds99 - 21.11-40 +- Create a softlink to dpdk default driver path + * Tue Apr 04 2023 chenjiji - 21.11-39 Sync some patchs from upstreaming branch and modifies are as follow: -- Gitee From 743c5a960b218ce59c2c572b0f3e616a28c3140b Mon Sep 17 00:00:00 2001 From: jammyjellyfish Date: Fri, 21 Apr 2023 21:48:00 +0800 Subject: [PATCH 10/10] Fix clang build error --- 0264-fix-clang-cflags.patch | 92 +++++++++++++++++++++++++++++++++++++ dpdk.spec | 6 ++- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 0264-fix-clang-cflags.patch diff --git a/0264-fix-clang-cflags.patch b/0264-fix-clang-cflags.patch new file mode 100644 index 0000000..bfb2c03 --- /dev/null +++ b/0264-fix-clang-cflags.patch @@ -0,0 +1,92 @@ +diff -up dpdk-21.11/app/meson.build.orig2 dpdk-21.11/app/meson.build +--- dpdk-21.11/app/meson.build.orig2 2023-04-21 18:37:25.851994629 +0800 ++++ dpdk-21.11/app/meson.build 2023-04-21 21:25:13.631388908 +0800 +@@ -21,9 +21,12 @@ apps = [ + ] + + default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] +-default_cflags += ['-fPIE', '-pie', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] +-default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] +-default_ldflags = [] ++if meson.get_compiler('c').get_id() == 'clang' ++ default_ldflags = ['-pie', '-Wl,-z,relro,-z,now,-z,noexecstack'] ++else ++ default_cflags += ['-fPIE', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] ++ default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++endif + if get_option('default_library') == 'static' and not is_windows + default_ldflags += ['-Wl,--export-dynamic'] + endif +diff -up dpdk-21.11/buildtools/chkincs/meson.build.orig2 dpdk-21.11/buildtools/chkincs/meson.build +--- dpdk-21.11/buildtools/chkincs/meson.build.orig2 2023-04-21 18:38:05.196444066 +0800 ++++ dpdk-21.11/buildtools/chkincs/meson.build 2023-04-21 21:25:14.095512696 +0800 +@@ -13,9 +13,12 @@ gen_c_files = generator(gen_c_file_for_h + + cflags = machine_args + cflags += '-DALLOW_EXPERIMENTAL_API' +-cflags += ['-fPIE', '-pie', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] +-cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] +- ++if meson.get_compiler('c').get_id() == 'clang' ++ ldflags = ['-pie', '-Wl,-z,relro,-z,now,-z,noexecstack'] ++else ++ cflags += ['-fPIE', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] ++ cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++endif + sources = files('main.c') + sources += gen_c_files.process(dpdk_chkinc_headers) + +diff -up dpdk-21.11/drivers/meson.build.orig2 dpdk-21.11/drivers/meson.build +--- dpdk-21.11/drivers/meson.build.orig2 2023-04-21 18:37:25.855994675 +0800 ++++ dpdk-21.11/drivers/meson.build 2023-04-21 21:25:14.495619407 +0800 +@@ -45,8 +45,12 @@ enable_drivers += always_enable + default_cflags = machine_args + default_cflags += ['-DALLOW_EXPERIMENTAL_API'] + default_cflags += ['-DALLOW_INTERNAL_API'] +-default_cflags += ['-fPIE', '-pie', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] +-default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++if meson.get_compiler('c').get_id() == 'clang' ++ default_ldflags = ['-pie', '-Wl,-z,relro,-z,now,-z,noexecstack'] ++else ++ default_cflags += ['-fPIE', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] ++ default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++endif + + if cc.has_argument('-Wno-format-truncation') + default_cflags += '-Wno-format-truncation' +diff -up dpdk-21.11/examples/meson.build.orig2 dpdk-21.11/examples/meson.build +--- dpdk-21.11/examples/meson.build.orig2 2023-04-21 18:37:25.859994720 +0800 ++++ dpdk-21.11/examples/meson.build 2023-04-21 21:25:14.911730388 +0800 +@@ -90,8 +90,12 @@ default_ldflags = dpdk_extra_ldflags + if get_option('default_library') == 'static' and not is_windows + default_ldflags += ['-Wl,--export-dynamic'] + endif +-default_cflags += ['-fPIE', '-pie', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] +-default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++if meson.get_compiler('c').get_id() == 'clang' ++ default_ldflags = ['-pie', '-Wl,-z,relro,-z,now,-z,noexecstack'] ++else ++ default_cflags += ['-fPIE', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] ++ default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++endif + + foreach example: examples + name = example.split('/')[-1] +diff -up dpdk-21.11/lib/meson.build.orig2 dpdk-21.11/lib/meson.build +--- dpdk-21.11/lib/meson.build.orig2 2023-04-21 18:37:25.863994766 +0800 ++++ dpdk-21.11/lib/meson.build 2023-04-21 21:25:15.543898993 +0800 +@@ -94,8 +94,12 @@ endforeach + default_cflags = machine_args + default_cflags += ['-DALLOW_EXPERIMENTAL_API'] + default_cflags += ['-DALLOW_INTERNAL_API'] +-default_cflags += ['-fPIE', '-pie', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] +-default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++if meson.get_compiler('c').get_id() == 'clang' ++ default_ldflags = ['-pie', '-Wl,-z,relro,-z,now,-z,noexecstack'] ++else ++ default_cflags += ['-fPIE', '-fPIC', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', '-O2', '-Wall', '-Werror'] ++ default_cflags += ['-Wl,-z,relro,-z,now,-z,noexecstack', '-Wtrampolines'] ++endif + + if cc.has_argument('-Wno-format-truncation') + default_cflags += '-Wno-format-truncation' diff --git a/dpdk.spec b/dpdk.spec index f1363e0..0c7a5b3 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 40 +Release: 41 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -281,6 +281,7 @@ Patch9260: 0260-net-virtio-support-private-dump.patch Patch9261: 0261-net-vhost-support-private-dump.patch Patch9262: 0262-app-testpmd-show-private-info-in-port-info.patch Patch9263: 0263-app-testpmd-display-RSS-hash-key-of-flow-rule.patch +Patch9264: 0264-fix-clang-cflags.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -428,6 +429,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Fri Apr 21 2023 jammyjellyfish - 21.11-41 +- fix clang build error + * Tue Apr 11 2023 bigclouds99 - 21.11-40 - Create a softlink to dpdk default driver path -- Gitee