Skip to content

Commit 68ece54

Browse files
Yunsheng Lindavem330
authored andcommitted
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: 46a3df9 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Yunsheng Lin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c472633 commit 68ece54

File tree

3 files changed

+38
-40
lines changed

3 files changed

+38
-40
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
26062606
u16 tc_valid[HCLGE_MAX_TC_NUM];
26072607
u16 tc_size[HCLGE_MAX_TC_NUM];
26082608
u32 *rss_indir = NULL;
2609+
u16 rss_size = 0, roundup_size;
26092610
const u8 *key;
26102611
int i, ret, j;
26112612

@@ -2620,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
26202621
for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
26212622
for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
26222623
vport[j].rss_indirection_tbl[i] =
2623-
i % hdev->rss_size_max;
2624+
i % vport[j].alloc_rss_size;
2625+
2626+
/* vport 0 is for PF */
2627+
if (j != 0)
2628+
continue;
2629+
2630+
rss_size = vport[j].alloc_rss_size;
26242631
rss_indir[i] = vport[j].rss_indirection_tbl[i];
26252632
}
26262633
}
@@ -2637,42 +2644,31 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
26372644
if (ret)
26382645
goto err;
26392646

2647+
/* Each TC have the same queue size, and tc_size set to hardware is
2648+
* the log2 of roundup power of two of rss_size, the acutal queue
2649+
* size is limited by indirection table.
2650+
*/
2651+
if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
2652+
dev_err(&hdev->pdev->dev,
2653+
"Configure rss tc size failed, invalid TC_SIZE = %d\n",
2654+
rss_size);
2655+
return -EINVAL;
2656+
}
2657+
2658+
roundup_size = roundup_pow_of_two(rss_size);
2659+
roundup_size = ilog2(roundup_size);
2660+
26402661
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
2641-
if (hdev->hw_tc_map & BIT(i))
2642-
tc_valid[i] = 1;
2643-
else
2644-
tc_valid[i] = 0;
2662+
tc_valid[i] = 0;
26452663

2646-
switch (hdev->rss_size_max) {
2647-
case HCLGE_RSS_TC_SIZE_0:
2648-
tc_size[i] = 0;
2649-
break;
2650-
case HCLGE_RSS_TC_SIZE_1:
2651-
tc_size[i] = 1;
2652-
break;
2653-
case HCLGE_RSS_TC_SIZE_2:
2654-
tc_size[i] = 2;
2655-
break;
2656-
case HCLGE_RSS_TC_SIZE_3:
2657-
tc_size[i] = 3;
2658-
break;
2659-
case HCLGE_RSS_TC_SIZE_4:
2660-
tc_size[i] = 4;
2661-
break;
2662-
case HCLGE_RSS_TC_SIZE_5:
2663-
tc_size[i] = 5;
2664-
break;
2665-
case HCLGE_RSS_TC_SIZE_6:
2666-
tc_size[i] = 6;
2667-
break;
2668-
case HCLGE_RSS_TC_SIZE_7:
2669-
tc_size[i] = 7;
2670-
break;
2671-
default:
2672-
break;
2673-
}
2674-
tc_offset[i] = hdev->rss_size_max * i;
2664+
if (!(hdev->hw_tc_map & BIT(i)))
2665+
continue;
2666+
2667+
tc_valid[i] = 1;
2668+
tc_size[i] = roundup_size;
2669+
tc_offset[i] = rss_size * i;
26752670
}
2671+
26762672
ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
26772673

26782674
err:
@@ -4167,12 +4163,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
41674163
return ret;
41684164
}
41694165

4170-
ret = hclge_rss_init_hw(hdev);
4171-
if (ret) {
4172-
dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
4173-
return ret;
4174-
}
4175-
41764166
ret = hclge_init_vlan_config(hdev);
41774167
if (ret) {
41784168
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)
41854175
return ret;
41864176
}
41874177

4178+
ret = hclge_rss_init_hw(hdev);
4179+
if (ret) {
4180+
dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
4181+
return ret;
4182+
}
4183+
41884184
setup_timer(&hdev->service_timer, hclge_service_timer,
41894185
(unsigned long)hdev);
41904186
INIT_WORK(&hdev->service_task, hclge_service_task);

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ struct hclge_vport {
477477
u8 rss_hash_key[HCLGE_RSS_KEY_SIZE]; /* User configured hash keys */
478478
/* User configured lookup table entries */
479479
u8 rss_indirection_tbl[HCLGE_RSS_IND_TBL_SIZE];
480+
u16 alloc_rss_size;
480481

481482
u16 qs_offset;
482483
u16 bw_limit; /* VSI BW Limit (0 = disabled) */

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
397397
kinfo->num_tqps / kinfo->num_tc);
398398
vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id;
399399
vport->dwrr = 100; /* 100 percent as init */
400+
vport->alloc_rss_size = kinfo->rss_size;
400401

401402
for (i = 0; i < kinfo->num_tc; i++) {
402403
if (hdev->hw_tc_map & BIT(i)) {

0 commit comments

Comments
 (0)