mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
net: core: Add offload stats to if_stats_msg
Add a nested attribute of offload stats to if_stats_msg named IFLA_STATS_LINK_OFFLOAD_XSTATS. Under it, add SW stats, meaning stats only per packets that went via slowpath to the cpu, named IFLA_OFFLOAD_XSTATS_CPU_HIT. Signed-off-by: Nogah Frankel <nogahf@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2c9d85d4d8
commit
69ae6ad2ff
@ -826,6 +826,7 @@ enum {
|
||||
IFLA_STATS_LINK_64,
|
||||
IFLA_STATS_LINK_XSTATS,
|
||||
IFLA_STATS_LINK_XSTATS_SLAVE,
|
||||
IFLA_STATS_LINK_OFFLOAD_XSTATS,
|
||||
__IFLA_STATS_MAX,
|
||||
};
|
||||
|
||||
@ -845,6 +846,14 @@ enum {
|
||||
};
|
||||
#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
|
||||
|
||||
/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */
|
||||
enum {
|
||||
IFLA_OFFLOAD_XSTATS_UNSPEC,
|
||||
IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */
|
||||
__IFLA_OFFLOAD_XSTATS_MAX
|
||||
};
|
||||
#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
|
||||
|
||||
/* XDP section */
|
||||
|
||||
enum {
|
||||
|
@ -3577,6 +3577,91 @@ static bool stats_attr_valid(unsigned int mask, int attrid, int idxattr)
|
||||
(!idxattr || idxattr == attrid);
|
||||
}
|
||||
|
||||
#define IFLA_OFFLOAD_XSTATS_FIRST (IFLA_OFFLOAD_XSTATS_UNSPEC + 1)
|
||||
static int rtnl_get_offload_stats_attr_size(int attr_id)
|
||||
{
|
||||
switch (attr_id) {
|
||||
case IFLA_OFFLOAD_XSTATS_CPU_HIT:
|
||||
return sizeof(struct rtnl_link_stats64);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtnl_get_offload_stats(struct sk_buff *skb, struct net_device *dev,
|
||||
int *prividx)
|
||||
{
|
||||
struct nlattr *attr = NULL;
|
||||
int attr_id, size;
|
||||
void *attr_data;
|
||||
int err;
|
||||
|
||||
if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
|
||||
dev->netdev_ops->ndo_get_offload_stats))
|
||||
return -ENODATA;
|
||||
|
||||
for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
|
||||
attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
|
||||
if (attr_id < *prividx)
|
||||
continue;
|
||||
|
||||
size = rtnl_get_offload_stats_attr_size(attr_id);
|
||||
if (!size)
|
||||
continue;
|
||||
|
||||
if (!dev->netdev_ops->ndo_has_offload_stats(attr_id))
|
||||
continue;
|
||||
|
||||
attr = nla_reserve_64bit(skb, attr_id, size,
|
||||
IFLA_OFFLOAD_XSTATS_UNSPEC);
|
||||
if (!attr)
|
||||
goto nla_put_failure;
|
||||
|
||||
attr_data = nla_data(attr);
|
||||
memset(attr_data, 0, size);
|
||||
err = dev->netdev_ops->ndo_get_offload_stats(attr_id, dev,
|
||||
attr_data);
|
||||
if (err)
|
||||
goto get_offload_stats_failure;
|
||||
}
|
||||
|
||||
if (!attr)
|
||||
return -ENODATA;
|
||||
|
||||
*prividx = 0;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
err = -EMSGSIZE;
|
||||
get_offload_stats_failure:
|
||||
*prividx = attr_id;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rtnl_get_offload_stats_size(const struct net_device *dev)
|
||||
{
|
||||
int nla_size = 0;
|
||||
int attr_id;
|
||||
int size;
|
||||
|
||||
if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
|
||||
dev->netdev_ops->ndo_get_offload_stats))
|
||||
return 0;
|
||||
|
||||
for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
|
||||
attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
|
||||
if (!dev->netdev_ops->ndo_has_offload_stats(attr_id))
|
||||
continue;
|
||||
size = rtnl_get_offload_stats_attr_size(attr_id);
|
||||
nla_size += nla_total_size_64bit(size);
|
||||
}
|
||||
|
||||
if (nla_size != 0)
|
||||
nla_size += nla_total_size(0);
|
||||
|
||||
return nla_size;
|
||||
}
|
||||
|
||||
static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
int type, u32 pid, u32 seq, u32 change,
|
||||
unsigned int flags, unsigned int filter_mask,
|
||||
@ -3586,6 +3671,7 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
struct nlmsghdr *nlh;
|
||||
struct nlattr *attr;
|
||||
int s_prividx = *prividx;
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@ -3614,8 +3700,6 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
|
||||
|
||||
if (ops && ops->fill_linkxstats) {
|
||||
int err;
|
||||
|
||||
*idxattr = IFLA_STATS_LINK_XSTATS;
|
||||
attr = nla_nest_start(skb,
|
||||
IFLA_STATS_LINK_XSTATS);
|
||||
@ -3639,8 +3723,6 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
if (master)
|
||||
ops = master->rtnl_link_ops;
|
||||
if (ops && ops->fill_linkxstats) {
|
||||
int err;
|
||||
|
||||
*idxattr = IFLA_STATS_LINK_XSTATS_SLAVE;
|
||||
attr = nla_nest_start(skb,
|
||||
IFLA_STATS_LINK_XSTATS_SLAVE);
|
||||
@ -3655,6 +3737,24 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_OFFLOAD_XSTATS,
|
||||
*idxattr)) {
|
||||
*idxattr = IFLA_STATS_LINK_OFFLOAD_XSTATS;
|
||||
attr = nla_nest_start(skb, IFLA_STATS_LINK_OFFLOAD_XSTATS);
|
||||
if (!attr)
|
||||
goto nla_put_failure;
|
||||
|
||||
err = rtnl_get_offload_stats(skb, dev, prividx);
|
||||
if (err == -ENODATA)
|
||||
nla_nest_cancel(skb, attr);
|
||||
else
|
||||
nla_nest_end(skb, attr);
|
||||
|
||||
if (err && err != -ENODATA)
|
||||
goto nla_put_failure;
|
||||
*idxattr = 0;
|
||||
}
|
||||
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
return 0;
|
||||
@ -3708,6 +3808,9 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_OFFLOAD_XSTATS, 0))
|
||||
size += rtnl_get_offload_stats_size(dev);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user