git: f0334cb8d345 - stable/13 - cxgbei: Better handle new tasks and transfers when disconnecting.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 29 Oct 2021 23:58:22 UTC
The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=f0334cb8d345da6039d76ed6be9790aba0e94b34 commit f0334cb8d345da6039d76ed6be9790aba0e94b34 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-06-18 23:15:50 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-10-29 23:10:14 +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. (cherry picked from commit abc273a2901b116cc98a1fb506c75ac1b0a14cd3) --- 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);