Date: Thu, 29 Nov 2012 21:05:51 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r243682 - user/np/stable_9_toe/sys/dev/cxgbe/tom Message-ID: <201211292105.qATL5pp6055467@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Thu Nov 29 21:05:50 2012 New Revision: 243682 URL: http://svnweb.freebsd.org/changeset/base/243682 Log: Pull in r243680 and r243681 from head. Modified: user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_cpl_io.c user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_ddp.c user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_listen.c user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_tom.h Directory Properties: user/np/stable_9_toe/sys/ (props changed) user/np/stable_9_toe/sys/dev/ (props changed) Modified: user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_cpl_io.c ============================================================================== --- user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_cpl_io.c Thu Nov 29 19:39:27 2012 (r243681) +++ user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_cpl_io.c Thu Nov 29 21:05:50 2012 (r243682) @@ -786,6 +786,29 @@ do_peer_close(struct sge_iq *iq, const s KASSERT(opcode == CPL_PEER_CLOSE, ("%s: unexpected opcode 0x%x", __func__, opcode)); KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); + + if (__predict_false(toep->flags & TPF_SYNQE)) { +#ifdef INVARIANTS + struct synq_entry *synqe = (void *)toep; + + INP_WLOCK(synqe->lctx->inp); + if (synqe->flags & TPF_SYNQE_HAS_L2TE) { + KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN, + ("%s: listen socket closed but tid %u not aborted.", + __func__, tid)); + } else { + /* + * do_pass_accept_req is still running and will + * eventually take care of this tid. + */ + } + INP_WUNLOCK(synqe->lctx->inp); +#endif + CTR4(KTR_CXGBE, "%s: tid %u, synqe %p (0x%x)", __func__, tid, + toep, toep->flags); + return (0); + } + KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__)); INP_INFO_WLOCK(&V_tcbinfo); @@ -1090,15 +1113,27 @@ do_rx_data(struct sge_iq *iq, const stru struct socket *so; struct sockbuf *sb; int len; + uint32_t ddp_placed = 0; if (__predict_false(toep->flags & TPF_SYNQE)) { - /* - * do_pass_establish failed and must be attempting to abort the - * synqe's tid. Meanwhile, the T4 has sent us data for such a - * connection. - */ - KASSERT(toep->flags & TPF_ABORT_SHUTDOWN, - ("%s: synqe and tid isn't being aborted.", __func__)); +#ifdef INVARIANTS + struct synq_entry *synqe = (void *)toep; + + INP_WLOCK(synqe->lctx->inp); + if (synqe->flags & TPF_SYNQE_HAS_L2TE) { + KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN, + ("%s: listen socket closed but tid %u not aborted.", + __func__, tid)); + } else { + /* + * do_pass_accept_req is still running and will + * eventually take care of this tid. + */ + } + INP_WUNLOCK(synqe->lctx->inp); +#endif + CTR4(KTR_CXGBE, "%s: tid %u, synqe %p (0x%x)", __func__, tid, + toep, toep->flags); m_freem(m); return (0); } @@ -1120,13 +1155,8 @@ do_rx_data(struct sge_iq *iq, const stru tp = intotcpcb(inp); -#ifdef INVARIANTS - if (__predict_false(tp->rcv_nxt != be32toh(cpl->seq))) { - log(LOG_ERR, - "%s: unexpected seq# %x for TID %u, rcv_nxt %x\n", - __func__, be32toh(cpl->seq), toep->tid, tp->rcv_nxt); - } -#endif + if (__predict_false(tp->rcv_nxt != be32toh(cpl->seq))) + ddp_placed = be32toh(cpl->seq) - tp->rcv_nxt; tp->rcv_nxt += len; KASSERT(tp->rcv_wnd >= len, ("%s: negative window size", __func__)); @@ -1173,12 +1203,20 @@ do_rx_data(struct sge_iq *iq, const stru int changed = !(toep->ddp_flags & DDP_ON) ^ cpl->ddp_off; if (changed) { - if (__predict_false(!(toep->ddp_flags & DDP_SC_REQ))) { - /* XXX: handle this if legitimate */ - panic("%s: unexpected DDP state change %d", - __func__, cpl->ddp_off); + if (toep->ddp_flags & DDP_SC_REQ) + toep->ddp_flags ^= DDP_ON | DDP_SC_REQ; + else { + KASSERT(cpl->ddp_off == 1, + ("%s: DDP switched on by itself.", + __func__)); + + /* Fell out of DDP mode */ + toep->ddp_flags &= ~(DDP_ON | DDP_BUF0_ACTIVE | + DDP_BUF1_ACTIVE); + + if (ddp_placed) + insert_ddp_data(toep, ddp_placed); } - toep->ddp_flags ^= DDP_ON | DDP_SC_REQ; } if ((toep->ddp_flags & DDP_OK) == 0 && Modified: user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_ddp.c ============================================================================== --- user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_ddp.c Thu Nov 29 19:39:27 2012 (r243681) +++ user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_ddp.c Thu Nov 29 21:05:50 2012 (r243682) @@ -205,6 +205,42 @@ release_ddp_resources(struct toepcb *toe } } +/* XXX: handle_ddp_data code duplication */ +void +insert_ddp_data(struct toepcb *toep, uint32_t n) +{ + struct inpcb *inp = toep->inp; + struct tcpcb *tp = intotcpcb(inp); + struct sockbuf *sb = &inp->inp_socket->so_rcv; + struct mbuf *m; + + INP_WLOCK_ASSERT(inp); + SOCKBUF_LOCK_ASSERT(sb); + + m = m_get(M_NOWAIT, MT_DATA); + if (m == NULL) + CXGBE_UNIMPLEMENTED("mbuf alloc failure"); + m->m_len = n; + m->m_flags |= M_DDP; /* Data is already where it should be */ + m->m_data = "nothing to see here"; + + tp->rcv_nxt += n; +#ifndef USE_DDP_RX_FLOW_CONTROL + KASSERT(tp->rcv_wnd >= n, ("%s: negative window size", __func__)); + tp->rcv_wnd -= n; +#endif + + KASSERT(toep->sb_cc >= sb->sb_cc, + ("%s: sb %p has more data (%d) than last time (%d).", + __func__, sb, sb->sb_cc, toep->sb_cc)); + toep->rx_credits += toep->sb_cc - sb->sb_cc; +#ifdef USE_DDP_RX_FLOW_CONTROL + toep->rx_credits -= n; /* adjust for F_RX_FC_DDP */ +#endif + sbappendstream_locked(sb, m); + toep->sb_cc = sb->sb_cc; +} + /* SET_TCB_FIELD sent as a ULP command looks like this */ #define LEN__SET_TCB_FIELD_ULP (sizeof(struct ulp_txpkt) + \ sizeof(struct ulptx_idata) + sizeof(struct cpl_set_tcb_field_core)) Modified: user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_listen.c ============================================================================== --- user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_listen.c Thu Nov 29 19:39:27 2012 (r243681) +++ user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_listen.c Thu Nov 29 21:05:50 2012 (r243682) @@ -282,8 +282,8 @@ send_reset_synqe(struct toedev *tod, str INP_WLOCK_ASSERT(synqe->lctx->inp); - CTR4(KTR_CXGBE, "%s: synqe %p, tid %d%s", - __func__, synqe, synqe->tid, + CTR5(KTR_CXGBE, "%s: synqe %p (0x%x), tid %d%s", + __func__, synqe, synqe->flags, synqe->tid, synqe->flags & TPF_ABORT_SHUTDOWN ? " (abort already in progress)" : ""); if (synqe->flags & TPF_ABORT_SHUTDOWN) @@ -501,8 +501,10 @@ t4_listen_stop(struct toedev *tod, struc * socket's so_comp. It doesn't know about the connections on the synq * so we need to take care of those. */ - TAILQ_FOREACH(synqe, &lctx->synq, link) - send_reset_synqe(tod, synqe); + TAILQ_FOREACH(synqe, &lctx->synq, link) { + if (synqe->flags & TPF_SYNQE_HAS_L2TE) + send_reset_synqe(tod, synqe); + } destroy_server(sc, lctx); return (0); @@ -1131,8 +1133,7 @@ do_pass_accept_req(struct sge_iq *iq, co synqe->lctx = lctx; synqe->syn = m; m = NULL; - refcount_init(&synqe->refcnt, 1); /* 1 so that it is held for the - duration of this function */ + refcount_init(&synqe->refcnt, 0); synqe->l2e_idx = e->idx; synqe->rcv_bufsize = rx_credits; atomic_store_rel_ptr(&synqe->wr, (uintptr_t)wr); @@ -1155,46 +1156,9 @@ do_pass_accept_req(struct sge_iq *iq, co * If we replied during syncache_add (synqe->wr has been consumed), * good. Otherwise, set it to 0 so that further syncache_respond * attempts by the kernel will be ignored. - * - * The extra hold on the synqe makes sure that it is still around, even - * if the listener has been dropped and the synqe was aborted and the - * reply to the abort has removed and released the synqe from the synq - * list. */ if (atomic_cmpset_ptr(&synqe->wr, (uintptr_t)wr, 0)) { - INP_WLOCK(inp); - if (__predict_false(inp->inp_flags & INP_DROPPED)) { - /* listener closed. synqe must have been aborted. */ - KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN, - ("%s: listener %p closed but synqe %p not aborted", - __func__, inp, synqe)); - - CTR5(KTR_CXGBE, - "%s: stid %u, tid %u, lctx %p, synqe %p, ABORTED", - __func__, stid, tid, lctx, synqe); - INP_WUNLOCK(inp); - free(wr, M_CXGBE); - release_synqe(synqe); /* about to exit function */ - return (__LINE__); - } - - /* - * synqe aborted before TOM replied to PASS_ACCEPT_REQ. But - * that can only happen if the listener was closed and we just - * checked for that. - */ - KASSERT(!(synqe->flags & TPF_ABORT_SHUTDOWN), - ("%s: synqe %p aborted, but listener %p not dropped.", - __func__, synqe, inp)); - - /* Yank the synqe out of the lctx synq. */ - TAILQ_REMOVE(&lctx->synq, synqe, link); - release_synqe(synqe); /* removed from synq list */ - inp = release_lctx(sc, lctx); - if (inp) - INP_WUNLOCK(inp); - /* * syncache may or may not have a hold on the synqe, which may * or may not be stashed in the original SYN mbuf passed to us. @@ -1205,13 +1169,39 @@ do_pass_accept_req(struct sge_iq *iq, co m->m_pkthdr.rcvif = ifp; remove_tid(sc, synqe->tid); - release_synqe(synqe); /* about to exit function */ free(wr, M_CXGBE); + + /* Yank the synqe out of the lctx synq. */ + INP_WLOCK(inp); + TAILQ_REMOVE(&lctx->synq, synqe, link); + release_synqe(synqe); /* removed from synq list */ + inp = release_lctx(sc, lctx); + if (inp) + INP_WUNLOCK(inp); + REJECT_PASS_ACCEPT(); } - release_synqe(synqe); /* about to exit function */ + CTR5(KTR_CXGBE, "%s: stid %u, tid %u, lctx %p, synqe %p, SYNACK", __func__, stid, tid, lctx, synqe); + + INP_WLOCK(inp); + synqe->flags |= TPF_SYNQE_HAS_L2TE; + if (__predict_false(inp->inp_flags & INP_DROPPED)) { + /* + * Listening socket closed but tod_listen_stop did not abort + * this tid because there was no L2T entry for the tid at that + * time. Abort it now. The reply to the abort will clean up. + */ + CTR5(KTR_CXGBE, "%s: stid %u, tid %u, lctx %p, synqe %p, ABORT", + __func__, stid, tid, lctx, synqe); + send_reset_synqe(tod, synqe); + INP_WUNLOCK(inp); + + return (__LINE__); + } + INP_WUNLOCK(inp); + return (0); reject: CTR4(KTR_CXGBE, "%s: stid %u, tid %u, REJECT (%d)", __func__, stid, tid, @@ -1293,15 +1283,12 @@ do_pass_establish(struct sge_iq *iq, con __func__, stid, tid, synqe, synqe->flags, inp->inp_flags); if (__predict_false(inp->inp_flags & INP_DROPPED)) { - /* - * The listening socket has closed. The TOM must have aborted - * all the embryonic connections (including this one) that were - * on the lctx's synq. do_abort_rpl for the tid is responsible - * for cleaning up. - */ - KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN, - ("%s: listen socket dropped but tid %u not aborted.", - __func__, tid)); + + if (synqe->flags & TPF_SYNQE_HAS_L2TE) { + KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN, + ("%s: listen socket closed but tid %u not aborted.", + __func__, tid)); + } INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_tcbinfo); @@ -1321,7 +1308,12 @@ do_pass_establish(struct sge_iq *iq, con toep = alloc_toepcb(pi, txqid, rxqid, M_NOWAIT); if (toep == NULL) { reset: - /* The reply to this abort will perform final cleanup */ + /* + * The reply to this abort will perform final cleanup. There is + * no need to check for HAS_L2TE here. We can be here only if + * we responded to the PASS_ACCEPT_REQ, and our response had the + * L2T idx. + */ send_reset_synqe(TOEDEV(ifp), synqe); INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_tcbinfo); Modified: user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_tom.h ============================================================================== --- user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_tom.h Thu Nov 29 19:39:27 2012 (r243681) +++ user/np/stable_9_toe/sys/dev/cxgbe/tom/t4_tom.h Thu Nov 29 21:05:50 2012 (r243682) @@ -67,6 +67,7 @@ enum { TPF_SYNQE_NEEDFREE = (1 << 9), /* synq_entry was malloc'd separately */ TPF_SYNQE_TCPDDP = (1 << 10), /* ulp_mode TCPDDP in toepcb */ TPF_SYNQE_EXPANDED = (1 << 11), /* toepcb ready, tid context updated */ + TPF_SYNQE_HAS_L2TE = (1 << 12), /* we've replied to PASS_ACCEPT_REQ */ }; enum { @@ -272,4 +273,5 @@ int t4_soreceive_ddp(struct socket *, st struct mbuf **, struct mbuf **, int *); void enable_ddp(struct adapter *, struct toepcb *toep); void release_ddp_resources(struct toepcb *toep); +void insert_ddp_data(struct toepcb *, uint32_t); #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211292105.qATL5pp6055467>