Skip to content

Commit 2565558

Browse files
Junxian Huangrleon
authored andcommitted
RDMA/hns: Fix soft lockup during bt pages loop
Driver runs a for-loop when allocating bt pages and mapping them with buffer pages. When a large buffer (e.g. MR over 100GB) is being allocated, it may require a considerable loop count. This will lead to soft lockup: watchdog: BUG: soft lockup - CPU#27 stuck for 22s! ... Call trace: hem_list_alloc_mid_bt+0x124/0x394 [hns_roce_hw_v2] hns_roce_hem_list_request+0xf8/0x160 [hns_roce_hw_v2] hns_roce_mtr_create+0x2e4/0x360 [hns_roce_hw_v2] alloc_mr_pbl+0xd4/0x17c [hns_roce_hw_v2] hns_roce_reg_user_mr+0xf8/0x190 [hns_roce_hw_v2] ib_uverbs_reg_mr+0x118/0x290 watchdog: BUG: soft lockup - CPU#35 stuck for 23s! ... Call trace: hns_roce_hem_list_find_mtt+0x7c/0xb0 [hns_roce_hw_v2] mtr_map_bufs+0xc4/0x204 [hns_roce_hw_v2] hns_roce_mtr_create+0x31c/0x3c4 [hns_roce_hw_v2] alloc_mr_pbl+0xb0/0x160 [hns_roce_hw_v2] hns_roce_reg_user_mr+0x108/0x1c0 [hns_roce_hw_v2] ib_uverbs_reg_mr+0x120/0x2bc Add a cond_resched() to fix soft lockup during these loops. In order not to affect the allocation performance of normal-size buffer, set the loop count of a 100GB MR as the threshold to call cond_resched(). Fixes: 38389ea ("RDMA/hns: Add mtr support for mixed multihop addressing") Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com> Link: https://patch.msgid.link/20250311084857.3803665-3-huangjunxian6@hisilicon.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 81c0db3 commit 2565558

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

drivers/infiniband/hw/hns/hns_roce_hem.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,11 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
13611361
return ret;
13621362
}
13631363

1364+
/* This is the bottom bt pages number of a 100G MR on 4K OS, assuming
1365+
* the bt page size is not expanded by cal_best_bt_pg_sz()
1366+
*/
1367+
#define RESCHED_LOOP_CNT_THRESHOLD_ON_4K 12800
1368+
13641369
/* construct the base address table and link them by address hop config */
13651370
int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
13661371
struct hns_roce_hem_list *hem_list,
@@ -1369,6 +1374,7 @@ int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
13691374
{
13701375
const struct hns_roce_buf_region *r;
13711376
int ofs, end;
1377+
int loop;
13721378
int unit;
13731379
int ret;
13741380
int i;
@@ -1386,7 +1392,10 @@ int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
13861392
continue;
13871393

13881394
end = r->offset + r->count;
1389-
for (ofs = r->offset; ofs < end; ofs += unit) {
1395+
for (ofs = r->offset, loop = 1; ofs < end; ofs += unit, loop++) {
1396+
if (!(loop % RESCHED_LOOP_CNT_THRESHOLD_ON_4K))
1397+
cond_resched();
1398+
13901399
ret = hem_list_alloc_mid_bt(hr_dev, r, unit, ofs,
13911400
hem_list->mid_bt[i],
13921401
&hem_list->btm_bt);
@@ -1443,9 +1452,14 @@ void *hns_roce_hem_list_find_mtt(struct hns_roce_dev *hr_dev,
14431452
struct list_head *head = &hem_list->btm_bt;
14441453
struct hns_roce_hem_item *hem, *temp_hem;
14451454
void *cpu_base = NULL;
1455+
int loop = 1;
14461456
int nr = 0;
14471457

14481458
list_for_each_entry_safe(hem, temp_hem, head, sibling) {
1459+
if (!(loop % RESCHED_LOOP_CNT_THRESHOLD_ON_4K))
1460+
cond_resched();
1461+
loop++;
1462+
14491463
if (hem_list_page_is_in_range(hem, offset)) {
14501464
nr = offset - hem->start;
14511465
cpu_base = hem->addr + nr * BA_BYTE_LEN;

0 commit comments

Comments
 (0)