Re: [PATCH stable 6.1 1/3] net: Move {l,t,d}stats allocation to core and convert veth & vrf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[ 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@xxxxxxxxxx>
         Link: https://lore.kernel.org/r/20231114004220.6495-3-daniel@xxxxxxxxxxxxx
         Signed-off-by: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
    +    Stable-dep-of: 024ee930cb3c ("bpf: Fix dev's rx stats for bpf_redirect_peer traffic")
    +    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
     
      ## 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   |




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux