diff mbox series

[net-next,2/2] veth: allow configuring GSO maximums

Message ID 20171201201158.25594-3-sthemmin@microsoft.com
State Changes Requested, archived
Delegated to: David Miller
Headers show
Series allow setting gso_maximum values | expand

Commit Message

Stephen Hemminger Dec. 1, 2017, 8:11 p.m. UTC
Veth's can be used in environments (like Azure) where the underlying
network device is impacted by large GSO packets. This patch allows
gso maximum values to be passed in when creating the device via
netlink.

In theory, other pseudo devices could also use netlink attributes
to set GSO maximums but for now veth is what has been observed
to be an issue.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/net/veth.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

David Ahern Dec. 4, 2017, 2:43 a.m. UTC | #1
On 12/1/17 1:11 PM, Stephen Hemminger wrote:
> diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> index f5438d0978ca..510c058ba227 100644
> --- a/drivers/net/veth.c
> +++ b/drivers/net/veth.c
> @@ -410,6 +410,26 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
>  	if (ifmp && (dev->ifindex != 0))
>  		peer->ifindex = ifmp->ifi_index;
>  
> +	if (tbp[IFLA_GSO_MAX_SIZE]) {
> +		u32 max_size = nla_get_u32(tbp[IFLA_GSO_MAX_SIZE]);
> +
> +		if (max_size > GSO_MAX_SIZE)
> +			return -EINVAL;
> +
> +		peer->gso_max_size = max_size;
> +		dev->gso_max_size = max_size;
> +	}
> +
> +	if (tbp[IFLA_GSO_MAX_SEGS]) {
> +		u32 max_segs = nla_get_u32(tbp[IFLA_GSO_MAX_SEGS]);
> +
> +		if (max_segs > GSO_MAX_SEGS)
> +			return -EINVAL;
> +
> +		peer->gso_max_segs = max_segs;
> +		dev->gso_max_segs = max_segs;
> +	}
> +
>  	err = register_netdevice(peer);
>  	put_net(net);
>  	net = NULL;
> 

Given the role of veth it seems odd to only allow these to be set at
create time. I think Solio is saying the same with respect to the Docker
use case.
Cong Wang Dec. 5, 2017, 12:03 a.m. UTC | #2
On Fri, Dec 1, 2017 at 12:11 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> Veth's can be used in environments (like Azure) where the underlying
> network device is impacted by large GSO packets. This patch allows
> gso maximum values to be passed in when creating the device via
> netlink.
>
> In theory, other pseudo devices could also use netlink attributes
> to set GSO maximums but for now veth is what has been observed
> to be an issue.

It looks odd that you only allow setting them but not dumping them.
Eric Dumazet Dec. 5, 2017, 1:04 a.m. UTC | #3
On Mon, 2017-12-04 at 16:03 -0800, Cong Wang wrote:
> On Fri, Dec 1, 2017 at 12:11 PM, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> > Veth's can be used in environments (like Azure) where the
> > underlying
> > network device is impacted by large GSO packets. This patch allows
> > gso maximum values to be passed in when creating the device via
> > netlink.
> > 
> > In theory, other pseudo devices could also use netlink attributes
> > to set GSO maximums but for now veth is what has been observed
> > to be an issue.
> 
> It looks odd that you only allow setting them but not dumping them.

Dump is already supported/provided by core stack

# ip -d link sh dev wlan0
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP
mode DORMANT group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff promiscuity 0
addrgenmode none numtxqueues 4 numrxqueues 1 gso_max_size 65536
gso_max_segs 65535
diff mbox series

Patch

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index f5438d0978ca..510c058ba227 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -410,6 +410,26 @@  static int veth_newlink(struct net *src_net, struct net_device *dev,
 	if (ifmp && (dev->ifindex != 0))
 		peer->ifindex = ifmp->ifi_index;
 
+	if (tbp[IFLA_GSO_MAX_SIZE]) {
+		u32 max_size = nla_get_u32(tbp[IFLA_GSO_MAX_SIZE]);
+
+		if (max_size > GSO_MAX_SIZE)
+			return -EINVAL;
+
+		peer->gso_max_size = max_size;
+		dev->gso_max_size = max_size;
+	}
+
+	if (tbp[IFLA_GSO_MAX_SEGS]) {
+		u32 max_segs = nla_get_u32(tbp[IFLA_GSO_MAX_SEGS]);
+
+		if (max_segs > GSO_MAX_SEGS)
+			return -EINVAL;
+
+		peer->gso_max_segs = max_segs;
+		dev->gso_max_segs = max_segs;
+	}
+
 	err = register_netdevice(peer);
 	put_net(net);
 	net = NULL;