public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf
@ 2024-12-06 15:34 Daniel Borkmann
  2024-12-06 15:34 ` [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic Daniel Borkmann
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Daniel Borkmann @ 2024-12-06 15:34 UTC (permalink / raw)
  To: gregkh
  Cc: stable, netdev, bpf, leitao, martin.lau, peilin.ye, kuba,
	Nikolay Aleksandrov, David Ahern, Martin KaFai Lau

[ Upstream commit 34d21de99cea9cb17967874313e5b0262527833c ]
[ Note: Simplified vrf bits to reduce patch given unrelated to the fix ]

Move {l,t,d}stats allocation to the core and let netdevs pick the stats
type they need. That way the driver doesn't have to bother with error
handling (allocation failure checking, making sure free happens in the
right spot, etc) - all happening in the core.

Co-developed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Cc: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20231114004220.6495-3-daniel@iogearbox.net
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Stable-dep-of: 024ee930cb3c ("bpf: Fix dev's rx stats for bpf_redirect_peer traffic")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 drivers/net/veth.c        | 16 ++----------
 drivers/net/vrf.c         | 24 ++++++------------
 include/linux/netdevice.h | 30 +++++++++++++++++++---
 net/core/dev.c            | 53 ++++++++++++++++++++++++++++++++++++---
 4 files changed, 85 insertions(+), 38 deletions(-)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8dcd3b6e143b..0a8154611d7f 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1381,25 +1381,12 @@ static void veth_free_queues(struct net_device *dev)
 
 static int veth_dev_init(struct net_device *dev)
 {
-	int err;
-
-	dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
-	if (!dev->lstats)
-		return -ENOMEM;
-
-	err = veth_alloc_queues(dev);
-	if (err) {
-		free_percpu(dev->lstats);
-		return err;
-	}
-
-	return 0;
+	return veth_alloc_queues(dev);
 }
 
 static void veth_dev_free(struct net_device *dev)
 {
 	veth_free_queues(dev);
-	free_percpu(dev->lstats);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1625,6 +1612,7 @@ static void veth_setup(struct net_device *dev)
 			       NETIF_F_HW_VLAN_STAG_RX);
 	dev->needs_free_netdev = true;
 	dev->priv_destructor = veth_dev_free;
+	dev->pcpu_stat_type = NETDEV_PCPU_STAT_LSTATS;
 	dev->max_mtu = ETH_MAX_MTU;
 
 	dev->hw_features = VETH_FEATURES;
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 208df4d41939..c8a1009d659e 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -121,22 +121,12 @@ struct net_vrf {
 	int			ifindex;
 };
 
-struct pcpu_dstats {
-	u64			tx_pkts;
-	u64			tx_bytes;
-	u64			tx_drps;
-	u64			rx_pkts;
-	u64			rx_bytes;
-	u64			rx_drps;
-	struct u64_stats_sync	syncp;
-};
-
 static void vrf_rx_stats(struct net_device *dev, int len)
 {
 	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
 
 	u64_stats_update_begin(&dstats->syncp);
-	dstats->rx_pkts++;
+	dstats->rx_packets++;
 	dstats->rx_bytes += len;
 	u64_stats_update_end(&dstats->syncp);
 }
@@ -161,10 +151,10 @@ static void vrf_get_stats64(struct net_device *dev,
 		do {
 			start = u64_stats_fetch_begin_irq(&dstats->syncp);
 			tbytes = dstats->tx_bytes;
-			tpkts = dstats->tx_pkts;
-			tdrops = dstats->tx_drps;
+			tpkts = dstats->tx_packets;
+			tdrops = dstats->tx_drops;
 			rbytes = dstats->rx_bytes;
-			rpkts = dstats->rx_pkts;
+			rpkts = dstats->rx_packets;
 		} while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
 		stats->tx_bytes += tbytes;
 		stats->tx_packets += tpkts;
@@ -421,7 +411,7 @@ static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,
 	if (likely(__netif_rx(skb) == NET_RX_SUCCESS))
 		vrf_rx_stats(dev, len);
 	else
-		this_cpu_inc(dev->dstats->rx_drps);
+		this_cpu_inc(dev->dstats->rx_drops);
 
 	return NETDEV_TX_OK;
 }
@@ -616,11 +606,11 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
 		struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
 
 		u64_stats_update_begin(&dstats->syncp);
-		dstats->tx_pkts++;
+		dstats->tx_packets++;
 		dstats->tx_bytes += len;
 		u64_stats_update_end(&dstats->syncp);
 	} else {
-		this_cpu_inc(dev->dstats->tx_drps);
+		this_cpu_inc(dev->dstats->tx_drops);
 	}
 
 	return ret;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index fbbd0df1106b..662183994e88 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1747,6 +1747,13 @@ enum netdev_ml_priv_type {
 	ML_PRIV_CAN,
 };
 
+enum netdev_stat_type {
+	NETDEV_PCPU_STAT_NONE,
+	NETDEV_PCPU_STAT_LSTATS, /* struct pcpu_lstats */
+	NETDEV_PCPU_STAT_TSTATS, /* struct pcpu_sw_netstats */
+	NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
+};
+
 /**
  *	struct net_device - The DEVICE structure.
  *
@@ -1941,10 +1948,14 @@ enum netdev_ml_priv_type {
  *
  * 	@ml_priv:	Mid-layer private
  *	@ml_priv_type:  Mid-layer private type
- * 	@lstats:	Loopback statistics
- * 	@tstats:	Tunnel statistics
- * 	@dstats:	Dummy statistics
- * 	@vstats:	Virtual ethernet statistics
+ *
+ *	@pcpu_stat_type:	Type of device statistics which the core should
+ *				allocate/free: none, lstats, tstats, dstats. none
+ *				means the driver is handling statistics allocation/
+ *				freeing internally.
+ *	@lstats:		Loopback statistics: packets, bytes
+ *	@tstats:		Tunnel statistics: RX/TX packets, RX/TX bytes
+ *	@dstats:		Dummy statistics: RX/TX/drop packets, RX/TX bytes
  *
  *	@garp_port:	GARP
  *	@mrp_port:	MRP
@@ -2287,6 +2298,7 @@ struct net_device {
 	void				*ml_priv;
 	enum netdev_ml_priv_type	ml_priv_type;
 
+	enum netdev_stat_type		pcpu_stat_type:8;
 	union {
 		struct pcpu_lstats __percpu		*lstats;
 		struct pcpu_sw_netstats __percpu	*tstats;
@@ -2670,6 +2682,16 @@ struct pcpu_sw_netstats {
 	struct u64_stats_sync   syncp;
 } __aligned(4 * sizeof(u64));
 
+struct pcpu_dstats {
+	u64			rx_packets;
+	u64			rx_bytes;
+	u64			rx_drops;
+	u64			tx_packets;
+	u64			tx_bytes;
+	u64			tx_drops;
+	struct u64_stats_sync	syncp;
+} __aligned(8 * sizeof(u64));
+
 struct pcpu_lstats {
 	u64_stats_t packets;
 	u64_stats_t bytes;
diff --git a/net/core/dev.c b/net/core/dev.c
index 42c16b3e86b9..5151f69dd724 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9991,6 +9991,46 @@ void netif_tx_stop_all_queues(struct net_device *dev)
 }
 EXPORT_SYMBOL(netif_tx_stop_all_queues);
 
+static int netdev_do_alloc_pcpu_stats(struct net_device *dev)
+{
+	void __percpu *v;
+
+	switch (dev->pcpu_stat_type) {
+	case NETDEV_PCPU_STAT_NONE:
+		return 0;
+	case NETDEV_PCPU_STAT_LSTATS:
+		v = dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
+		break;
+	case NETDEV_PCPU_STAT_TSTATS:
+		v = dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+		break;
+	case NETDEV_PCPU_STAT_DSTATS:
+		v = dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return v ? 0 : -ENOMEM;
+}
+
+static void netdev_do_free_pcpu_stats(struct net_device *dev)
+{
+	switch (dev->pcpu_stat_type) {
+	case NETDEV_PCPU_STAT_NONE:
+		return;
+	case NETDEV_PCPU_STAT_LSTATS:
+		free_percpu(dev->lstats);
+		break;
+	case NETDEV_PCPU_STAT_TSTATS:
+		free_percpu(dev->tstats);
+		break;
+	case NETDEV_PCPU_STAT_DSTATS:
+		free_percpu(dev->dstats);
+		break;
+	}
+}
+
 /**
  * register_netdevice() - register a network device
  * @dev: device to register
@@ -10051,11 +10091,15 @@ int register_netdevice(struct net_device *dev)
 		goto err_uninit;
 	}
 
+	ret = netdev_do_alloc_pcpu_stats(dev);
+	if (ret)
+		goto err_uninit;
+
 	ret = -EBUSY;
 	if (!dev->ifindex)
 		dev->ifindex = dev_new_index(net);
 	else if (__dev_get_by_index(net, dev->ifindex))
-		goto err_uninit;
+		goto err_free_pcpu;
 
 	/* Transfer changeable features to wanted_features and enable
 	 * software offloads (GSO and GRO).
@@ -10102,14 +10146,14 @@ int register_netdevice(struct net_device *dev)
 	ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
 	ret = notifier_to_errno(ret);
 	if (ret)
-		goto err_uninit;
+		goto err_free_pcpu;
 
 	ret = netdev_register_kobject(dev);
 	write_lock(&dev_base_lock);
 	dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED;
 	write_unlock(&dev_base_lock);
 	if (ret)
-		goto err_uninit;
+		goto err_free_pcpu;
 
 	__netdev_update_features(dev);
 
@@ -10156,6 +10200,8 @@ int register_netdevice(struct net_device *dev)
 out:
 	return ret;
 
+err_free_pcpu:
+	netdev_do_free_pcpu_stats(dev);
 err_uninit:
 	if (dev->netdev_ops->ndo_uninit)
 		dev->netdev_ops->ndo_uninit(dev);
@@ -10409,6 +10455,7 @@ void netdev_run_todo(void)
 		WARN_ON(rcu_access_pointer(dev->ip_ptr));
 		WARN_ON(rcu_access_pointer(dev->ip6_ptr));
 
+		netdev_do_free_pcpu_stats(dev);
 		if (dev->priv_destructor)
 			dev->priv_destructor(dev);
 		if (dev->needs_free_netdev)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic
  2024-12-06 15:34 [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Daniel Borkmann
@ 2024-12-06 15:34 ` Daniel Borkmann
  2024-12-06 23:11   ` Sasha Levin
  2024-12-06 15:34 ` [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters Daniel Borkmann
  2024-12-06 23:11 ` [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Sasha Levin
  2 siblings, 1 reply; 6+ messages in thread
From: Daniel Borkmann @ 2024-12-06 15:34 UTC (permalink / raw)
  To: gregkh
  Cc: stable, netdev, bpf, leitao, martin.lau, peilin.ye, kuba,
	Youlun Zhang, Nikolay Aleksandrov, Martin KaFai Lau

From: Peilin Ye <peilin.ye@bytedance.com>

[ Upstream commit 024ee930cb3c9ae49e4266aee89cfde0ebb407e1 ]

Traffic redirected by bpf_redirect_peer() (used by recent CNIs like Cilium)
is not accounted for in the RX stats of supported devices (that is, veth
and netkit), confusing user space metrics collectors such as cAdvisor [0],
as reported by Youlun.

Fix it by calling dev_sw_netstats_rx_add() in skb_do_redirect(), to update
RX traffic counters. Devices that support ndo_get_peer_dev _must_ use the
@tstats per-CPU counters (instead of @lstats, or @dstats).

To make this more fool-proof, error out when ndo_get_peer_dev is set but
@tstats are not selected.

  [0] Specifically, the "container_network_receive_{byte,packet}s_total"
      counters are affected.

Fixes: 9aa1206e8f48 ("bpf: Add redirect_peer helper")
Reported-by: Youlun Zhang <zhangyoulun@bytedance.com>
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
Co-developed-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://lore.kernel.org/r/20231114004220.6495-6-daniel@iogearbox.net
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 net/core/dev.c    | 8 ++++++++
 net/core/filter.c | 1 +
 2 files changed, 9 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index 5151f69dd724..2ee1a535b3cb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9995,6 +9995,14 @@ static int netdev_do_alloc_pcpu_stats(struct net_device *dev)
 {
 	void __percpu *v;
 
+	/* Drivers implementing ndo_get_peer_dev must support tstat
+	 * accounting, so that skb_do_redirect() can bump the dev's
+	 * RX stats upon network namespace switch.
+	 */
+	if (dev->netdev_ops->ndo_get_peer_dev &&
+	    dev->pcpu_stat_type != NETDEV_PCPU_STAT_TSTATS)
+		return -EOPNOTSUPP;
+
 	switch (dev->pcpu_stat_type) {
 	case NETDEV_PCPU_STAT_NONE:
 		return 0;
diff --git a/net/core/filter.c b/net/core/filter.c
index 2f6fef5f5864..e766e66ef62a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2491,6 +2491,7 @@ int skb_do_redirect(struct sk_buff *skb)
 			     net_eq(net, dev_net(dev))))
 			goto out_drop;
 		skb->dev = dev;
+		dev_sw_netstats_rx_add(dev, skb->len);
 		return -EAGAIN;
 	}
 	return flags & BPF_F_NEIGH ?
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters
  2024-12-06 15:34 [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Daniel Borkmann
  2024-12-06 15:34 ` [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic Daniel Borkmann
@ 2024-12-06 15:34 ` Daniel Borkmann
  2024-12-06 23:11   ` Sasha Levin
  2024-12-06 23:11 ` [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Sasha Levin
  2 siblings, 1 reply; 6+ messages in thread
From: Daniel Borkmann @ 2024-12-06 15:34 UTC (permalink / raw)
  To: gregkh
  Cc: stable, netdev, bpf, leitao, martin.lau, peilin.ye, kuba,
	Nikolay Aleksandrov, Martin KaFai Lau

From: Peilin Ye <peilin.ye@bytedance.com>

[ Upstream commit 6f2684bf2b4460c84d0d34612a939f78b96b03fc ]

Currently veth devices use the lstats per-CPU traffic counters, which only
cover TX traffic. veth_get_stats64() actually populates RX stats of a veth
device from its peer's TX counters, based on the assumption that a veth
device can _only_ receive packets from its peer, which is no longer true:

For example, recent CNIs (like Cilium) can use the bpf_redirect_peer() BPF
helper to redirect traffic from NIC's tc ingress to veth's tc ingress (in
a different netns), skipping veth's peer device. Unfortunately, this kind
of traffic isn't currently accounted for in veth's RX stats.

In preparation for the fix, use tstats (instead of lstats) to maintain
both RX and TX counters for each veth device. We'll use RX counters for
bpf_redirect_peer() traffic, and keep using TX counters for the usual
"peer-to-peer" traffic. In veth_get_stats64(), calculate RX stats by
_adding_ RX count to peer's TX count, in order to cover both kinds of
traffic.

veth_stats_rx() might need a name change (perhaps to "veth_stats_xdp()")
for less confusion, but let's leave it to another patch to keep the fix
minimal.

Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
Co-developed-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://lore.kernel.org/r/20231114004220.6495-5-daniel@iogearbox.net
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 drivers/net/veth.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 0a8154611d7f..e1e7df00e85c 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -342,7 +342,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_tx_timestamp(skb);
 	if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) {
 		if (!use_napi)
-			dev_lstats_add(dev, length);
+			dev_sw_netstats_tx_add(dev, 1, length);
 	} else {
 drop:
 		atomic64_inc(&priv->dropped);
@@ -357,14 +357,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
 	return ret;
 }
 
-static u64 veth_stats_tx(struct net_device *dev, u64 *packets, u64 *bytes)
-{
-	struct veth_priv *priv = netdev_priv(dev);
-
-	dev_lstats_read(dev, packets, bytes);
-	return atomic64_read(&priv->dropped);
-}
-
 static void veth_stats_rx(struct veth_stats *result, struct net_device *dev)
 {
 	struct veth_priv *priv = netdev_priv(dev);
@@ -402,24 +394,24 @@ static void veth_get_stats64(struct net_device *dev,
 	struct veth_priv *priv = netdev_priv(dev);
 	struct net_device *peer;
 	struct veth_stats rx;
-	u64 packets, bytes;
 
-	tot->tx_dropped = veth_stats_tx(dev, &packets, &bytes);
-	tot->tx_bytes = bytes;
-	tot->tx_packets = packets;
+	tot->tx_dropped = atomic64_read(&priv->dropped);
+	dev_fetch_sw_netstats(tot, dev->tstats);
 
 	veth_stats_rx(&rx, dev);
 	tot->tx_dropped += rx.xdp_tx_err;
 	tot->rx_dropped = rx.rx_drops + rx.peer_tq_xdp_xmit_err;
-	tot->rx_bytes = rx.xdp_bytes;
-	tot->rx_packets = rx.xdp_packets;
+	tot->rx_bytes += rx.xdp_bytes;
+	tot->rx_packets += rx.xdp_packets;
 
 	rcu_read_lock();
 	peer = rcu_dereference(priv->peer);
 	if (peer) {
-		veth_stats_tx(peer, &packets, &bytes);
-		tot->rx_bytes += bytes;
-		tot->rx_packets += packets;
+		struct rtnl_link_stats64 tot_peer = {};
+
+		dev_fetch_sw_netstats(&tot_peer, peer->tstats);
+		tot->rx_bytes += tot_peer.tx_bytes;
+		tot->rx_packets += tot_peer.tx_packets;
 
 		veth_stats_rx(&rx, peer);
 		tot->tx_dropped += rx.peer_tq_xdp_xmit_err;
@@ -1612,7 +1604,7 @@ static void veth_setup(struct net_device *dev)
 			       NETIF_F_HW_VLAN_STAG_RX);
 	dev->needs_free_netdev = true;
 	dev->priv_destructor = veth_dev_free;
-	dev->pcpu_stat_type = NETDEV_PCPU_STAT_LSTATS;
+	dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
 	dev->max_mtu = ETH_MAX_MTU;
 
 	dev->hw_features = VETH_FEATURES;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic
  2024-12-06 15:34 ` [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic Daniel Borkmann
@ 2024-12-06 23:11   ` Sasha Levin
  0 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2024-12-06 23:11 UTC (permalink / raw)
  To: stable; +Cc: Daniel Borkmann, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

The upstream commit SHA1 provided is correct: 024ee930cb3c9ae49e4266aee89cfde0ebb407e1

WARNING: Author mismatch between patch and upstream commit:
Backport author: Daniel Borkmann <daniel@iogearbox.net>
Commit author: Peilin Ye <peilin.ye@bytedance.com>


Status in newer kernel trees:
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: 959f301635dc)
6.1.y | Not found

Note: The patch differs from the upstream commit:
---
Failed to apply patch cleanly, falling back to interdiff...
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters
  2024-12-06 15:34 ` [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters Daniel Borkmann
@ 2024-12-06 23:11   ` Sasha Levin
  0 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2024-12-06 23:11 UTC (permalink / raw)
  To: stable; +Cc: Daniel Borkmann, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

The upstream commit SHA1 provided is correct: 6f2684bf2b4460c84d0d34612a939f78b96b03fc

WARNING: Author mismatch between patch and upstream commit:
Backport author: Daniel Borkmann <daniel@iogearbox.net>
Commit author: Peilin Ye <peilin.ye@bytedance.com>


Status in newer kernel trees:
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: b74095a4945f)
6.1.y | Not found

Note: The patch differs from the upstream commit:
---
Failed to apply patch cleanly, falling back to interdiff...
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf
  2024-12-06 15:34 [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Daniel Borkmann
  2024-12-06 15:34 ` [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic Daniel Borkmann
  2024-12-06 15:34 ` [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters Daniel Borkmann
@ 2024-12-06 23:11 ` Sasha Levin
  2 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2024-12-06 23:11 UTC (permalink / raw)
  To: stable; +Cc: Daniel Borkmann, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

The upstream commit SHA1 provided is correct: 34d21de99cea9cb17967874313e5b0262527833c


Status in newer kernel trees:
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: 6ae7b3fc7ae8)
6.1.y | Not found

Note: The patch differs from the upstream commit:
---
1:  34d21de99cea9 ! 1:  927b0635b3b95 net: Move {l,t,d}stats allocation to core and convert veth & vrf
    @@ Metadata
      ## Commit message ##
         net: Move {l,t,d}stats allocation to core and convert veth & vrf
     
    +    [ Upstream commit 34d21de99cea9cb17967874313e5b0262527833c ]
    +    [ Note: Simplified vrf bits to reduce patch given unrelated to the fix ]
    +
         Move {l,t,d}stats allocation to the core and let netdevs pick the stats
         type they need. That way the driver doesn't have to bother with error
         handling (allocation failure checking, making sure free happens in the
    @@ Commit message
         Cc: David Ahern <dsahern@kernel.org>
         Link: https://lore.kernel.org/r/20231114004220.6495-3-daniel@iogearbox.net
         Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
    +    Stable-dep-of: 024ee930cb3c ("bpf: Fix dev's rx stats for bpf_redirect_peer traffic")
    +    Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
     
      ## drivers/net/veth.c ##
     @@ drivers/net/veth.c: static void veth_free_queues(struct net_device *dev)
    @@ drivers/net/veth.c: static void veth_setup(struct net_device *dev)
      	dev->hw_features = VETH_FEATURES;
     
      ## drivers/net/vrf.c ##
    -@@ drivers/net/vrf.c: static void vrf_dev_uninit(struct net_device *dev)
    +@@ drivers/net/vrf.c: struct net_vrf {
    + 	int			ifindex;
    + };
      
    - 	vrf_rtable_release(dev, vrf);
    - 	vrf_rt6_release(dev, vrf);
    +-struct pcpu_dstats {
    +-	u64			tx_pkts;
    +-	u64			tx_bytes;
    +-	u64			tx_drps;
    +-	u64			rx_pkts;
    +-	u64			rx_bytes;
    +-	u64			rx_drps;
    +-	struct u64_stats_sync	syncp;
    +-};
     -
    --	free_percpu(dev->dstats);
    --	dev->dstats = NULL;
    - }
    - 
    - static int vrf_dev_init(struct net_device *dev)
    + static void vrf_rx_stats(struct net_device *dev, int len)
      {
    - 	struct net_vrf *vrf = netdev_priv(dev);
    + 	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
      
    --	dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
    --	if (!dev->dstats)
    --		goto out_nomem;
    --
    - 	/* create the default dst which points back to us */
    - 	if (vrf_rtable_create(dev) != 0)
    --		goto out_stats;
    -+		goto out_nomem;
    - 
    - 	if (vrf_rt6_create(dev) != 0)
    - 		goto out_rth;
    -@@ drivers/net/vrf.c: static int vrf_dev_init(struct net_device *dev)
    - 
    - out_rth:
    - 	vrf_rtable_release(dev, vrf);
    --out_stats:
    --	free_percpu(dev->dstats);
    --	dev->dstats = NULL;
    - out_nomem:
    - 	return -ENOMEM;
    + 	u64_stats_update_begin(&dstats->syncp);
    +-	dstats->rx_pkts++;
    ++	dstats->rx_packets++;
    + 	dstats->rx_bytes += len;
    + 	u64_stats_update_end(&dstats->syncp);
      }
    -@@ drivers/net/vrf.c: static void vrf_setup(struct net_device *dev)
    - 	dev->min_mtu = IPV6_MIN_MTU;
    - 	dev->max_mtu = IP6_MAX_MTU;
    - 	dev->mtu = dev->max_mtu;
    -+
    -+	dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
    +@@ drivers/net/vrf.c: static void vrf_get_stats64(struct net_device *dev,
    + 		do {
    + 			start = u64_stats_fetch_begin_irq(&dstats->syncp);
    + 			tbytes = dstats->tx_bytes;
    +-			tpkts = dstats->tx_pkts;
    +-			tdrops = dstats->tx_drps;
    ++			tpkts = dstats->tx_packets;
    ++			tdrops = dstats->tx_drops;
    + 			rbytes = dstats->rx_bytes;
    +-			rpkts = dstats->rx_pkts;
    ++			rpkts = dstats->rx_packets;
    + 		} while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
    + 		stats->tx_bytes += tbytes;
    + 		stats->tx_packets += tpkts;
    +@@ drivers/net/vrf.c: static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,
    + 	if (likely(__netif_rx(skb) == NET_RX_SUCCESS))
    + 		vrf_rx_stats(dev, len);
    + 	else
    +-		this_cpu_inc(dev->dstats->rx_drps);
    ++		this_cpu_inc(dev->dstats->rx_drops);
    + 
    + 	return NETDEV_TX_OK;
      }
    +@@ drivers/net/vrf.c: static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
    + 		struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
      
    - static int vrf_validate(struct nlattr *tb[], struct nlattr *data[],
    + 		u64_stats_update_begin(&dstats->syncp);
    +-		dstats->tx_pkts++;
    ++		dstats->tx_packets++;
    + 		dstats->tx_bytes += len;
    + 		u64_stats_update_end(&dstats->syncp);
    + 	} else {
    +-		this_cpu_inc(dev->dstats->tx_drps);
    ++		this_cpu_inc(dev->dstats->tx_drops);
    + 	}
    + 
    + 	return ret;
     
      ## include/linux/netdevice.h ##
     @@ include/linux/netdevice.h: enum netdev_ml_priv_type {
    @@ include/linux/netdevice.h: struct net_device {
      	union {
      		struct pcpu_lstats __percpu		*lstats;
      		struct pcpu_sw_netstats __percpu	*tstats;
    +@@ include/linux/netdevice.h: struct pcpu_sw_netstats {
    + 	struct u64_stats_sync   syncp;
    + } __aligned(4 * sizeof(u64));
    + 
    ++struct pcpu_dstats {
    ++	u64			rx_packets;
    ++	u64			rx_bytes;
    ++	u64			rx_drops;
    ++	u64			tx_packets;
    ++	u64			tx_bytes;
    ++	u64			tx_drops;
    ++	struct u64_stats_sync	syncp;
    ++} __aligned(8 * sizeof(u64));
    ++
    + struct pcpu_lstats {
    + 	u64_stats_t packets;
    + 	u64_stats_t bytes;
     
      ## net/core/dev.c ##
     @@ net/core/dev.c: void netif_tx_stop_all_queues(struct net_device *dev)
    @@ net/core/dev.c: int register_netdevice(struct net_device *dev)
     +	if (ret)
     +		goto err_uninit;
     +
    - 	ret = dev_index_reserve(net, dev->ifindex);
    - 	if (ret < 0)
    + 	ret = -EBUSY;
    + 	if (!dev->ifindex)
    + 		dev->ifindex = dev_new_index(net);
    + 	else if (__dev_get_by_index(net, dev->ifindex))
     -		goto err_uninit;
     +		goto err_free_pcpu;
    - 	dev->ifindex = ret;
      
      	/* Transfer changeable features to wanted_features and enable
    + 	 * software offloads (GSO and GRO).
    +@@ net/core/dev.c: int register_netdevice(struct net_device *dev)
    + 	ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
    + 	ret = notifier_to_errno(ret);
    + 	if (ret)
    +-		goto err_uninit;
    ++		goto err_free_pcpu;
    + 
    + 	ret = netdev_register_kobject(dev);
    + 	write_lock(&dev_base_lock);
    + 	dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED;
    + 	write_unlock(&dev_base_lock);
    + 	if (ret)
    +-		goto err_uninit;
    ++		goto err_free_pcpu;
    + 
    + 	__netdev_update_features(dev);
    + 
     @@ net/core/dev.c: int register_netdevice(struct net_device *dev)
    - 	call_netdevice_notifiers(NETDEV_PRE_UNINIT, dev);
    - err_ifindex_release:
    - 	dev_index_release(net, dev->ifindex);
    + out:
    + 	return ret;
    + 
     +err_free_pcpu:
     +	netdev_do_free_pcpu_stats(dev);
      err_uninit:
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-12-06 23:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-06 15:34 [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Daniel Borkmann
2024-12-06 15:34 ` [PATCH stable 6.1 2/3] bpf: Fix dev's rx stats for bpf_redirect_peer traffic Daniel Borkmann
2024-12-06 23:11   ` Sasha Levin
2024-12-06 15:34 ` [PATCH stable 6.1 3/3] veth: Use tstats per-CPU traffic counters Daniel Borkmann
2024-12-06 23:11   ` Sasha Levin
2024-12-06 23:11 ` [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox