All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: vikas.gupta@broadcom.com
Cc: Simon Horman <horms@kernel.org>,
	andrew+netdev@lunn.ch, linux-kernel@vger.kernel.org,
	kuba@kernel.org, pabeni@redhat.com,
	vsrama-krishna.nemani@broadcom.com, michael.chan@broadcom.com,
	pavan.chebbi@broadcom.com, ajit.khaparde@broadcom.com,
	bhargava.marreddy@broadcom.com, rajashekar.hudumula@broadcom.com,
	davem@davemloft.net, edumazet@google.com, netdev@vger.kernel.org
Subject: Re: [PATCH net-next v8 09/10] bng_en: implement netdev_stat_ops
Date: Fri, 20 Mar 2026 11:27:04 +0000	[thread overview]
Message-ID: <20260320112704.2065290-1-horms@kernel.org> (raw)
In-Reply-To: <20260319055124.1350670-10-vikas.gupta@broadcom.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
bng_en: implement netdev_stat_ops

This patch adds netdev_stat_ops implementation to provide standardized
per-queue statistics via the Netlink API, including hardware drop
counters.

> diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
> index 2513b0907693..fa732b99358e 100644
> --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
> +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
> @@ -3031,6 +3031,81 @@ static int bnge_close(struct net_device *dev)
>  	return 0;
>  }
>
> +static void bnge_get_queue_stats_rx(struct net_device *dev, int i,
> +				    struct netdev_queue_stats_rx *stats)
> +{
> +	struct bnge_net *bn = netdev_priv(dev);
> +	struct bnge_nq_ring_info *nqr;
> +	u64 *sw;
> +
> +	if (!bn->bnapi)
> +		return;
> +
> +	nqr = &bn->bnapi[i]->nq_ring;
                ^^^^

Can this race with bnge_close_core and dereference bn->bnapi after it's
freed? The NULL check at line 3041 doesn't prevent the race since
bnge_close_core can free bn->bnapi between the check and dereference.

Looking at the existing bnge_get_stats64, it uses rcu_read_lock() when
accessing bn->bnapi:

bnge_get_stats64() {
    rcu_read_lock();
    if (test_bit(BNGE_STATE_OPEN, &bd->state)) {
        ... access bn->bnapi ...
    }
    rcu_read_unlock();
}

And bnge_close_core uses synchronize_rcu() to wait for readers before
freeing:

bnge_close_core() {
    ...
    synchronize_rcu();
    bnge_del_napi(bn);
        -> bnge_free_core(bn);
            -> bn->bnapi = NULL;
}

Without RCU protection, this sequence can occur:

Thread A (stats)                  Thread B (close)
----------------                  ----------------
if (!bn->bnapi)  [PASSES]
                                  bnge_close_core()
                                    bnge_free_core()
                                      bn->bnapi = NULL
nqr = &bn->bnapi[i]  [CRASH]

Should bnge_get_queue_stats_rx acquire rcu_read_lock() and check
test_bit(BNGE_STATE_OPEN) before accessing bn->bnapi?

> +	sw = nqr->stats.sw_stats;
> +
> +	stats->packets = 0;
> +	stats->packets += BNGE_GET_RING_STATS64(sw, rx_ucast_pkts);
> +	stats->packets += BNGE_GET_RING_STATS64(sw, rx_mcast_pkts);
> +	stats->packets += BNGE_GET_RING_STATS64(sw, rx_bcast_pkts);
> +
> +	stats->bytes = 0;
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, rx_ucast_bytes);
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, rx_mcast_bytes);
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, rx_bcast_bytes);
> +
> +	stats->hw_drop_overruns = BNGE_GET_RING_STATS64(sw, rx_discard_pkts);
> +	stats->hw_drops = BNGE_GET_RING_STATS64(sw, rx_error_pkts) +
> +				stats->hw_drop_overruns;
> +}
> +
> +static void bnge_get_queue_stats_tx(struct net_device *dev, int i,
> +				    struct netdev_queue_stats_tx *stats)
> +{
> +	struct bnge_net *bn = netdev_priv(dev);
> +	struct bnge_napi *bnapi;
> +	u64 *sw;
> +
> +	if (!bn->tx_ring)
> +		return;
> +
> +	bnapi = bn->tx_ring[bn->tx_ring_map[i]].bnapi;
                ^^^^

Does this have the same race with bnge_close_core? The NULL check doesn't
prevent bnge_close_core from freeing bn->tx_ring between the check and
dereference.

Following the same pattern as bnge_get_stats64, should this also use
rcu_read_lock() and check BNGE_STATE_OPEN before accessing bn->tx_ring?

> +	sw = bnapi->nq_ring.stats.sw_stats;
> +
> +	stats->packets = 0;
> +	stats->packets += BNGE_GET_RING_STATS64(sw, tx_ucast_pkts);
> +	stats->packets += BNGE_GET_RING_STATS64(sw, tx_mcast_pkts);
> +	stats->packets += BNGE_GET_RING_STATS64(sw, tx_bcast_pkts);
> +
> +	stats->bytes = 0;
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, tx_ucast_bytes);
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, tx_mcast_bytes);
> +	stats->bytes += BNGE_GET_RING_STATS64(sw, tx_bcast_bytes);
> +
> +	stats->hw_drop_errors = BNGE_GET_RING_STATS64(sw, tx_error_pkts);
> +	stats->hw_drops = BNGE_GET_RING_STATS64(sw, tx_discard_pkts) +
> +				stats->hw_drop_errors;
> +}
> +
> +static void bnge_get_base_stats(struct net_device *dev,
> +				struct netdev_queue_stats_rx *rx,
> +				struct netdev_queue_stats_tx *tx)
> +{
> +	struct bnge_net *bn = netdev_priv(dev);
> +
> +	rx->packets = bn->net_stats_prev.rx_packets;
> +	rx->bytes = bn->net_stats_prev.rx_bytes;
       ^^^^

Can this race with bnge_close_core when reading bn->net_stats_prev?
bnge_close_core writes to bn->net_stats_prev while this function reads
it without any locking.

Looking at bnge_get_stats64, it uses rcu_read_lock() before accessing
bn->net_stats_prev. While this won't cause a crash like the other two
issues, it could result in torn reads on 32-bit systems where reading
u64 is not atomic, potentially returning inconsistent statistics to
userspace.

Should bnge_get_base_stats also use rcu_read_lock() when reading
bn->net_stats_prev?

> +
> +	tx->packets = bn->net_stats_prev.tx_packets;
> +	tx->bytes = bn->net_stats_prev.tx_bytes;
> +}
> +
> +static const struct netdev_stat_ops bnge_stat_ops = {
> +	.get_queue_stats_rx	= bnge_get_queue_stats_rx,
> +	.get_queue_stats_tx	= bnge_get_queue_stats_tx,
> +	.get_base_stats		= bnge_get_base_stats,
> +};
> +

[ ... ]

  reply	other threads:[~2026-03-20 11:27 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-19  5:51 [PATCH net-next v8 00/10] bng_en: add link management and statistics support Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 01/10] bng_en: add per-PF workqueue, timer, and slow-path task Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 02/10] bng_en: query PHY capabilities and report link status Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 03/10] bng_en: add ethtool link settings, get_link, and nway_reset Vikas Gupta
2026-03-20 11:26   ` Simon Horman
2026-03-21  3:11   ` Jakub Kicinski
2026-03-19  5:51 ` [PATCH net-next v8 04/10] bng_en: implement ethtool pauseparam operations Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 05/10] bng_en: add support for link async events Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 06/10] bng_en: add HW stats infra and structured ethtool ops Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 07/10] bng_en: periodically fetch and accumulate hardware statistics Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 08/10] bng_en: implement ndo_get_stats64 Vikas Gupta
2026-03-19  5:51 ` [PATCH net-next v8 09/10] bng_en: implement netdev_stat_ops Vikas Gupta
2026-03-20 11:27   ` Simon Horman [this message]
2026-03-20 20:27     ` Bhargava Chenna Marreddy
2026-03-21  9:15       ` Simon Horman
2026-03-19  5:51 ` [PATCH net-next v8 10/10] bng_en: add support for ethtool -S stats display Vikas Gupta
2026-03-20 11:27   ` Simon Horman
2026-03-20 19:51     ` Bhargava Chenna Marreddy
2026-03-21  9:06       ` Simon Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260320112704.2065290-1-horms@kernel.org \
    --to=horms@kernel.org \
    --cc=ajit.khaparde@broadcom.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=bhargava.marreddy@broadcom.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.chan@broadcom.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pavan.chebbi@broadcom.com \
    --cc=rajashekar.hudumula@broadcom.com \
    --cc=vikas.gupta@broadcom.com \
    --cc=vsrama-krishna.nemani@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.