From owner-p4-projects@FreeBSD.ORG Tue Nov 27 06:36:38 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D610916A4CB; Tue, 27 Nov 2007 06:36:37 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7298016A417 for ; Tue, 27 Nov 2007 06:36:37 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5ABE313C459 for ; Tue, 27 Nov 2007 06:36:37 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lAR6abrF003060 for ; Tue, 27 Nov 2007 06:36:37 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lAR6abVJ003056 for perforce@freebsd.org; Tue, 27 Nov 2007 06:36:37 GMT (envelope-from kmacy@freebsd.org) Date: Tue, 27 Nov 2007 06:36:37 GMT Message-Id: <200711270636.lAR6abVJ003056@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 129611 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Nov 2007 06:36:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=129611 Change 129611 by kmacy@kmacy:storage:toestack on 2007/11/27 06:36:32 make locking a bit more consistent fix socket buffer accounting in t3_push_frames by only skipping the last buffer if sndptroff is not zero Affected files ... .. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#27 edit Differences ... ==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#27 (text+ko) ==== @@ -170,10 +170,13 @@ send_or_defer(struct socket *so, struct tcpcb *tp, struct mbuf *m, int through_l2t) { struct toepcb *toep = tp->t_toe; + - if (__predict_false(tp->t_state == TCPS_SYN_SENT)) + if (__predict_false(tp->t_state == TCPS_SYN_SENT)) { + INP_LOCK(tp->t_inpcb); mbufq_tail(&toep->out_of_order_queue, m); // defer - else if (through_l2t) + INP_UNLOCK(tp->t_inpcb); + } else if (through_l2t) l2t_send(T3C_DEV(so), m, toep->tp_l2t); // send through L2T else cxgb_ofld_send(T3C_DEV(so), m); // send directly @@ -207,11 +210,12 @@ struct toepcb *toep = tp->t_toe; struct tx_data_wr *req; + INP_LOCK_ASSERT(tp->t_inpcb); + req = mtod(m, struct tx_data_wr *); m->m_len = sizeof(*req); req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); req->wr_lo = htonl(V_WR_TID(toep->tp_tid)); - req->sndseq = htonl(tp->snd_nxt); /* len includes the length of any HW ULP additions */ req->len = htonl(len); req->param = htonl(V_TX_PORT(toep->tp_l2t->smt_idx)); @@ -220,7 +224,7 @@ V_TX_URG(/* skb_urgent(skb) */ 0 ) | V_TX_SHOVE((!(tp->t_flags & TF_MORETOCOME) && (tail ? 0 : 1)))); - + req->sndseq = htonl(tp->snd_nxt); if (__predict_false((toep->tp_flags & TP_DATASENT) == 0)) { req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT | V_TX_CPU_IDX(toep->tp_qset)); @@ -259,16 +263,18 @@ return (0); } + INP_LOCK_ASSERT(tp->t_inpcb); + SOCKBUF_LOCK(&so->so_snd); d = TOM_DATA(TOE_DEV(so)); cdev = d->cdev; last = tail = so->so_snd.sb_sndptr ? so->so_snd.sb_sndptr : so->so_snd.sb_mb; total_bytes = 0; - printf("tail=%p snd.cc=%d tp_last=%p\n", tail, so->so_snd.sb_cc, - toep->tp_m_last); + DPRINTF("wr_avail=%d tail=%p snd.cc=%d tp_last=%p\n", + toep->tp_wr_avail, tail, so->so_snd.sb_cc, toep->tp_m_last); - if (last && toep->tp_m_last == last) { + if (last && toep->tp_m_last == last && so->so_snd.sb_sndptroff != 0) { KASSERT(tail, ("sbdrop error")); last = tail = tail->m_next; } @@ -279,16 +285,15 @@ return (0); } + toep->tp_m_last = NULL; while (toep->tp_wr_avail && (tail != NULL)) { - - count = bytes = 0; if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) { SOCKBUF_UNLOCK(&so->so_snd); return (0); } - - while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail) && (tail != NULL) && (count < TX_MAX_SEGS)) { + while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail) + && (tail != NULL) && (count < TX_MAX_SEGS)) { bytes += tail->m_len; count++; last = tail; @@ -360,8 +365,6 @@ return (total_bytes); } - - /* * Close a connection by sending a CPL_CLOSE_CON_REQ message. Cannot fail * under any circumstances. We take the easy way out and always queue the @@ -475,6 +478,8 @@ if (!((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1) || (tp->t_state == TCPS_FIN_WAIT_2))) return; + INP_LOCK_ASSERT(tp->t_inpcb); + so = tp->t_inpcb->inp_socket; SOCKBUF_LOCK(&so->so_rcv); read = toep->tp_enqueued_bytes - so->so_rcv.sb_cc; @@ -764,7 +769,7 @@ { struct toepcb *toep = sototoep(so); toepcb_hold(toep); - + cxgb_insert_tid(d->cdev, d->client, toep, tid); } @@ -843,6 +848,7 @@ if (!cdev) return; + INP_LOCK_ASSERT(tp->t_inpcb); toep->tp_qset = 0; t3_release_ddp_resources(so); @@ -945,8 +951,9 @@ { struct tcpcb *tp = sototcpcb(so); struct t3c_data *td = T3C_DATA(TOM_DATA(dev)->cdev); + + SOCK_LOCK_ASSERT(so); - printf("initializing offload socket\n"); so->so_rcv.sb_flags |= SB_TOE; so->so_snd.sb_flags |= SB_TOE; @@ -1070,7 +1077,8 @@ fail_act_open(struct socket *so, int errno) { struct tcpcb *tp = sototcpcb(so); - + + INP_LOCK_ASSERT(tp->t_inpcb); t3_release_offload_resources(so); tcp_drop(tp, errno); @@ -1193,18 +1201,23 @@ e = t3_l2t_get(d->cdev, dst, egress_ifp); if (!e) goto free_tid; - + + INP_LOCK_ASSERT(inp); m = m_gethdr(MT_DATA, M_WAITOK); #if 0 m->m_toe.mt_toepcb = tp->t_toe; set_arp_failure_handler((struct mbuf *)m, act_open_req_arp_failure); -#endif +#endif + SOCK_LOCK(so); + init_offload_socket(so, tdev, atid, e, dst, toep); install_offload_ops(so); mk_act_open_req(so, m, atid, e); + SOCK_UNLOCK(so); + soisconnecting(so); toep = tp->t_toe; m_set_toep(m, tp->t_toe); @@ -1239,9 +1252,9 @@ int mode = CPL_ABORT_SEND_RST; struct mbuf *m; + INP_LOCK_ASSERT(tp->t_inpcb); if (__predict_false((toep->tp_flags & TP_ABORT_SHUTDOWN) || !TOE_DEV(so))) return; - toep->tp_flags |= (TP_ABORT_RPL_PENDING|TP_ABORT_SHUTDOWN); /* Purge the send queue so we don't send anything after an abort. */ @@ -1260,6 +1273,7 @@ req->rsvd0 = htonl(tp->snd_nxt); req->rsvd1 = !(toep->tp_flags & TP_DATASENT); req->cmd = mode; + INP_LOCK_ASSERT(tp->t_inpcb); if (tp->t_state == TCPS_SYN_SENT) mbufq_tail(&toep->out_of_order_queue, m); // defer else @@ -1440,21 +1454,7 @@ #endif SOCKBUF_LOCK(&so->so_rcv); if (sb_notify(&so->so_rcv)) - printf("rx_data so=%p flags=0x%x len=%d\n", so, so->so_rcv.sb_flags, m->m_pkthdr.len); - if (m->m_pkthdr.len == 80) { - int i; - uint64_t *data; - - data = mtod(m, uint64_t *); - printf("80 byte packet:\n"); - for (i = 0; i < 10; i++, data++) { - uint8_t *dp = (uint8_t *)data; - - printf("%02x%02x%02x%02x%02x%02x%02x%02x\n", - dp[0],dp[1],dp[2],dp[3],dp[4],dp[5],dp[6],dp[7]); - } - } - + DPRINTF("rx_data so=%p flags=0x%x len=%d\n", so, so->so_rcv.sb_flags, m->m_pkthdr.len); sbappendstream_locked(&so->so_rcv, m); INP_UNLOCK(tp->t_inpcb); @@ -1695,6 +1695,7 @@ { struct tcpcb *tp = sototcpcb(so); + INP_LOCK_ASSERT(tp->t_inpcb); /* * Bump rcv_nxt for the peer FIN. We don't do this at the time we * process peer_close because we don't want to carry the peer FIN in @@ -1709,7 +1710,6 @@ tcp_twstart(tp); } - /* * Handle a peer FIN. */ @@ -1741,6 +1741,8 @@ sk->sk_shutdown |= RCV_SHUTDOWN; sock_set_flag(so, SOCK_DONE); #endif + INP_INFO_WLOCK(&tcbinfo); + INP_LOCK(tp->t_inpcb); if (TCPS_HAVERCVDFIN(tp->t_state) == 0) socantrcvmore(so); switch (tp->t_state) { @@ -1765,11 +1767,7 @@ */ t3_release_offload_resources(so); if (toep->tp_flags & TP_ABORT_RPL_PENDING) { - INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(tp->t_inpcb); tcp_close(tp); - INP_INFO_WUNLOCK(&tcbinfo); - INP_UNLOCK(tp->t_inpcb); } else enter_timewait(so); break; @@ -1778,6 +1776,8 @@ "%s: TID %u received PEER_CLOSE in bad state %d\n", TOE_DEV(so)->name, toep->tp_tid, tp->t_state); } + INP_INFO_WUNLOCK(&tcbinfo); + INP_UNLOCK(tp->t_inpcb); if (!dead) { printf("waking up waiters on %p rcv_notify=%d flags=0x%x\n", so, sb_notify(&so->so_rcv), so->so_rcv.sb_flags); @@ -1831,16 +1831,14 @@ if (!is_t3a(TOE_DEV(so)) && (toep->tp_flags & TP_ABORT_RPL_PENDING)) goto out; + INP_INFO_WLOCK(&tcbinfo); + INP_LOCK(inp); switch (tp->t_state) { case TCPS_CLOSING: /* see FIN_WAIT2 case in do_peer_fin */ t3_release_offload_resources(so); if (toep->tp_flags & TP_ABORT_RPL_PENDING) { - INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); tp = tcp_close(tp); - INP_INFO_WUNLOCK(&tcbinfo); - if (tp) - INP_UNLOCK(inp); + } else enter_timewait(so); break; @@ -1851,13 +1849,7 @@ * late, this close_con_rpl is the actual last message. */ t3_release_offload_resources(so); - INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); tp = tcp_close(tp); - INP_INFO_WUNLOCK(&tcbinfo); - if (tp) - INP_UNLOCK(inp); - break; case TCPS_FIN_WAIT_1: #ifdef notyet @@ -1885,6 +1877,9 @@ TOE_DEV(so)->name, toep->tp_tid, tp->t_state); } + INP_INFO_WUNLOCK(&tcbinfo); + if (tp) + INP_UNLOCK(inp); out: m_free(m); } @@ -1922,7 +1917,8 @@ "process_abort_rpl: GTS rpl pending %d", sock_flag(sk, ABORT_RPL_PENDING)); #endif - + INP_LOCK_ASSERT(tp->t_inpcb); + if (toep->tp_flags & TP_ABORT_RPL_PENDING) { if (!(toep->tp_flags & TP_ABORT_RPL_RCVD) && !is_t3a(TOE_DEV(so))) toep->tp_flags |= TP_ABORT_RPL_RCVD; @@ -1968,7 +1964,6 @@ } toep = (struct toepcb *)ctx; - so = toeptoso(toep); /* * Sometimes we've already closed the socket, e.g., a post-close @@ -1977,9 +1972,10 @@ * but FW turns the ABORT_REQ into a regular one and so we get * ABORT_RPL_RSS with status 0 and no socket. Only on T3A. */ - if (!so) + if (!toep) goto discard; + so = toeptoso(toep); toepcb_hold(toep); process_abort_rpl(so, m); toepcb_release(toep); @@ -2161,7 +2157,8 @@ const struct cpl_abort_req_rss *req = cplhdr(m); struct tcpcb *tp = sototcpcb(so); struct toepcb *toep = tp->t_toe; - + + INP_LOCK_ASSERT(tp->t_inpcb); if ((toep->tp_flags & TP_ABORT_REQ_RCVD) == 0) { toep->tp_flags |= (TP_ABORT_REQ_RCVD|TP_ABORT_SHUTDOWN); m_free(m); @@ -2745,6 +2742,8 @@ const struct t3c_data *td = T3C_DATA(T3C_DEV(so)); struct tcpcb *tp = sototcpcb(so); struct toepcb *toep = tp->t_toe; + + INP_LOCK_ASSERT(tp->t_inpcb); toep->tp_mss_clamp = td->mtus[G_TCPOPT_MSS(opt)] - 40; tp->t_flags |= G_TCPOPT_TSTAMP(opt) ? TF_RCVD_TSTMP : 0; @@ -2884,6 +2883,7 @@ } tp = sototcpcb(so); + INP_LOCK(tp->t_inpcb); so->so_snd.sb_flags |= SB_TOE; so->so_rcv.sb_flags |= SB_TOE; toep->tp_tp = tp; @@ -2906,7 +2906,7 @@ make_established(so, ntohl(req->snd_isn), ntohs(req->tcp_opt)); INP_INFO_WUNLOCK(&tcbinfo); - + INP_UNLOCK(tp->t_inpcb); soisconnected(so); #ifdef notyet @@ -2954,6 +2954,7 @@ printf("fixup_and_send_ofo\n"); + INP_LOCK_ASSERT(tp->t_inpcb); while ((m = mbufq_dequeue(&toep->out_of_order_queue)) != NULL) { /* * A variety of messages can be waiting but the fields we'll @@ -3192,9 +3193,7 @@ static void t3_reset_listen_child(struct socket *child) { - SOCK_LOCK(child); t3_send_reset(child); - SOCK_UNLOCK(child); } /*