mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Merge branch 'rx_nohandler'
Jarod Wilson says: ==================== net: add and use rx_nohandler stat counter The network core tries to keep track of dropped packets, but some packets you wouldn't really call dropped, so much as intentionally ignored, under certain circumstances. One such case is that of bonding and team device slaves that are currently inactive. Their respective rx_handler functions return RX_HANDLER_EXACT (the only places in the kernel that return that), which ends up tracking into the network core's __netif_receive_skb_core() function's drop path, with no pt_prev set. On a noisy network, this can result in a very rapidly incrementing rx_dropped counter, not only on the inactive slave(s), but also on the master device, such as the following: $ cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed p7p1: 14783346 140430 0 140428 0 0 0 2040 680 8 0 0 0 0 0 0 p7p2: 14805198 140648 0 0 0 0 0 2034 0 0 0 0 0 0 0 0 bond0: 53365248 532798 0 421160 0 0 0 115151 2040 24 0 0 0 0 0 0 lo: 5420 54 0 0 0 0 0 0 5420 54 0 0 0 0 0 0 p5p1: 19292195 196197 0 140368 0 0 0 56564 680 8 0 0 0 0 0 0 p5p2: 19289707 196171 0 140364 0 0 0 56547 680 8 0 0 0 0 0 0 em3: 20996626 158214 0 0 0 0 0 383 0 0 0 0 0 0 0 0 em2: 14065122 138462 0 0 0 0 0 310 0 0 0 0 0 0 0 0 em1: 14063162 138440 0 0 0 0 0 308 0 0 0 0 0 0 0 0 em4: 21050830 158729 0 0 0 0 0 385 71662 469 0 0 0 0 0 0 ib0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 In this scenario, p5p1, p5p2 and p7p1 are all inactive slaves in an active-backup bond0, and you can see that all three have high drop counts, with the master bond0 showing a tally of all three. I know that this was previously discussed some here: http://www.spinics.net/lists/netdev/msg226341.html It seems additional counters never came to fruition, so this is a first attempt at creating one of them, so that we stop calling these drops, which for users monitoring rx_dropped, causes great alarm, and renders the counter much less useful for them. This adds a sysfs statistics node and makes the counter available via netlink. Additionally, I'm not certain if this set qualifies for net, or if it should be put aside and resubmitted for net-next after 4.5 is put to bed, but I do have users who consider this an important bugfix. This has been tested quite a bit on x86_64, and now lightly on i686 as well, to verify functionality of updates to netdev_stats_to_stats64() on 32-bit arches. ==================== Signed-off-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
df03288bb4
@ -3309,6 +3309,7 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
|
||||
stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes;
|
||||
stats->rx_errors += sstats->rx_errors - pstats->rx_errors;
|
||||
stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped;
|
||||
stats->rx_nohandler += sstats->rx_nohandler - pstats->rx_nohandler;
|
||||
|
||||
stats->tx_packets += sstats->tx_packets - pstats->tx_packets;;
|
||||
stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes;
|
||||
|
@ -758,6 +758,8 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
|
||||
u64_stats_update_end(&pcpu_stats->syncp);
|
||||
|
||||
skb->dev = team->dev;
|
||||
} else if (res == RX_HANDLER_EXACT) {
|
||||
this_cpu_inc(team->pcpu_stats->rx_nohandler);
|
||||
} else {
|
||||
this_cpu_inc(team->pcpu_stats->rx_dropped);
|
||||
}
|
||||
@ -1807,7 +1809,7 @@ team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
struct team *team = netdev_priv(dev);
|
||||
struct team_pcpu_stats *p;
|
||||
u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes;
|
||||
u32 rx_dropped = 0, tx_dropped = 0;
|
||||
u32 rx_dropped = 0, tx_dropped = 0, rx_nohandler = 0;
|
||||
unsigned int start;
|
||||
int i;
|
||||
|
||||
@ -1828,14 +1830,16 @@ team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
stats->tx_packets += tx_packets;
|
||||
stats->tx_bytes += tx_bytes;
|
||||
/*
|
||||
* rx_dropped & tx_dropped are u32, updated
|
||||
* without syncp protection.
|
||||
* rx_dropped, tx_dropped & rx_nohandler are u32,
|
||||
* updated without syncp protection.
|
||||
*/
|
||||
rx_dropped += p->rx_dropped;
|
||||
tx_dropped += p->tx_dropped;
|
||||
rx_nohandler += p->rx_nohandler;
|
||||
}
|
||||
stats->rx_dropped = rx_dropped;
|
||||
stats->tx_dropped = tx_dropped;
|
||||
stats->rx_nohandler = rx_nohandler;
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ struct team_pcpu_stats {
|
||||
struct u64_stats_sync syncp;
|
||||
u32 rx_dropped;
|
||||
u32 tx_dropped;
|
||||
u32 rx_nohandler;
|
||||
};
|
||||
|
||||
struct team;
|
||||
|
@ -1397,6 +1397,8 @@ enum netdev_priv_flags {
|
||||
* do not use this in drivers
|
||||
* @tx_dropped: Dropped packets by core network,
|
||||
* do not use this in drivers
|
||||
* @rx_nohandler: nohandler dropped packets by core network on
|
||||
* inactive devices, do not use this in drivers
|
||||
*
|
||||
* @wireless_handlers: List of functions to handle Wireless Extensions,
|
||||
* instead of ioctl,
|
||||
@ -1611,6 +1613,7 @@ struct net_device {
|
||||
|
||||
atomic_long_t rx_dropped;
|
||||
atomic_long_t tx_dropped;
|
||||
atomic_long_t rx_nohandler;
|
||||
|
||||
#ifdef CONFIG_WIRELESS_EXT
|
||||
const struct iw_handler_def * wireless_handlers;
|
||||
|
@ -35,6 +35,8 @@ struct rtnl_link_stats {
|
||||
/* for cslip etc */
|
||||
__u32 rx_compressed;
|
||||
__u32 tx_compressed;
|
||||
|
||||
__u32 rx_nohandler; /* dropped, no handler found */
|
||||
};
|
||||
|
||||
/* The main device statistics structure */
|
||||
@ -68,6 +70,8 @@ struct rtnl_link_stats64 {
|
||||
/* for cslip etc */
|
||||
__u64 rx_compressed;
|
||||
__u64 tx_compressed;
|
||||
|
||||
__u64 rx_nohandler; /* dropped, no handler found */
|
||||
};
|
||||
|
||||
/* The struct should be in sync with struct ifmap */
|
||||
|
@ -4154,7 +4154,10 @@ ncls:
|
||||
ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
|
||||
} else {
|
||||
drop:
|
||||
atomic_long_inc(&skb->dev->rx_dropped);
|
||||
if (!deliver_exact)
|
||||
atomic_long_inc(&skb->dev->rx_dropped);
|
||||
else
|
||||
atomic_long_inc(&skb->dev->rx_nohandler);
|
||||
kfree_skb(skb);
|
||||
/* Jamal, now you will not able to escape explaining
|
||||
* me how you were going to use this. :-)
|
||||
@ -7253,24 +7256,31 @@ void netdev_run_todo(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert net_device_stats to rtnl_link_stats64. They have the same
|
||||
* fields in the same order, with only the type differing.
|
||||
/* Convert net_device_stats to rtnl_link_stats64. rtnl_link_stats64 has
|
||||
* all the same fields in the same order as net_device_stats, with only
|
||||
* the type differing, but rtnl_link_stats64 may have additional fields
|
||||
* at the end for newer counters.
|
||||
*/
|
||||
void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
|
||||
const struct net_device_stats *netdev_stats)
|
||||
{
|
||||
#if BITS_PER_LONG == 64
|
||||
BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
|
||||
BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
|
||||
memcpy(stats64, netdev_stats, sizeof(*stats64));
|
||||
/* zero out counters that only exist in rtnl_link_stats64 */
|
||||
memset((char *)stats64 + sizeof(*netdev_stats), 0,
|
||||
sizeof(*stats64) - sizeof(*netdev_stats));
|
||||
#else
|
||||
size_t i, n = sizeof(*stats64) / sizeof(u64);
|
||||
size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long);
|
||||
const unsigned long *src = (const unsigned long *)netdev_stats;
|
||||
u64 *dst = (u64 *)stats64;
|
||||
|
||||
BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) !=
|
||||
sizeof(*stats64) / sizeof(u64));
|
||||
BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64));
|
||||
for (i = 0; i < n; i++)
|
||||
dst[i] = src[i];
|
||||
/* zero out counters that only exist in rtnl_link_stats64 */
|
||||
memset((char *)stats64 + n * sizeof(u64), 0,
|
||||
sizeof(*stats64) - n * sizeof(u64));
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(netdev_stats_to_stats64);
|
||||
@ -7300,6 +7310,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
|
||||
}
|
||||
storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
|
||||
storage->tx_dropped += atomic_long_read(&dev->tx_dropped);
|
||||
storage->rx_nohandler += atomic_long_read(&dev->rx_nohandler);
|
||||
return storage;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_get_stats);
|
||||
|
@ -574,6 +574,7 @@ NETSTAT_ENTRY(tx_heartbeat_errors);
|
||||
NETSTAT_ENTRY(tx_window_errors);
|
||||
NETSTAT_ENTRY(rx_compressed);
|
||||
NETSTAT_ENTRY(tx_compressed);
|
||||
NETSTAT_ENTRY(rx_nohandler);
|
||||
|
||||
static struct attribute *netstat_attrs[] = {
|
||||
&dev_attr_rx_packets.attr,
|
||||
@ -599,6 +600,7 @@ static struct attribute *netstat_attrs[] = {
|
||||
&dev_attr_tx_window_errors.attr,
|
||||
&dev_attr_rx_compressed.attr,
|
||||
&dev_attr_tx_compressed.attr,
|
||||
&dev_attr_rx_nohandler.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -804,6 +804,8 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
|
||||
|
||||
a->rx_compressed = b->rx_compressed;
|
||||
a->tx_compressed = b->tx_compressed;
|
||||
|
||||
a->rx_nohandler = b->rx_nohandler;
|
||||
}
|
||||
|
||||
static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
|
||||
|
Loading…
Reference in New Issue
Block a user