Commit a003ec1f authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-add-and-use-function-dev_fetch_sw_netstats-for-fetching-pcpu_sw_netstats'

Heiner Kallweit says:

====================
net: add and use function dev_fetch_sw_netstats for fetching pcpu_sw_netstats

In several places the same code is used to populate rtnl_link_stats64
fields with data from pcpu_sw_netstats. Therefore factor out this code
to a new function dev_fetch_sw_netstats().
====================
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3618ad2a 5fc3594d
...@@ -97,41 +97,9 @@ static void hfi1_ipoib_dev_get_stats64(struct net_device *dev, ...@@ -97,41 +97,9 @@ static void hfi1_ipoib_dev_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *storage) struct rtnl_link_stats64 *storage)
{ {
struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev);
u64 rx_packets = 0ull;
u64 rx_bytes = 0ull;
u64 tx_packets = 0ull;
u64 tx_bytes = 0ull;
int i;
netdev_stats_to_stats64(storage, &dev->stats); netdev_stats_to_stats64(storage, &dev->stats);
dev_fetch_sw_netstats(storage, priv->netstats);
for_each_possible_cpu(i) {
const struct pcpu_sw_netstats *stats;
unsigned int start;
u64 trx_packets;
u64 trx_bytes;
u64 ttx_packets;
u64 ttx_bytes;
stats = per_cpu_ptr(priv->netstats, i);
do {
start = u64_stats_fetch_begin_irq(&stats->syncp);
trx_packets = stats->rx_packets;
trx_bytes = stats->rx_bytes;
ttx_packets = stats->tx_packets;
ttx_bytes = stats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
rx_packets += trx_packets;
rx_bytes += trx_bytes;
tx_packets += ttx_packets;
tx_bytes += ttx_bytes;
}
storage->rx_packets += rx_packets;
storage->rx_bytes += rx_bytes;
storage->tx_packets += tx_packets;
storage->tx_bytes += tx_bytes;
} }
static const struct net_device_ops hfi1_ipoib_netdev_ops = { static const struct net_device_ops hfi1_ipoib_netdev_ops = {
......
...@@ -3647,30 +3647,10 @@ static int macsec_change_mtu(struct net_device *dev, int new_mtu) ...@@ -3647,30 +3647,10 @@ static int macsec_change_mtu(struct net_device *dev, int new_mtu)
static void macsec_get_stats64(struct net_device *dev, static void macsec_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *s) struct rtnl_link_stats64 *s)
{ {
int cpu;
if (!dev->tstats) if (!dev->tstats)
return; return;
for_each_possible_cpu(cpu) { dev_fetch_sw_netstats(s, dev->tstats);
struct pcpu_sw_netstats *stats;
struct pcpu_sw_netstats tmp;
int start;
stats = per_cpu_ptr(dev->tstats, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats->syncp);
tmp.rx_packets = stats->rx_packets;
tmp.rx_bytes = stats->rx_bytes;
tmp.tx_packets = stats->tx_packets;
tmp.tx_bytes = stats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
s->rx_packets += tmp.rx_packets;
s->rx_bytes += tmp.rx_bytes;
s->tx_packets += tmp.tx_packets;
s->tx_bytes += tmp.tx_bytes;
}
s->rx_dropped = dev->stats.rx_dropped; s->rx_dropped = dev->stats.rx_dropped;
s->tx_dropped = dev->stats.tx_dropped; s->tx_dropped = dev->stats.tx_dropped;
......
...@@ -126,31 +126,9 @@ static void qmimux_get_stats64(struct net_device *net, ...@@ -126,31 +126,9 @@ static void qmimux_get_stats64(struct net_device *net,
struct rtnl_link_stats64 *stats) struct rtnl_link_stats64 *stats)
{ {
struct qmimux_priv *priv = netdev_priv(net); struct qmimux_priv *priv = netdev_priv(net);
unsigned int start;
int cpu;
netdev_stats_to_stats64(stats, &net->stats); netdev_stats_to_stats64(stats, &net->stats);
dev_fetch_sw_netstats(stats, priv->stats64);
for_each_possible_cpu(cpu) {
struct pcpu_sw_netstats *stats64;
u64 rx_packets, rx_bytes;
u64 tx_packets, tx_bytes;
stats64 = per_cpu_ptr(priv->stats64, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats64->syncp);
rx_packets = stats64->rx_packets;
rx_bytes = stats64->rx_bytes;
tx_packets = stats64->tx_packets;
tx_bytes = stats64->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
}
} }
static const struct net_device_ops qmimux_netdev_ops = { static const struct net_device_ops qmimux_netdev_ops = {
......
...@@ -983,31 +983,9 @@ EXPORT_SYMBOL_GPL(usbnet_set_link_ksettings); ...@@ -983,31 +983,9 @@ EXPORT_SYMBOL_GPL(usbnet_set_link_ksettings);
void usbnet_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) void usbnet_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats)
{ {
struct usbnet *dev = netdev_priv(net); struct usbnet *dev = netdev_priv(net);
unsigned int start;
int cpu;
netdev_stats_to_stats64(stats, &net->stats); netdev_stats_to_stats64(stats, &net->stats);
dev_fetch_sw_netstats(stats, dev->stats64);
for_each_possible_cpu(cpu) {
struct pcpu_sw_netstats *stats64;
u64 rx_packets, rx_bytes;
u64 tx_packets, tx_bytes;
stats64 = per_cpu_ptr(dev->stats64, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats64->syncp);
rx_packets = stats64->rx_packets;
rx_bytes = stats64->rx_bytes;
tx_packets = stats64->tx_packets;
tx_bytes = stats64->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
}
} }
EXPORT_SYMBOL_GPL(usbnet_get_stats64); EXPORT_SYMBOL_GPL(usbnet_get_stats64);
......
...@@ -139,34 +139,13 @@ static void qtnf_netdev_get_stats64(struct net_device *ndev, ...@@ -139,34 +139,13 @@ static void qtnf_netdev_get_stats64(struct net_device *ndev,
struct rtnl_link_stats64 *stats) struct rtnl_link_stats64 *stats)
{ {
struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev); struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
unsigned int start;
int cpu;
netdev_stats_to_stats64(stats, &ndev->stats); netdev_stats_to_stats64(stats, &ndev->stats);
if (!vif->stats64) if (!vif->stats64)
return; return;
for_each_possible_cpu(cpu) { dev_fetch_sw_netstats(stats, vif->stats64);
struct pcpu_sw_netstats *stats64;
u64 rx_packets, rx_bytes;
u64 tx_packets, tx_bytes;
stats64 = per_cpu_ptr(vif->stats64, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats64->syncp);
rx_packets = stats64->rx_packets;
rx_bytes = stats64->rx_bytes;
tx_packets = stats64->tx_packets;
tx_bytes = stats64->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
}
} }
/* Netdev handler for transmission timeout. /* Netdev handler for transmission timeout.
......
...@@ -4499,6 +4499,8 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, ...@@ -4499,6 +4499,8 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
struct rtnl_link_stats64 *storage); struct rtnl_link_stats64 *storage);
void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
const struct net_device_stats *netdev_stats); const struct net_device_stats *netdev_stats);
void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
const struct pcpu_sw_netstats __percpu *netstats);
extern int netdev_max_backlog; extern int netdev_max_backlog;
extern int netdev_tstamp_prequeue; extern int netdev_tstamp_prequeue;
......
...@@ -206,27 +206,8 @@ static void br_get_stats64(struct net_device *dev, ...@@ -206,27 +206,8 @@ static void br_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats) struct rtnl_link_stats64 *stats)
{ {
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
struct pcpu_sw_netstats tmp, sum = { 0 };
unsigned int cpu;
for_each_possible_cpu(cpu) {
unsigned int start;
const struct pcpu_sw_netstats *bstats
= per_cpu_ptr(br->stats, cpu);
do {
start = u64_stats_fetch_begin_irq(&bstats->syncp);
memcpy(&tmp, bstats, sizeof(tmp));
} while (u64_stats_fetch_retry_irq(&bstats->syncp, start));
sum.tx_bytes += tmp.tx_bytes;
sum.tx_packets += tmp.tx_packets;
sum.rx_bytes += tmp.rx_bytes;
sum.rx_packets += tmp.rx_packets;
}
stats->tx_bytes = sum.tx_bytes; dev_fetch_sw_netstats(stats, br->stats);
stats->tx_packets = sum.tx_packets;
stats->rx_bytes = sum.rx_bytes;
stats->rx_packets = sum.rx_packets;
} }
static int br_change_mtu(struct net_device *dev, int new_mtu) static int br_change_mtu(struct net_device *dev, int new_mtu)
......
...@@ -10328,6 +10328,40 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, ...@@ -10328,6 +10328,40 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
} }
EXPORT_SYMBOL(dev_get_stats); EXPORT_SYMBOL(dev_get_stats);
/**
* dev_fetch_sw_netstats - get per-cpu network device statistics
* @s: place to store stats
* @netstats: per-cpu network stats to read from
*
* Read per-cpu network statistics and populate the related fields in @s.
*/
void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
const struct pcpu_sw_netstats __percpu *netstats)
{
int cpu;
for_each_possible_cpu(cpu) {
const struct pcpu_sw_netstats *stats;
struct pcpu_sw_netstats tmp;
unsigned int start;
stats = per_cpu_ptr(netstats, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats->syncp);
tmp.rx_packets = stats->rx_packets;
tmp.rx_bytes = stats->rx_bytes;
tmp.tx_packets = stats->tx_packets;
tmp.tx_bytes = stats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
s->rx_packets += tmp.rx_packets;
s->rx_bytes += tmp.rx_bytes;
s->tx_packets += tmp.tx_packets;
s->tx_bytes += tmp.tx_bytes;
}
}
EXPORT_SYMBOL_GPL(dev_fetch_sw_netstats);
struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) struct netdev_queue *dev_ingress_queue_create(struct net_device *dev)
{ {
struct netdev_queue *queue = dev_ingress_queue(dev); struct netdev_queue *queue = dev_ingress_queue(dev);
......
...@@ -1221,28 +1221,9 @@ static void dsa_slave_get_stats64(struct net_device *dev, ...@@ -1221,28 +1221,9 @@ static void dsa_slave_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats) struct rtnl_link_stats64 *stats)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct pcpu_sw_netstats *s;
unsigned int start;
int i;
netdev_stats_to_stats64(stats, &dev->stats); netdev_stats_to_stats64(stats, &dev->stats);
for_each_possible_cpu(i) { dev_fetch_sw_netstats(stats, p->stats64);
u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
s = per_cpu_ptr(p->stats64, i);
do {
start = u64_stats_fetch_begin_irq(&s->syncp);
tx_packets = s->tx_packets;
tx_bytes = s->tx_bytes;
rx_packets = s->rx_packets;
rx_bytes = s->rx_bytes;
} while (u64_stats_fetch_retry_irq(&s->syncp, start));
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
}
} }
static int dsa_slave_get_rxnfc(struct net_device *dev, static int dsa_slave_get_rxnfc(struct net_device *dev,
......
...@@ -433,29 +433,8 @@ EXPORT_SYMBOL(skb_tunnel_check_pmtu); ...@@ -433,29 +433,8 @@ EXPORT_SYMBOL(skb_tunnel_check_pmtu);
void ip_tunnel_get_stats64(struct net_device *dev, void ip_tunnel_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *tot) struct rtnl_link_stats64 *tot)
{ {
int i;
netdev_stats_to_stats64(tot, &dev->stats); netdev_stats_to_stats64(tot, &dev->stats);
dev_fetch_sw_netstats(tot, dev->tstats);
for_each_possible_cpu(i) {
const struct pcpu_sw_netstats *tstats =
per_cpu_ptr(dev->tstats, i);
u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
unsigned int start;
do {
start = u64_stats_fetch_begin_irq(&tstats->syncp);
rx_packets = tstats->rx_packets;
tx_packets = tstats->tx_packets;
rx_bytes = tstats->rx_bytes;
tx_bytes = tstats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
tot->rx_packets += rx_packets;
tot->tx_packets += tx_packets;
tot->rx_bytes += rx_bytes;
tot->tx_bytes += tx_bytes;
}
} }
EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64);
......
...@@ -709,28 +709,7 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev, ...@@ -709,28 +709,7 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev,
static void static void
ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{ {
int i; dev_fetch_sw_netstats(stats, dev->tstats);
for_each_possible_cpu(i) {
const struct pcpu_sw_netstats *tstats;
u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
unsigned int start;
tstats = per_cpu_ptr(dev->tstats, i);
do {
start = u64_stats_fetch_begin_irq(&tstats->syncp);
rx_packets = tstats->rx_packets;
tx_packets = tstats->tx_packets;
rx_bytes = tstats->rx_bytes;
tx_bytes = tstats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
stats->rx_packets += rx_packets;
stats->tx_packets += tx_packets;
stats->rx_bytes += rx_bytes;
stats->tx_bytes += tx_bytes;
}
} }
static const struct net_device_ops ieee80211_dataif_ops = { static const struct net_device_ops ieee80211_dataif_ops = {
......
...@@ -86,31 +86,13 @@ static void internal_dev_destructor(struct net_device *dev) ...@@ -86,31 +86,13 @@ static void internal_dev_destructor(struct net_device *dev)
static void static void
internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
{ {
int i;
memset(stats, 0, sizeof(*stats)); memset(stats, 0, sizeof(*stats));
stats->rx_errors = dev->stats.rx_errors; stats->rx_errors = dev->stats.rx_errors;
stats->tx_errors = dev->stats.tx_errors; stats->tx_errors = dev->stats.tx_errors;
stats->tx_dropped = dev->stats.tx_dropped; stats->tx_dropped = dev->stats.tx_dropped;
stats->rx_dropped = dev->stats.rx_dropped; stats->rx_dropped = dev->stats.rx_dropped;
for_each_possible_cpu(i) { dev_fetch_sw_netstats(stats, dev->tstats);
const struct pcpu_sw_netstats *percpu_stats;
struct pcpu_sw_netstats local_stats;
unsigned int start;
percpu_stats = per_cpu_ptr(dev->tstats, i);
do {
start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
local_stats = *percpu_stats;
} while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
stats->rx_bytes += local_stats.rx_bytes;
stats->rx_packets += local_stats.rx_packets;
stats->tx_bytes += local_stats.tx_bytes;
stats->tx_packets += local_stats.tx_packets;
}
} }
static const struct net_device_ops internal_dev_netdev_ops = { static const struct net_device_ops internal_dev_netdev_ops = {
......
...@@ -541,27 +541,7 @@ static int xfrmi_update(struct xfrm_if *xi, struct xfrm_if_parms *p) ...@@ -541,27 +541,7 @@ static int xfrmi_update(struct xfrm_if *xi, struct xfrm_if_parms *p)
static void xfrmi_get_stats64(struct net_device *dev, static void xfrmi_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *s) struct rtnl_link_stats64 *s)
{ {
int cpu; dev_fetch_sw_netstats(s, dev->tstats);
for_each_possible_cpu(cpu) {
struct pcpu_sw_netstats *stats;
struct pcpu_sw_netstats tmp;
int start;
stats = per_cpu_ptr(dev->tstats, cpu);
do {
start = u64_stats_fetch_begin_irq(&stats->syncp);
tmp.rx_packets = stats->rx_packets;
tmp.rx_bytes = stats->rx_bytes;
tmp.tx_packets = stats->tx_packets;
tmp.tx_bytes = stats->tx_bytes;
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
s->rx_packets += tmp.rx_packets;
s->rx_bytes += tmp.rx_bytes;
s->tx_packets += tmp.tx_packets;
s->tx_bytes += tmp.tx_bytes;
}
s->rx_dropped = dev->stats.rx_dropped; s->rx_dropped = dev->stats.rx_dropped;
s->tx_dropped = dev->stats.tx_dropped; s->tx_dropped = dev->stats.tx_dropped;
......
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