Skip to content

Commit bf692e7

Browse files
justin-hegregkh
authored andcommitted
qed: fix possible unpaired spin_{un}lock_bh in _qed_mcp_cmd_and_union()
[ Upstream commit 6206b79 ] Liajian reported a bug_on hit on a ThunderX2 arm64 server with FastLinQ QL41000 ethernet controller: BUG: scheduling while atomic: kworker/0:4/531/0x00000200 [qed_probe:488()]hw prepare failed kernel BUG at mm/vmalloc.c:2355! Internal error: Oops - BUG: 0 [#1] SMP CPU: 0 PID: 531 Comm: kworker/0:4 Tainted: G W 5.4.0-77-generic #86-Ubuntu pstate: 00400009 (nzcv daif +PAN -UAO) Call trace: vunmap+0x4c/0x50 iounmap+0x48/0x58 qed_free_pci+0x60/0x80 [qed] qed_probe+0x35c/0x688 [qed] __qede_probe+0x88/0x5c8 [qede] qede_probe+0x60/0xe0 [qede] local_pci_probe+0x48/0xa0 work_for_cpu_fn+0x24/0x38 process_one_work+0x1d0/0x468 worker_thread+0x238/0x4e0 kthread+0xf0/0x118 ret_from_fork+0x10/0x18 In this case, qed_hw_prepare() returns error due to hw/fw error, but in theory work queue should be in process context instead of interrupt. The root cause might be the unpaired spin_{un}lock_bh() in _qed_mcp_cmd_and_union(), which causes botton half is disabled incorrectly. Reported-by: Lijian Zhang <[email protected]> Signed-off-by: Jia He <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 6bc4834 commit bf692e7

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

drivers/net/ethernet/qlogic/qed/qed_mcp.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,18 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
498498

499499
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
500500

501-
if (!qed_mcp_has_pending_cmd(p_hwfn))
501+
if (!qed_mcp_has_pending_cmd(p_hwfn)) {
502+
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
502503
break;
504+
}
503505

504506
rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt);
505-
if (!rc)
507+
if (!rc) {
508+
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
506509
break;
507-
else if (rc != -EAGAIN)
510+
} else if (rc != -EAGAIN) {
508511
goto err;
512+
}
509513

510514
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
511515

@@ -522,6 +526,8 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
522526
return -EAGAIN;
523527
}
524528

529+
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
530+
525531
/* Send the mailbox command */
526532
qed_mcp_reread_offsets(p_hwfn, p_ptt);
527533
seq_num = ++p_hwfn->mcp_info->drv_mb_seq;
@@ -548,14 +554,18 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
548554

549555
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
550556

551-
if (p_cmd_elem->b_is_completed)
557+
if (p_cmd_elem->b_is_completed) {
558+
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
552559
break;
560+
}
553561

554562
rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt);
555-
if (!rc)
563+
if (!rc) {
564+
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
556565
break;
557-
else if (rc != -EAGAIN)
566+
} else if (rc != -EAGAIN) {
558567
goto err;
568+
}
559569

560570
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
561571
} while (++cnt < max_retries);
@@ -576,6 +586,7 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
576586
return -EAGAIN;
577587
}
578588

589+
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
579590
qed_mcp_cmd_del_elem(p_hwfn, p_cmd_elem);
580591
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
581592

0 commit comments

Comments
 (0)