@@ -718,7 +718,6 @@ struct net_device_context {
/* State to manage the associated VF interface. */
struct net_device __rcu *vf_netdev;
struct work_struct vf_takeover;
- struct pcpu_sw_netstats __percpu *vf_stats;
/* 1: allocated, serial number is valid. 0: not allocated */
u32 vf_alloc;
@@ -374,16 +374,8 @@ static u32 net_checksum_info(struct sk_buff *skb)
static int netvsc_vf_xmit(struct net_device *net, struct net_device *vf_netdev,
struct sk_buff *skb)
{
- struct net_device_context *ndev_ctx = netdev_priv(net);
- struct pcpu_sw_netstats *pcpu_stats
- = this_cpu_ptr(ndev_ctx->vf_stats);
-
skb->dev = vf_netdev;
-
- u64_stats_update_begin(&pcpu_stats->syncp);
- pcpu_stats->tx_packets++;
- pcpu_stats->tx_bytes += skb->len;
- u64_stats_update_end(&pcpu_stats->syncp);
+ /* TODO stats */
return dev_queue_xmit(skb);
}
@@ -946,35 +938,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
return ret;
}
-static void netvsc_get_vf_stats(struct net_device *net,
- struct pcpu_sw_netstats *tot)
-{
- struct net_device_context *ndev_ctx = netdev_priv(net);
- int i;
-
- memset(tot, 0, sizeof(*tot));
-
- for_each_possible_cpu(i) {
- const struct pcpu_sw_netstats *stats
- = per_cpu_ptr(ndev_ctx->vf_stats, i);
- u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
- unsigned int start;
-
- do {
- start = u64_stats_fetch_begin_irq(&stats->syncp);
- rx_packets = stats->rx_packets;
- tx_packets = stats->tx_packets;
- rx_bytes = stats->rx_bytes;
- tx_bytes = stats->tx_bytes;
- } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
-
- tot->rx_packets += rx_packets;
- tot->tx_packets += tx_packets;
- tot->rx_bytes += rx_bytes;
- tot->tx_bytes += tx_bytes;
- }
-}
-
static void netvsc_get_stats64(struct net_device *net,
struct rtnl_link_stats64 *t)
{
@@ -985,19 +948,6 @@ static void netvsc_get_stats64(struct net_device *net,
if (!nvdev)
return;
- netdev_stats_to_stats64(t, &net->stats);
-
- if (transparent_vf) {
- struct pcpu_sw_netstats vf_tot;
-
- netvsc_get_vf_stats(net, &vf_tot);
-
- t->rx_packets += vf_tot.rx_packets;
- t->tx_packets += vf_tot.tx_packets;
- t->rx_bytes += vf_tot.rx_bytes;
- t->tx_bytes += vf_tot.tx_bytes;
- }
-
for (i = 0; i < nvdev->num_chn; i++) {
const struct netvsc_channel *nvchan = &nvdev->chan_table[i];
const struct netvsc_stats *stats;
@@ -1026,6 +976,12 @@ static void netvsc_get_stats64(struct net_device *net,
t->rx_packets += packets;
t->multicast += multicast;
}
+
+ t->tx_dropped = net->stats.tx_dropped;
+ t->tx_errors = net->stats.tx_errors;
+
+ t->rx_dropped = net->stats.rx_dropped;
+ t->rx_errors = net->stats.rx_errors;
}
static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
@@ -1061,15 +1017,9 @@ static const struct {
{ "tx_no_space", offsetof(struct netvsc_ethtool_stats, tx_no_space) },
{ "tx_too_big", offsetof(struct netvsc_ethtool_stats, tx_too_big) },
{ "tx_busy", offsetof(struct netvsc_ethtool_stats, tx_busy) },
-}, vf_stats[] = {
- { "vf_rx_packets", offsetof(struct pcpu_sw_netstats, rx_packets) },
- { "vf_rx_bytes", offsetof(struct pcpu_sw_netstats, rx_bytes) },
- { "vf_tx_packets", offsetof(struct pcpu_sw_netstats, tx_packets) },
- { "vf_tx_bytes", offsetof(struct pcpu_sw_netstats, tx_bytes) },
};
#define NETVSC_GLOBAL_STATS_LEN ARRAY_SIZE(netvsc_stats)
-#define NETVSC_VF_STATS_LEN ARRAY_SIZE(vf_stats)
/* 4 statistics per queue (rx/tx packets/bytes) */
#define NETVSC_QUEUE_STATS_LEN(dev) ((dev)->num_chn * 4)
@@ -1084,9 +1034,7 @@ static int netvsc_get_sset_count(struct net_device *dev, int string_set)
switch (string_set) {
case ETH_SS_STATS:
- return NETVSC_GLOBAL_STATS_LEN
- + (transparent_vf ? NETVSC_VF_STATS_LEN : 0)
- + NETVSC_QUEUE_STATS_LEN(nvdev);
+ return NETVSC_GLOBAL_STATS_LEN + NETVSC_QUEUE_STATS_LEN(nvdev);
default:
return -EINVAL;
}
@@ -1109,14 +1057,6 @@ static void netvsc_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < NETVSC_GLOBAL_STATS_LEN; i++)
data[i] = *(unsigned long *)(nds + netvsc_stats[i].offset);
- if (transparent_vf) {
- struct pcpu_sw_netstats sum;
-
- netvsc_get_vf_stats(dev, &sum);
- for (j = 0; j < NETVSC_VF_STATS_LEN; j++)
- data[i++] = *(u64 *)((void *)&sum + vf_stats[j].offset);
- }
-
for (j = 0; j < nvdev->num_chn; j++) {
qstats = &nvdev->chan_table[j].tx_stats;
@@ -1151,18 +1091,11 @@ static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data)
switch (stringset) {
case ETH_SS_STATS:
- for (i = 0; i < ARRAY_SIZE(netvsc_stats); i++) {
- memcpy(p, netvsc_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- if (transparent_vf) {
- for (i = 0; i < ARRAY_SIZE(vf_stats); i++) {
- memcpy(p, vf_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
- }
+ for (i = 0; i < ARRAY_SIZE(netvsc_stats); i++)
+ memcpy(p + i * ETH_GSTRING_LEN,
+ netvsc_stats[i].name, ETH_GSTRING_LEN);
+ p += i * ETH_GSTRING_LEN;
for (i = 0; i < nvdev->num_chn; i++) {
sprintf(p, "tx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
@@ -1495,17 +1428,10 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct net_device *ndev = rcu_dereference(skb->dev->rx_handler_data);
- struct net_device_context *ndev_ctx = netdev_priv(ndev);
- struct pcpu_sw_netstats *pcpu_stats
- = this_cpu_ptr(ndev_ctx->vf_stats);
skb->dev = ndev;
- u64_stats_update_begin(&pcpu_stats->syncp);
- pcpu_stats->rx_packets++;
- pcpu_stats->rx_bytes += skb->len;
- u64_stats_update_end(&pcpu_stats->syncp);
-
+ /* TODO: stats */
return RX_HANDLER_ANOTHER;
}
@@ -1720,12 +1646,12 @@ static int netvsc_probe(struct hv_device *dev,
struct net_device_context *net_device_ctx;
struct netvsc_device_info device_info;
struct netvsc_device *nvdev;
- int ret = -ENOMEM;
+ int ret;
net = alloc_etherdev_mq(sizeof(struct net_device_context),
VRSS_CHANNEL_MAX);
if (!net)
- goto no_net;
+ return -ENOMEM;
netif_carrier_off(net);
@@ -1745,10 +1671,6 @@ static int netvsc_probe(struct hv_device *dev,
spin_lock_init(&net_device_ctx->lock);
INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
INIT_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
- net_device_ctx->vf_stats
- = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
- if (!net_device_ctx->vf_stats)
- goto no_stats;
net->netdev_ops = &device_ops;
net->ethtool_ops = ðtool_ops;
@@ -1768,9 +1690,10 @@ static int netvsc_probe(struct hv_device *dev,
if (IS_ERR(nvdev)) {
ret = PTR_ERR(nvdev);
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
- goto rndis_failed;
+ free_netdev(net);
+ hv_set_drvdata(dev, NULL);
+ return ret;
}
-
memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
/* hw_features computed in rndis_filter_device_add */
@@ -1794,20 +1717,11 @@ static int netvsc_probe(struct hv_device *dev,
ret = register_netdev(net);
if (ret != 0) {
pr_err("Unable to register netdev.\n");
- goto register_failed;
+ rndis_filter_device_remove(dev, nvdev);
+ free_netdev(net);
}
return ret;
-
-register_failed:
- rndis_filter_device_remove(dev, nvdev);
-rndis_failed:
- free_percpu(net_device_ctx->vf_stats);
-no_stats:
- hv_set_drvdata(dev, NULL);
- free_netdev(net);
-no_net:
- return ret;
}
static int netvsc_remove(struct hv_device *dev)
@@ -1840,7 +1754,6 @@ static int netvsc_remove(struct hv_device *dev)
hv_set_drvdata(dev, NULL);
- free_percpu(ndev_ctx->vf_stats);
free_netdev(net);
return 0;
}
BugLink: http://bugs.launchpad.net/bugs/1708469 This reverts commit 350771e4b20a888e9d5d857f46497ae08e8cf8bb. That commit was replaced by net-next commit 0c195567a8f6 ("netvsc: transparent VF management"). Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com> --- drivers/net/hyperv/hyperv_net.h | 1 - drivers/net/hyperv/netvsc_drv.c | 127 +++++++--------------------------------- 2 files changed, 20 insertions(+), 108 deletions(-)