diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netlink/specs/rt-link.yaml index 5217d0bb4a3a..7a72cd1b7e1e 100644 --- a/Documentation/netlink/specs/rt-link.yaml +++ b/Documentation/netlink/specs/rt-link.yaml @@ -1091,6 +1091,10 @@ attribute-sets: - name: tailroom type: u16 + - + name: pacing-offload + type: u32 + doc: Enable EDT pacing offload (0 - disabled, 1 - enabled). - name: prop-list-link-attrs subset-of: link-attrs @@ -2559,6 +2563,7 @@ operations: - devlink-port - gso-ipv4-max-size - gro-ipv4-max-size + - pacing-offload dump: request: value: 18 diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst index 512f6d6fa3d8..8eceaa80b686 100644 --- a/Documentation/networking/net_cachelines/net_device.rst +++ b/Documentation/networking/net_cachelines/net_device.rst @@ -11,6 +11,7 @@ Type Name fastpath_tx_acce unsigned_long:32 priv_flags read_mostly __dev_queue_xmit(tx) unsigned_long:1 lltx read_mostly HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx) unsigned_long:2 netmem_tx:2; read_mostly +unsigned_long:1 pacing_offload read_mostly sch_fq char name[16] struct netdev_name_node* name_node struct dev_ifalias* ifalias diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 707b2e51c2b9..1f0710eef185 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1840,6 +1840,7 @@ enum netdev_reg_state { * drivers. Mainly used by logical interfaces, such as * bonding and tunnels * @netmem_tx: device netmem TX mode + * @pacing_offload: enable EDT pacing offload. * * @name: This is the first field of the "visible" part of this structure * (i.e. as seen by users in the "Space.c" file). It is the name @@ -2170,6 +2171,7 @@ struct net_device { unsigned long priv_flags:32; unsigned long lltx:1; unsigned long netmem_tx:2; + unsigned long pacing_offload:1; ); const struct net_device_ops *netdev_ops; const struct header_ops *header_ops; diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 43cecca49f01..245b36204525 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -381,6 +381,7 @@ enum { IFLA_NETNS_IMMUTABLE, IFLA_HEADROOM, IFLA_TAILROOM, + IFLA_PACING_OFFLOAD, __IFLA_MAX }; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index be9d1625bac3..e3444fd24061 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1396,6 +1396,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + rtnl_devlink_port_size(dev) + rtnl_dpll_pin_size() + nla_total_size(8) /* IFLA_MAX_PACING_OFFLOAD_HORIZON */ + + nla_total_size(4) /* IFLA_PACING_OFFLOAD */ + nla_total_size(2) /* IFLA_HEADROOM */ + nla_total_size(2) /* IFLA_TAILROOM */ + rtnl_dev_parent_size(dev) @@ -2176,6 +2177,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, READ_ONCE(dev->tso_max_segs)) || nla_put_uint(skb, IFLA_MAX_PACING_OFFLOAD_HORIZON, READ_ONCE(dev->max_pacing_offload_horizon)) || + nla_put_u32(skb, IFLA_PACING_OFFLOAD, + dev->pacing_offload) || #ifdef CONFIG_RPS nla_put_u32(skb, IFLA_NUM_RX_QUEUES, READ_ONCE(dev->num_rx_queues)) || @@ -2349,9 +2352,11 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_ALLMULTI] = { .type = NLA_REJECT }, [IFLA_GSO_IPV4_MAX_SIZE] = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1), [IFLA_GRO_IPV4_MAX_SIZE] = { .type = NLA_U32 }, + [IFLA_MAX_PACING_OFFLOAD_HORIZON] = { .type = NLA_REJECT }, [IFLA_NETNS_IMMUTABLE] = { .type = NLA_REJECT }, [IFLA_HEADROOM] = { .type = NLA_REJECT }, [IFLA_TAILROOM] = { .type = NLA_REJECT }, + [IFLA_PACING_OFFLOAD] = NLA_POLICY_MAX(NLA_U32, 1), }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { @@ -2825,6 +2830,14 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[], return -EINVAL; } + if (tb[IFLA_PACING_OFFLOAD]) { + if (nla_get_u32(tb[IFLA_PACING_OFFLOAD]) && + !dev->max_pacing_offload_horizon) { + NL_SET_ERR_MSG(extack, "pacing offload not supported by device"); + return -EOPNOTSUPP; + } + } + if (tb[IFLA_AF_SPEC]) { struct nlattr *af; int rem, err; @@ -3342,6 +3355,15 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev, } } + if (tb[IFLA_PACING_OFFLOAD]) { + bool val = nla_get_u32(tb[IFLA_PACING_OFFLOAD]); + + if (dev->pacing_offload != val) { + dev->pacing_offload = val; + status |= DO_SETLINK_MODIFIED; + } + } + if (tb[IFLA_OPERSTATE]) set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));