Skip to content

Commit 82cc1a7

Browse files
ppwaskiedavem330
authored andcommitted
[NET]: Add per-connection option to set max TSO frame size
Update: My mailer ate one of Jarek's feedback mails... Fixed the parameter in netif_set_gso_max_size() to be u32, not u16. Fixed the whitespace issue due to a patch import botch. Changed the types from u32 to unsigned int to be more consistent with other variables in the area. Also brought the patch up to the latest net-2.6.26 tree. Update: Made gso_max_size container 32 bits, not 16. Moved the location of gso_max_size within netdev to be less hotpath. Made more consistent names between the sock and netdev layers, and added a define for the max GSO size. Update: Respun for net-2.6.26 tree. Update: changed max_gso_frame_size and sk_gso_max_size from signed to unsigned - thanks Stephen! This patch adds the ability for device drivers to control the size of the TSO frames being sent to them, per TCP connection. By setting the netdevice's gso_max_size value, the socket layer will set the GSO frame size based on that value. This will propogate into the TCP layer, and send TSO's of that size to the hardware. This can be desirable to help tune the bursty nature of TSO on a per-adapter basis, where one may have 1 GbE and 10 GbE devices coexisting in a system, one running multiqueue and the other not, etc. This can also be desirable for devices that cannot support full 64 KB TSO's, but still want to benefit from some level of segmentation offloading. Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a25606c commit 82cc1a7

File tree

5 files changed

+19
-4
lines changed

5 files changed

+19
-4
lines changed

include/linux/netdevice.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,10 @@ struct net_device
724724
/* rtnetlink link ops */
725725
const struct rtnl_link_ops *rtnl_link_ops;
726726

727+
/* for setting kernel sock attribute on TCP connection setup */
728+
#define GSO_MAX_SIZE 65536
729+
unsigned int gso_max_size;
730+
727731
/* The TX queue control structures */
728732
unsigned int egress_subqueue_count;
729733
struct net_device_subqueue egress_subqueue[1];
@@ -1475,6 +1479,12 @@ static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
14751479
unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
14761480
}
14771481

1482+
static inline void netif_set_gso_max_size(struct net_device *dev,
1483+
unsigned int size)
1484+
{
1485+
dev->gso_max_size = size;
1486+
}
1487+
14781488
/* On bonding slaves other than the currently active slave, suppress
14791489
* duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
14801490
* ARP on active-backup slaves with arp_validate enabled.

include/net/sock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct sock_common {
151151
* @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
152152
* @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
153153
* @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
154+
* @sk_gso_max_size: Maximum GSO segment size to build
154155
* @sk_lingertime: %SO_LINGER l_linger setting
155156
* @sk_backlog: always used with the per-socket spinlock held
156157
* @sk_callback_lock: used with the callbacks in the end of this struct
@@ -237,6 +238,7 @@ struct sock {
237238
gfp_t sk_allocation;
238239
int sk_route_caps;
239240
int sk_gso_type;
241+
unsigned int sk_gso_max_size;
240242
int sk_rcvlowat;
241243
unsigned long sk_flags;
242244
unsigned long sk_lingertime;

net/core/dev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4021,6 +4021,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
40214021
}
40224022

40234023
dev->egress_subqueue_count = queue_count;
4024+
dev->gso_max_size = GSO_MAX_SIZE;
40244025

40254026
dev->get_stats = internal_stats;
40264027
netpoll_netdev_init(dev);

net/core/sock.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,10 +1095,12 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
10951095
if (sk->sk_route_caps & NETIF_F_GSO)
10961096
sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
10971097
if (sk_can_gso(sk)) {
1098-
if (dst->header_len)
1098+
if (dst->header_len) {
10991099
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
1100-
else
1100+
} else {
11011101
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
1102+
sk->sk_gso_max_size = dst->dev->gso_max_size;
1103+
}
11021104
}
11031105
}
11041106
EXPORT_SYMBOL_GPL(sk_setup_caps);

net/ipv4/tcp_output.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
998998
xmit_size_goal = mss_now;
999999

10001000
if (doing_tso) {
1001-
xmit_size_goal = (65535 -
1001+
xmit_size_goal = ((sk->sk_gso_max_size - 1) -
10021002
inet_csk(sk)->icsk_af_ops->net_header_len -
10031003
inet_csk(sk)->icsk_ext_hdr_len -
10041004
tp->tcp_header_len);
@@ -1282,7 +1282,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
12821282
limit = min(send_win, cong_win);
12831283

12841284
/* If a full-sized TSO skb can be sent, do it. */
1285-
if (limit >= 65536)
1285+
if (limit >= sk->sk_gso_max_size)
12861286
goto send_now;
12871287

12881288
if (sysctl_tcp_tso_win_divisor) {

0 commit comments

Comments
 (0)