Author: lstewart
Date: Sat Sep 25 04:58:46 2010
New Revision: 213158
URL: http://svn.freebsd.org/changeset/base/213158

Log:
  Internalise reassembly queue related functionality and variables which should
  not be used outside of the reassembly queue implementation. Provide a new
  function to flush all segments from a reassembly queue and call it from the
  appropriate places instead of manipulating the queue directly.
  
  Sponsored by: FreeBSD Foundation
  Reviewed by:  andre, gnn, rpaulo
  MFC after:    2 weeks

Modified:
  head/sys/netinet/tcp_reass.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_var.h

Modified: head/sys/netinet/tcp_reass.c
==============================================================================
--- head/sys/netinet/tcp_reass.c        Sat Sep 25 04:41:42 2010        
(r213157)
+++ head/sys/netinet/tcp_reass.c        Sat Sep 25 04:58:46 2010        
(r213158)
@@ -83,7 +83,8 @@ SYSCTL_VNET_INT(_net_inet_tcp_reass, OID
     &VNET_NAME(tcp_reass_maxseg), 0,
     "Global maximum number of TCP Segments in Reassembly Queue");
 
-VNET_DEFINE(int, tcp_reass_qsize) = 0;
+static VNET_DEFINE(int, tcp_reass_qsize) = 0;
+#define        V_tcp_reass_qsize               VNET(tcp_reass_qsize)
 SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
     &VNET_NAME(tcp_reass_qsize), 0,
     "Global number of TCP Segments currently in Reassembly Queue");
@@ -100,6 +101,9 @@ SYSCTL_VNET_INT(_net_inet_tcp_reass, OID
     &VNET_NAME(tcp_reass_overflows), 0,
     "Global number of TCP Segment Reassembly Queue Overflows");
 
+static VNET_DEFINE(uma_zone_t, tcp_reass_zone);
+#define        V_tcp_reass_zone                VNET(tcp_reass_zone)
+
 /* Initialize TCP reassembly queue */
 static void
 tcp_reass_zone_change(void *tag)
@@ -109,8 +113,6 @@ tcp_reass_zone_change(void *tag)
        uma_zone_set_max(V_tcp_reass_zone, V_tcp_reass_maxseg);
 }
 
-VNET_DEFINE(uma_zone_t, tcp_reass_zone);
-
 void
 tcp_reass_init(void)
 {
@@ -134,6 +136,26 @@ tcp_reass_destroy(void)
 }
 #endif
 
+void
+tcp_reass_flush(struct tcpcb *tp)
+{
+       struct tseg_qent *qe;
+
+       INP_WLOCK_ASSERT(tp->t_inpcb);
+
+       while ((qe = LIST_FIRST(&tp->t_segq)) != NULL) {
+               LIST_REMOVE(qe, tqe_q);
+               m_freem(qe->tqe_m);
+               uma_zfree(V_tcp_reass_zone, qe);
+               tp->t_segqlen--;
+               V_tcp_reass_qsize--;
+       }
+
+       KASSERT((tp->t_segqlen == 0),
+           ("TCP reass queue %p segment count is %d instead of 0 after flush.",
+           tp, tp->t_segqlen));
+}
+
 int
 tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
 {

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c Sat Sep 25 04:41:42 2010        (r213157)
+++ head/sys/netinet/tcp_subr.c Sat Sep 25 04:58:46 2010        (r213158)
@@ -714,7 +714,6 @@ tcp_drop(struct tcpcb *tp, int errno)
 void
 tcp_discardcb(struct tcpcb *tp)
 {
-       struct tseg_qent *q;
        struct inpcb *inp = tp->t_inpcb;
        struct socket *so = inp->inp_socket;
 #ifdef INET6
@@ -801,13 +800,7 @@ tcp_discardcb(struct tcpcb *tp)
        }
 
        /* free the reassembly queue, if any */
-       while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
-               LIST_REMOVE(q, tqe_q);
-               m_freem(q->tqe_m);
-               uma_zfree(V_tcp_reass_zone, q);
-               tp->t_segqlen--;
-               V_tcp_reass_qsize--;
-       }
+       tcp_reass_flush(tp);
        /* Disconnect offload device, if any. */
        tcp_offload_detach(tp);
                
@@ -865,7 +858,6 @@ tcp_drain(void)
                CURVNET_SET(vnet_iter);
                struct inpcb *inpb;
                struct tcpcb *tcpb;
-               struct tseg_qent *te;
 
        /*
         * Walk the tcpbs, if existing, and flush the reassembly queue,
@@ -881,14 +873,7 @@ tcp_drain(void)
                                continue;
                        INP_WLOCK(inpb);
                        if ((tcpb = intotcpcb(inpb)) != NULL) {
-                               while ((te = LIST_FIRST(&tcpb->t_segq))
-                                   != NULL) {
-                                       LIST_REMOVE(te, tqe_q);
-                                       m_freem(te->tqe_m);
-                                       uma_zfree(V_tcp_reass_zone, te);
-                                       tcpb->t_segqlen--;
-                                       V_tcp_reass_qsize--;
-                               }
+                               tcp_reass_flush(tcpb);
                                tcp_clean_sackreport(tcpb);
                        }
                        INP_WUNLOCK(inpb);

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h  Sat Sep 25 04:41:42 2010        (r213157)
+++ head/sys/netinet/tcp_var.h  Sat Sep 25 04:58:46 2010        (r213158)
@@ -44,10 +44,6 @@
 VNET_DECLARE(int, tcp_do_rfc1323);
 #define        V_tcp_do_rfc1323        VNET(tcp_do_rfc1323)
 
-VNET_DECLARE(int, tcp_reass_qsize);
-VNET_DECLARE(struct uma_zone *, tcp_reass_zone);
-#define        V_tcp_reass_qsize       VNET(tcp_reass_qsize)
-#define        V_tcp_reass_zone        VNET(tcp_reass_zone)
 #endif /* _KERNEL */
 
 /* TCP segment queue entry */
@@ -617,6 +613,7 @@ char        *tcp_log_vain(struct in_conninfo *,
            const void *);
 int     tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
 void    tcp_reass_init(void);
+void    tcp_reass_flush(struct tcpcb *);
 #ifdef VIMAGE
 void    tcp_reass_destroy(void);
 #endif
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to