Restructure the ASYNC case to allow calling idpf_vc_xn_forward_reply()
outside of idpf_vc_xn_lock(). This avoids invalid wait context reported by
the kernel due to the async handler taking BH spinlock:
[ 805.726977] =============================
[ 805.726991] [ BUG: Invalid wait context ]
[ 805.727006] 7.0.0-rc2-net-devq-031026+ #28 Tainted: G S OE
[ 805.727026] -----------------------------
[ 805.727038] kworker/u261:0/572 is trying to lock:
[ 805.727051] ff190da6a8dbb6a0
(&vport_config->mac_filter_list_lock){+...}-{3:3}, at:
idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[ 805.727099] other info that might help us debug this:
[ 805.727111] context-{5:5}
[ 805.727119] 3 locks held by kworker/u261:0/572:
[ 805.727132] #0: ff190da6db3e6148
((wq_completion)idpf-0000:83:00.0-mbx){+.+.}-{0:0}, at:
process_one_work+0x4b5/0x730
[ 805.727163] #1: ff3c6f0a6131fe50
((work_completion)(&(&adapter->mbx_task)->work)){+.+.}-{0:0}, at:
process_one_work+0x1e5/0x730
[ 805.727191] #2: ff190da765190020 (&x->wait#34){+.+.}-{2:2}, at:
idpf_recv_mb_msg+0xc8/0x710 [idpf]
[ 805.727218] stack backtrace:
...
[ 805.727238] Workqueue: idpf-0000:83:00.0-mbx idpf_mbx_task [idpf]
[ 805.727247] Call Trace:
[ 805.727249] <TASK>
[ 805.727251] dump_stack_lvl+0x77/0xb0
[ 805.727259] __lock_acquire+0xb3b/0x2290
[ 805.727268] ? __irq_work_queue_local+0x59/0x130
[ 805.727275] lock_acquire+0xc6/0x2f0
[ 805.727277] ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[ 805.727284] ? _printk+0x5b/0x80
[ 805.727290] _raw_spin_lock_bh+0x38/0x50
[ 805.727298] ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[ 805.727303] idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[ 805.727310] idpf_recv_mb_msg+0x1c8/0x710 [idpf]
[ 805.727317] process_one_work+0x226/0x730
[ 805.727322] worker_thread+0x19e/0x340
[ 805.727325] ? __pfx_worker_thread+0x10/0x10
[ 805.727328] kthread+0xf4/0x130
[ 805.727333] ? __pfx_kthread+0x10/0x10
[ 805.727336] ret_from_fork+0x32c/0x410
[ 805.727345] ? __pfx_kthread+0x10/0x10
[ 805.727347] ret_from_fork_asm+0x1a/0x30
[ 805.727354] </TASK>
Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
Reported-by: Ray Zhang <[email protected]>
Signed-off-by: Emil Tantilov <[email protected]>
Reviewed-by: Aleksandr Loktionov <[email protected]>
---
.../net/ethernet/intel/idpf/idpf_virtchnl.c | 21 +++++++------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 6b9692b30040..8ceabd86e172 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -546,32 +546,24 @@ static int
idpf_vc_xn_forward_async(struct idpf_adapter *adapter, struct idpf_vc_xn *xn,
const struct idpf_ctlq_msg *ctlq_msg)
{
- int err = 0;
-
if (ctlq_msg->cookie.mbx.chnl_opcode != xn->vc_op) {
dev_err_ratelimited(&adapter->pdev->dev, "Async message opcode
does not match transaction opcode (msg: %d) (xn: %d)\n",
ctlq_msg->cookie.mbx.chnl_opcode,
xn->vc_op);
xn->reply_sz = 0;
- err = -EINVAL;
- goto release_bufs;
+ return -EINVAL;
}
- if (xn->async_handler) {
- err = xn->async_handler(adapter, xn, ctlq_msg);
- goto release_bufs;
- }
+ if (xn->async_handler)
+ return xn->async_handler(adapter, xn, ctlq_msg);
if (ctlq_msg->cookie.mbx.chnl_retval) {
xn->reply_sz = 0;
dev_err_ratelimited(&adapter->pdev->dev, "Async message failure
(op %d)\n",
ctlq_msg->cookie.mbx.chnl_opcode);
- err = -EINVAL;
+ return -EINVAL;
}
-release_bufs:
- idpf_vc_xn_release_bufs(xn);
-
- return err;
+ return 0;
}
/**
@@ -631,7 +623,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
* can evaluate the response.
*/
xn->reply_sz = ctlq_msg->data_len;
+ idpf_vc_xn_unlock(xn);
err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
+ idpf_vc_xn_lock(xn);
+ idpf_vc_xn_release_bufs(xn);
idpf_vc_xn_unlock(xn);
idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
return err;
--
2.37.3