From: Greg Kroah-Hartman Date: Mon, 9 Aug 2021 13:54:49 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.4.280~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1f0ce47da3bd1fb8bd0f6fc97d95dc75b3859f51;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch --- 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 index 00000000000..358acf39730 --- /dev/null +++ b/queue-4.19/qmi_wwan-add-network-device-usage-statistics-for-qmimux-devices.patch @@ -0,0 +1,151 @@ +From 44f82312fe9113bab6642f4d0eab6b1b7902b6e1 Mon Sep 17 00:00:00 2001 +From: Reinhard Speyerer +Date: Wed, 12 Jun 2019 19:02:46 +0200 +Subject: qmi_wwan: add network device usage statistics for qmimux devices + +From: Reinhard Speyerer + +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 +Signed-off-by: Reinhard Speyerer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + /* 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); + diff --git a/queue-4.19/series b/queue-4.19/series index d0b9a4715cb..aea033aed83 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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