public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: jiawenwu@trustnetic.com
Cc: Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, mengyuanlou@net-swift.com,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	pabeni@redhat.com, richardcochran@gmail.com,
	linux@armlinux.org.uk, horms@kernel.org,
	michal.swiatkowski@linux.intel.com, jacob.e.keller@intel.com,
	kees@kernel.org, joe@dama.to, larysa.zaremba@intel.com,
	abdun.nihaal@gmail.com, leitao@debian.org
Subject: Re: [PATCH net-next v6 10/11] net: wangxun: improve flow control setting
Date: Mon, 30 Mar 2026 17:55:49 -0700	[thread overview]
Message-ID: <20260331005549.3459818-1-kuba@kernel.org> (raw)
In-Reply-To: <20260326021406.30444-11-jiawenwu@trustnetic.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.
---
net: wangxun: improve flow control setting

Save the current mode of flow control, check the pause frame statistics
in watchdog to clear WX_HANG_CHECK_ARMED. The received pause frames are
divided into XON and XOFF to be counted, and Tx XON pause is disabled by
default for SP devices.

> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
> index 2f71dc24306d4..4e0195f7df39e 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
[ ... ]
> @@ -2831,6 +2842,28 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause)
>  }
>  EXPORT_SYMBOL(wx_fc_enable);
>  
> +static void wx_update_xoff_rx_lfc(struct wx *wx)
> +{
> +	struct wx_hw_stats *hwstats = &wx->stats;
> +	u64 data;
> +	int i;
> +
> +	if (wx->fc.mode != wx_fc_full &&
> +	    wx->fc.mode != wx_fc_rx_pause)
> +		return;
> +
> +	data = rd64(wx, WX_MAC_LXOFFRXC);

Is it possible that rd64() is reading a 32-bit register here?

Looking at wx_clear_hw_cntrs(), WX_MAC_LXOFFRXC is cleared using rd32().

If rd64() reads an adjacent unmapped address, could it populate the upper 32
bits of data with garbage?

> +	hwstats->lxoffrxc += data;
> +
> +	/* refill credits (no tx hang) if we received xoff */
> +	if (!data)
> +		return;
> +
> +	for (i = 0; i < wx->num_tx_queues; i++)
> +		clear_bit(WX_HANG_CHECK_ARMED,
> +			  wx->tx_ring[i]->state);
> +}

If data is populated with garbage from the upper 32 bits, would this bypass
the check for zero and unconditionally clear the WX_HANG_CHECK_ARMED bit on
all Tx queues, preventing the Tx hang recovery watchdog from operating?

>  /**
>   * wx_update_stats - Update the board statistics counters.
>   * @wx: board private structure
> @@ -2844,6 +2877,10 @@ void wx_update_stats(struct wx *wx)
>  	u64 restart_queue = 0, tx_busy = 0;
>  	u32 i;
>  
> +	if (!netif_running(wx->netdev) ||
> +	    test_bit(WX_STATE_RESETTING, wx->state))
> +		return;
> +

Does this early return cause the final hardware statistics to be lost on
interface teardown?

Since the explicit wx_update_stats() calls were removed from
ngbe_disable_device() and txgbe_disable_device(), and the interface is
marked down before hardware disablement completes, it seems any statistics
accumulated since the last periodic service task will be lost when the
registers are cleared on reset.

[ ... ]
> @@ -2893,7 +2932,10 @@ void wx_update_stats(struct wx *wx)
>  	hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L);
>  	hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD);
>  	hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD);
> -	hwstats->lxonoffrxc += rd32(wx, WX_MAC_LXONOFFRXC);
> +	if (wx->mac.type >= wx_mac_aml)
> +		hwstats->lxonrxc = rd32(wx, WX_MAC_LXONRXC_AML);

Will this 64-bit software statistic wrap back to zero when the hardware
counter overflows?

As seen in wx_clear_hw_cntrs(), WX_MAC_LXONRXC_AML is cleared by writing 0:

    wr32(wx, WX_MAC_LXONRXC_AML, 0);

This suggests it is a continuous 32-bit hardware counter rather than
clear-on-read. Direct assignment might break the monotonic property expected
by ethtool.

> +	else
> +		hwstats->lxonrxc += rd32(wx, WX_MAC_LXONRXC);
>  	hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC);
>  	hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC);
>  	hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT);
[ ... ]
> diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
> index b8db772c37c5c..080310a51ef86 100644
> --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
> +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
> @@ -150,6 +150,7 @@ static void ngbe_service_task(struct work_struct *work)
>  	struct wx *wx = container_of(work, struct wx, service_task);
>  
>  	wx_handle_errors_subtask(wx);
> +	wx_update_stats(wx);
>  
>  	wx_service_event_complete(wx);
>  }

Can this introduce data races with userspace ethtool callbacks?

The service task executes asynchronously without holding rtnl_lock, while
ethtool callbacks like wx_get_pause_stats() hold rtnl_lock() and also call
wx_update_stats().

This might lead to double-reads of clear-on-read hardware registers and
lost software counter increments.

Also, could this cause a concurrency issue during interface teardown?

During reconfiguration, ngbe_close() deletes the service timer but does not
call cancel_work_sync(&wx->service_task).

If the service task runs concurrently with wx_clear_interrupt_scheme(),
it might bypass early return checks and access wx->tx_ring[i] while it
is being freed and set to NULL, potentially causing a use-after-free or
NULL pointer dereference.

[ ... ]
> diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
> index d4f87fbb95655..e9439e4ebe61e 100644
> --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
> +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
> @@ -132,6 +132,7 @@ static void txgbe_service_task(struct work_struct *work)
>  	wx_handle_errors_subtask(wx);
>  	txgbe_module_detection_subtask(wx);
>  	txgbe_link_config_subtask(wx);
> +	wx_update_stats(wx);
>  
>  	wx_service_event_complete(wx);
>  }

(Same questions apply to txgbe_service_task regarding data races and
teardown concurrency.)

[ ... ]

  reply	other threads:[~2026-03-31  0:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-26  2:13 [PATCH net-next v6 00/11] Wangxun improvement and new support Jiawen Wu
2026-03-26  2:13 ` [PATCH net-next v6 01/11] net: ngbe: remove netdev->ethtool->wol_enabled setting Jiawen Wu
2026-03-26  2:13 ` [PATCH net-next v6 02/11] net: ngbe: move the WOL functions to libwx Jiawen Wu
2026-03-26  2:13 ` [PATCH net-next v6 03/11] net: ngbe: remove redundant macros Jiawen Wu
2026-03-26  2:13 ` [PATCH net-next v6 04/11] net: ngbe: implement libwx reset ops Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-31  7:19     ` Jiawen Wu
2026-03-31 13:03       ` Andrew Lunn
2026-03-31 23:05       ` Jacob Keller
2026-03-26  2:14 ` [PATCH net-next v6 05/11] net: wangxun: move reusable PCI driver ops functions into libwx Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-26  2:14 ` [PATCH net-next v6 06/11] net: txgbe: add power management support Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-26  2:14 ` [PATCH net-next v6 07/11] net: wangxun: move ethtool_ops.set_channels into libwx Jiawen Wu
2026-03-26  2:14 ` [PATCH net-next v6 08/11] net: wangxun: delete service_timer before cancel service_work Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-26  2:14 ` [PATCH net-next v6 09/11] net: wangxun: add Tx timeout process Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-26  2:14 ` [PATCH net-next v6 10/11] net: wangxun: improve flow control setting Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski [this message]
2026-03-26  2:14 ` [PATCH net-next v6 11/11] net: wangxun: implement pci_error_handlers ops Jiawen Wu
2026-03-31  0:55   ` Jakub Kicinski
2026-03-31  0:54 ` [PATCH net-next v6 00/11] Wangxun improvement and new support Jakub Kicinski

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=20260331005549.3459818-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=abdun.nihaal@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jacob.e.keller@intel.com \
    --cc=jiawenwu@trustnetic.com \
    --cc=joe@dama.to \
    --cc=kees@kernel.org \
    --cc=larysa.zaremba@intel.com \
    --cc=leitao@debian.org \
    --cc=linux@armlinux.org.uk \
    --cc=mengyuanlou@net-swift.com \
    --cc=michal.swiatkowski@linux.intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=richardcochran@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox