Commit be226352 authored by Guillaume Nault's avatar Guillaume Nault Committed by Jakub Kicinski
Browse files

vxlan: Handle stats using NETDEV_PCPU_STAT_DSTATS.



VXLAN uses the TSTATS infrastructure (dev_sw_netstats_*()) for RX and
TX packet counters. It also uses the device core stats
(dev_core_stats_*()) for RX and TX drops.

Let's consolidate that using the DSTATS infrastructure, which can
handle both packet counters and packet drops. Statistics that don't
fit DSTATS are still updated atomically with DEV_STATS_INC().

While there, convert the "len" variable of vxlan_encap_bypass() to
unsigned int, to respect the types of skb->len and
dev_dstats_[rt]x_add().

Signed-off-by: default avatarGuillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/145558b184b3cda77911ca5682b6eb83c3ffed8e.1733313925.git.gnault@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 18eabadd
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -1818,14 +1818,14 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)

	if (unlikely(!(vxlan->dev->flags & IFF_UP))) {
		rcu_read_unlock();
		dev_core_stats_rx_dropped_inc(vxlan->dev);
		dev_dstats_rx_dropped(vxlan->dev);
		vxlan_vnifilter_count(vxlan, vni, vninode,
				      VXLAN_VNI_STATS_RX_DROPS, 0);
		reason = SKB_DROP_REASON_DEV_READY;
		goto drop;
	}

	dev_sw_netstats_rx_add(vxlan->dev, skb->len);
	dev_dstats_rx_add(vxlan->dev, skb->len);
	vxlan_vnifilter_count(vxlan, vni, vninode, VXLAN_VNI_STATS_RX, skb->len);
	gro_cells_receive(&vxlan->gro_cells, skb);

@@ -1880,7 +1880,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
		goto out;

	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
		dev_core_stats_tx_dropped_inc(dev);
		dev_dstats_tx_dropped(dev);
		vxlan_vnifilter_count(vxlan, vni, NULL,
				      VXLAN_VNI_STATS_TX_DROPS, 0);
		goto out;
@@ -1938,7 +1938,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
		reply->pkt_type = PACKET_HOST;

		if (netif_rx(reply) == NET_RX_DROP) {
			dev_core_stats_rx_dropped_inc(dev);
			dev_dstats_rx_dropped(dev);
			vxlan_vnifilter_count(vxlan, vni, NULL,
					      VXLAN_VNI_STATS_RX_DROPS, 0);
		}
@@ -2097,7 +2097,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
			goto out;

		if (netif_rx(reply) == NET_RX_DROP) {
			dev_core_stats_rx_dropped_inc(dev);
			dev_dstats_rx_dropped(dev);
			vxlan_vnifilter_count(vxlan, vni, NULL,
					      VXLAN_VNI_STATS_RX_DROPS, 0);
		}
@@ -2271,8 +2271,8 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
{
	union vxlan_addr loopback;
	union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
	unsigned int len = skb->len;
	struct net_device *dev;
	int len = skb->len;

	skb->pkt_type = PACKET_HOST;
	skb->encapsulation = 0;
@@ -2299,16 +2299,16 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
	if ((dst_vxlan->cfg.flags & VXLAN_F_LEARN) && snoop)
		vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni);

	dev_sw_netstats_tx_add(src_vxlan->dev, 1, len);
	dev_dstats_tx_add(src_vxlan->dev, len);
	vxlan_vnifilter_count(src_vxlan, vni, NULL, VXLAN_VNI_STATS_TX, len);

	if (__netif_rx(skb) == NET_RX_SUCCESS) {
		dev_sw_netstats_rx_add(dst_vxlan->dev, len);
		dev_dstats_rx_add(dst_vxlan->dev, len);
		vxlan_vnifilter_count(dst_vxlan, vni, NULL, VXLAN_VNI_STATS_RX,
				      len);
	} else {
drop:
		dev_core_stats_rx_dropped_inc(dev);
		dev_dstats_rx_dropped(dev);
		vxlan_vnifilter_count(dst_vxlan, vni, NULL,
				      VXLAN_VNI_STATS_RX_DROPS, 0);
	}
@@ -2621,7 +2621,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
	return;

drop:
	dev_core_stats_tx_dropped_inc(dev);
	dev_dstats_tx_dropped(dev);
	vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_DROPS, 0);
	kfree_skb_reason(skb, reason);
	return;
@@ -2666,7 +2666,7 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
	return;

drop:
	dev_core_stats_tx_dropped_inc(dev);
	dev_dstats_tx_dropped(dev);
	vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
			      VXLAN_VNI_STATS_TX_DROPS, 0);
	dev_kfree_skb(skb);
@@ -2704,7 +2704,7 @@ static netdev_tx_t vxlan_xmit_nhid(struct sk_buff *skb, struct net_device *dev,
	return NETDEV_TX_OK;

drop:
	dev_core_stats_tx_dropped_inc(dev);
	dev_dstats_tx_dropped(dev);
	vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
			      VXLAN_VNI_STATS_TX_DROPS, 0);
	dev_kfree_skb(skb);
@@ -2801,7 +2801,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
			    !is_multicast_ether_addr(eth->h_dest))
				vxlan_fdb_miss(vxlan, eth->h_dest);

			dev_core_stats_tx_dropped_inc(dev);
			dev_dstats_tx_dropped(dev);
			vxlan_vnifilter_count(vxlan, vni, NULL,
					      VXLAN_VNI_STATS_TX_DROPS, 0);
			kfree_skb_reason(skb, SKB_DROP_REASON_VXLAN_NO_REMOTE);
@@ -3371,7 +3371,7 @@ static void vxlan_setup(struct net_device *dev)
	dev->min_mtu = ETH_MIN_MTU;
	dev->max_mtu = ETH_MAX_MTU;

	dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
	dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
	INIT_LIST_HEAD(&vxlan->next);

	timer_setup(&vxlan->age_timer, vxlan_cleanup, TIMER_DEFERRABLE);