]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 13:54:49 +0000 (15:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 13:54:49 +0000 (15:54 +0200)
added patches:
qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch

queue-4.19/qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch b/queue-4.19/qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch
new file mode 100644 (file)
index 0000000..358acf3
--- /dev/null
@@ -0,0 +1,151 @@
+From 44f82312fe9113bab6642f4d0eab6b1b7902b6e1 Mon Sep 17 00:00:00 2001
+From: Reinhard Speyerer <rspmn@arcor.de>
+Date: Wed, 12 Jun 2019 19:02:46 +0200
+Subject: qmi_wwan: add network device usage statistics for qmimux devices
+
+From: Reinhard Speyerer <rspmn@arcor.de>
+
+commit 44f82312fe9113bab6642f4d0eab6b1b7902b6e1 upstream.
+
+Add proper network device usage statistics for qmimux devices
+instead of reporting all-zero values for them.
+
+Fixes: c6adf77953bc ("net: usb: qmi_wwan: add qmap mux protocol support")
+Cc: Daniele Palmas <dnlplm@gmail.com>
+Signed-off-by: Reinhard Speyerer <rspmn@arcor.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |   76 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 71 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -22,6 +22,7 @@
+ #include <linux/usb/cdc.h>
+ #include <linux/usb/usbnet.h>
+ #include <linux/usb/cdc-wdm.h>
++#include <linux/u64_stats_sync.h>
+ /* This driver supports wwan (3G/LTE/?) devices using a vendor
+  * specific management protocol called Qualcomm MSM Interface (QMI) -
+@@ -74,6 +75,7 @@ struct qmimux_hdr {
+ struct qmimux_priv {
+       struct net_device *real_dev;
+       u8 mux_id;
++      struct pcpu_sw_netstats __percpu *stats64;
+ };
+ static int qmimux_open(struct net_device *dev)
+@@ -100,19 +102,65 @@ static netdev_tx_t qmimux_start_xmit(str
+       struct qmimux_priv *priv = netdev_priv(dev);
+       unsigned int len = skb->len;
+       struct qmimux_hdr *hdr;
++      netdev_tx_t ret;
+       hdr = skb_push(skb, sizeof(struct qmimux_hdr));
+       hdr->pad = 0;
+       hdr->mux_id = priv->mux_id;
+       hdr->pkt_len = cpu_to_be16(len);
+       skb->dev = priv->real_dev;
+-      return dev_queue_xmit(skb);
++      ret = dev_queue_xmit(skb);
++
++      if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
++              struct pcpu_sw_netstats *stats64 = this_cpu_ptr(priv->stats64);
++
++              u64_stats_update_begin(&stats64->syncp);
++              stats64->tx_packets++;
++              stats64->tx_bytes += len;
++              u64_stats_update_end(&stats64->syncp);
++      } else {
++              dev->stats.tx_dropped++;
++      }
++
++      return ret;
++}
++
++static void qmimux_get_stats64(struct net_device *net,
++                             struct rtnl_link_stats64 *stats)
++{
++      struct qmimux_priv *priv = netdev_priv(net);
++      unsigned int start;
++      int cpu;
++
++      netdev_stats_to_stats64(stats, &net->stats);
++
++      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 = {
+-      .ndo_open       = qmimux_open,
+-      .ndo_stop       = qmimux_stop,
+-      .ndo_start_xmit = qmimux_start_xmit,
++      .ndo_open        = qmimux_open,
++      .ndo_stop        = qmimux_stop,
++      .ndo_start_xmit  = qmimux_start_xmit,
++      .ndo_get_stats64 = qmimux_get_stats64,
+ };
+ static void qmimux_setup(struct net_device *dev)
+@@ -197,8 +245,19 @@ static int qmimux_rx_fixup(struct usbnet
+               }
+               skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, pkt_len);
+-              if (netif_rx(skbn) != NET_RX_SUCCESS)
++              if (netif_rx(skbn) != NET_RX_SUCCESS) {
++                      net->stats.rx_errors++;
+                       return 0;
++              } else {
++                      struct pcpu_sw_netstats *stats64;
++                      struct qmimux_priv *priv = netdev_priv(net);
++
++                      stats64 = this_cpu_ptr(priv->stats64);
++                      u64_stats_update_begin(&stats64->syncp);
++                      stats64->rx_packets++;
++                      stats64->rx_bytes += pkt_len;
++                      u64_stats_update_end(&stats64->syncp);
++              }
+ skip:
+               offset += len + qmimux_hdr_sz;
+@@ -222,6 +281,12 @@ static int qmimux_register_device(struct
+       priv->mux_id = mux_id;
+       priv->real_dev = real_dev;
++      priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
++      if (!priv->stats64) {
++              err = -ENOBUFS;
++              goto out_free_newdev;
++      }
++
+       err = register_netdevice(new_dev);
+       if (err < 0)
+               goto out_free_newdev;
+@@ -252,6 +317,7 @@ static void qmimux_unregister_device(str
+       struct qmimux_priv *priv = netdev_priv(dev);
+       struct net_device *real_dev = priv->real_dev;
++      free_percpu(priv->stats64);
+       netdev_upper_dev_unlink(real_dev, dev);
+       unregister_netdevice_queue(dev, head);
index d0b9a4715cbde8dda94f1887a560ca3f19bb43b1..aea033aed8393950bf61fe27f70f84db9dab8a44 100644 (file)
@@ -45,3 +45,4 @@ kvm-x86-accept-userspace-interrupt-only-if-no-event-is-injected.patch
 kvm-x86-mmu-fix-per-cpu-counter-corruption-on-32-bit-builds.patch
 spi-meson-spicc-fix-memory-leak-in-meson_spicc_remove.patch
 perf-x86-amd-don-t-touch-the-amd64_eventsel_hostonly-bit-inside-the-guest.patch
+qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch