From hkallweit1 at gmail.com Wed Nov 4 14:23:04 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:23:04 +0100 Subject: [PATCH net-next v2 00/10] net: add and use dev_get_tstats64 Message-ID: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> It's a frequent pattern to use netdev->stats for the less frequently accessed counters and per-cpu counters for the frequently accessed counters (rx/tx bytes/packets). Add a default ndo_get_stats64() implementation for this use case. Subsequently switch more drivers to use this pattern. v2: - add patches for replacing ip_tunnel_get_stats64 Requested additional migrations will come in a separate series. Heiner Kallweit (10): net: core: add dev_get_tstats64 as a ndo_get_stats64 implementation net: dsa: use net core stats64 handling tun: switch to net core provided statistics counters ip6_tunnel: switch to dev_get_tstats64 net: switch to dev_get_tstats64 gtp: switch to dev_get_tstats64 wireguard: switch to dev_get_tstats64 vti: switch to dev_get_tstats64 ipv4/ipv6: switch to dev_get_tstats64 net: remove ip_tunnel_get_stats64 drivers/net/bareudp.c | 2 +- drivers/net/geneve.c | 2 +- drivers/net/gtp.c | 2 +- drivers/net/tun.c | 127 ++++++++------------------------- drivers/net/vxlan.c | 4 +- drivers/net/wireguard/device.c | 2 +- include/linux/netdevice.h | 1 + include/net/ip_tunnels.h | 2 - net/core/dev.c | 15 ++++ net/dsa/dsa.c | 7 +- net/dsa/dsa_priv.h | 2 - net/dsa/slave.c | 29 ++------ net/ipv4/ip_gre.c | 6 +- net/ipv4/ip_tunnel_core.c | 9 --- net/ipv4/ip_vti.c | 2 +- net/ipv4/ipip.c | 2 +- net/ipv6/ip6_gre.c | 6 +- net/ipv6/ip6_tunnel.c | 32 +-------- net/ipv6/ip6_vti.c | 2 +- net/ipv6/sit.c | 2 +- 20 files changed, 72 insertions(+), 184 deletions(-) -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:24:01 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:24:01 +0100 Subject: [PATCH net-next v2 01/10] net: core: add dev_get_tstats64 as a ndo_get_stats64 implementation In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <91133597-bd18-20ab-2a98-fd061ff90fed@gmail.com> It's a frequent pattern to use netdev->stats for the less frequently accessed counters and per-cpu counters for the frequently accessed counters (rx/tx bytes/packets). Add a default ndo_get_stats64() implementation for this use case. Reviewed-by: Florian Fainelli Signed-off-by: Heiner Kallweit --- include/linux/netdevice.h | 1 + net/core/dev.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a53ed2d1e..7ce648a56 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4527,6 +4527,7 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, const struct net_device_stats *netdev_stats); void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, const struct pcpu_sw_netstats __percpu *netstats); +void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s); extern int netdev_max_backlog; extern int netdev_tstamp_prequeue; diff --git a/net/core/dev.c b/net/core/dev.c index 9e7f071b8..88acc03fa 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10366,6 +10366,21 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, } EXPORT_SYMBOL_GPL(dev_fetch_sw_netstats); +/** + * dev_get_tstats64 - ndo_get_stats64 implementation + * @dev: device to get statistics from + * @s: place to store stats + * + * Populate @s from dev->stats and dev->tstats. Can be used as + * ndo_get_stats64() callback. + */ +void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s) +{ + netdev_stats_to_stats64(s, &dev->stats); + dev_fetch_sw_netstats(s, dev->tstats); +} +EXPORT_SYMBOL_GPL(dev_get_tstats64); + struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) { struct netdev_queue *queue = dev_ingress_queue(dev); -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:24:46 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:24:46 +0100 Subject: [PATCH net-next v2 02/10] net: dsa: use net core stats64 handling In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <9c091e28-8585-c082-9587-d73ac5e4680d@gmail.com> Use netdev->tstats instead of a member of dsa_slave_priv for storing a pointer to the per-cpu counters. This allows us to use core functionality for statistics handling. Reviewed-by: Florian Fainelli Tested-by: Vladimir Oltean Signed-off-by: Heiner Kallweit --- net/dsa/dsa.c | 7 +------ net/dsa/dsa_priv.h | 2 -- net/dsa/slave.c | 29 +++++++---------------------- 3 files changed, 8 insertions(+), 30 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 2131bf2b3..a1b1dc8a4 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -201,7 +201,6 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, { struct dsa_port *cpu_dp = dev->dsa_ptr; struct sk_buff *nskb = NULL; - struct pcpu_sw_netstats *s; struct dsa_slave_priv *p; if (unlikely(!cpu_dp)) { @@ -234,11 +233,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, skb = nskb; } - s = this_cpu_ptr(p->stats64); - u64_stats_update_begin(&s->syncp); - s->rx_packets++; - s->rx_bytes += skb->len; - u64_stats_update_end(&s->syncp); + dev_sw_netstats_rx_add(skb->dev, skb->len); if (dsa_skb_defer_rx_timestamp(p, skb)) return 0; diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 12998bf04..7c96aae90 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -78,8 +78,6 @@ struct dsa_slave_priv { struct sk_buff * (*xmit)(struct sk_buff *skb, struct net_device *dev); - struct pcpu_sw_netstats __percpu *stats64; - struct gro_cells gcells; /* DSA port data, such as switch, port index, etc. */ diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 3bc5ca40c..c6a797d75 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -551,14 +551,9 @@ EXPORT_SYMBOL_GPL(dsa_enqueue_skb); static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); - struct pcpu_sw_netstats *s; struct sk_buff *nskb; - s = this_cpu_ptr(p->stats64); - u64_stats_update_begin(&s->syncp); - s->tx_packets++; - s->tx_bytes += skb->len; - u64_stats_update_end(&s->syncp); + dev_sw_netstats_tx_add(dev, 1, skb->len); DSA_SKB_CB(skb)->clone = NULL; @@ -679,7 +674,6 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, uint64_t *data) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_switch *ds = dp->ds; struct pcpu_sw_netstats *s; unsigned int start; @@ -688,7 +682,7 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, for_each_possible_cpu(i) { u64 tx_packets, tx_bytes, rx_packets, rx_bytes; - s = per_cpu_ptr(p->stats64, i); + s = per_cpu_ptr(dev->tstats, i); do { start = u64_stats_fetch_begin_irq(&s->syncp); tx_packets = s->tx_packets; @@ -1217,15 +1211,6 @@ static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type, return ds->ops->port_setup_tc(ds, dp->index, type, type_data); } -static void dsa_slave_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) -{ - struct dsa_slave_priv *p = netdev_priv(dev); - - netdev_stats_to_stats64(stats, &dev->stats); - dev_fetch_sw_netstats(stats, p->stats64); -} - static int dsa_slave_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc, u32 *rule_locs) { @@ -1601,7 +1586,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = { #endif .ndo_get_phys_port_name = dsa_slave_get_phys_port_name, .ndo_setup_tc = dsa_slave_setup_tc, - .ndo_get_stats64 = dsa_slave_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_port_parent_id = dsa_slave_get_port_parent_id, .ndo_vlan_rx_add_vid = dsa_slave_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, @@ -1801,8 +1786,8 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->vlan_features = master->vlan_features; p = netdev_priv(slave_dev); - p->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); - if (!p->stats64) { + slave_dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!slave_dev->tstats) { free_netdev(slave_dev); return -ENOMEM; } @@ -1864,7 +1849,7 @@ int dsa_slave_create(struct dsa_port *port) out_gcells: gro_cells_destroy(&p->gcells); out_free: - free_percpu(p->stats64); + free_percpu(slave_dev->tstats); free_netdev(slave_dev); port->slave = NULL; return ret; @@ -1886,7 +1871,7 @@ void dsa_slave_destroy(struct net_device *slave_dev) dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER); phylink_destroy(dp->pl); gro_cells_destroy(&p->gcells); - free_percpu(p->stats64); + free_percpu(slave_dev->tstats); free_netdev(slave_dev); } -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:25:24 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:25:24 +0100 Subject: [PATCH net-next v2 03/10] tun: switch to net core provided statistics counters In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> Switch tun to the standard statistics pattern: - use netdev->stats for the less frequently accessed counters - use netdev->tstats for the frequently accessed per-cpu counters Signed-off-by: Heiner Kallweit --- drivers/net/tun.c | 127 +++++++++++----------------------------------- 1 file changed, 31 insertions(+), 96 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index be69d2720..504bdf501 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -107,17 +107,6 @@ struct tap_filter { #define TUN_FLOW_EXPIRE (3 * HZ) -struct tun_pcpu_stats { - u64_stats_t rx_packets; - u64_stats_t rx_bytes; - u64_stats_t tx_packets; - u64_stats_t tx_bytes; - struct u64_stats_sync syncp; - u32 rx_dropped; - u32 tx_dropped; - u32 rx_frame_errors; -}; - /* A tun_file connects an open character device to a tuntap netdevice. It * also contains all socket related structures (except sock_fprog and tap_filter) * to serve as one transmit queue for tuntap device. The sock_fprog and @@ -207,7 +196,6 @@ struct tun_struct { void *security; u32 flow_count; u32 rx_batched; - struct tun_pcpu_stats __percpu *pcpu_stats; struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; @@ -1066,7 +1054,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; drop: - this_cpu_inc(tun->pcpu_stats->tx_dropped); + dev->stats.tx_dropped++; skb_tx_error(skb); kfree_skb(skb); rcu_read_unlock(); @@ -1100,42 +1088,6 @@ static void tun_set_headroom(struct net_device *dev, int new_hr) tun->align = new_hr; } -static void -tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -{ - u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; - struct tun_struct *tun = netdev_priv(dev); - struct tun_pcpu_stats *p; - int i; - - for_each_possible_cpu(i) { - u64 rxpackets, rxbytes, txpackets, txbytes; - unsigned int start; - - p = per_cpu_ptr(tun->pcpu_stats, i); - do { - start = u64_stats_fetch_begin(&p->syncp); - rxpackets = u64_stats_read(&p->rx_packets); - rxbytes = u64_stats_read(&p->rx_bytes); - txpackets = u64_stats_read(&p->tx_packets); - txbytes = u64_stats_read(&p->tx_bytes); - } while (u64_stats_fetch_retry(&p->syncp, start)); - - stats->rx_packets += rxpackets; - stats->rx_bytes += rxbytes; - stats->tx_packets += txpackets; - stats->tx_bytes += txbytes; - - /* u32 counters */ - rx_dropped += p->rx_dropped; - rx_frame_errors += p->rx_frame_errors; - tx_dropped += p->tx_dropped; - } - stats->rx_dropped = rx_dropped; - stats->rx_frame_errors = rx_frame_errors; - stats->tx_dropped = tx_dropped; -} - static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog, struct netlink_ext_ack *extack) { @@ -1199,7 +1151,7 @@ static const struct net_device_ops tun_netdev_ops = { .ndo_fix_features = tun_net_fix_features, .ndo_select_queue = tun_select_queue, .ndo_set_rx_headroom = tun_set_headroom, - .ndo_get_stats64 = tun_net_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_change_carrier = tun_net_change_carrier, }; @@ -1247,7 +1199,7 @@ static int tun_xdp_xmit(struct net_device *dev, int n, void *frame = tun_xdp_to_ptr(xdp); if (__ptr_ring_produce(&tfile->tx_ring, frame)) { - this_cpu_inc(tun->pcpu_stats->tx_dropped); + dev->stats.tx_dropped++; xdp_return_frame_rx_napi(xdp); drops++; } @@ -1283,7 +1235,7 @@ static const struct net_device_ops tap_netdev_ops = { .ndo_select_queue = tun_select_queue, .ndo_features_check = passthru_features_check, .ndo_set_rx_headroom = tun_set_headroom, - .ndo_get_stats64 = tun_net_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_bpf = tun_xdp, .ndo_xdp_xmit = tun_xdp_xmit, .ndo_change_carrier = tun_net_change_carrier, @@ -1577,7 +1529,7 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog, trace_xdp_exception(tun->dev, xdp_prog, act); fallthrough; case XDP_DROP: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; break; } @@ -1683,7 +1635,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, size_t total_len = iov_iter_count(from); size_t len = total_len, align = tun->align, linear; struct virtio_net_hdr gso = { 0 }; - struct tun_pcpu_stats *stats; int good_linear; int copylen; bool zerocopy = false; @@ -1752,7 +1703,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, */ skb = tun_build_skb(tun, tfile, from, &gso, len, &skb_xdp); if (IS_ERR(skb)) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; return PTR_ERR(skb); } if (!skb) @@ -1781,7 +1732,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (IS_ERR(skb)) { if (PTR_ERR(skb) != -EAGAIN) - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; if (frags) mutex_unlock(&tfile->napi_mutex); return PTR_ERR(skb); @@ -1795,7 +1746,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (err) { err = -EFAULT; drop: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; kfree_skb(skb); if (frags) { tfile->napi.skb = NULL; @@ -1807,7 +1758,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } if (virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun))) { - this_cpu_inc(tun->pcpu_stats->rx_frame_errors); + tun->dev->stats.rx_frame_errors++; kfree_skb(skb); if (frags) { tfile->napi.skb = NULL; @@ -1830,7 +1781,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, pi.proto = htons(ETH_P_IPV6); break; default: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; kfree_skb(skb); return -EINVAL; } @@ -1910,7 +1861,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_headlen(skb)); if (unlikely(headlen > skb_headlen(skb))) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); + tun->dev->stats.rx_dropped++; napi_free_frags(&tfile->napi); rcu_read_unlock(); mutex_unlock(&tfile->napi_mutex); @@ -1942,12 +1893,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } rcu_read_unlock(); - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->rx_packets); - u64_stats_add(&stats->rx_bytes, len); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(stats); + preempt_disable(); + dev_sw_netstats_rx_add(tun->dev, len); + preempt_enable(); if (rxhash) tun_flow_update(tun, rxhash, tfile); @@ -1979,7 +1927,6 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tun, { int vnet_hdr_sz = 0; size_t size = xdp_frame->len; - struct tun_pcpu_stats *stats; size_t ret; if (tun->flags & IFF_VNET_HDR) { @@ -1996,12 +1943,9 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tun, ret = copy_to_iter(xdp_frame->data, size, iter) + vnet_hdr_sz; - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->tx_packets); - u64_stats_add(&stats->tx_bytes, ret); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(tun->pcpu_stats); + preempt_disable(); + dev_sw_netstats_tx_add(tun->dev, 1, ret); + preempt_enable(); return ret; } @@ -2013,7 +1957,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, struct iov_iter *iter) { struct tun_pi pi = { 0, skb->protocol }; - struct tun_pcpu_stats *stats; ssize_t total; int vlan_offset = 0; int vlan_hlen = 0; @@ -2091,12 +2034,9 @@ static ssize_t tun_put_user(struct tun_struct *tun, done: /* caller is in process context, */ - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->tx_packets); - u64_stats_add(&stats->tx_bytes, skb->len + vlan_hlen); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(tun->pcpu_stats); + preempt_disable(); + dev_sw_netstats_tx_add(tun->dev, 1, skb->len + vlan_hlen); + preempt_enable(); return total; } @@ -2235,11 +2175,11 @@ static void tun_free_netdev(struct net_device *dev) BUG_ON(!(list_empty(&tun->disabled))); - free_percpu(tun->pcpu_stats); - /* We clear pcpu_stats so that tun_set_iff() can tell if + free_percpu(dev->tstats); + /* We clear tstats so that tun_set_iff() can tell if * tun_free_netdev() has been called from register_netdevice(). */ - tun->pcpu_stats = NULL; + dev->tstats = NULL; tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); @@ -2370,7 +2310,6 @@ static int tun_xdp_one(struct tun_struct *tun, unsigned int datasize = xdp->data_end - xdp->data; struct tun_xdp_hdr *hdr = xdp->data_hard_start; struct virtio_net_hdr *gso = &hdr->gso; - struct tun_pcpu_stats *stats; struct bpf_prog *xdp_prog; struct sk_buff *skb = NULL; u32 rxhash = 0, act; @@ -2428,7 +2367,7 @@ static int tun_xdp_one(struct tun_struct *tun, skb_put(skb, xdp->data_end - xdp->data); if (virtio_net_hdr_to_skb(skb, gso, tun_is_little_endian(tun))) { - this_cpu_inc(tun->pcpu_stats->rx_frame_errors); + tun->dev->stats.rx_frame_errors++; kfree_skb(skb); err = -EINVAL; goto out; @@ -2451,14 +2390,10 @@ static int tun_xdp_one(struct tun_struct *tun, netif_receive_skb(skb); - /* No need for get_cpu_ptr() here since this function is + /* No need to disable preemption here since this function is * always called with bh disabled */ - stats = this_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->rx_packets); - u64_stats_add(&stats->rx_bytes, datasize); - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_rx_add(tun->dev, datasize); if (rxhash) tun_flow_update(tun, rxhash, tfile); @@ -2751,8 +2686,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->rx_batched = 0; RCU_INIT_POINTER(tun->steering_prog, NULL); - tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); - if (!tun->pcpu_stats) { + dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!dev->tstats) { err = -ENOMEM; goto err_free_dev; } @@ -2807,16 +2742,16 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun_detach_all(dev); /* We are here because register_netdevice() has failed. * If register_netdevice() already called tun_free_netdev() - * while dealing with the error, tun->pcpu_stats has been cleared. + * while dealing with the error, dev->stats has been cleared. */ - if (!tun->pcpu_stats) + if (!dev->tstats) goto err_free_dev; err_free_flow: tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); err_free_stat: - free_percpu(tun->pcpu_stats); + free_percpu(dev->tstats); err_free_dev: free_netdev(dev); return err; -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:26:11 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:26:11 +0100 Subject: [PATCH net-next v2 04/10] ip6_tunnel: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <4dc3d9f1-bf5e-1f56-9810-7af29988a5f1@gmail.com> Switch ip6_tunnel to the standard statistics pattern: - use dev->stats for the less frequently accessed counters - use dev->tstats for the frequently accessed counters An additional benefit is that we now have 64bit statistics also on 32bit systems. Signed-off-by: Heiner Kallweit --- net/ipv6/ip6_tunnel.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 648db3fe5..321d057c5 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -94,36 +94,6 @@ static inline int ip6_tnl_mpls_supported(void) return IS_ENABLED(CONFIG_MPLS); } -static struct net_device_stats *ip6_get_stats(struct net_device *dev) -{ - struct pcpu_sw_netstats tmp, sum = { 0 }; - int i; - - for_each_possible_cpu(i) { - unsigned int start; - const struct pcpu_sw_netstats *tstats = - per_cpu_ptr(dev->tstats, i); - - do { - start = u64_stats_fetch_begin_irq(&tstats->syncp); - tmp.rx_packets = tstats->rx_packets; - tmp.rx_bytes = tstats->rx_bytes; - tmp.tx_packets = tstats->tx_packets; - tmp.tx_bytes = tstats->tx_bytes; - } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); - - sum.rx_packets += tmp.rx_packets; - sum.rx_bytes += tmp.rx_bytes; - sum.tx_packets += tmp.tx_packets; - sum.tx_bytes += tmp.tx_bytes; - } - dev->stats.rx_packets = sum.rx_packets; - dev->stats.rx_bytes = sum.rx_bytes; - dev->stats.tx_packets = sum.tx_packets; - dev->stats.tx_bytes = sum.tx_bytes; - return &dev->stats; -} - #define for_each_ip6_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) @@ -1835,7 +1805,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { .ndo_start_xmit = ip6_tnl_start_xmit, .ndo_do_ioctl = ip6_tnl_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats = ip6_get_stats, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:27:12 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:27:12 +0100 Subject: [PATCH net-next v2 05/10] net: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core fucntion dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- drivers/net/bareudp.c | 2 +- drivers/net/geneve.c | 2 +- drivers/net/vxlan.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index ff0bea155..28257bcce 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -510,7 +510,7 @@ static const struct net_device_ops bareudp_netdev_ops = { .ndo_open = bareudp_open, .ndo_stop = bareudp_stop, .ndo_start_xmit = bareudp_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_fill_metadata_dst = bareudp_fill_metadata_dst, }; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index d07008a81..a3c8ce6de 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1138,7 +1138,7 @@ static const struct net_device_ops geneve_netdev_ops = { .ndo_open = geneve_open, .ndo_stop = geneve_stop, .ndo_start_xmit = geneve_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_change_mtu = geneve_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 1a557aeba..cb9930595 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -3210,7 +3210,7 @@ static const struct net_device_ops vxlan_netdev_ether_ops = { .ndo_open = vxlan_open, .ndo_stop = vxlan_stop, .ndo_start_xmit = vxlan_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_set_rx_mode = vxlan_set_multicast_list, .ndo_change_mtu = vxlan_change_mtu, .ndo_validate_addr = eth_validate_addr, @@ -3229,7 +3229,7 @@ static const struct net_device_ops vxlan_netdev_raw_ops = { .ndo_open = vxlan_open, .ndo_stop = vxlan_stop, .ndo_start_xmit = vxlan_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_change_mtu = vxlan_change_mtu, .ndo_fill_metadata_dst = vxlan_fill_metadata_dst, }; -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:27:47 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:27:47 +0100 Subject: [PATCH net-next v2 06/10] gtp: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <52d228fe-9ed3-7cd0-eebc-051c38b5e45f@gmail.com> Replace ip_tunnel_get_stats64() with the new identical core fucntion dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- drivers/net/gtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index dc668ed28..4c04e271f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -607,7 +607,7 @@ static const struct net_device_ops gtp_netdev_ops = { .ndo_init = gtp_dev_init, .ndo_uninit = gtp_dev_uninit, .ndo_start_xmit = gtp_dev_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, }; static void gtp_link_setup(struct net_device *dev) -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:28:22 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:28:22 +0100 Subject: [PATCH net-next v2 07/10] wireguard: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <4f731535-2a51-a673-5daf-d9ec2536a8f8@gmail.com> Replace ip_tunnel_get_stats64() with the new identical core fucntion dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- drivers/net/wireguard/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index c9f65e96c..a3ed49cd9 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -215,7 +215,7 @@ static const struct net_device_ops netdev_ops = { .ndo_open = wg_open, .ndo_stop = wg_stop, .ndo_start_xmit = wg_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64 + .ndo_get_stats64 = dev_get_tstats64 }; static void wg_destruct(struct net_device *dev) -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:28:57 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:28:57 +0100 Subject: [PATCH net-next v2 08/10] vti: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core fucntion dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- net/ipv4/ip_vti.c | 2 +- net/ipv6/ip6_vti.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index b957cbee2..abc171e79 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -404,7 +404,7 @@ static const struct net_device_ops vti_netdev_ops = { .ndo_start_xmit = vti_tunnel_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = vti_tunnel_ctl, }; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 5f9c4fdc1..b7b2bb27d 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -889,7 +889,7 @@ static const struct net_device_ops vti6_netdev_ops = { .ndo_uninit = vti6_dev_uninit, .ndo_start_xmit = vti6_tnl_xmit, .ndo_do_ioctl = vti6_ioctl, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:29:35 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:29:35 +0100 Subject: [PATCH net-next v2 09/10] ipv4/ipv6: switch to dev_get_tstats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core fucntion dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- net/ipv4/ip_gre.c | 6 +++--- net/ipv4/ipip.c | 2 +- net/ipv6/ip6_gre.c | 6 +++--- net/ipv6/sit.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e70291748..a68bf4c6f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -920,7 +920,7 @@ static const struct net_device_ops ipgre_netdev_ops = { .ndo_start_xmit = ipgre_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipgre_tunnel_ctl, }; @@ -1275,7 +1275,7 @@ static const struct net_device_ops gre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_fill_metadata_dst = gre_fill_metadata_dst, }; @@ -1308,7 +1308,7 @@ static const struct net_device_ops erspan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_fill_metadata_dst = gre_fill_metadata_dst, }; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 75d35e76b..d5bfa087c 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -347,7 +347,7 @@ static const struct net_device_ops ipip_netdev_ops = { .ndo_start_xmit = ipip_tunnel_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipip_tunnel_ctl, }; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 931b186d2..8cf659994 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -1391,7 +1391,7 @@ static const struct net_device_ops ip6gre_netdev_ops = { .ndo_start_xmit = ip6gre_tunnel_xmit, .ndo_do_ioctl = ip6gre_tunnel_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; @@ -1828,7 +1828,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; @@ -1896,7 +1896,7 @@ static const struct net_device_ops ip6erspan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 5e2c34c0a..4dc5f9366 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1396,7 +1396,7 @@ static const struct net_device_ops ipip6_netdev_ops = { .ndo_uninit = ipip6_tunnel_uninit, .ndo_start_xmit = sit_tunnel_xmit, .ndo_do_ioctl = ipip6_tunnel_ioctl, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipip6_tunnel_ctl, }; -- 2.29.2 From hkallweit1 at gmail.com Wed Nov 4 14:31:02 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Wed, 4 Nov 2020 15:31:02 +0100 Subject: [PATCH net-next v2 10/10] net: remove ip_tunnel_get_stats64 In-Reply-To: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> Message-ID: <1d40c040-7b4b-9531-2cb0-0e8e3f954e25@gmail.com> After having migrated all users remove ip_tunnel_get_stats64(). Signed-off-by: Heiner Kallweit --- include/net/ip_tunnels.h | 2 -- net/ipv4/ip_tunnel_core.c | 9 --------- 2 files changed, 11 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 02ccd3254..1b7905eb7 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -274,8 +274,6 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); -void ip_tunnel_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *tot); struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, int link, __be16 flags, __be32 remote, __be32 local, diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 25f1caf5a..923a9fa2e 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -429,15 +429,6 @@ int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst, } EXPORT_SYMBOL(skb_tunnel_check_pmtu); -/* Often modified stats are per cpu, other are shared (netdev->stats) */ -void ip_tunnel_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *tot) -{ - netdev_stats_to_stats64(tot, &dev->stats); - dev_fetch_sw_netstats(tot, dev->tstats); -} -EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); - static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = { [LWTUNNEL_IP_UNSPEC] = { .strict_start_type = LWTUNNEL_IP_OPTS }, [LWTUNNEL_IP_ID] = { .type = NLA_U64 }, -- 2.29.2 From Jason at zx2c4.com Wed Nov 4 19:46:20 2020 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Wed, 4 Nov 2020 20:46:20 +0100 Subject: [PATCH net-next v2 07/10] wireguard: switch to dev_get_tstats64 In-Reply-To: <4f731535-2a51-a673-5daf-d9ec2536a8f8@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <4f731535-2a51-a673-5daf-d9ec2536a8f8@gmail.com> Message-ID: On Wed, Nov 4, 2020 at 3:31 PM Heiner Kallweit wrote: > > Replace ip_tunnel_get_stats64() with the new identical core fucntion > dev_get_tstats64(). > > Signed-off-by: Heiner Kallweit > --- > drivers/net/wireguard/device.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c > index c9f65e96c..a3ed49cd9 100644 > --- a/drivers/net/wireguard/device.c > +++ b/drivers/net/wireguard/device.c > @@ -215,7 +215,7 @@ static const struct net_device_ops netdev_ops = { > .ndo_open = wg_open, > .ndo_stop = wg_stop, > .ndo_start_xmit = wg_xmit, > - .ndo_get_stats64 = ip_tunnel_get_stats64 > + .ndo_get_stats64 = dev_get_tstats64 > }; > > static void wg_destruct(struct net_device *dev) > -- > 2.29.2 Looks fine to me. Reviewed-by: Jason A. Donenfeld From laforge at gnumonks.org Thu Nov 5 07:58:31 2020 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 5 Nov 2020 08:58:31 +0100 Subject: [PATCH net-next v2 06/10] gtp: switch to dev_get_tstats64 In-Reply-To: <52d228fe-9ed3-7cd0-eebc-051c38b5e45f@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <52d228fe-9ed3-7cd0-eebc-051c38b5e45f@gmail.com> Message-ID: <20201105075831.GD1078888@nataraja> Looks good to me. On Wed, Nov 04, 2020 at 03:27:47PM +0100, Heiner Kallweit wrote: > Replace ip_tunnel_get_stats64() with the new identical core fucntion > dev_get_tstats64(). > > Signed-off-by: Heiner Kallweit Acked-by: Harald Welte -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From kuba at kernel.org Fri Nov 6 01:14:46 2020 From: kuba at kernel.org (Jakub Kicinski) Date: Thu, 5 Nov 2020 17:14:46 -0800 Subject: [PATCH net-next v2 03/10] tun: switch to net core provided statistics counters In-Reply-To: <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> Message-ID: <20201105171446.5f78f1a6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> On Wed, 4 Nov 2020 15:25:24 +0100 Heiner Kallweit wrote: > @@ -1066,7 +1054,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) > return NETDEV_TX_OK; > > drop: > - this_cpu_inc(tun->pcpu_stats->tx_dropped); > + dev->stats.tx_dropped++; > skb_tx_error(skb); > kfree_skb(skb); > rcu_read_unlock(); This is no longer atomic. Multiple CPUs may try to update it at the same time. Do you know what the story on dev->rx_dropped is? The kdoc says drivers are not supposed to use it but: drivers/net/ipvlan/ipvlan_core.c: atomic_long_inc(&skb->dev->rx_dropped); drivers/net/macvlan.c: atomic_long_inc(&skb->dev->rx_dropped); drivers/net/vxlan.c: atomic_long_inc(&vxlan->dev->rx_dropped); Maybe tun can use it, too? From hkallweit1 at gmail.com Fri Nov 6 07:48:48 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Fri, 6 Nov 2020 08:48:48 +0100 Subject: [PATCH net-next v2 03/10] tun: switch to net core provided statistics counters In-Reply-To: <20201105171446.5f78f1a6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> <20201105171446.5f78f1a6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> Message-ID: On 06.11.2020 02:14, Jakub Kicinski wrote: > On Wed, 4 Nov 2020 15:25:24 +0100 Heiner Kallweit wrote: >> @@ -1066,7 +1054,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) >> return NETDEV_TX_OK; >> >> drop: >> - this_cpu_inc(tun->pcpu_stats->tx_dropped); >> + dev->stats.tx_dropped++; >> skb_tx_error(skb); >> kfree_skb(skb); >> rcu_read_unlock(); > > This is no longer atomic. Multiple CPUs may try to update it at the > same time. > > Do you know what the story on dev->rx_dropped is? The kdoc says drivers > are not supposed to use it but: > > drivers/net/ipvlan/ipvlan_core.c: atomic_long_inc(&skb->dev->rx_dropped); > drivers/net/macvlan.c: atomic_long_inc(&skb->dev->rx_dropped); > drivers/net/vxlan.c: atomic_long_inc(&vxlan->dev->rx_dropped); > > Maybe tun can use it, too? > Thanks, yes that should be possible. Here we speak about tx_dropped, but AFAICS the same applies as for rx_dropped. Will change it accordingly in a v3. From hkallweit1 at gmail.com Fri Nov 6 08:27:45 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Fri, 6 Nov 2020 09:27:45 +0100 Subject: [PATCH net-next v2 03/10] tun: switch to net core provided statistics counters In-Reply-To: References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> <20201105171446.5f78f1a6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> Message-ID: On 06.11.2020 08:48, Heiner Kallweit wrote: > On 06.11.2020 02:14, Jakub Kicinski wrote: >> On Wed, 4 Nov 2020 15:25:24 +0100 Heiner Kallweit wrote: >>> @@ -1066,7 +1054,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) >>> return NETDEV_TX_OK; >>> >>> drop: >>> - this_cpu_inc(tun->pcpu_stats->tx_dropped); >>> + dev->stats.tx_dropped++; >>> skb_tx_error(skb); >>> kfree_skb(skb); >>> rcu_read_unlock(); >> >> This is no longer atomic. Multiple CPUs may try to update it at the >> same time. >> >> Do you know what the story on dev->rx_dropped is? The kdoc says drivers >> are not supposed to use it but: >> >> drivers/net/ipvlan/ipvlan_core.c: atomic_long_inc(&skb->dev->rx_dropped); >> drivers/net/macvlan.c: atomic_long_inc(&skb->dev->rx_dropped); >> drivers/net/vxlan.c: atomic_long_inc(&vxlan->dev->rx_dropped); >> >> Maybe tun can use it, too? >> > Thanks, yes that should be possible. Here we speak about tx_dropped, > but AFAICS the same applies as for rx_dropped. Will change it accordingly > in a v3. > For rx_dropped and tx_dropped it's easy, however tun also has a per-cpu counter for rx_frame_errors that is incremented if virtio_net_hdr_to_skb() fails. Not sure how to deal best with this one. From kuba at kernel.org Fri Nov 6 16:18:46 2020 From: kuba at kernel.org (Jakub Kicinski) Date: Fri, 6 Nov 2020 08:18:46 -0800 Subject: [PATCH net-next v2 03/10] tun: switch to net core provided statistics counters In-Reply-To: References: <059fcb95-fba8-673e-0cd6-fb26e8ed4861@gmail.com> <30fd49be-f467-95f5-9586-fec9fbde8e48@gmail.com> <20201105171446.5f78f1a6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> Message-ID: <20201106081846.27212e9e@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> On Fri, 6 Nov 2020 09:27:45 +0100 Heiner Kallweit wrote: > On 06.11.2020 08:48, Heiner Kallweit wrote: > > On 06.11.2020 02:14, Jakub Kicinski wrote: > >> On Wed, 4 Nov 2020 15:25:24 +0100 Heiner Kallweit wrote: > >>> @@ -1066,7 +1054,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) > >>> return NETDEV_TX_OK; > >>> > >>> drop: > >>> - this_cpu_inc(tun->pcpu_stats->tx_dropped); > >>> + dev->stats.tx_dropped++; > >>> skb_tx_error(skb); > >>> kfree_skb(skb); > >>> rcu_read_unlock(); > >> > >> This is no longer atomic. Multiple CPUs may try to update it at the > >> same time. > >> > >> Do you know what the story on dev->rx_dropped is? The kdoc says drivers > >> are not supposed to use it but: > >> > >> drivers/net/ipvlan/ipvlan_core.c: atomic_long_inc(&skb->dev->rx_dropped); > >> drivers/net/macvlan.c: atomic_long_inc(&skb->dev->rx_dropped); > >> drivers/net/vxlan.c: atomic_long_inc(&vxlan->dev->rx_dropped); > >> > >> Maybe tun can use it, too? > >> > > Thanks, yes that should be possible. Here we speak about tx_dropped, > > but AFAICS the same applies as for rx_dropped. Will change it accordingly > > in a v3. > > > For rx_dropped and tx_dropped it's easy, however tun also has a per-cpu > counter for rx_frame_errors that is incremented if virtio_net_hdr_to_skb() > fails. Not sure how to deal best with this one. Umpf, yeah, so I'd probably add an atomic long to struct tun_struct, but then you'll need to keep the ndo implementation instead of using dev_get_tstats64 directly. I can't think of a better way, tho. From hkallweit1 at gmail.com Sat Nov 7 20:48:13 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:48:13 +0100 Subject: [PATCH net-next v3 00/10] net: add and use dev_get_tstats64 Message-ID: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> It's a frequent pattern to use netdev->stats for the less frequently accessed counters and per-cpu counters for the frequently accessed counters (rx/tx bytes/packets). Add a default ndo_get_stats64() implementation for this use case. Subsequently switch more drivers to use this pattern. v2: - add patches for replacing ip_tunnel_get_stats64 Requested additional migrations will come in a separate series. v3: - add atomic_long_t member rx_frame_errors in patch 3 for making counter updates atomic Heiner Kallweit (10): net: core: add dev_get_tstats64 as a ndo_get_stats64 implementation net: dsa: use net core stats64 handling tun: switch to net core provided statistics counters ip6_tunnel: use ip_tunnel_get_stats64 as ndo_get_stats64 callback net: switch to dev_get_tstats64 gtp: switch to dev_get_tstats64 wireguard: switch to dev_get_tstats64 vti: switch to dev_get_tstats64 ipv4/ipv6: switch to dev_get_tstats64 net: remove ip_tunnel_get_stats64 drivers/net/bareudp.c | 2 +- drivers/net/geneve.c | 2 +- drivers/net/gtp.c | 2 +- drivers/net/tun.c | 121 +++++++++------------------------ drivers/net/vxlan.c | 4 +- drivers/net/wireguard/device.c | 2 +- include/linux/netdevice.h | 1 + include/net/ip_tunnels.h | 2 - net/core/dev.c | 15 ++++ net/dsa/dsa.c | 7 +- net/dsa/dsa_priv.h | 2 - net/dsa/slave.c | 29 ++------ net/ipv4/ip_gre.c | 6 +- net/ipv4/ip_tunnel_core.c | 9 --- net/ipv4/ip_vti.c | 2 +- net/ipv4/ipip.c | 2 +- net/ipv6/ip6_gre.c | 6 +- net/ipv6/ip6_tunnel.c | 32 +-------- net/ipv6/ip6_vti.c | 2 +- net/ipv6/sit.c | 2 +- 20 files changed, 75 insertions(+), 175 deletions(-) -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:49:07 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:49:07 +0100 Subject: [PATCH net-next v3 01/10] net: core: add dev_get_tstats64 as a ndo_get_stats64 implementation In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <484218db-e035-dba4-dfb7-93c2cf177cec@gmail.com> It's a frequent pattern to use netdev->stats for the less frequently accessed counters and per-cpu counters for the frequently accessed counters (rx/tx bytes/packets). Add a default ndo_get_stats64() implementation for this use case. Reviewed-by: Florian Fainelli Signed-off-by: Heiner Kallweit --- include/linux/netdevice.h | 1 + net/core/dev.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a53ed2d1e..7ce648a56 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4527,6 +4527,7 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, const struct net_device_stats *netdev_stats); void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, const struct pcpu_sw_netstats __percpu *netstats); +void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s); extern int netdev_max_backlog; extern int netdev_tstamp_prequeue; diff --git a/net/core/dev.c b/net/core/dev.c index bd6100da6..60d325bda 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10366,6 +10366,21 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, } EXPORT_SYMBOL_GPL(dev_fetch_sw_netstats); +/** + * dev_get_tstats64 - ndo_get_stats64 implementation + * @dev: device to get statistics from + * @s: place to store stats + * + * Populate @s from dev->stats and dev->tstats. Can be used as + * ndo_get_stats64() callback. + */ +void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s) +{ + netdev_stats_to_stats64(s, &dev->stats); + dev_fetch_sw_netstats(s, dev->tstats); +} +EXPORT_SYMBOL_GPL(dev_get_tstats64); + struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) { struct netdev_queue *queue = dev_ingress_queue(dev); -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:49:46 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:49:46 +0100 Subject: [PATCH net-next v3 02/10] net: dsa: use net core stats64 handling In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <74c82e15-c44e-8368-6d60-4f61f6aba92f@gmail.com> Use netdev->tstats instead of a member of dsa_slave_priv for storing a pointer to the per-cpu counters. This allows us to use core functionality for statistics handling. Reviewed-by: Florian Fainelli Tested-by: Vladimir Oltean Signed-off-by: Heiner Kallweit --- net/dsa/dsa.c | 7 +------ net/dsa/dsa_priv.h | 2 -- net/dsa/slave.c | 29 +++++++---------------------- 3 files changed, 8 insertions(+), 30 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 2131bf2b3..a1b1dc8a4 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -201,7 +201,6 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, { struct dsa_port *cpu_dp = dev->dsa_ptr; struct sk_buff *nskb = NULL; - struct pcpu_sw_netstats *s; struct dsa_slave_priv *p; if (unlikely(!cpu_dp)) { @@ -234,11 +233,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, skb = nskb; } - s = this_cpu_ptr(p->stats64); - u64_stats_update_begin(&s->syncp); - s->rx_packets++; - s->rx_bytes += skb->len; - u64_stats_update_end(&s->syncp); + dev_sw_netstats_rx_add(skb->dev, skb->len); if (dsa_skb_defer_rx_timestamp(p, skb)) return 0; diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 12998bf04..7c96aae90 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -78,8 +78,6 @@ struct dsa_slave_priv { struct sk_buff * (*xmit)(struct sk_buff *skb, struct net_device *dev); - struct pcpu_sw_netstats __percpu *stats64; - struct gro_cells gcells; /* DSA port data, such as switch, port index, etc. */ diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 59c80052e..ff2266d2b 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -575,14 +575,9 @@ static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev) static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); - struct pcpu_sw_netstats *s; struct sk_buff *nskb; - s = this_cpu_ptr(p->stats64); - u64_stats_update_begin(&s->syncp); - s->tx_packets++; - s->tx_bytes += skb->len; - u64_stats_update_end(&s->syncp); + dev_sw_netstats_tx_add(dev, 1, skb->len); DSA_SKB_CB(skb)->clone = NULL; @@ -714,7 +709,6 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, uint64_t *data) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_switch *ds = dp->ds; struct pcpu_sw_netstats *s; unsigned int start; @@ -723,7 +717,7 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, for_each_possible_cpu(i) { u64 tx_packets, tx_bytes, rx_packets, rx_bytes; - s = per_cpu_ptr(p->stats64, i); + s = per_cpu_ptr(dev->tstats, i); do { start = u64_stats_fetch_begin_irq(&s->syncp); tx_packets = s->tx_packets; @@ -1252,15 +1246,6 @@ static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type, return ds->ops->port_setup_tc(ds, dp->index, type, type_data); } -static void dsa_slave_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) -{ - struct dsa_slave_priv *p = netdev_priv(dev); - - netdev_stats_to_stats64(stats, &dev->stats); - dev_fetch_sw_netstats(stats, p->stats64); -} - static int dsa_slave_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc, u32 *rule_locs) { @@ -1636,7 +1621,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = { #endif .ndo_get_phys_port_name = dsa_slave_get_phys_port_name, .ndo_setup_tc = dsa_slave_setup_tc, - .ndo_get_stats64 = dsa_slave_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_port_parent_id = dsa_slave_get_port_parent_id, .ndo_vlan_rx_add_vid = dsa_slave_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, @@ -1846,8 +1831,8 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->vlan_features = master->vlan_features; p = netdev_priv(slave_dev); - p->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); - if (!p->stats64) { + slave_dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!slave_dev->tstats) { free_netdev(slave_dev); return -ENOMEM; } @@ -1909,7 +1894,7 @@ int dsa_slave_create(struct dsa_port *port) out_gcells: gro_cells_destroy(&p->gcells); out_free: - free_percpu(p->stats64); + free_percpu(slave_dev->tstats); free_netdev(slave_dev); port->slave = NULL; return ret; @@ -1931,7 +1916,7 @@ void dsa_slave_destroy(struct net_device *slave_dev) dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER); phylink_destroy(dp->pl); gro_cells_destroy(&p->gcells); - free_percpu(p->stats64); + free_percpu(slave_dev->tstats); free_netdev(slave_dev); } -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:50:56 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:50:56 +0100 Subject: [PATCH net-next v3 03/10] tun: switch to net core provided statistics counters In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <7dbbdd3b-4e99-25b1-273c-232ab34d2e78@gmail.com> Switch tun to the standard statistics pattern: - use netdev->stats for the less frequently accessed counters - use netdev->tstats for the frequently accessed per-cpu counters v3: - add atomic_long_t member rx_frame_errors for making counter updates atomic Signed-off-by: Heiner Kallweit --- drivers/net/tun.c | 121 +++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 87 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index be69d2720..3d45d5617 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -107,17 +107,6 @@ struct tap_filter { #define TUN_FLOW_EXPIRE (3 * HZ) -struct tun_pcpu_stats { - u64_stats_t rx_packets; - u64_stats_t rx_bytes; - u64_stats_t tx_packets; - u64_stats_t tx_bytes; - struct u64_stats_sync syncp; - u32 rx_dropped; - u32 tx_dropped; - u32 rx_frame_errors; -}; - /* A tun_file connects an open character device to a tuntap netdevice. It * also contains all socket related structures (except sock_fprog and tap_filter) * to serve as one transmit queue for tuntap device. The sock_fprog and @@ -207,7 +196,7 @@ struct tun_struct { void *security; u32 flow_count; u32 rx_batched; - struct tun_pcpu_stats __percpu *pcpu_stats; + atomic_long_t rx_frame_errors; struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; @@ -1066,7 +1055,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; drop: - this_cpu_inc(tun->pcpu_stats->tx_dropped); + atomic_long_inc(&dev->tx_dropped); skb_tx_error(skb); kfree_skb(skb); rcu_read_unlock(); @@ -1103,37 +1092,12 @@ static void tun_set_headroom(struct net_device *dev, int new_hr) static void tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; struct tun_struct *tun = netdev_priv(dev); - struct tun_pcpu_stats *p; - int i; - - for_each_possible_cpu(i) { - u64 rxpackets, rxbytes, txpackets, txbytes; - unsigned int start; - p = per_cpu_ptr(tun->pcpu_stats, i); - do { - start = u64_stats_fetch_begin(&p->syncp); - rxpackets = u64_stats_read(&p->rx_packets); - rxbytes = u64_stats_read(&p->rx_bytes); - txpackets = u64_stats_read(&p->tx_packets); - txbytes = u64_stats_read(&p->tx_bytes); - } while (u64_stats_fetch_retry(&p->syncp, start)); + dev_get_tstats64(dev, stats); - stats->rx_packets += rxpackets; - stats->rx_bytes += rxbytes; - stats->tx_packets += txpackets; - stats->tx_bytes += txbytes; - - /* u32 counters */ - rx_dropped += p->rx_dropped; - rx_frame_errors += p->rx_frame_errors; - tx_dropped += p->tx_dropped; - } - stats->rx_dropped = rx_dropped; - stats->rx_frame_errors = rx_frame_errors; - stats->tx_dropped = tx_dropped; + stats->rx_frame_errors += + (unsigned long)atomic_long_read(&tun->rx_frame_errors); } static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog, @@ -1247,7 +1211,7 @@ static int tun_xdp_xmit(struct net_device *dev, int n, void *frame = tun_xdp_to_ptr(xdp); if (__ptr_ring_produce(&tfile->tx_ring, frame)) { - this_cpu_inc(tun->pcpu_stats->tx_dropped); + atomic_long_inc(&dev->tx_dropped); xdp_return_frame_rx_napi(xdp); drops++; } @@ -1283,7 +1247,7 @@ static const struct net_device_ops tap_netdev_ops = { .ndo_select_queue = tun_select_queue, .ndo_features_check = passthru_features_check, .ndo_set_rx_headroom = tun_set_headroom, - .ndo_get_stats64 = tun_net_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_bpf = tun_xdp, .ndo_xdp_xmit = tun_xdp_xmit, .ndo_change_carrier = tun_net_change_carrier, @@ -1577,7 +1541,7 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog, trace_xdp_exception(tun->dev, xdp_prog, act); fallthrough; case XDP_DROP: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); break; } @@ -1683,7 +1647,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, size_t total_len = iov_iter_count(from); size_t len = total_len, align = tun->align, linear; struct virtio_net_hdr gso = { 0 }; - struct tun_pcpu_stats *stats; int good_linear; int copylen; bool zerocopy = false; @@ -1752,7 +1715,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, */ skb = tun_build_skb(tun, tfile, from, &gso, len, &skb_xdp); if (IS_ERR(skb)) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); return PTR_ERR(skb); } if (!skb) @@ -1781,7 +1744,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (IS_ERR(skb)) { if (PTR_ERR(skb) != -EAGAIN) - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); if (frags) mutex_unlock(&tfile->napi_mutex); return PTR_ERR(skb); @@ -1795,7 +1758,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (err) { err = -EFAULT; drop: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); kfree_skb(skb); if (frags) { tfile->napi.skb = NULL; @@ -1807,7 +1770,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } if (virtio_net_hdr_to_skb(skb, &gso, tun_is_little_endian(tun))) { - this_cpu_inc(tun->pcpu_stats->rx_frame_errors); + atomic_long_inc(&tun->rx_frame_errors); kfree_skb(skb); if (frags) { tfile->napi.skb = NULL; @@ -1830,7 +1793,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, pi.proto = htons(ETH_P_IPV6); break; default: - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); kfree_skb(skb); return -EINVAL; } @@ -1910,7 +1873,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_headlen(skb)); if (unlikely(headlen > skb_headlen(skb))) { - this_cpu_inc(tun->pcpu_stats->rx_dropped); + atomic_long_inc(&tun->dev->rx_dropped); napi_free_frags(&tfile->napi); rcu_read_unlock(); mutex_unlock(&tfile->napi_mutex); @@ -1942,12 +1905,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } rcu_read_unlock(); - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->rx_packets); - u64_stats_add(&stats->rx_bytes, len); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(stats); + preempt_disable(); + dev_sw_netstats_rx_add(tun->dev, len); + preempt_enable(); if (rxhash) tun_flow_update(tun, rxhash, tfile); @@ -1979,7 +1939,6 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tun, { int vnet_hdr_sz = 0; size_t size = xdp_frame->len; - struct tun_pcpu_stats *stats; size_t ret; if (tun->flags & IFF_VNET_HDR) { @@ -1996,12 +1955,9 @@ static ssize_t tun_put_user_xdp(struct tun_struct *tun, ret = copy_to_iter(xdp_frame->data, size, iter) + vnet_hdr_sz; - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->tx_packets); - u64_stats_add(&stats->tx_bytes, ret); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(tun->pcpu_stats); + preempt_disable(); + dev_sw_netstats_tx_add(tun->dev, 1, ret); + preempt_enable(); return ret; } @@ -2013,7 +1969,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, struct iov_iter *iter) { struct tun_pi pi = { 0, skb->protocol }; - struct tun_pcpu_stats *stats; ssize_t total; int vlan_offset = 0; int vlan_hlen = 0; @@ -2091,12 +2046,9 @@ static ssize_t tun_put_user(struct tun_struct *tun, done: /* caller is in process context, */ - stats = get_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->tx_packets); - u64_stats_add(&stats->tx_bytes, skb->len + vlan_hlen); - u64_stats_update_end(&stats->syncp); - put_cpu_ptr(tun->pcpu_stats); + preempt_disable(); + dev_sw_netstats_tx_add(tun->dev, 1, skb->len + vlan_hlen); + preempt_enable(); return total; } @@ -2235,11 +2187,11 @@ static void tun_free_netdev(struct net_device *dev) BUG_ON(!(list_empty(&tun->disabled))); - free_percpu(tun->pcpu_stats); - /* We clear pcpu_stats so that tun_set_iff() can tell if + free_percpu(dev->tstats); + /* We clear tstats so that tun_set_iff() can tell if * tun_free_netdev() has been called from register_netdevice(). */ - tun->pcpu_stats = NULL; + dev->tstats = NULL; tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); @@ -2370,7 +2322,6 @@ static int tun_xdp_one(struct tun_struct *tun, unsigned int datasize = xdp->data_end - xdp->data; struct tun_xdp_hdr *hdr = xdp->data_hard_start; struct virtio_net_hdr *gso = &hdr->gso; - struct tun_pcpu_stats *stats; struct bpf_prog *xdp_prog; struct sk_buff *skb = NULL; u32 rxhash = 0, act; @@ -2428,7 +2379,7 @@ static int tun_xdp_one(struct tun_struct *tun, skb_put(skb, xdp->data_end - xdp->data); if (virtio_net_hdr_to_skb(skb, gso, tun_is_little_endian(tun))) { - this_cpu_inc(tun->pcpu_stats->rx_frame_errors); + atomic_long_inc(&tun->rx_frame_errors); kfree_skb(skb); err = -EINVAL; goto out; @@ -2451,14 +2402,10 @@ static int tun_xdp_one(struct tun_struct *tun, netif_receive_skb(skb); - /* No need for get_cpu_ptr() here since this function is + /* No need to disable preemption here since this function is * always called with bh disabled */ - stats = this_cpu_ptr(tun->pcpu_stats); - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->rx_packets); - u64_stats_add(&stats->rx_bytes, datasize); - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_rx_add(tun->dev, datasize); if (rxhash) tun_flow_update(tun, rxhash, tfile); @@ -2751,8 +2698,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->rx_batched = 0; RCU_INIT_POINTER(tun->steering_prog, NULL); - tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); - if (!tun->pcpu_stats) { + dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!dev->tstats) { err = -ENOMEM; goto err_free_dev; } @@ -2807,16 +2754,16 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun_detach_all(dev); /* We are here because register_netdevice() has failed. * If register_netdevice() already called tun_free_netdev() - * while dealing with the error, tun->pcpu_stats has been cleared. + * while dealing with the error, dev->stats has been cleared. */ - if (!tun->pcpu_stats) + if (!dev->tstats) goto err_free_dev; err_free_flow: tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); err_free_stat: - free_percpu(tun->pcpu_stats); + free_percpu(dev->tstats); err_free_dev: free_netdev(dev); return err; -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:51:32 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:51:32 +0100 Subject: [PATCH net-next v3 04/10] ip6_tunnel: use ip_tunnel_get_stats64 as ndo_get_stats64 callback In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <70653bd6-41de-8a4f-61d6-41245257048f@gmail.com> Switch ip6_tunnel to the standard statistics pattern: - use dev->stats for the less frequently accessed counters - use dev->tstats for the frequently accessed counters An additional benefit is that we now have 64bit statistics also on 32bit systems. Signed-off-by: Heiner Kallweit --- net/ipv6/ip6_tunnel.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 74a6ea9f8..a7950baa0 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -94,36 +94,6 @@ static inline int ip6_tnl_mpls_supported(void) return IS_ENABLED(CONFIG_MPLS); } -static struct net_device_stats *ip6_get_stats(struct net_device *dev) -{ - struct pcpu_sw_netstats tmp, sum = { 0 }; - int i; - - for_each_possible_cpu(i) { - unsigned int start; - const struct pcpu_sw_netstats *tstats = - per_cpu_ptr(dev->tstats, i); - - do { - start = u64_stats_fetch_begin_irq(&tstats->syncp); - tmp.rx_packets = tstats->rx_packets; - tmp.rx_bytes = tstats->rx_bytes; - tmp.tx_packets = tstats->tx_packets; - tmp.tx_bytes = tstats->tx_bytes; - } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); - - sum.rx_packets += tmp.rx_packets; - sum.rx_bytes += tmp.rx_bytes; - sum.tx_packets += tmp.tx_packets; - sum.tx_bytes += tmp.tx_bytes; - } - dev->stats.rx_packets = sum.rx_packets; - dev->stats.rx_bytes = sum.rx_bytes; - dev->stats.tx_packets = sum.tx_packets; - dev->stats.tx_bytes = sum.tx_bytes; - return &dev->stats; -} - #define for_each_ip6_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) @@ -1834,7 +1804,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { .ndo_start_xmit = ip6_tnl_start_xmit, .ndo_do_ioctl = ip6_tnl_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats = ip6_get_stats, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:52:06 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:52:06 +0100 Subject: [PATCH net-next v3 05/10] net: switch to dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <0f7cd95e-896d-2313-88e8-e0af23d011bb@gmail.com> Replace ip_tunnel_get_stats64() with the new identical core function dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- drivers/net/bareudp.c | 2 +- drivers/net/geneve.c | 2 +- drivers/net/vxlan.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index ff0bea155..28257bcce 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -510,7 +510,7 @@ static const struct net_device_ops bareudp_netdev_ops = { .ndo_open = bareudp_open, .ndo_stop = bareudp_stop, .ndo_start_xmit = bareudp_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_fill_metadata_dst = bareudp_fill_metadata_dst, }; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index d07008a81..a3c8ce6de 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1138,7 +1138,7 @@ static const struct net_device_ops geneve_netdev_ops = { .ndo_open = geneve_open, .ndo_stop = geneve_stop, .ndo_start_xmit = geneve_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_change_mtu = geneve_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 876679af6..0de912729 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -3211,7 +3211,7 @@ static const struct net_device_ops vxlan_netdev_ether_ops = { .ndo_open = vxlan_open, .ndo_stop = vxlan_stop, .ndo_start_xmit = vxlan_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_set_rx_mode = vxlan_set_multicast_list, .ndo_change_mtu = vxlan_change_mtu, .ndo_validate_addr = eth_validate_addr, @@ -3230,7 +3230,7 @@ static const struct net_device_ops vxlan_netdev_raw_ops = { .ndo_open = vxlan_open, .ndo_stop = vxlan_stop, .ndo_start_xmit = vxlan_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_change_mtu = vxlan_change_mtu, .ndo_fill_metadata_dst = vxlan_fill_metadata_dst, }; -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:52:42 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:52:42 +0100 Subject: [PATCH net-next v3 06/10] gtp: switch to dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core function dev_get_tstats64(). Acked-by: Harald Welte Signed-off-by: Heiner Kallweit --- drivers/net/gtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index dc668ed28..4c04e271f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -607,7 +607,7 @@ static const struct net_device_ops gtp_netdev_ops = { .ndo_init = gtp_dev_init, .ndo_uninit = gtp_dev_uninit, .ndo_start_xmit = gtp_dev_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, }; static void gtp_link_setup(struct net_device *dev) -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:53:19 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:53:19 +0100 Subject: [PATCH net-next v3 07/10] wireguard: switch to dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <79e9a040-c097-1d33-8de1-4833f1c68828@gmail.com> Replace ip_tunnel_get_stats64() with the new identical core function dev_get_tstats64(). Reviewed-by: Jason A. Donenfeld Signed-off-by: Heiner Kallweit --- drivers/net/wireguard/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index c9f65e96c..a3ed49cd9 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -215,7 +215,7 @@ static const struct net_device_ops netdev_ops = { .ndo_open = wg_open, .ndo_stop = wg_stop, .ndo_start_xmit = wg_xmit, - .ndo_get_stats64 = ip_tunnel_get_stats64 + .ndo_get_stats64 = dev_get_tstats64 }; static void wg_destruct(struct net_device *dev) -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:53:53 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:53:53 +0100 Subject: [PATCH net-next v3 08/10] vti: switch to dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core function dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- net/ipv4/ip_vti.c | 2 +- net/ipv6/ip6_vti.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index b957cbee2..abc171e79 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -404,7 +404,7 @@ static const struct net_device_ops vti_netdev_ops = { .ndo_start_xmit = vti_tunnel_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = vti_tunnel_ctl, }; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 46d137a69..0225fd694 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -890,7 +890,7 @@ static const struct net_device_ops vti6_netdev_ops = { .ndo_uninit = vti6_dev_uninit, .ndo_start_xmit = vti6_tnl_xmit, .ndo_do_ioctl = vti6_ioctl, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:54:33 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:54:33 +0100 Subject: [PATCH net-next v3 09/10] ipv4/ipv6: switch to dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: Replace ip_tunnel_get_stats64() with the new identical core function dev_get_tstats64(). Signed-off-by: Heiner Kallweit --- net/ipv4/ip_gre.c | 6 +++--- net/ipv4/ipip.c | 2 +- net/ipv6/ip6_gre.c | 6 +++--- net/ipv6/sit.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e70291748..a68bf4c6f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -920,7 +920,7 @@ static const struct net_device_ops ipgre_netdev_ops = { .ndo_start_xmit = ipgre_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipgre_tunnel_ctl, }; @@ -1275,7 +1275,7 @@ static const struct net_device_ops gre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_fill_metadata_dst = gre_fill_metadata_dst, }; @@ -1308,7 +1308,7 @@ static const struct net_device_ops erspan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_fill_metadata_dst = gre_fill_metadata_dst, }; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 75d35e76b..d5bfa087c 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -347,7 +347,7 @@ static const struct net_device_ops ipip_netdev_ops = { .ndo_start_xmit = ipip_tunnel_xmit, .ndo_do_ioctl = ip_tunnel_ioctl, .ndo_change_mtu = ip_tunnel_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipip_tunnel_ctl, }; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 931b186d2..8cf659994 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -1391,7 +1391,7 @@ static const struct net_device_ops ip6gre_netdev_ops = { .ndo_start_xmit = ip6gre_tunnel_xmit, .ndo_do_ioctl = ip6gre_tunnel_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; @@ -1828,7 +1828,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; @@ -1896,7 +1896,7 @@ static const struct net_device_ops ip6erspan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ip6_tnl_change_mtu, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip6_tnl_get_iflink, }; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 5e2c34c0a..4dc5f9366 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1396,7 +1396,7 @@ static const struct net_device_ops ipip6_netdev_ops = { .ndo_uninit = ipip6_tunnel_uninit, .ndo_start_xmit = sit_tunnel_xmit, .ndo_do_ioctl = ipip6_tunnel_ioctl, - .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_get_iflink = ip_tunnel_get_iflink, .ndo_tunnel_ctl = ipip6_tunnel_ctl, }; -- 2.29.2 From hkallweit1 at gmail.com Sat Nov 7 20:55:11 2020 From: hkallweit1 at gmail.com (Heiner Kallweit) Date: Sat, 7 Nov 2020 21:55:11 +0100 Subject: [PATCH net-next v3 10/10] net: remove ip_tunnel_get_stats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <1d5992f4-6d88-1bef-9756-06d48fc10a31@gmail.com> After having migrated all users remove ip_tunnel_get_stats64(). Signed-off-by: Heiner Kallweit --- include/net/ip_tunnels.h | 2 -- net/ipv4/ip_tunnel_core.c | 9 --------- 2 files changed, 11 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 02ccd3254..1b7905eb7 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -274,8 +274,6 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); -void ip_tunnel_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *tot); struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, int link, __be16 flags, __be32 remote, __be32 local, diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 25f1caf5a..923a9fa2e 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -429,15 +429,6 @@ int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst, } EXPORT_SYMBOL(skb_tunnel_check_pmtu); -/* Often modified stats are per cpu, other are shared (netdev->stats) */ -void ip_tunnel_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *tot) -{ - netdev_stats_to_stats64(tot, &dev->stats); - dev_fetch_sw_netstats(tot, dev->tstats); -} -EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); - static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = { [LWTUNNEL_IP_UNSPEC] = { .strict_start_type = LWTUNNEL_IP_OPTS }, [LWTUNNEL_IP_ID] = { .type = NLA_U64 }, -- 2.29.2 From kuba at kernel.org Tue Nov 10 03:58:11 2020 From: kuba at kernel.org (Jakub Kicinski) Date: Mon, 9 Nov 2020 19:58:11 -0800 Subject: [PATCH net-next v3 00/10] net: add and use dev_get_tstats64 In-Reply-To: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> References: <99273e2f-c218-cd19-916e-9161d8ad8c56@gmail.com> Message-ID: <20201109195811.7be5882c@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> On Sat, 7 Nov 2020 21:48:13 +0100 Heiner Kallweit wrote: > It's a frequent pattern to use netdev->stats for the less frequently > accessed counters and per-cpu counters for the frequently accessed > counters (rx/tx bytes/packets). Add a default ndo_get_stats64() > implementation for this use case. Subsequently switch more drivers > to use this pattern. > > v2: > - add patches for replacing ip_tunnel_get_stats64 > Requested additional migrations will come in a separate series. > > v3: > - add atomic_long_t member rx_frame_errors in patch 3 for making > counter updates atomic Applied, thank you!