Skip to content

Commit 8673a6c

Browse files
wenglianfarleon
authored andcommitted
RDMA/hns: Fix mapping error of zero-hop WQE buffer
Due to HW limitation, the three region of WQE buffer must be mapped and set to HW in a fixed order: SQ buffer, SGE buffer, and RQ buffer. Currently when one region is zero-hop while the other two are not, the zero-hop region will not be mapped. This violate the limitation above and leads to address error. Fixes: 38389ea ("RDMA/hns: Add mtr support for mixed multihop addressing") Signed-off-by: wenglianfa <wenglianfa@huawei.com> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com> Link: https://patch.msgid.link/20241220055249.146943-2-huangjunxian6@hisilicon.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 9272cba commit 8673a6c

File tree

2 files changed

+29
-19
lines changed

2 files changed

+29
-19
lines changed

drivers/infiniband/hw/hns/hns_roce_hem.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ struct hns_roce_hem_item {
931931
size_t count; /* max ba numbers */
932932
int start; /* start buf offset in this hem */
933933
int end; /* end buf offset in this hem */
934+
bool exist_bt;
934935
};
935936

936937
/* All HEM items are linked in a tree structure */
@@ -959,6 +960,7 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count,
959960
}
960961
}
961962

963+
hem->exist_bt = exist_bt;
962964
hem->count = count;
963965
hem->start = start;
964966
hem->end = end;
@@ -969,22 +971,22 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count,
969971
}
970972

971973
static void hem_list_free_item(struct hns_roce_dev *hr_dev,
972-
struct hns_roce_hem_item *hem, bool exist_bt)
974+
struct hns_roce_hem_item *hem)
973975
{
974-
if (exist_bt)
976+
if (hem->exist_bt)
975977
dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN,
976978
hem->addr, hem->dma_addr);
977979
kfree(hem);
978980
}
979981

980982
static void hem_list_free_all(struct hns_roce_dev *hr_dev,
981-
struct list_head *head, bool exist_bt)
983+
struct list_head *head)
982984
{
983985
struct hns_roce_hem_item *hem, *temp_hem;
984986

985987
list_for_each_entry_safe(hem, temp_hem, head, list) {
986988
list_del(&hem->list);
987-
hem_list_free_item(hr_dev, hem, exist_bt);
989+
hem_list_free_item(hr_dev, hem);
988990
}
989991
}
990992

@@ -1084,6 +1086,10 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
10841086

10851087
for (i = 0; i < region_cnt; i++) {
10861088
r = (struct hns_roce_buf_region *)&regions[i];
1089+
/* when r->hopnum = 0, the region should not occupy root_ba. */
1090+
if (!r->hopnum)
1091+
continue;
1092+
10871093
if (r->hopnum > 1) {
10881094
step = hem_list_calc_ba_range(r->hopnum, 1, unit);
10891095
if (step > 0)
@@ -1177,7 +1183,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
11771183

11781184
err_exit:
11791185
for (level = 1; level < hopnum; level++)
1180-
hem_list_free_all(hr_dev, &temp_list[level], true);
1186+
hem_list_free_all(hr_dev, &temp_list[level]);
11811187

11821188
return ret;
11831189
}
@@ -1218,16 +1224,26 @@ static int alloc_fake_root_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
12181224
{
12191225
struct hns_roce_hem_item *hem;
12201226

1227+
/* This is on the has_mtt branch, if r->hopnum
1228+
* is 0, there is no root_ba to reuse for the
1229+
* region's fake hem, so a dma_alloc request is
1230+
* necessary here.
1231+
*/
12211232
hem = hem_list_alloc_item(hr_dev, r->offset, r->offset + r->count - 1,
1222-
r->count, false);
1233+
r->count, !r->hopnum);
12231234
if (!hem)
12241235
return -ENOMEM;
12251236

1226-
hem_list_assign_bt(hem, cpu_base, phy_base);
1237+
/* The root_ba can be reused only when r->hopnum > 0. */
1238+
if (r->hopnum)
1239+
hem_list_assign_bt(hem, cpu_base, phy_base);
12271240
list_add(&hem->list, branch_head);
12281241
list_add(&hem->sibling, leaf_head);
12291242

1230-
return r->count;
1243+
/* If r->hopnum == 0, 0 is returned,
1244+
* so that the root_bt entry is not occupied.
1245+
*/
1246+
return r->hopnum ? r->count : 0;
12311247
}
12321248

12331249
static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
@@ -1271,7 +1287,7 @@ setup_root_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem_list *hem_list,
12711287
return -ENOMEM;
12721288

12731289
total = 0;
1274-
for (i = 0; i < region_cnt && total < max_ba_num; i++) {
1290+
for (i = 0; i < region_cnt && total <= max_ba_num; i++) {
12751291
r = &regions[i];
12761292
if (!r->count)
12771293
continue;
@@ -1337,9 +1353,9 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
13371353
region_cnt);
13381354
if (ret) {
13391355
for (i = 0; i < region_cnt; i++)
1340-
hem_list_free_all(hr_dev, &head.branch[i], false);
1356+
hem_list_free_all(hr_dev, &head.branch[i]);
13411357

1342-
hem_list_free_all(hr_dev, &head.root, true);
1358+
hem_list_free_all(hr_dev, &head.root);
13431359
}
13441360

13451361
return ret;
@@ -1402,10 +1418,9 @@ void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev,
14021418

14031419
for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++)
14041420
for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++)
1405-
hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j],
1406-
j != 0);
1421+
hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j]);
14071422

1408-
hem_list_free_all(hr_dev, &hem_list->root_bt, true);
1423+
hem_list_free_all(hr_dev, &hem_list->root_bt);
14091424
INIT_LIST_HEAD(&hem_list->btm_bt);
14101425
hem_list->root_ba = 0;
14111426
}

drivers/infiniband/hw/hns/hns_roce_mr.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -814,11 +814,6 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
814814
for (i = 0, mapped_cnt = 0; i < mtr->hem_cfg.region_count &&
815815
mapped_cnt < page_cnt; i++) {
816816
r = &mtr->hem_cfg.region[i];
817-
/* if hopnum is 0, no need to map pages in this region */
818-
if (!r->hopnum) {
819-
mapped_cnt += r->count;
820-
continue;
821-
}
822817

823818
if (r->offset + r->count > page_cnt) {
824819
ret = -EINVAL;

0 commit comments

Comments
 (0)