Author: andre
Date: Fri Jul  5 13:48:32 2013
New Revision: 252781
URL: http://svnweb.freebsd.org/changeset/base/252781

Log:
  MFC r291296, r291297, r291393:
  
   Allow drivers to specify a maximum TSP length in bytes if they
   are limited in the amount of data they can handle at once.
  
   Apply this to the netfront driver.
  
   Spare fields in struct tcpcb and struct ifnet are used to keep
   the structure sizes the same.

Modified:
  stable/9/sys/dev/xen/netfront/netfront.c
  stable/9/sys/net/if.c
  stable/9/sys/net/if_var.h
  stable/9/sys/netinet/tcp_input.c
  stable/9/sys/netinet/tcp_output.c
  stable/9/sys/netinet/tcp_subr.c
  stable/9/sys/netinet/tcp_var.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/net/   (props changed)

Modified: stable/9/sys/dev/xen/netfront/netfront.c
==============================================================================
--- stable/9/sys/dev/xen/netfront/netfront.c    Fri Jul  5 13:37:57 2013        
(r252780)
+++ stable/9/sys/dev/xen/netfront/netfront.c    Fri Jul  5 13:48:32 2013        
(r252781)
@@ -134,6 +134,7 @@ static const int MODPARM_rx_flip = 0;
  * to mirror the Linux MAX_SKB_FRAGS constant.
  */
 #define        MAX_TX_REQ_FRAGS (65536 / PAGE_SIZE + 2)
+#define        NF_TSO_MAXBURST ((IP_MAXPACKET / PAGE_SIZE) * MCLBYTES)
 
 #define RX_COPY_THRESHOLD 256
 
@@ -2123,6 +2124,7 @@ create_netdev(device_t dev)
        
        ifp->if_hwassist = XN_CSUM_FEATURES;
        ifp->if_capabilities = IFCAP_HWCSUM;
+       ifp->if_hw_tsomax = NF_TSO_MAXBURST;
        
        ether_ifattach(ifp, np->mac);
        callout_init(&np->xn_stat_ch, CALLOUT_MPSAFE);

Modified: stable/9/sys/net/if.c
==============================================================================
--- stable/9/sys/net/if.c       Fri Jul  5 13:37:57 2013        (r252780)
+++ stable/9/sys/net/if.c       Fri Jul  5 13:48:32 2013        (r252781)
@@ -74,18 +74,18 @@
 #include <net/vnet.h>
 
 #if defined(INET) || defined(INET6)
-/*XXX*/
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#include <netinet/ip.h>
 #include <netinet/ip_carp.h>
+#ifdef INET
+#include <netinet/if_ether.h>
+#endif /* INET */
 #ifdef INET6
 #include <netinet6/in6_var.h>
 #include <netinet6/in6_ifattach.h>
-#endif
-#endif
-#ifdef INET
-#include <netinet/if_ether.h>
-#endif
+#endif /* INET6 */
+#endif /* INET || INET6 */
 
 #include <security/mac/mac_framework.h>
 
@@ -669,6 +669,15 @@ if_attach_internal(struct ifnet *ifp, in
                TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
                /* Reliably crash if used uninitialized. */
                ifp->if_broadcastaddr = NULL;
+
+#if defined(INET) || defined(INET6)
+               /* Initialize to max value. */
+               if (ifp->if_hw_tsomax == 0)
+                       ifp->if_hw_tsomax = IP_MAXPACKET;
+               KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET &&
+                   ifp->if_hw_tsomax >= IP_MAXPACKET / 8,
+                   ("%s: tsomax outside of range", __func__));
+#endif
        }
 #ifdef VIMAGE
        else {

Modified: stable/9/sys/net/if_var.h
==============================================================================
--- stable/9/sys/net/if_var.h   Fri Jul  5 13:37:57 2013        (r252780)
+++ stable/9/sys/net/if_var.h   Fri Jul  5 13:48:32 2013        (r252781)
@@ -205,7 +205,11 @@ struct ifnet {
         * be used with care where binary compatibility is required.
         */
        char    if_cspare[3];
-       int     if_ispare[4];
+       u_int   if_hw_tsomax;           /* tso burst length limit, the minmum
+                                        * is (IP_MAXPACKET / 8).
+                                        * XXXAO: Have to find a better place
+                                        * for it eventually. */
+       int     if_ispare[3];
        void    *if_pspare[8];          /* 1 netmap, 7 TDB */
 };
 

Modified: stable/9/sys/netinet/tcp_input.c
==============================================================================
--- stable/9/sys/netinet/tcp_input.c    Fri Jul  5 13:37:57 2013        
(r252780)
+++ stable/9/sys/netinet/tcp_input.c    Fri Jul  5 13:48:32 2013        
(r252781)
@@ -3393,7 +3393,7 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt
  */
 void
 tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer,
-    struct hc_metrics_lite *metricptr, int *mtuflags)
+    struct hc_metrics_lite *metricptr, struct tcp_ifcap *cap)
 {
        int mss = 0;
        u_long maxmtu = 0;
@@ -3420,7 +3420,7 @@ tcp_mss_update(struct tcpcb *tp, int off
        /* Initialize. */
 #ifdef INET6
        if (isipv6) {
-               maxmtu = tcp_maxmtu6(&inp->inp_inc, mtuflags);
+               maxmtu = tcp_maxmtu6(&inp->inp_inc, cap);
                tp->t_maxopd = tp->t_maxseg = V_tcp_v6mssdflt;
        }
 #endif
@@ -3429,7 +3429,7 @@ tcp_mss_update(struct tcpcb *tp, int off
 #endif
 #ifdef INET
        {
-               maxmtu = tcp_maxmtu(&inp->inp_inc, mtuflags);
+               maxmtu = tcp_maxmtu(&inp->inp_inc, cap);
                tp->t_maxopd = tp->t_maxseg = V_tcp_mssdflt;
        }
 #endif
@@ -3571,11 +3571,12 @@ tcp_mss(struct tcpcb *tp, int offer)
        struct inpcb *inp;
        struct socket *so;
        struct hc_metrics_lite metrics;
-       int mtuflags = 0;
+       struct tcp_ifcap cap;
 
        KASSERT(tp != NULL, ("%s: tp == NULL", __func__));
-       
-       tcp_mss_update(tp, offer, -1, &metrics, &mtuflags);
+
+       bzero(&cap, sizeof(cap));
+       tcp_mss_update(tp, offer, -1, &metrics, &cap);
 
        mss = tp->t_maxseg;
        inp = tp->t_inpcb;
@@ -3620,8 +3621,10 @@ tcp_mss(struct tcpcb *tp, int offer)
        SOCKBUF_UNLOCK(&so->so_rcv);
 
        /* Check the interface for TSO capabilities. */
-       if (mtuflags & CSUM_TSO)
+       if (cap.ifcap & CSUM_TSO) {
                tp->t_flags |= TF_TSO;
+               tp->t_tsomax = cap.tsomax;
+       }
 }
 
 /*

Modified: stable/9/sys/netinet/tcp_output.c
==============================================================================
--- stable/9/sys/netinet/tcp_output.c   Fri Jul  5 13:37:57 2013        
(r252780)
+++ stable/9/sys/netinet/tcp_output.c   Fri Jul  5 13:48:32 2013        
(r252781)
@@ -752,12 +752,13 @@ send:
                            ("%s: TSO can't do IP options", __func__));
 
                        /*
-                        * Limit a burst to IP_MAXPACKET minus IP,
+                        * Limit a burst to t_tsomax minus IP,
                         * TCP and options length to keep ip->ip_len
-                        * from overflowing.
+                        * from overflowing or exceeding the maximum
+                        * length allowed by the network interface.
                         */
-                       if (len > IP_MAXPACKET - hdrlen) {
-                               len = IP_MAXPACKET - hdrlen;
+                       if (len > tp->t_tsomax - hdrlen) {
+                               len = tp->t_tsomax - hdrlen;
                                sendalot = 1;
                        }
 

Modified: stable/9/sys/netinet/tcp_subr.c
==============================================================================
--- stable/9/sys/netinet/tcp_subr.c     Fri Jul  5 13:37:57 2013        
(r252780)
+++ stable/9/sys/netinet/tcp_subr.c     Fri Jul  5 13:48:32 2013        
(r252781)
@@ -1714,7 +1714,7 @@ tcp_mtudisc(struct inpcb *inp, int mtuof
  * tcp_mss_update to get the peer/interface MTU.
  */
 u_long
-tcp_maxmtu(struct in_conninfo *inc, int *flags)
+tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap)
 {
        struct route sro;
        struct sockaddr_in *dst;
@@ -1739,10 +1739,11 @@ tcp_maxmtu(struct in_conninfo *inc, int 
                        maxmtu = min(sro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu);
 
                /* Report additional interface capabilities. */
-               if (flags != NULL) {
+               if (cap != NULL) {
                        if (ifp->if_capenable & IFCAP_TSO4 &&
                            ifp->if_hwassist & CSUM_TSO)
-                               *flags |= CSUM_TSO;
+                               cap->ifcap |= CSUM_TSO;
+                               cap->tsomax = ifp->if_hw_tsomax;
                }
                RTFREE(sro.ro_rt);
        }
@@ -1752,7 +1753,7 @@ tcp_maxmtu(struct in_conninfo *inc, int 
 
 #ifdef INET6
 u_long
-tcp_maxmtu6(struct in_conninfo *inc, int *flags)
+tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap)
 {
        struct route_in6 sro6;
        struct ifnet *ifp;
@@ -1776,10 +1777,11 @@ tcp_maxmtu6(struct in_conninfo *inc, int
                                     IN6_LINKMTU(sro6.ro_rt->rt_ifp));
 
                /* Report additional interface capabilities. */
-               if (flags != NULL) {
+               if (cap != NULL) {
                        if (ifp->if_capenable & IFCAP_TSO6 &&
                            ifp->if_hwassist & CSUM_TSO)
-                               *flags |= CSUM_TSO;
+                               cap->ifcap |= CSUM_TSO;
+                               cap->tsomax = ifp->if_hw_tsomax;
                }
                RTFREE(sro6.ro_rt);
        }

Modified: stable/9/sys/netinet/tcp_var.h
==============================================================================
--- stable/9/sys/netinet/tcp_var.h      Fri Jul  5 13:37:57 2013        
(r252780)
+++ stable/9/sys/netinet/tcp_var.h      Fri Jul  5 13:48:32 2013        
(r252781)
@@ -208,7 +208,9 @@ struct tcpcb {
        u_int   t_keepintvl;            /* interval between keepalives */
        u_int   t_keepcnt;              /* number of keepalives before close */
 
-       uint32_t t_ispare[8];           /* 5 UTO, 3 TBD */
+       u_int   t_tsomax;               /* tso burst length limit */
+
+       uint32_t t_ispare[7];           /* 5 UTO, 2 TBD */
        void    *t_pspare2[4];          /* 4 TBD */
        uint64_t _pad[6];               /* 6 TBD (1-2 CC/RTT?) */
 };
@@ -324,6 +326,15 @@ struct hc_metrics_lite {   /* must stay in
        u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */
 };
 
+/*
+ * Used by tcp_maxmtu() to communicate interface specific features
+ * and limits at the time of connection setup.
+ */
+struct tcp_ifcap {
+       int     ifcap;
+       u_int   tsomax;
+};
+
 #ifndef _NETINET_IN_PCB_H_
 struct in_conninfo;
 #endif /* _NETINET_IN_PCB_H_ */
@@ -673,10 +684,10 @@ void       tcp_reass_flush(struct tcpcb *);
 void    tcp_reass_destroy(void);
 #endif
 void    tcp_input(struct mbuf *, int);
-u_long  tcp_maxmtu(struct in_conninfo *, int *);
-u_long  tcp_maxmtu6(struct in_conninfo *, int *);
+u_long  tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
+u_long  tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
 void    tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
-           int *);
+           struct tcp_ifcap *);
 void    tcp_mss(struct tcpcb *, int);
 int     tcp_mssopt(struct in_conninfo *);
 struct inpcb *
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "[email protected]"

Reply via email to