Date: Thu, 12 Aug 2021 16:06:15 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 2eb0e53a6b5e - main - cxgbei: Wait for the final CPL to be received in icl_cxgbei_conn_close. Message-ID: <202108121606.17CG6FWj038816@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=2eb0e53a6b5ec1a72be70e966d4e562e1a8d4e88 commit 2eb0e53a6b5ec1a72be70e966d4e562e1a8d4e88 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-08-12 15:48:14 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-08-12 15:48:35 +0000 cxgbei: Wait for the final CPL to be received in icl_cxgbei_conn_close. A socket in the FIN_WAIT_1 state is marked disconnected by do_close_con_rpl() even though there might still receive data pending. This is because the socket at that point has set SBS_CANTRCVMORE which causes the protocol layer to discard any data received before the FIN. However, icl_cxgbei_conn_close needs to wait until all the data has been discarded. Replace the wait for SS_ISDISCONNECTED with instead waiting for final_cpl_received() to be called. Reported by: Jithesh Arakkan @ Chelsio Sponsored by: Chelsio Communications --- sys/dev/cxgbe/cxgbei/icl_cxgbei.c | 28 +++++++++++++++++++++------- sys/dev/cxgbe/tom/t4_tom.c | 12 +++++++++++- sys/dev/cxgbe/tom/t4_tom.h | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c index a57d26ae21b8..5526388915f7 100644 --- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c +++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c @@ -947,6 +947,18 @@ icl_cxgbei_conn_close(struct icl_conn *ic) icl_cxgbei_pdu_done(ip, ENOTCONN); } SOCKBUF_UNLOCK(sb); + + /* + * Grab a reference to use when waiting for the final + * CPL to be received. If toep->inp is NULL, then + * final_cpl_received() has already been called (e.g. + * due to the peer sending a RST). + */ + if (toep->inp != NULL) { + toep = hold_toepcb(toep); + toep->flags |= TPF_WAITING_FOR_FINAL; + } else + toep = NULL; } INP_WUNLOCK(inp); @@ -959,7 +971,6 @@ icl_cxgbei_conn_close(struct icl_conn *ic) * queues were purged instead of delivered reliably but soabort isn't * really general purpose and wouldn't do the right thing here. */ - soref(so); soclose(so); /* @@ -969,12 +980,15 @@ icl_cxgbei_conn_close(struct icl_conn *ic) * Callers assume that it is safe to free buffers for tasks * and transfers after this function returns. */ - SOCK_LOCK(so); - while ((so->so_state & SS_ISDISCONNECTED) == 0) - mtx_sleep(&so->so_timeo, SOCK_MTX(so), PSOCK, "conclo2", 0); - CURVNET_SET(so->so_vnet); - sorele(so); - CURVNET_RESTORE(); + if (toep != NULL) { + struct mtx *lock = mtx_pool_find(mtxpool_sleep, toep); + + mtx_lock(lock); + while ((toep->flags & TPF_WAITING_FOR_FINAL) != 0) + mtx_sleep(toep, lock, PSOCK, "conclo2", 0); + mtx_unlock(lock); + free_toepcb(toep); + } } static void diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index 1d065ade77c4..a444f0c9d690 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -1008,6 +1008,7 @@ void final_cpl_received(struct toepcb *toep) { struct inpcb *inp = toep->inp; + bool need_wakeup; KASSERT(inp != NULL, ("%s: inp is NULL", __func__)); INP_WLOCK_ASSERT(inp); @@ -1022,7 +1023,8 @@ final_cpl_received(struct toepcb *toep) else if (ulp_mode(toep) == ULP_MODE_TLS) tls_detach(toep); toep->inp = NULL; - toep->flags &= ~TPF_CPL_PENDING; + need_wakeup = (toep->flags & TPF_WAITING_FOR_FINAL) != 0; + toep->flags &= ~(TPF_CPL_PENDING | TPF_WAITING_FOR_FINAL); mbufq_drain(&toep->ulp_pduq); mbufq_drain(&toep->ulp_pdu_reclaimq); @@ -1031,6 +1033,14 @@ final_cpl_received(struct toepcb *toep) if (!in_pcbrele_wlocked(inp)) INP_WUNLOCK(inp); + + if (need_wakeup) { + struct mtx *lock = mtx_pool_find(mtxpool_sleep, toep); + + mtx_lock(lock); + wakeup(toep); + mtx_unlock(lock); + } } void diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h index 10d9cfe87960..dc462d4b4a66 100644 --- a/sys/dev/cxgbe/tom/t4_tom.h +++ b/sys/dev/cxgbe/tom/t4_tom.h @@ -76,6 +76,7 @@ enum { TPF_INITIALIZED = (1 << 12), /* init_toepcb has been called */ TPF_TLS_RECEIVE = (1 << 13), /* should receive TLS records */ TPF_TLS_ESTABLISHED = (1 << 14), /* TLS handshake timer initialized */ + TPF_WAITING_FOR_FINAL = (1<< 15), /* waiting for wakeup on final CPL */ }; enum {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108121606.17CG6FWj038816>