net: mana: Refactor GF stats handling and add rx_missed_errors counter
Subsystems (5)
v3 cover net: mana: Refactor GF stats handling and add rx_missed_errors counter
Restructure mana_query_gf_stats() to operate on the per-VF mana_context, instead of per-port statistics. Introduce mana_ethtool_hc_stats to isolate hardware counter statistics and update the
"ethtool -S <interface>" output to expose all relevant counters while preserving backward compatibility.
Add support for the standard rx_missed_errors counter by mapping it to the hardware's hc_rx_discards_no_wqe metric. Introduce a global workqueue that refreshes statistics every 2 seconds, ensuring timely and consistent updates of hardware counters.
---
Changes in v3:
* Use schedule_delayed_work (global workqueue) instead of queue_delayed_work (dedicated workqueue for MANA driver).
* Update commit message for more readability.
* Use reverse x-mas tree format in mana_query_gf_stats. Changes in v2:
* Update commit message.
* Stop rescheduling workqueue only when HWC timeout is observed.
* Introduce new variable in mana_context for detecting HWC timeout.
* Warn once in mana_get_stat64 when HWC timeout is observed.
---
Erni Sri Satya Vennela (2):
net: mana: Move hardware counter stats from per-port to per-device
context
net: mana: Add standard counter rx_missed_errors
drivers/net/ethernet/microsoft/mana/mana_en.c | 101 ++++++++++++------ .../ethernet/microsoft/mana/mana_ethtool.c | 85 ++++++++------- include/net/mana/gdma.h | 6 +- include/net/mana/mana.h | 18 +++- 4 files changed, 130 insertions(+), 80 deletions(-)
Signature · 2 lines
2.34.1 For internal review only.
PATCH v3 1/2 net: mana: Move hardware counter stats from per-port to per-VF context
Move hardware counter (HC) statistics from mana_port_context to mana_context to enable sharing stats across multiple network ports on the same MANA VF. Previously, each network port queried hardware counters independently using MANA_QUERY_GF_STAT command (GF = Generic Function stats from GDMA hardware), resulting in redundant queries when multiple ports existed on the same device.
Isolate hardware counter stats by introducing mana_ethtool_hc_stats in mana_context and update the code to ensure all stats are properly reported via ethtool -S <interface>, maintaining consistency with previous behavior.
---
Changes in v3:
* Update commit message for more readability.
* Use reverse x-mas tree format in mana_query_gf_stats. Changes in v2:
* No change
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 67 ++++++++------- .../ethernet/microsoft/mana/mana_ethtool.c | 85 ++++++++++--------- include/net/mana/mana.h | 14 +-- 3 files changed, 90 insertions(+), 76 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +34 -33
@@ -2809,11 +2809,12 @@ int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,return 0 ; } -void mana_query_gf_stats (struct mana_port_context *apc) +void mana_query_gf_stats (struct mana_context *ac) { +struct gdma_context *gc = ac->gdma_dev->gdma_context;struct mana_query_gf_stat_resp resp = {};struct mana_query_gf_stat_req req = {}; -struct net_device *ndev = apc->ndev; +struct device *dev = gc->dev;int err; mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_GF_STAT,
@@ -2847,52 +2848,52 @@ void mana_query_gf_stats(struct mana_port_context *apc)STATISTICS_FLAGS_HC_TX_BCAST_BYTES |STATISTICS_FLAGS_TX_ERRORS_GDMA_ERROR ; - err =mana_send_request (apc->ac, &req,sizeof (req), &resp, + err =mana_send_request (ac, &req,sizeof (req), &resp,sizeof (resp));if (err) { -netdev_err (ndev,"Failed to query GF stats: %d\n" , err); +dev_err (dev,"Failed to query GF stats: %d\n" , err);return ; } err =mana_verify_resp_hdr (&resp.hdr,MANA_QUERY_GF_STAT ,sizeof (resp));if (err || resp.hdr.status) { -netdev_err (ndev,"Failed to query GF stats: %d, 0x%x\n" , err, - resp.hdr.status); +dev_err (dev,"Failed to query GF stats: %d, 0x%x\n" , err, + resp.hdr.status);return ; } - apc->eth_stats.hc_rx_discards_no_wqe = resp.rx_discards_nowqe; - apc->eth_stats.hc_rx_err_vport_disabled = resp.rx_err_vport_disabled; - apc->eth_stats.hc_rx_bytes = resp.hc_rx_bytes; - apc->eth_stats.hc_rx_ucast_pkts = resp.hc_rx_ucast_pkts; - apc->eth_stats.hc_rx_ucast_bytes = resp.hc_rx_ucast_bytes; - apc->eth_stats.hc_rx_bcast_pkts = resp.hc_rx_bcast_pkts; - apc->eth_stats.hc_rx_bcast_bytes = resp.hc_rx_bcast_bytes; - apc->eth_stats.hc_rx_mcast_pkts = resp.hc_rx_mcast_pkts; - apc->eth_stats.hc_rx_mcast_bytes = resp.hc_rx_mcast_bytes; - apc->eth_stats.hc_tx_err_gf_disabled = resp.tx_err_gf_disabled; - apc->eth_stats.hc_tx_err_vport_disabled = resp.tx_err_vport_disabled; - apc->eth_stats.hc_tx_err_inval_vportoffset_pkt = + ac->hc_stats.hc_rx_discards_no_wqe = resp.rx_discards_nowqe; + ac->hc_stats.hc_rx_err_vport_disabled = resp.rx_err_vport_disabled; + ac->hc_stats.hc_rx_bytes = resp.hc_rx_bytes; + ac->hc_stats.hc_rx_ucast_pkts = resp.hc_rx_ucast_pkts; + ac->hc_stats.hc_rx_ucast_bytes = resp.hc_rx_ucast_bytes; + ac->hc_stats.hc_rx_bcast_pkts = resp.hc_rx_bcast_pkts; + ac->hc_stats.hc_rx_bcast_bytes = resp.hc_rx_bcast_bytes; + ac->hc_stats.hc_rx_mcast_pkts = resp.hc_rx_mcast_pkts; + ac->hc_stats.hc_rx_mcast_bytes = resp.hc_rx_mcast_bytes; + ac->hc_stats.hc_tx_err_gf_disabled = resp.tx_err_gf_disabled; + ac->hc_stats.hc_tx_err_vport_disabled = resp.tx_err_vport_disabled; + ac->hc_stats.hc_tx_err_inval_vportoffset_pkt = resp.tx_err_inval_vport_offset_pkt; - apc->eth_stats.hc_tx_err_vlan_enforcement = + ac->hc_stats.hc_tx_err_vlan_enforcement = resp.tx_err_vlan_enforcement; - apc->eth_stats.hc_tx_err_eth_type_enforcement = + ac->hc_stats.hc_tx_err_eth_type_enforcement = resp.tx_err_ethtype_enforcement; - apc->eth_stats.hc_tx_err_sa_enforcement = resp.tx_err_SA_enforcement; - apc->eth_stats.hc_tx_err_sqpdid_enforcement = + ac->hc_stats.hc_tx_err_sa_enforcement = resp.tx_err_SA_enforcement; + ac->hc_stats.hc_tx_err_sqpdid_enforcement = resp.tx_err_SQPDID_enforcement; - apc->eth_stats.hc_tx_err_cqpdid_enforcement = + ac->hc_stats.hc_tx_err_cqpdid_enforcement = resp.tx_err_CQPDID_enforcement; - apc->eth_stats.hc_tx_err_mtu_violation = resp.tx_err_mtu_violation; - apc->eth_stats.hc_tx_err_inval_oob = resp.tx_err_inval_oob; - apc->eth_stats.hc_tx_bytes = resp.hc_tx_bytes; - apc->eth_stats.hc_tx_ucast_pkts = resp.hc_tx_ucast_pkts; - apc->eth_stats.hc_tx_ucast_bytes = resp.hc_tx_ucast_bytes; - apc->eth_stats.hc_tx_bcast_pkts = resp.hc_tx_bcast_pkts; - apc->eth_stats.hc_tx_bcast_bytes = resp.hc_tx_bcast_bytes; - apc->eth_stats.hc_tx_mcast_pkts = resp.hc_tx_mcast_pkts; - apc->eth_stats.hc_tx_mcast_bytes = resp.hc_tx_mcast_bytes; - apc->eth_stats.hc_tx_err_gdma = resp.tx_err_gdma; + ac->hc_stats.hc_tx_err_mtu_violation = resp.tx_err_mtu_violation; + ac->hc_stats.hc_tx_err_inval_oob = resp.tx_err_inval_oob; + ac->hc_stats.hc_tx_bytes = resp.hc_tx_bytes; + ac->hc_stats.hc_tx_ucast_pkts = resp.hc_tx_ucast_pkts; + ac->hc_stats.hc_tx_ucast_bytes = resp.hc_tx_ucast_bytes; + ac->hc_stats.hc_tx_bcast_pkts = resp.hc_tx_bcast_pkts; + ac->hc_stats.hc_tx_bcast_bytes = resp.hc_tx_bcast_bytes; + ac->hc_stats.hc_tx_mcast_pkts = resp.hc_tx_mcast_pkts; + ac->hc_stats.hc_tx_mcast_bytes = resp.hc_tx_mcast_bytes; + ac->hc_stats.hc_tx_err_gdma = resp.tx_err_gdma; }void mana_query_phy_stats (struct mana_port_context *apc)
drivers/net/ethernet/microsoft/mana/mana_ethtool.c +47 -38
149 lines not on this page · raw message
include/net/mana/mana.h +9 -5
@@ -375,6 +375,13 @@ struct mana_tx_qp {struct mana_ethtool_stats {u64 stop_queue;u64 wake_queue; +u64 tx_cqe_err; +u64 tx_cqe_unknown_type; +u64 rx_coalesced_err; +u64 rx_cqe_unknown_type; +}; + +struct mana_ethtool_hc_stats {u64 hc_rx_discards_no_wqe;u64 hc_rx_err_vport_disabled;u64 hc_rx_bytes;
@@ -402,10 +409,6 @@ struct mana_ethtool_stats {u64 hc_tx_mcast_pkts;u64 hc_tx_mcast_bytes;u64 hc_tx_err_gdma; -u64 tx_cqe_err; -u64 tx_cqe_unknown_type; -u64 rx_coalesced_err; -u64 rx_cqe_unknown_type; };struct mana_ethtool_phy_stats {
@@ -473,6 +476,7 @@ struct mana_context {u16 num_ports;u8 bm_hostmode; +struct mana_ethtool_hc_stats hc_stats;struct mana_eq *eqs;struct dentry *mana_eqs_debugfs;
@@ -577,7 +581,7 @@ u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq,struct bpf_prog *mana_xdp_get (struct mana_port_context *apc);void mana_chn_setxdp (struct mana_port_context *apc,struct bpf_prog *prog);int mana_bpf (struct net_device *ndev,struct netdev_bpf *bpf); -void mana_query_gf_stats (struct mana_port_context *apc); +void mana_query_gf_stats (struct mana_context *ac);int mana_query_link_cfg (struct mana_port_context *apc);int mana_set_bw_clamp (struct mana_port_context *apc,u32 speed,int enable_clamping);
Signature · 1 line
2.34.1
RE: [PATCH net-next v3 1/2] net: mana: Move hardware counter stats from per-port to per-VF context
Quoted 26 lines
-----Original Message-----
From: Erni Sri Satya Vennela <[email protected]>
Sent: Friday, November 14, 2025 6:43 AM
To: KY Srinivasan <[email protected]>; Haiyang Zhang <[email protected]>; [email protected]; Dexuan Cui <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Long Li <[email protected]>; Konstantin Taranov <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Shiraz Saleem <[email protected]>; [email protected]; linux- [email protected]; [email protected]; linux- [email protected]; [email protected]
Subject: [PATCH net-next v3 1/2] net: mana: Move hardware counter stats from per-port to per-VF contextMove hardware counter (HC) statistics from
mana_port_contexttomana_contextto enable sharing stats across multiple network ports on the same MANA VF. Previously, each network port queried hardware counters independently usingMANA_QUERY_GF_STATcommand (GF = Generic Function stats from GDMA hardware), resulting in redundant queries when multiple ports existed on the same device.
Quoted 6 lines
Isolate hardware counter stats by introducing
mana_ethtool_hc_statsinmana_contextand update the code to ensure all stats are properly reported via ethtool -S <interface>, maintaining consistency with previous behavior.Signed-off-by Erni Sri Satya Vennela <[email protected]>
PATCH v3 2/2 net: mana: Add standard counter rx_missed_errors
In reply to Erni Sri Satya VennelaReport standard counter stats->rx_missed_errors
using hc_rx_discards_no_wqe from the hardware.
Add a global workqueue to periodically run mana_query_gf_stats every 2 seconds to get the latest info in eth_stats and define a driver capability flag to notify hardware of the periodic queries.
To avoid repeated failures and log flooding, the workqueue is not rescheduled if mana_query_gf_stats fails on HWC timeout error and the stats are reset to 0. Other errors are transient which will not need a VF reset for recovery.
---
Changes in v3:
* Use schedule_delayed_work (global workqueue) instead of queue_delayed_work (dedicated workqueue) in MANA driver.
* Update commit message.
Changes in v2:
* Update commit message.
* Stop rescheduling workqueue only when HWC timeout is observed.
* Introduce new variable in mana_context for detecting HWC timeout.
* Warn once in mana_get_stat64 when HWC timeout is observed.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 36 +++++++++++++++++-- .../ethernet/microsoft/mana/mana_ethtool.c | 2 -- include/net/mana/gdma.h | 6 +++- include/net/mana/mana.h | 6 +++- 4 files changed, 43 insertions(+), 7 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +33 -3
@@ -534,6 +534,11 @@ static void mana_get_stats64(struct net_device *ndev,netdev_stats_to_stats64 (st, &ndev->stats); +if (apc->ac->hwc_timeout_occurred) +netdev_warn_once (ndev,"HWC timeout occurred\n" ); + + st->rx_missed_errors = apc->ac->hc_stats.hc_rx_discards_no_wqe; +for (q =0 ; q < num_queues; q++) { rx_stats = &apc->rxqs[q]->stats;
@@ -2809,7 +2814,7 @@ int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,return 0 ; } -void mana_query_gf_stats (struct mana_context *ac) +int mana_query_gf_stats (struct mana_context *ac) {struct gdma_context *gc = ac->gdma_dev->gdma_context;struct mana_query_gf_stat_resp resp = {};
@@ -2852,14 +2857,14 @@ void mana_query_gf_stats(struct mana_context *ac) sizeof(resp));if (err) {dev_err (dev,"Failed to query GF stats: %d\n" , err); -return ; +return err; } err =mana_verify_resp_hdr (&resp.hdr,MANA_QUERY_GF_STAT ,sizeof (resp));if (err || resp.hdr.status) {dev_err (dev,"Failed to query GF stats: %d, 0x%x\n" , err, resp.hdr.status); -return ; +return err; } ac->hc_stats.hc_rx_discards_no_wqe = resp.rx_discards_nowqe;
@@ -2894,6 +2899,8 @@ void mana_query_gf_stats(struct mana_context *ac) ac->hc_stats.hc_tx_mcast_pkts = resp.hc_tx_mcast_pkts; ac->hc_stats.hc_tx_mcast_bytes = resp.hc_tx_mcast_bytes; ac->hc_stats.hc_tx_err_gdma = resp.tx_err_gdma; + +return 0 ; }void mana_query_phy_stats (struct mana_port_context *apc)
@@ -3428,6 +3435,24 @@ int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type evenreturn 0 ; } +#define MANA_GF_STATS_PERIOD (2 * HZ) + +static void mana_gf_stats_work_handler (struct work_struct *work) +{ +struct mana_context *ac = + container_of(to_delayed_work(work), struct mana_context, gf_stats_work); +int err; + + err =mana_query_gf_stats (ac); +if (err == -ETIMEDOUT ) { +/* HWC timeout detected - reset stats and stop rescheduling */ + ac->hwc_timeout_occurred = true; +memset (&ac->hc_stats,0 ,sizeof (ac->hc_stats)); +return ; + } +schedule_delayed_work (&ac->gf_stats_work,MANA_GF_STATS_PERIOD ); +} +int mana_probe (struct gdma_dev *gd,bool resuming) {struct gdma_context *gc = gd->gdma_context;
@@ -3520,6 +3545,10 @@ int mana_probe(struct gdma_dev *gd, bool resuming) } err =add_adev (gd,"eth" ); + +INIT_DELAYED_WORK (&ac->gf_stats_work, mana_gf_stats_work_handler); +schedule_delayed_work (&ac->gf_stats_work,MANA_GF_STATS_PERIOD ); + out:if (err) {mana_remove (gd, false);
@@ -3544,6 +3573,7 @@ void mana_remove(struct gdma_dev *gd, bool suspending)int i;disable_work_sync (&ac->link_change_work); +cancel_delayed_work_sync (&ac->gf_stats_work);/* adev currently doesn't support suspending, always remove it */ if (gd->adev)
drivers/net/ethernet/microsoft/mana/mana_ethtool.c +0 -2
@@ -213,8 +213,6 @@ static void mana_get_ethtool_stats(struct net_device *ndev,if (!apc->port_is_up)return ; -/* we call mana function to update stats from GDMA */ -mana_query_gf_stats (apc->ac);/* We call this mana function to get the phy stats from GDMA and includes * aggregate tx/rx drop counters, Per-TC(Traffic Channel) tx/rx and pause
include/net/mana/gdma.h +5 -1
@@ -592,6 +592,9 @@ enum {#define GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE BIT(17)#define GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE BIT(6) +/* Driver can send HWC periodically to query stats */ +#define GDMA_DRV_CAP_FLAG_1_PERIODIC_STATS_QUERY BIT(21) +#define GDMA_DRV_CAP_FLAGS1 \ (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
@@ -601,7 +604,8 @@ enum {GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE | \ - GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE) +GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE | \ + GDMA_DRV_CAP_FLAG_1_PERIODIC_STATS_QUERY) #define GDMA_DRV_CAP_FLAGS2 0
include/net/mana/mana.h +5 -1
@@ -480,6 +480,10 @@ struct mana_context {struct mana_eq *eqs;struct dentry *mana_eqs_debugfs; +/* Workqueue for querying hardware stats */ +struct delayed_work gf_stats_work; +bool hwc_timeout_occurred; +struct net_device *ports[MAX_PORTS_IN_MANA_DEV ];/* Link state change work */
@@ -581,7 +585,7 @@ u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq,struct bpf_prog *mana_xdp_get (struct mana_port_context *apc);void mana_chn_setxdp (struct mana_port_context *apc,struct bpf_prog *prog);int mana_bpf (struct net_device *ndev,struct netdev_bpf *bpf); -void mana_query_gf_stats (struct mana_context *ac); +int mana_query_gf_stats (struct mana_context *ac);int mana_query_link_cfg (struct mana_port_context *apc);int mana_set_bw_clamp (struct mana_port_context *apc,u32 speed,int enable_clamping);
Signature · 1 line
2.34.1
RE: [PATCH net-next v3 2/2] net: mana: Add standard counter rx_missed_errors
Quoted 27 lines
-----Original Message-----
From: Erni Sri Satya Vennela <[email protected]>
Sent: Friday, November 14, 2025 6:43 AM
To: KY Srinivasan <[email protected]>; Haiyang Zhang <[email protected]>; [email protected]; Dexuan Cui <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Long Li <[email protected]>; Konstantin Taranov <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Shiraz Saleem <[email protected]>; [email protected]; linux- [email protected]; [email protected]; linux- [email protected]; [email protected]
Subject: [PATCH net-next v3 2/2] net: mana: Add standard counterrx_missed_errorsReport standard counter
stats->rx_missed_errors
usinghc_rx_discards_no_wqefrom the hardware.Add a global workqueue to periodically run
mana_query_gf_statsevery 2 seconds to get the latest info ineth_statsand define a driver capability flag to notify hardware of the periodic queries.
Quoted 6 lines
To avoid repeated failures and log flooding, the workqueue is not rescheduled if
mana_query_gf_statsfails on HWC timeout error and the stats are reset to 0. Other errors are transient which will not need a VF reset for recovery.Signed-off-by Erni Sri Satya Vennela <[email protected]>
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Quoted 6 lines · On Fri, 14 Nov 2025 03:43:17 -0800 you wrote:
Restructure
mana_query_gf_stats()to operate on the per-VFmana_context, instead of per-port statistics. Introducemana_ethtool_hc_statsto isolate hardware counter statistics and update the
"ethtool -S <interface>" output to expose all relevant counters while preserving backward compatibility.
Quoted 6 lines
Add support for the standard
rx_missed_errorscounter by mapping it to the hardware'shc_rx_discards_no_wqemetric. Introduce a global workqueue that refreshes statistics every 2 seconds, ensuring timely and consistent updates of hardware counters.[...]
Here is the summary with links:
- [net-next,v3,1/2] net: mana: Move hardware counter stats from per-port to per-VF context
https://git.kernel.org/netdev/net-next/c/e275d9091c01 - [net-next,v3,2/2] net: mana: Add standard counter rx_missed_errors https://git.kernel.org/netdev/net-next/c/be4f1d67ec56
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html