git: abc273a2901b - main - cxgbei: Better handle new tasks and transfers when disconnecting.
John Baldwin
jhb at FreeBSD.org
Tue Jun 22 23:10:30 UTC 2021
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=abc273a2901b116cc98a1fb506c75ac1b0a14cd3
commit abc273a2901b116cc98a1fb506c75ac1b0a14cd3
Author: John Baldwin <jhb at FreeBSD.org>
AuthorDate: 2021-06-18 23:15:50 +0000
Commit: John Baldwin <jhb at FreeBSD.org>
CommitDate: 2021-06-22 23:09:54 +0000
cxgbei: Better handle new tasks and transfers when disconnecting.
If the connection is in the process of disconnecting, ic_socket can be
NULL. For icl_cxgbei_conn_transfer_setup(), lock the connection and
check ic_socket before using it. For icl_cxgbei_conn_task_setup(),
the caller already holds the connection lock, so assert it and bail
early with ECONNRESET if the connection is disconnecting.
Reported by: Jithesh Arakkan @ Chelsio
Fixes: f949967c8eb3 cxgbei: Fix a race between transfer setup and a peer reset.
---
sys/dev/cxgbe/cxgbei/icl_cxgbei.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
index 01759d929c0e..e974ad73a935 100644
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -988,10 +988,15 @@ icl_cxgbei_conn_task_setup(struct icl_conn *ic, struct icl_pdu *ip,
uint32_t itt;
int rc = 0;
+ ICL_CONN_LOCK_ASSERT(ic);
+
/* This is for the offload driver's state. Must not be set already. */
MPASS(arg != NULL);
MPASS(*arg == NULL);
+ if (ic->ic_disconnecting || ic->ic_socket == NULL)
+ return (ECONNRESET);
+
if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_IN ||
csio->dxfer_len < ci->ddp_threshold) {
no_ddp:
@@ -1209,8 +1214,17 @@ no_ddp:
* Do not get inp from toep->inp as the toepcb might
* have detached already.
*/
+ ICL_CONN_LOCK(ic);
+ if (ic->ic_disconnecting || ic->ic_socket == NULL) {
+ ICL_CONN_UNLOCK(ic);
+ mbufq_drain(&mq);
+ t4_free_page_pods(prsv);
+ free(ddp, M_CXGBEI);
+ return (ECONNRESET);
+ }
inp = sotoinpcb(ic->ic_socket);
INP_WLOCK(inp);
+ ICL_CONN_UNLOCK(ic);
if ((inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT)) != 0) {
INP_WUNLOCK(inp);
mbufq_drain(&mq);
More information about the dev-commits-src-all
mailing list