* [PATCH net v4] net: wwan: qcom_bam_dmux: account network packets
@ 2026-09-04 18:37 Dmitry Sinyavin
2026-09-09 21:40 ` netdev-bot+sashiko
0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Sinyavin @ 2026-09-04 18:37 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Dmitry Sinyavin, Stephan Gerhold, Loic Poulain, Sergey Ryazanov,
Johannes Berg, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, linux-arm-msm, netdev, linux-kernel
The BAM-DMUX data path does not update the network device packet and byte
counters. As a result, userspace sees zero traffic even while packets are
being transferred.
Use the standard per-CPU software statistics helpers. Account transmitted
packets after the driver has prepared and accepted them, before returning
NETDEV_TX_OK. The asynchronous DMA completion may run after the network
device has been unregistered. Account received packets after removing the
BAM-DMUX header and padding.
Fixes: 21a0ffd9b38c ("net: wwan: Add Qualcomm BAM-DMUX WWAN network driver")
Signed-off-by: Dmitry Sinyavin <sinyavin@gmail.com>
---
v4:
- Move TX accounting from the asynchronous DMA completion to the transmit
path, avoiding access to statistics after netdev unregistration.
v3:
- Count packets discarded by the transmit error path.
v2:
- Read the TX payload length after unmapping the DMA buffer and combine the
network-device checks.
v3: https://lore.kernel.org/netdev/20260902124506.363174-1-sinyavin@gmail.com/
v2: https://lore.kernel.org/netdev/20260831181006.1382372-1-sinyavin@gmail.com/
v1: https://lore.kernel.org/netdev/20260830085400.2542956-1-sinyavin@gmail.com/
Build-tested for ARM with Clang and W=1 using allmodconfig and allyesconfig.
Tested on a ZTE MF283V with an MDM9607. The modem registered on LTE and
three 32-byte ICMP echo requests increased both wwan0 RX and TX counters by
three packets and 180 bytes. Bringing the interface down afterwards produced
no DMA, BAM-DMUX, or kernel fault messages.
drivers/net/wwan/qcom_bam_dmux.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c
index cc6ace8d6437..03360301c8ee 100644
--- a/drivers/net/wwan/qcom_bam_dmux.c
+++ b/drivers/net/wwan/qcom_bam_dmux.c
@@ -335,6 +335,7 @@ static netdev_tx_t bam_dmux_netdev_start_xmit(struct sk_buff *skb,
struct bam_dmux_netdev *bndev = netdev_priv(netdev);
struct bam_dmux *dmux = bndev->dmux;
struct bam_dmux_skb_dma *skb_dma;
+ unsigned int len = skb->len;
int active, ret;
skb_dma = bam_dmux_tx_queue(dmux, skb);
@@ -357,17 +358,19 @@ static netdev_tx_t bam_dmux_netdev_start_xmit(struct sk_buff *skb,
if (!atomic_long_fetch_or(BIT(skb_dma - dmux->tx_skbs),
&dmux->tx_deferred_skb))
queue_pm_work(&dmux->tx_wakeup_work);
- return NETDEV_TX_OK;
- }
+ } else {
+ if (!bam_dmux_skb_dma_submit_tx(skb_dma))
+ goto drop;
- if (!bam_dmux_skb_dma_submit_tx(skb_dma))
- goto drop;
+ dma_async_issue_pending(dmux->tx);
+ }
- dma_async_issue_pending(dmux->tx);
+ dev_sw_netstats_tx_add(netdev, 1, len);
return NETDEV_TX_OK;
drop:
bam_dmux_tx_done(skb_dma);
+ dev_core_stats_tx_dropped_inc(netdev);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -402,6 +405,7 @@ static const struct net_device_ops bam_dmux_ops = {
.ndo_open = bam_dmux_netdev_open,
.ndo_stop = bam_dmux_netdev_stop,
.ndo_start_xmit = bam_dmux_netdev_start_xmit,
+ .ndo_get_stats64 = dev_get_tstats64,
};
static const struct device_type wwan_type = {
@@ -421,6 +425,7 @@ static void bam_dmux_netdev_setup(struct net_device *dev)
dev->needed_headroom = sizeof(struct bam_dmux_hdr);
dev->needed_tailroom = sizeof(u32); /* word-aligned */
dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
+ dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
/* This perm addr will be used as interface identifier by IPv6 */
dev->addr_assign_type = NET_ADDR_RANDOM;
@@ -533,6 +538,7 @@ static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
break;
}
+ dev_sw_netstats_rx_add(netdev, skb->len);
netif_receive_skb(skb);
}
base-commit: 2188569e7e1b0bc3f3b557dc97ab7a02befc11c8
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net v4] net: wwan: qcom_bam_dmux: account network packets
2026-09-04 18:37 [PATCH net v4] net: wwan: qcom_bam_dmux: account network packets Dmitry Sinyavin
@ 2026-09-09 21:40 ` netdev-bot+sashiko
2026-09-10 15:05 ` Jakub Kicinski
0 siblings, 1 reply; 3+ messages in thread
From: netdev-bot+sashiko @ 2026-09-09 21:40 UTC (permalink / raw)
To: sinyavin
Cc: stephan, stephan.gerhold, loic.poulain, ryazanov.s.a, johannes,
andrew+netdev, davem, edumazet, kuba, pabeni, linux-arm-msm,
netdev, linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 · Low: 0
- [Medium] In `bam_dmux_netdev_start_xmit()` the new
`dev_sw_netstats_tx_add(netdev, 1, len)`…
--
net: wwan: qcom_bam_dmux: account network packets
The BAM-DMUX data path did not update the netdev packet and byte counters,
so userspace saw zero traffic. This adds per-CPU software statistics with
NETDEV_PCPU_STAT_TSTATS and dev_get_tstats64(), counting TX in
bam_dmux_netdev_start_xmit() and RX in bam_dmux_cmd_data().
> diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c
> index cc6ace8d64371..03360301c8ee5 100644
> --- a/drivers/net/wwan/qcom_bam_dmux.c
> +++ b/drivers/net/wwan/qcom_bam_dmux.c
[ ... ]
> @@ -357,17 +358,19 @@ static netdev_tx_t bam_dmux_netdev_start_xmit(struct sk_buff *skb,
> if (!atomic_long_fetch_or(BIT(skb_dma - dmux->tx_skbs),
> &dmux->tx_deferred_skb))
> queue_pm_work(&dmux->tx_wakeup_work);
> - return NETDEV_TX_OK;
> - }
> + } else {
> + if (!bam_dmux_skb_dma_submit_tx(skb_dma))
> + goto drop;
>
> - if (!bam_dmux_skb_dma_submit_tx(skb_dma))
> - goto drop;
> + dma_async_issue_pending(dmux->tx);
> + }
>
> - dma_async_issue_pending(dmux->tx);
> + dev_sw_netstats_tx_add(netdev, 1, len);
> return NETDEV_TX_OK;
[Severity: Medium]
Is it intended that dev_sw_netstats_tx_add() now also covers the deferred
branch, where nothing has been submitted to the DMA engine yet?
In the active <= 0 case the skb is only marked in dmux->tx_deferred_skb and
bam_dmux_tx_wakeup_work() is queued. The descriptor is prepared later in
that worker, which can bail out before submitting anything:
drivers/net/wwan/qcom_bam_dmux.c:bam_dmux_tx_wakeup_work() {
ret = pm_runtime_resume_and_get(dmux->dev);
if (ret < 0) {
dev_err(dmux->dev, "Failed to resume: %d\n", ret);
return;
}
...
for_each_set_bit(i, &pending, BAM_DMUX_NUM_SKB) {
bam_dmux_skb_dma_submit_tx(&dmux->tx_skbs[i]);
}
...
}
bam_dmux_runtime_resume() can return -ETIMEDOUT from any of its three 2
second waits on the remote modem, or -ENXIO when the TX channel cannot be
requested, for example after a modem crash or power collapse. In that case
the worker returns with the packet still sitting in dmux->tx_skbs[], while
tx_packets/tx_bytes have already been incremented for it and tx_dropped is
never touched.
The other failure mode is the return value of the same helper being ignored
in the worker:
drivers/net/wwan/qcom_bam_dmux.c:bam_dmux_skb_dma_submit_tx() {
desc = dmaengine_prep_slave_single(dmux->tx, skb_dma->addr,
skb_dma->skb->len, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT);
if (!desc) {
dev_err(dmux->dev, "Failed to prepare TX DMA buffer\n");
return false;
}
...
}
So the two callers of bam_dmux_skb_dma_submit_tx() end up with opposite
accounting: start_xmit() counts a drop via dev_core_stats_tx_dropped_inc(),
the worker counts nothing at all.
The commit message says the counters are updated "after the driver has
prepared and accepted them", which explains counting at accept time, but
would it be better to account the deferred packets from
bam_dmux_tx_wakeup_work() once submission succeeds, and to increment
tx_dropped there when it does not?
> drop:
> bam_dmux_tx_done(skb_dma);
> + dev_core_stats_tx_dropped_inc(netdev);
> dev_kfree_skb_any(skb);
> return NETDEV_TX_OK;
> }
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260904183737.2994139-1-sinyavin%40gmail.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net v4] net: wwan: qcom_bam_dmux: account network packets
2026-09-09 21:40 ` netdev-bot+sashiko
@ 2026-09-10 15:05 ` Jakub Kicinski
0 siblings, 0 replies; 3+ messages in thread
From: Jakub Kicinski @ 2026-09-10 15:05 UTC (permalink / raw)
To: netdev-bot+sashiko
Cc: sinyavin, stephan, stephan.gerhold, loic.poulain, ryazanov.s.a,
johannes, andrew+netdev, davem, edumazet, pabeni, linux-arm-msm,
netdev, linux-kernel
On Wed, 09 Sep 2026 21:40:11 +0000 netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider:
>
> Critical: 0 · High: 0 · Medium: 1 · Low: 0
>
> - [Medium] In `bam_dmux_netdev_start_xmit()` the new
> `dev_sw_netstats_tx_add(netdev, 1, len)`…
AI is right, the typical flow is to account packets and bytes
on completion of the transfer rather than initiation.
Also please drop the Fixes tag and re-target at net-next,
this is not a fix, as important as stats are.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-10 15:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-04 18:37 [PATCH net v4] net: wwan: qcom_bam_dmux: account network packets Dmitry Sinyavin
2026-09-09 21:40 ` netdev-bot+sashiko
2026-09-10 15:05 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®