Thu, May 12, 2016 at 01:33:11PM CEST, niko...@cumulusnetworks.com wrote: > >> On May 12, 2016, at 12:59 PM, Jiri Pirko <j...@resnulli.us> wrote: >> >> From: Nogah Frankel <nog...@mellanox.com> >> >> If there is a dedicated ndo to return SW stats - use >> it. Otherwise (indicates that there is no HW stats) use >> the default stats ndo. >> Return results under IFLA_STATS_LINK_SW_64. >> >> Signed-off-by: Nogah Frankel <nog...@mellanox.com> >> Reviewed-by: Ido Schimmel <ido...@mellanox.com> >> Signed-off-by: Jiri Pirko <j...@mellanox.com> >> --- >> include/uapi/linux/if_link.h | 1 + >> net/core/rtnetlink.c | 35 +++++++++++++++++++++++++++++------ >> 2 files changed, 30 insertions(+), 6 deletions(-) >> >> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h >> index 98175e7..fcfb944 100644 >> --- a/include/uapi/linux/if_link.h >> +++ b/include/uapi/linux/if_link.h >> @@ -823,6 +823,7 @@ enum { >> IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ >> IFLA_STATS_LINK_64, >> IFLA_STATS_LINK_XSTATS, >> + IFLA_STATS_LINK_SW_64, >> __IFLA_STATS_MAX, >> }; >> >> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c >> index a127d67..f8b12e4 100644 >> --- a/net/core/rtnetlink.c >> +++ b/net/core/rtnetlink.c >> @@ -3481,6 +3481,9 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, >> struct net_device *dev, >> struct nlmsghdr *nlh; >> struct nlattr *attr; >> int s_prividx = *prividx; >> + struct rtnl_link_stats64 *sp; >> + struct rtnl_link_stats64 *stats64_sp = 0; > >s/0/NULL/ >net/core//rtnetlink.c:3485:48: warning: Using plain integer as NULL pointer
Will fix and send v2. Thanks. > >> + int err; >> >> ASSERT_RTNL(); >> >> @@ -3493,24 +3496,20 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, >> struct net_device *dev, >> ifsm->filter_mask = filter_mask; >> >> if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, *idxattr)) { >> - struct rtnl_link_stats64 *sp; >> - >> attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_64, >> sizeof(struct rtnl_link_stats64), >> IFLA_STATS_UNSPEC); >> if (!attr) >> goto nla_put_failure; >> >> - sp = nla_data(attr); >> - dev_get_stats(dev, sp); >> + stats64_sp = nla_data(attr); >> + dev_get_stats(dev, stats64_sp); >> } >> >> if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) { >> 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); >> @@ -3525,6 +3524,27 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, >> struct net_device *dev, >> } >> } >> >> + if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_SW_64, *idxattr)) { >> + attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_SW_64, >> + sizeof(struct rtnl_link_stats64), >> + IFLA_STATS_UNSPEC); >> + if (!attr) >> + goto nla_put_failure; >> + >> + sp = nla_data(attr); >> + err = dev_get_sw_stats(dev, sp); >> + if (err) { >> + /* if err it means there is no dedicated ndo to >> + * get SW stats - so it is returned by the default >> + * stats ndo >> + */ >> + if (stats64_sp) >> + copy_rtnl_link_stats64(sp, stats64_sp); >> + else >> + dev_get_stats(dev, sp); >> + } >> + } >> + >> nlmsg_end(skb, nlh); >> >> return 0; >> @@ -3541,6 +3561,7 @@ nla_put_failure: >> >> static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = { >> [IFLA_STATS_LINK_64] = { .len = sizeof(struct rtnl_link_stats64) }, >> + [IFLA_STATS_LINK_SW_64] = { .len = sizeof(struct rtnl_link_stats64) }, >> }; >> >> static size_t if_nlmsg_stats_size(const struct net_device *dev, >> @@ -3550,6 +3571,8 @@ static size_t if_nlmsg_stats_size(const struct >> net_device *dev, >> >> if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) >> size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); >> + if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_SW_64, 0)) >> + size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); >> >> if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, 0)) { >> const struct rtnl_link_ops *ops = dev->rtnl_link_ops; >> -- >> 2.5.5 >> >