Commit 3b766cd8 authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by David S. Miller

net/core: Add reading VF statistics through the PF netdevice

Add ndo_get_vf_stats where the PF retrieves and fills the VFs traffic
statistics. We encode the VF stats in a nested manner to allow for
future extensions.
Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: default avatarHadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b42de4d0
...@@ -5,6 +5,15 @@ ...@@ -5,6 +5,15 @@
/* We don't want this structure exposed to user space */ /* We don't want this structure exposed to user space */
struct ifla_vf_stats {
__u64 rx_packets;
__u64 tx_packets;
__u64 rx_bytes;
__u64 tx_bytes;
__u64 broadcast;
__u64 multicast;
};
struct ifla_vf_info { struct ifla_vf_info {
__u32 vf; __u32 vf;
__u8 mac[32]; __u8 mac[32];
......
...@@ -1100,6 +1100,10 @@ struct net_device_ops { ...@@ -1100,6 +1100,10 @@ struct net_device_ops {
struct ifla_vf_info *ivf); struct ifla_vf_info *ivf);
int (*ndo_set_vf_link_state)(struct net_device *dev, int (*ndo_set_vf_link_state)(struct net_device *dev,
int vf, int link_state); int vf, int link_state);
int (*ndo_get_vf_stats)(struct net_device *dev,
int vf,
struct ifla_vf_stats
*vf_stats);
int (*ndo_set_vf_port)(struct net_device *dev, int (*ndo_set_vf_port)(struct net_device *dev,
int vf, int vf,
struct nlattr *port[]); struct nlattr *port[]);
......
...@@ -484,6 +484,7 @@ enum { ...@@ -484,6 +484,7 @@ enum {
IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query
* on/off switch * on/off switch
*/ */
IFLA_VF_STATS, /* network device statistics */
__IFLA_VF_MAX, __IFLA_VF_MAX,
}; };
...@@ -533,6 +534,18 @@ struct ifla_vf_rss_query_en { ...@@ -533,6 +534,18 @@ struct ifla_vf_rss_query_en {
__u32 setting; __u32 setting;
}; };
enum {
IFLA_VF_STATS_RX_PACKETS,
IFLA_VF_STATS_TX_PACKETS,
IFLA_VF_STATS_RX_BYTES,
IFLA_VF_STATS_TX_BYTES,
IFLA_VF_STATS_BROADCAST,
IFLA_VF_STATS_MULTICAST,
__IFLA_VF_STATS_MAX,
};
#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
/* VF ports management section /* VF ports management section
* *
* Nested layout of set/get msg is: * Nested layout of set/get msg is:
......
...@@ -819,7 +819,19 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, ...@@ -819,7 +819,19 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
nla_total_size(sizeof(struct ifla_vf_spoofchk)) + nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
nla_total_size(sizeof(struct ifla_vf_rate)) + nla_total_size(sizeof(struct ifla_vf_rate)) +
nla_total_size(sizeof(struct ifla_vf_link_state)) + nla_total_size(sizeof(struct ifla_vf_link_state)) +
nla_total_size(sizeof(struct ifla_vf_rss_query_en))); nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
/* IFLA_VF_STATS_RX_PACKETS */
nla_total_size(sizeof(__u64)) +
/* IFLA_VF_STATS_TX_PACKETS */
nla_total_size(sizeof(__u64)) +
/* IFLA_VF_STATS_RX_BYTES */
nla_total_size(sizeof(__u64)) +
/* IFLA_VF_STATS_TX_BYTES */
nla_total_size(sizeof(__u64)) +
/* IFLA_VF_STATS_BROADCAST */
nla_total_size(sizeof(__u64)) +
/* IFLA_VF_STATS_MULTICAST */
nla_total_size(sizeof(__u64)));
return size; return size;
} else } else
return 0; return 0;
...@@ -1123,7 +1135,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -1123,7 +1135,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
&& (ext_filter_mask & RTEXT_FILTER_VF)) { && (ext_filter_mask & RTEXT_FILTER_VF)) {
int i; int i;
struct nlattr *vfinfo, *vf; struct nlattr *vfinfo, *vf, *vfstats;
int num_vfs = dev_num_vf(dev->dev.parent); int num_vfs = dev_num_vf(dev->dev.parent);
vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
...@@ -1138,6 +1150,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -1138,6 +1150,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
struct ifla_vf_spoofchk vf_spoofchk; struct ifla_vf_spoofchk vf_spoofchk;
struct ifla_vf_link_state vf_linkstate; struct ifla_vf_link_state vf_linkstate;
struct ifla_vf_rss_query_en vf_rss_query_en; struct ifla_vf_rss_query_en vf_rss_query_en;
struct ifla_vf_stats vf_stats;
/* /*
* Not all SR-IOV capable drivers support the * Not all SR-IOV capable drivers support the
...@@ -1190,6 +1203,30 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -1190,6 +1203,30 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
sizeof(vf_rss_query_en), sizeof(vf_rss_query_en),
&vf_rss_query_en)) &vf_rss_query_en))
goto nla_put_failure; goto nla_put_failure;
memset(&vf_stats, 0, sizeof(vf_stats));
if (dev->netdev_ops->ndo_get_vf_stats)
dev->netdev_ops->ndo_get_vf_stats(dev, i,
&vf_stats);
vfstats = nla_nest_start(skb, IFLA_VF_STATS);
if (!vfstats) {
nla_nest_cancel(skb, vf);
nla_nest_cancel(skb, vfinfo);
goto nla_put_failure;
}
if (nla_put_u64(skb, IFLA_VF_STATS_RX_PACKETS,
vf_stats.rx_packets) ||
nla_put_u64(skb, IFLA_VF_STATS_TX_PACKETS,
vf_stats.tx_packets) ||
nla_put_u64(skb, IFLA_VF_STATS_RX_BYTES,
vf_stats.rx_bytes) ||
nla_put_u64(skb, IFLA_VF_STATS_TX_BYTES,
vf_stats.tx_bytes) ||
nla_put_u64(skb, IFLA_VF_STATS_BROADCAST,
vf_stats.broadcast) ||
nla_put_u64(skb, IFLA_VF_STATS_MULTICAST,
vf_stats.multicast))
goto nla_put_failure;
nla_nest_end(skb, vfstats);
nla_nest_end(skb, vf); nla_nest_end(skb, vf);
} }
nla_nest_end(skb, vfinfo); nla_nest_end(skb, vfinfo);
...@@ -1303,6 +1340,16 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { ...@@ -1303,6 +1340,16 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
[IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) },
[IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) },
[IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) }, [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) },
[IFLA_VF_STATS] = { .type = NLA_NESTED },
};
static const struct nla_policy ifla_vf_stats_policy[IFLA_VF_STATS_MAX + 1] = {
[IFLA_VF_STATS_RX_PACKETS] = { .type = NLA_U64 },
[IFLA_VF_STATS_TX_PACKETS] = { .type = NLA_U64 },
[IFLA_VF_STATS_RX_BYTES] = { .type = NLA_U64 },
[IFLA_VF_STATS_TX_BYTES] = { .type = NLA_U64 },
[IFLA_VF_STATS_BROADCAST] = { .type = NLA_U64 },
[IFLA_VF_STATS_MULTICAST] = { .type = NLA_U64 },
}; };
static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment