net/hns3: fix RSS max queue id allowed in multi-TC
authorHuisong Li <lihuisong@huawei.com>
Thu, 29 Oct 2020 12:51:51 +0000 (20:51 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 22:35:06 +0000 (23:35 +0100)
Currently, driver uses the maximum number of queues configured by user
as the maximum queue id that can be specified by the RSS rule or the
reta_update api. It is unreasonable and may trigger an incorrect
behavior in the multi-TC scenario. The driver must ensure that the queue
id configured in the redirection table must be within the range of the
number of queues allocated to a TC.

Fixes: c37ca66f2b27 ("net/hns3: support RSS")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
drivers/net/hns3/hns3_flow.c
drivers/net/hns3/hns3_rss.c

index 73f5e8e..0d5dd1a 100644 (file)
@@ -1367,13 +1367,18 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
                                          act, "no valid queues");
        }
 
+       if (rss->queue_num > RTE_DIM(rss_conf->queue))
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
+                                         "queue number configured exceeds "
+                                         "queue buffer size driver supported");
+
        for (n = 0; n < rss->queue_num; n++) {
-               if (rss->queue[n] < dev->data->nb_rx_queues)
+               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 > max number of queues");
+                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
+                                         "queue id must be less than queue number allocated to a TC");
        }
 
        if (!(rss->types & HNS3_ETH_RSS_SUPPORT) && rss->types)
@@ -1394,10 +1399,6 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
                return rte_flow_error_set(error, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
                                          "RSS hash key must be exactly 40 bytes");
-       if (rss->queue_num > RTE_DIM(rss_conf->queue))
-               return rte_flow_error_set(error, ENOTSUP,
-                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF, act,
-                                         "too many queues for RSS context");
 
        /*
         * For Kunpeng920 and Kunpeng930 NIC hardware, it is not supported to
@@ -1450,9 +1451,8 @@ hns3_disable_rss(struct hns3_hw *hw)
 static void
 hns3_parse_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_info(hw, "Default RSS hash key to be set");
+       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;
        }
@@ -1493,10 +1493,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
        struct hns3_rss_tuple_cfg *tuple;
        int ret;
 
-       /* Parse hash key */
        hns3_parse_rss_key(hw, rss_config);
 
-       /* Parse hash algorithm */
        ret = hns3_parse_rss_algorithm(hw, &rss_config->func,
                                       &hw->rss_info.hash_algo);
        if (ret)
@@ -1525,20 +1523,18 @@ hns3_update_indir_table(struct rte_eth_dev *dev,
        struct hns3_adapter *hns = dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
        uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE];
-       uint16_t j, allow_rss_queues;
+       uint16_t j;
        uint32_t i;
 
-       allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max);
        /* 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 < HNS3_RSS_IND_TBL_SIZE; i++, j++) {
                j %= num;
-               if (conf->queue[j] >= allow_rss_queues) {
-                       hns3_err(hw, "Invalid queue id(%u) to be set in "
-                                    "redirection table, max number of rss "
-                                    "queues: %u", conf->queue[j],
-                                allow_rss_queues);
+               if (conf->queue[j] >= hw->alloc_rss_size) {
+                       hns3_err(hw, "queue id(%u) set to redirection table "
+                                "exceeds queue number(%u) allocated to a TC.",
+                                conf->queue[j], hw->alloc_rss_size);
                        return -EINVAL;
                }
                indir_tbl[i] = conf->queue[j];
@@ -1607,11 +1603,8 @@ hns3_config_rss_filter(struct rte_eth_dev *dev,
                return 0;
        }
 
-       /* Get rx queues num */
-       num = dev->data->nb_rx_queues;
-
        /* Set rx queues to use */
-       num = RTE_MIN(num, rss_flow_conf.queue_num);
+       num = RTE_MIN(dev->data->nb_rx_queues, rss_flow_conf.queue_num);
        if (rss_flow_conf.queue_num > num)
                hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated",
                          rss_flow_conf.queue_num);
@@ -1648,7 +1641,6 @@ rss_config_err:
        return ret;
 }
 
-/* Remove the rss filter */
 static int
 hns3_clear_rss_filter(struct rte_eth_dev *dev)
 {
@@ -1684,7 +1676,6 @@ hns3_clear_rss_filter(struct rte_eth_dev *dev)
        return ret;
 }
 
-/* Restore the rss filter */
 int
 hns3_restore_rss_filter(struct rte_eth_dev *dev)
 {
@@ -1706,7 +1697,6 @@ hns3_flow_parse_rss(struct rte_eth_dev *dev,
        struct hns3_hw *hw = &hns->hw;
        bool ret;
 
-       /* Action rss same */
        ret = hns3_action_rss_same(&hw->rss_info.conf, &conf->conf);
        if (ret) {
                hns3_err(hw, "Enter duplicate RSS configuration : %d", ret);
@@ -1864,6 +1854,7 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        ret = -ENOMEM;
                        goto err_fdir;
                }
+
                memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule,
                        sizeof(struct hns3_fdir_rule));
                TAILQ_INSERT_TAIL(&process_list->fdir_list,
index 2efd410..a4e552b 100644 (file)
@@ -510,7 +510,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
        struct hns3_rss_conf *rss_cfg = &hw->rss_info;
        uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */
        uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE];
-       uint16_t idx, shift, allow_rss_queues;
+       uint16_t idx, shift;
        int ret;
 
        if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) {
@@ -522,16 +522,15 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev,
        rte_spinlock_lock(&hw->lock);
        memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl,
               sizeof(rss_cfg->rss_indirection_tbl));
-       allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max);
        for (i = 0; i < reta_size; i++) {
                idx = i / RTE_RETA_GROUP_SIZE;
                shift = i % RTE_RETA_GROUP_SIZE;
-               if (reta_conf[idx].reta[shift] >= allow_rss_queues) {
+               if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) {
                        rte_spinlock_unlock(&hw->lock);
-                       hns3_err(hw, "Invalid queue id(%u) to be set in "
-                                "redirection table, max number of rss "
-                                "queues: %u", reta_conf[idx].reta[shift],
-                                allow_rss_queues);
+                       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;
                }