dpdk/0073-net-hns3-support-flow-rule-priority.patch
Dengdui Huang e782454207 sync some patchs from upstreaming
Sync some patchs from upstreaming, includind some bugfixes, hns3 pmd
flow rule priority feature, hns3 pmd outer VLAN flow match feature,
and support dump reigser names and filter.
This patch set is modified as follows:
- net/hns3: fix cannot fully use hardware flow director table
- net/hns3: fix error code for repeatedly create counter
- net/hns3: support flow rule priority
- common/nfp: use new kvargs process API
- net/tap: use new kvargs process API
- net/sfc: use new kvargs process API
- kvargs: rework process API
- net/hns3: fix variable type
- net/hns3: fix pointer offset
- net/hns3: fix error log
- net/hns3: support filtering registers by module names
- net/hns3: support reporting names of registers
- net/hns3: refactor register dump
- net/hns3: remove separators between register module
- net/hns3: fix dump counter of registers
- net/hns3: remove some basic address dump
- telemetry: register command with private argument
- ethdev: fix race on ports in telemetry endpoints
- ethdev: add telemetry command for registers
- ethdev: add report of register names and filter
- net/hns3: support outer VLAN flow match
- net/hns3: register VLAN flow match mode parameter
- net/hns3: support general tunnel flow match
- net/hns3: restrict tunnel flow rule to one header
- net/hns3: remove ROH devices
- net/hns3: dump queue head and tail pointer info
- dmadev: fix potential null pointer access
- net/hns3: verify reset type from firmware
- ethdev: verify queue ID in Tx done cleanup

Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
(cherry picked from commit a1c828e1eb9cf716187d2a7656023e95bdce9b55)
2024-11-22 10:06:08 +08:00

381 lines
13 KiB
Diff

From a93a030ea0c817a229ce92df315a3cd72dcee6d5 Mon Sep 17 00:00:00 2001
From: Dengdui Huang <huangdengdui@huawei.com>
Date: Wed, 30 Oct 2024 17:29:19 +0800
Subject: [PATCH] net/hns3: support flow rule priority
[ upstream commit ac72aae60f71b8716f65d1e2daf531a5ca38c998 ]
The hardware determines the priority of the flow rule based on the position
of the rule in the hardware flow director table. Lower index denotes higher
priority (it means when a packet matches multiple indexes, the smaller
index wins). This patch implements flow priority based on this feature.
To avoid affecting the current use, use runtime config 'fdir_index_config'
to select flow director index strategy. The options are as follows:
1. hash: Default config, the rule priority level cannot be set.
The driver generates a flow index based on the hash of the rte_flow key.
2. priority: The flow rule priority feature is supported.
The driver uses the rte_flow priority field as the flow director index.
Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
Signed-off-by: Jie Hai <haijie1@huawei.com>
---
doc/guides/nics/hns3.rst | 12 +++++++
drivers/net/hns3/hns3_common.c | 25 ++++++++++++++
drivers/net/hns3/hns3_common.h | 1 +
drivers/net/hns3/hns3_dump.c | 2 ++
drivers/net/hns3/hns3_ethdev.c | 3 +-
drivers/net/hns3/hns3_fdir.c | 62 ++++++++++++++++++++++++----------
drivers/net/hns3/hns3_fdir.h | 10 ++++++
drivers/net/hns3/hns3_flow.c | 45 +++++++++++++++++++++---
8 files changed, 136 insertions(+), 24 deletions(-)
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index bdc10da..b8e79c1 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -193,6 +193,15 @@ Runtime Configuration
``+outvlan-sctptag``: means disable sctp tag tuple, and enable outer vlan tuple.
``+outvlan-tunvni``: means disable tunnel vni tuple, and enable outer vlan tuple.
+- ``fdir_index_config`` (default ``hash``)
+
+ Used to select flow director index strategy, the flow director index is the index
+ position in the hardware flow director table. Lower index denotes higher priority
+ (it means when a packet matches multiple indexes, the smaller index wins).
+ Current supported options are as follows:
+ ``hash``: The driver generates a flow index based on the hash of the rte_flow key.
+ ``priority``: the driver uses the rte_flow priority field as the flow director index.
+
Driver compilation and testing
------------------------------
@@ -322,6 +331,9 @@ Generic flow API
configuration for hardware which will affect other rules.
The rule just setting input tuple is completely independent.
+ In addition, if the rule priority level is set, no error is reported,
+ but the rule priority level does not take effect.
+
Run ``testpmd``:
.. code-block:: console
diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c
index 99a1d59..25a4521 100644
--- a/drivers/net/hns3/hns3_common.c
+++ b/drivers/net/hns3/hns3_common.c
@@ -290,6 +290,27 @@ hns3_parse_fdir_tuple_config(const char *key, const char *value, void *args)
return 0;
}
+static int
+hns3_parse_fdir_index_config(const char *key, const char *value, void *args)
+{
+ enum hns3_fdir_index_config cfg;
+
+ if (strcmp(value, "hash") == 0) {
+ cfg = HNS3_FDIR_INDEX_CONFIG_HASH;
+ } else if (strcmp(value, "priority") == 0) {
+ cfg = HNS3_FDIR_INDEX_CONFIG_PRIORITY;
+ } else {
+ PMD_INIT_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+ "value must be 'hash' or 'priority'",
+ value, key);
+ return -1;
+ }
+
+ *(enum hns3_fdir_index_config *)args = cfg;
+
+ return 0;
+}
+
void
hns3_parse_devargs(struct rte_eth_dev *dev)
{
@@ -333,6 +354,10 @@ hns3_parse_devargs(struct rte_eth_dev *dev)
HNS3_DEVARG_FDIR_TUPLE_CONFIG,
&hns3_parse_fdir_tuple_config,
&hns->pf.fdir.tuple_cfg);
+ (void)rte_kvargs_process(kvlist,
+ HNS3_DEVARG_FDIR_INDEX_CONFIG,
+ &hns3_parse_fdir_index_config,
+ &hns->pf.fdir.index_cfg);
}
rte_kvargs_free(kvlist);
diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h
index ca90936..7b3f96b 100644
--- a/drivers/net/hns3/hns3_common.h
+++ b/drivers/net/hns3/hns3_common.h
@@ -29,6 +29,7 @@ enum {
#define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode"
#define HNS3_DEVARG_FDIR_TUPLE_CONFIG "fdir_tuple_config"
+#define HNS3_DEVARG_FDIR_INDEX_CONFIG "fdir_index_config"
#define MSEC_PER_SEC 1000L
#define USEC_PER_MSEC 1000L
diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c
index fbe3716..dcdfcf4 100644
--- a/drivers/net/hns3/hns3_dump.c
+++ b/drivers/net/hns3/hns3_dump.c
@@ -169,6 +169,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
"\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
"\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
"\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
+ "\t -- index_cfg: %s\n"
"\t -- tuple_config: %s\n"
"\t -- active_tuples:\n",
fdcfg->fd_mode, fdcfg->max_key_length,
@@ -181,6 +182,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en,
+ hns3_fdir_index_config_name(pf->fdir.index_cfg),
hns3_tuple_config_name(pf->fdir.tuple_cfg));
for (i = 0; i < MAX_TUPLE; i++) {
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 30b7aaa..12bb834 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -6672,7 +6672,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3,
HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict "
HNS3_DEVARG_FDIR_TUPLE_CONFIG "=+outvlan-insmac|+outvlan-indmac|"
"+outvlan-insip|+outvlan-indip"
- "+outvlan-sctptag|+outvlan-tunvni ");
+ "+outvlan-sctptag|+outvlan-tunvni "
+ HNS3_DEVARG_FDIR_INDEX_CONFIG "=hash|priority ");
RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE);
RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE);
#ifdef RTE_ETHDEV_DEBUG_RX
diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c
index 389dec2..1e9932b 100644
--- a/drivers/net/hns3/hns3_fdir.c
+++ b/drivers/net/hns3/hns3_fdir.c
@@ -981,39 +981,44 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw,
{
struct hns3_fdir_key_conf *key;
hash_sig_t sig;
- int ret;
+ int index;
key = &fdir_filter->fdir_conf.key_conf;
sig = rte_hash_crc(key, sizeof(*key), 0);
- ret = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig);
- if (ret < 0) {
- hns3_err(hw, "Hash table full? err:%d!", ret);
- return ret;
+ index = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig);
+ if (index < 0) {
+ hns3_err(hw, "Hash table full? err:%d!", index);
+ return index;
}
- fdir_info->hash_map[ret] = fdir_filter;
+ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY)
+ index = fdir_filter->fdir_conf.location;
+
+ fdir_info->hash_map[index] = fdir_filter;
TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries);
- return ret;
+ return index;
}
static int hns3_remove_fdir_filter(struct hns3_hw *hw,
struct hns3_fdir_info *fdir_info,
- struct hns3_fdir_key_conf *key)
+ struct hns3_fdir_rule *rule)
{
struct hns3_fdir_rule_ele *fdir_filter;
hash_sig_t sig;
- int ret;
+ int index;
- sig = rte_hash_crc(key, sizeof(*key), 0);
- ret = rte_hash_del_key_with_hash(fdir_info->hash_handle, key, sig);
- if (ret < 0) {
- hns3_err(hw, "Delete hash key fail ret=%d", ret);
- return ret;
+ sig = rte_hash_crc(&rule->key_conf, sizeof(rule->key_conf), 0);
+ index = rte_hash_del_key_with_hash(fdir_info->hash_handle, &rule->key_conf, sig);
+ if (index < 0) {
+ hns3_err(hw, "Delete hash key fail ret=%d", index);
+ return index;
}
- fdir_filter = fdir_info->hash_map[ret];
- fdir_info->hash_map[ret] = NULL;
+ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY)
+ index = rule->location;
+ fdir_filter = fdir_info->hash_map[index];
+ fdir_info->hash_map[index] = NULL;
TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries);
rte_free(fdir_filter);
@@ -1042,7 +1047,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns,
rule->key_conf.spec.src_port,
rule->key_conf.spec.dst_port, ret);
else
- ret = hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf);
+ ret = hns3_remove_fdir_filter(hw, fdir_info, rule);
return ret;
}
@@ -1080,7 +1085,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns,
rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID],
rule->key_conf.spec.src_port,
rule->key_conf.spec.dst_port, ret);
- (void)hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf);
+ (void)hns3_remove_fdir_filter(hw, fdir_info, rule);
}
return ret;
@@ -1231,3 +1236,24 @@ hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg)
return "unknown";
}
+
+static struct {
+ enum hns3_fdir_index_config cfg;
+ const char *name;
+} index_cfg_map[] = {
+ { HNS3_FDIR_INDEX_CONFIG_HASH, "hash"},
+ { HNS3_FDIR_INDEX_CONFIG_PRIORITY, "priority"},
+};
+
+const char *
+hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg)
+{
+ uint32_t i;
+
+ for (i = 0; i < RTE_DIM(index_cfg_map); i++) {
+ if (cfg == index_cfg_map[i].cfg)
+ return index_cfg_map[i].name;
+ }
+
+ return "unknown";
+}
diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h
index 2d0c9bf..5ba7b5b 100644
--- a/drivers/net/hns3/hns3_fdir.h
+++ b/drivers/net/hns3/hns3_fdir.h
@@ -228,6 +228,14 @@ enum hns3_fdir_tuple_config {
HNS3_FDIR_TUPLE_CONFIG_BUTT
};
+enum hns3_fdir_index_config {
+ /* Generate the hardware flow director index based on rte_hash (Default) */
+ HNS3_FDIR_INDEX_CONFIG_HASH,
+
+ /* Use the rte_flow priority field as the hardware flow director index. */
+ HNS3_FDIR_INDEX_CONFIG_PRIORITY
+};
+
/*
* A structure used to define fields of a FDIR related info.
*/
@@ -238,6 +246,7 @@ struct hns3_fdir_info {
struct hns3_fd_cfg fd_cfg;
uint8_t vlan_match_mode;
enum hns3_fdir_tuple_config tuple_cfg;
+ enum hns3_fdir_index_config index_cfg;
};
struct hns3_adapter;
@@ -254,5 +263,6 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns);
enum hns3_fdir_tuple_config hns3_parse_tuple_config(const char *name);
const char *hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg);
+const char *hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg);
#endif /* HNS3_FDIR_H */
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 4674f74..40e2409 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -597,10 +597,6 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error)
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
attr, "No support for transfer");
- if (attr->priority)
- return rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
- attr, "Not support priority");
if (attr->group)
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
@@ -1441,6 +1437,40 @@ is_tunnel_packet(enum rte_flow_item_type type)
return false;
}
+static int
+hns3_handle_attributes(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ struct hns3_fdir_rule *rule,
+ struct rte_flow_error *error)
+{
+ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct hns3_fdir_info fdir = pf->fdir;
+ uint32_t rule_num;
+
+ if (fdir.index_cfg != HNS3_FDIR_INDEX_CONFIG_PRIORITY) {
+ if (attr->priority == 0)
+ return 0;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Not support priority");
+ }
+
+ rule_num = fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1];
+ if (attr->priority >= rule_num)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Priority out of range");
+
+ if (fdir.hash_map[attr->priority] != NULL)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Priority already exists");
+
+ rule->location = attr->priority;
+
+ return 0;
+}
+
/*
* Parse the flow director rule.
* The supported PATTERN:
@@ -1468,6 +1498,7 @@ is_tunnel_packet(enum rte_flow_item_type type)
*/
static int
hns3_parse_fdir_filter(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
struct hns3_fdir_rule *rule,
@@ -1484,6 +1515,10 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
"Fdir not supported in VF");
+ ret = hns3_handle_attributes(dev, attr, rule, error);
+ if (ret)
+ return ret;
+
step_mngr.items = first_items;
step_mngr.count = RTE_DIM(first_items);
for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
@@ -2248,7 +2283,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
return hns3_parse_rss_filter(dev, pattern, actions,
&conf->rss_conf, error);
- return hns3_parse_fdir_filter(dev, pattern, actions,
+ return hns3_parse_fdir_filter(dev, attr, pattern, actions,
&conf->fdir_conf, error);
}
--
2.33.0