Skip to content

Commit 9eefedd

Browse files
lxinkuba-moo
authored andcommitted
net: add gso_ipv4_max_size and gro_ipv4_max_size per device
This patch introduces gso_ipv4_max_size and gro_ipv4_max_size per device and adds netlink attributes for them, so that IPV4 BIG TCP can be guarded by a separate tunable in the next patch. To not break the old application using "gso/gro_max_size" for IPv4 GSO packets, this patch updates "gso/gro_ipv4_max_size" in netif_set_gso/gro_max_size() if the new size isn't greater than GSO_LEGACY_MAX_SIZE, so that nothing will change even if userspace doesn't realize the new netlink attributes. Signed-off-by: Xin Long <[email protected]> Reviewed-by: David Ahern <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8e08bb7 commit 9eefedd

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

include/linux/netdevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,6 +1964,8 @@ enum netdev_ml_priv_type {
19641964
* @gso_max_segs: Maximum number of segments that can be passed to the
19651965
* NIC for GSO
19661966
* @tso_max_segs: Device (as in HW) limit on the max TSO segment count
1967+
* @gso_ipv4_max_size: Maximum size of generic segmentation offload,
1968+
* for IPv4.
19671969
*
19681970
* @dcbnl_ops: Data Center Bridging netlink ops
19691971
* @num_tc: Number of traffic classes in the net device
@@ -2004,6 +2006,8 @@ enum netdev_ml_priv_type {
20042006
* keep a list of interfaces to be deleted.
20052007
* @gro_max_size: Maximum size of aggregated packet in generic
20062008
* receive offload (GRO)
2009+
* @gro_ipv4_max_size: Maximum size of aggregated packet in generic
2010+
* receive offload (GRO), for IPv4.
20072011
*
20082012
* @dev_addr_shadow: Copy of @dev_addr to catch direct writes.
20092013
* @linkwatch_dev_tracker: refcount tracker used by linkwatch.
@@ -2207,6 +2211,7 @@ struct net_device {
22072211
*/
22082212
#define GRO_MAX_SIZE (8 * 65535u)
22092213
unsigned int gro_max_size;
2214+
unsigned int gro_ipv4_max_size;
22102215
rx_handler_func_t __rcu *rx_handler;
22112216
void __rcu *rx_handler_data;
22122217

@@ -2330,6 +2335,7 @@ struct net_device {
23302335
u16 gso_max_segs;
23312336
#define TSO_MAX_SEGS U16_MAX
23322337
u16 tso_max_segs;
2338+
unsigned int gso_ipv4_max_size;
23332339

23342340
#ifdef CONFIG_DCB
23352341
const struct dcbnl_rtnl_ops *dcbnl_ops;

include/uapi/linux/if_link.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ enum {
374374

375375
IFLA_DEVLINK_PORT,
376376

377+
IFLA_GSO_IPV4_MAX_SIZE,
378+
IFLA_GRO_IPV4_MAX_SIZE,
379+
377380
__IFLA_MAX
378381
};
379382

net/core/dev.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3001,6 +3001,8 @@ void netif_set_tso_max_size(struct net_device *dev, unsigned int size)
30013001
dev->tso_max_size = min(GSO_MAX_SIZE, size);
30023002
if (size < READ_ONCE(dev->gso_max_size))
30033003
netif_set_gso_max_size(dev, size);
3004+
if (size < READ_ONCE(dev->gso_ipv4_max_size))
3005+
netif_set_gso_ipv4_max_size(dev, size);
30043006
}
30053007
EXPORT_SYMBOL(netif_set_tso_max_size);
30063008

@@ -10614,6 +10616,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
1061410616
dev->gso_max_size = GSO_LEGACY_MAX_SIZE;
1061510617
dev->gso_max_segs = GSO_MAX_SEGS;
1061610618
dev->gro_max_size = GRO_LEGACY_MAX_SIZE;
10619+
dev->gso_ipv4_max_size = GSO_LEGACY_MAX_SIZE;
10620+
dev->gro_ipv4_max_size = GRO_LEGACY_MAX_SIZE;
1061710621
dev->tso_max_size = TSO_LEGACY_MAX_SIZE;
1061810622
dev->tso_max_segs = TSO_MAX_SEGS;
1061910623
dev->upper_level = 1;

net/core/dev.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ static inline void netif_set_gso_max_size(struct net_device *dev,
100100
{
101101
/* dev->gso_max_size is read locklessly from sk_setup_caps() */
102102
WRITE_ONCE(dev->gso_max_size, size);
103+
if (size <= GSO_LEGACY_MAX_SIZE)
104+
WRITE_ONCE(dev->gso_ipv4_max_size, size);
103105
}
104106

105107
static inline void netif_set_gso_max_segs(struct net_device *dev,
@@ -114,6 +116,22 @@ static inline void netif_set_gro_max_size(struct net_device *dev,
114116
{
115117
/* This pairs with the READ_ONCE() in skb_gro_receive() */
116118
WRITE_ONCE(dev->gro_max_size, size);
119+
if (size <= GRO_LEGACY_MAX_SIZE)
120+
WRITE_ONCE(dev->gro_ipv4_max_size, size);
121+
}
122+
123+
static inline void netif_set_gso_ipv4_max_size(struct net_device *dev,
124+
unsigned int size)
125+
{
126+
/* dev->gso_ipv4_max_size is read locklessly from sk_setup_caps() */
127+
WRITE_ONCE(dev->gso_ipv4_max_size, size);
128+
}
129+
130+
static inline void netif_set_gro_ipv4_max_size(struct net_device *dev,
131+
unsigned int size)
132+
{
133+
/* This pairs with the READ_ONCE() in skb_gro_receive() */
134+
WRITE_ONCE(dev->gro_ipv4_max_size, size);
117135
}
118136

119137
#endif

net/core/rtnetlink.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
10741074
+ nla_total_size(4) /* IFLA_GSO_MAX_SEGS */
10751075
+ nla_total_size(4) /* IFLA_GSO_MAX_SIZE */
10761076
+ nla_total_size(4) /* IFLA_GRO_MAX_SIZE */
1077+
+ nla_total_size(4) /* IFLA_GSO_IPV4_MAX_SIZE */
1078+
+ nla_total_size(4) /* IFLA_GRO_IPV4_MAX_SIZE */
10771079
+ nla_total_size(4) /* IFLA_TSO_MAX_SIZE */
10781080
+ nla_total_size(4) /* IFLA_TSO_MAX_SEGS */
10791081
+ nla_total_size(1) /* IFLA_OPERSTATE */
@@ -1807,6 +1809,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
18071809
nla_put_u32(skb, IFLA_GSO_MAX_SEGS, dev->gso_max_segs) ||
18081810
nla_put_u32(skb, IFLA_GSO_MAX_SIZE, dev->gso_max_size) ||
18091811
nla_put_u32(skb, IFLA_GRO_MAX_SIZE, dev->gro_max_size) ||
1812+
nla_put_u32(skb, IFLA_GSO_IPV4_MAX_SIZE, dev->gso_ipv4_max_size) ||
1813+
nla_put_u32(skb, IFLA_GRO_IPV4_MAX_SIZE, dev->gro_ipv4_max_size) ||
18101814
nla_put_u32(skb, IFLA_TSO_MAX_SIZE, dev->tso_max_size) ||
18111815
nla_put_u32(skb, IFLA_TSO_MAX_SEGS, dev->tso_max_segs) ||
18121816
#ifdef CONFIG_RPS
@@ -1968,6 +1972,8 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
19681972
[IFLA_TSO_MAX_SIZE] = { .type = NLA_REJECT },
19691973
[IFLA_TSO_MAX_SEGS] = { .type = NLA_REJECT },
19701974
[IFLA_ALLMULTI] = { .type = NLA_REJECT },
1975+
[IFLA_GSO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
1976+
[IFLA_GRO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
19711977
};
19721978

19731979
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
@@ -2883,6 +2889,29 @@ static int do_setlink(const struct sk_buff *skb,
28832889
}
28842890
}
28852891

2892+
if (tb[IFLA_GSO_IPV4_MAX_SIZE]) {
2893+
u32 max_size = nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]);
2894+
2895+
if (max_size > dev->tso_max_size) {
2896+
err = -EINVAL;
2897+
goto errout;
2898+
}
2899+
2900+
if (dev->gso_ipv4_max_size ^ max_size) {
2901+
netif_set_gso_ipv4_max_size(dev, max_size);
2902+
status |= DO_SETLINK_MODIFIED;
2903+
}
2904+
}
2905+
2906+
if (tb[IFLA_GRO_IPV4_MAX_SIZE]) {
2907+
u32 gro_max_size = nla_get_u32(tb[IFLA_GRO_IPV4_MAX_SIZE]);
2908+
2909+
if (dev->gro_ipv4_max_size ^ gro_max_size) {
2910+
netif_set_gro_ipv4_max_size(dev, gro_max_size);
2911+
status |= DO_SETLINK_MODIFIED;
2912+
}
2913+
}
2914+
28862915
if (tb[IFLA_OPERSTATE])
28872916
set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
28882917

@@ -3325,6 +3354,10 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
33253354
netif_set_gso_max_segs(dev, nla_get_u32(tb[IFLA_GSO_MAX_SEGS]));
33263355
if (tb[IFLA_GRO_MAX_SIZE])
33273356
netif_set_gro_max_size(dev, nla_get_u32(tb[IFLA_GRO_MAX_SIZE]));
3357+
if (tb[IFLA_GSO_IPV4_MAX_SIZE])
3358+
netif_set_gso_ipv4_max_size(dev, nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]));
3359+
if (tb[IFLA_GRO_IPV4_MAX_SIZE])
3360+
netif_set_gro_ipv4_max_size(dev, nla_get_u32(tb[IFLA_GRO_IPV4_MAX_SIZE]));
33283361

33293362
return dev;
33303363
}

0 commit comments

Comments
 (0)