net: hns3: Fix for setting rss_size incorrectly

rss_size is 1, 2, 4, 8, 16, 32, 64, 128, but acutal tc queue
size can be any u16 less than 128. If tc queue size is 5, we
set the rss_size to 8, indirection table will be used to limit
the size of actual queue size.
It may cause dropping of receiving packet in hardware if
rss_size is not set correctly.
For now, each TC has the same rss size.

Fixes: 46a3df9f97 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yunsheng Lin 2017-09-20 18:52:57 +08:00 committed by David S. Miller
parent c4726338d9
commit 68ece54efd
3 changed files with 40 additions and 42 deletions

View File

@ -2606,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
u16 tc_valid[HCLGE_MAX_TC_NUM];
u16 tc_size[HCLGE_MAX_TC_NUM];
u32 *rss_indir = NULL;
u16 rss_size = 0, roundup_size;
const u8 *key;
int i, ret, j;
@ -2620,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
vport[j].rss_indirection_tbl[i] =
i % hdev->rss_size_max;
i % vport[j].alloc_rss_size;
/* vport 0 is for PF */
if (j != 0)
continue;
rss_size = vport[j].alloc_rss_size;
rss_indir[i] = vport[j].rss_indirection_tbl[i];
}
}
@ -2637,42 +2644,31 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
if (ret)
goto err;
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
if (hdev->hw_tc_map & BIT(i))
tc_valid[i] = 1;
else
tc_valid[i] = 0;
switch (hdev->rss_size_max) {
case HCLGE_RSS_TC_SIZE_0:
tc_size[i] = 0;
break;
case HCLGE_RSS_TC_SIZE_1:
tc_size[i] = 1;
break;
case HCLGE_RSS_TC_SIZE_2:
tc_size[i] = 2;
break;
case HCLGE_RSS_TC_SIZE_3:
tc_size[i] = 3;
break;
case HCLGE_RSS_TC_SIZE_4:
tc_size[i] = 4;
break;
case HCLGE_RSS_TC_SIZE_5:
tc_size[i] = 5;
break;
case HCLGE_RSS_TC_SIZE_6:
tc_size[i] = 6;
break;
case HCLGE_RSS_TC_SIZE_7:
tc_size[i] = 7;
break;
default:
break;
}
tc_offset[i] = hdev->rss_size_max * i;
/* Each TC have the same queue size, and tc_size set to hardware is
* the log2 of roundup power of two of rss_size, the acutal queue
* size is limited by indirection table.
*/
if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
dev_err(&hdev->pdev->dev,
"Configure rss tc size failed, invalid TC_SIZE = %d\n",
rss_size);
return -EINVAL;
}
roundup_size = roundup_pow_of_two(rss_size);
roundup_size = ilog2(roundup_size);
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
tc_valid[i] = 0;
if (!(hdev->hw_tc_map & BIT(i)))
continue;
tc_valid[i] = 1;
tc_size[i] = roundup_size;
tc_offset[i] = rss_size * i;
}
ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
err:
@ -4167,12 +4163,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
ret = hclge_rss_init_hw(hdev);
if (ret) {
dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
return ret;
}
ret = hclge_init_vlan_config(hdev);
if (ret) {
dev_err(&pdev->dev, "VLAN init fail, ret =%d\n", ret);
@ -4185,6 +4175,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
ret = hclge_rss_init_hw(hdev);
if (ret) {
dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
return ret;
}
setup_timer(&hdev->service_timer, hclge_service_timer,
(unsigned long)hdev);
INIT_WORK(&hdev->service_task, hclge_service_task);

View File

@ -477,6 +477,7 @@ struct hclge_vport {
u8 rss_hash_key[HCLGE_RSS_KEY_SIZE]; /* User configured hash keys */
/* User configured lookup table entries */
u8 rss_indirection_tbl[HCLGE_RSS_IND_TBL_SIZE];
u16 alloc_rss_size;
u16 qs_offset;
u16 bw_limit; /* VSI BW Limit (0 = disabled) */

View File

@ -397,6 +397,7 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
kinfo->num_tqps / kinfo->num_tc);
vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id;
vport->dwrr = 100; /* 100 percent as init */
vport->alloc_rss_size = kinfo->rss_size;
for (i = 0; i < kinfo->num_tc; i++) {
if (hdev->hw_tc_map & BIT(i)) {