From: Martin Habets <mhabets@solarflare.com>
To: Edward Cree <ecree@solarflare.com>
Cc: <linux-net-drivers@solarflare.com>, <tglx@linutronix.de>,
<linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>
Subject: Re: [RFC PATCH net-next] sfc: replace in_interrupt() usage
Date: Tue, 29 Sep 2020 10:39:00 +0100 [thread overview]
Message-ID: <20200929093900.GA744783@mh-desktop> (raw)
In-Reply-To: <e45d9556-2759-6f33-01a0-d1739ce5760d@solarflare.com>
On Mon, Sep 28, 2020 at 09:05:52PM +0100, Edward Cree wrote:
> efx_ef10_try_update_nic_stats_vf() used in_interrupt() to figure out
> whether it is safe to sleep (for MCDI) or not.
> The only caller from which it was not is efx_net_stats(), which can be
> invoked under dev_base_lock from net-sysfs::netstat_show().
> So add a new update_stats_atomic() method to struct efx_nic_type, and
> call it from efx_net_stats(), removing the need for
> efx_ef10_try_update_nic_stats_vf() to behave differently for this case
> (which it wasn't doing correctly anyway).
> For all nic_types other than EF10 VF, this method is NULL and so we
> call the regular update_stats() methods, which are happy with being
> called from atomic contexts.
>
> Fixes: f00bf2305cab ("sfc: don't update stats on VF when called in atomic context")
> Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Edward Cree <ecree@solarflare.com>
Reviewed-by: Martin Habets <mhabets@solarflare.com>
> ---
> Only compile-tested so far, because I'm waiting for my kernel to
> finish rebuilding with CONFIG_DEBUG_ATOMIC_SLEEP which I'm hoping
> is the right thing to detect the bug in the existing code.
> I also wasn't quite sure how to give credit to the thorough analysis
> in the commit message of Sebastian's patch. I don't think we have
> a Whatever-by: tag to cover that, do we?
> And this doesn't include your GFP_KERNEL change, which should
> probably go in separately if you take this.
>
> drivers/net/ethernet/sfc/ef10.c | 22 +++++++++++++---------
> drivers/net/ethernet/sfc/efx_common.c | 2 +-
> drivers/net/ethernet/sfc/net_driver.h | 5 +++++
> drivers/net/ethernet/sfc/nic_common.h | 7 +++++++
> 4 files changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
> index c9df2e96ebe4..b702ba5986dc 100644
> --- a/drivers/net/ethernet/sfc/ef10.c
> +++ b/drivers/net/ethernet/sfc/ef10.c
> @@ -1871,15 +1871,6 @@ static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx)
>
> spin_unlock_bh(&efx->stats_lock);
>
> - if (in_interrupt()) {
> - /* If in atomic context, cannot update stats. Just update the
> - * software stats and return so the caller can continue.
> - */
> - spin_lock_bh(&efx->stats_lock);
> - efx_update_sw_stats(efx, stats);
> - return 0;
> - }
> -
> efx_ef10_get_stat_mask(efx, mask);
>
> rc = efx_nic_alloc_buffer(efx, &stats_buf, dma_len, GFP_ATOMIC);
> @@ -1938,6 +1929,18 @@ static size_t efx_ef10_update_stats_vf(struct efx_nic *efx, u64 *full_stats,
> return efx_ef10_update_stats_common(efx, full_stats, core_stats);
> }
>
> +static size_t efx_ef10_update_stats_atomic_vf(struct efx_nic *efx, u64 *full_stats,
> + struct rtnl_link_stats64 *core_stats)
> +{
> + struct efx_ef10_nic_data *nic_data = efx->nic_data;
> +
> + /* In atomic context, cannot update HW stats. Just update the
> + * software stats and return so the caller can continue.
> + */
> + efx_update_sw_stats(efx, nic_data->stats);
> + return efx_ef10_update_stats_common(efx, full_stats, core_stats);
> +}
> +
> static void efx_ef10_push_irq_moderation(struct efx_channel *channel)
> {
> struct efx_nic *efx = channel->efx;
> @@ -3998,6 +4001,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
> .finish_flr = efx_port_dummy_op_void,
> .describe_stats = efx_ef10_describe_stats,
> .update_stats = efx_ef10_update_stats_vf,
> + .update_stats_atomic = efx_ef10_update_stats_atomic_vf,
> .start_stats = efx_port_dummy_op_void,
> .pull_stats = efx_port_dummy_op_void,
> .stop_stats = efx_port_dummy_op_void,
> diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
> index c256db241570..72a3f0e09f52 100644
> --- a/drivers/net/ethernet/sfc/efx_common.c
> +++ b/drivers/net/ethernet/sfc/efx_common.c
> @@ -602,7 +602,7 @@ void efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats)
> struct efx_nic *efx = netdev_priv(net_dev);
>
> spin_lock_bh(&efx->stats_lock);
> - efx->type->update_stats(efx, NULL, stats);
> + efx_nic_update_stats_atomic(efx, NULL, stats);
> spin_unlock_bh(&efx->stats_lock);
> }
>
> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
> index 47aa753e64bd..9f7dfdf708cf 100644
> --- a/drivers/net/ethernet/sfc/net_driver.h
> +++ b/drivers/net/ethernet/sfc/net_driver.h
> @@ -1172,6 +1172,9 @@ struct efx_udp_tunnel {
> * @describe_stats: Describe statistics for ethtool
> * @update_stats: Update statistics not provided by event handling.
> * Either argument may be %NULL.
> + * @update_stats_atomic: Update statistics while in atomic context, if that
> + * is more limiting than @update_stats. Otherwise, leave %NULL and
> + * driver core will call @update_stats.
> * @start_stats: Start the regular fetching of statistics
> * @pull_stats: Pull stats from the NIC and wait until they arrive.
> * @stop_stats: Stop the regular fetching of statistics
> @@ -1316,6 +1319,8 @@ struct efx_nic_type {
> size_t (*describe_stats)(struct efx_nic *efx, u8 *names);
> size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats,
> struct rtnl_link_stats64 *core_stats);
> + size_t (*update_stats_atomic)(struct efx_nic *efx, u64 *full_stats,
> + struct rtnl_link_stats64 *core_stats);
> void (*start_stats)(struct efx_nic *efx);
> void (*pull_stats)(struct efx_nic *efx);
> void (*stop_stats)(struct efx_nic *efx);
> diff --git a/drivers/net/ethernet/sfc/nic_common.h b/drivers/net/ethernet/sfc/nic_common.h
> index 82271f0b8627..b9cafe9cd568 100644
> --- a/drivers/net/ethernet/sfc/nic_common.h
> +++ b/drivers/net/ethernet/sfc/nic_common.h
> @@ -244,6 +244,13 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
> const unsigned long *mask, u64 *stats,
> const void *dma_buf, bool accumulate);
> void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *stat);
> +static inline size_t efx_nic_update_stats_atomic(struct efx_nic *efx, u64 *full_stats,
> + struct rtnl_link_stats64 *core_stats)
> +{
> + if (efx->type->update_stats_atomic)
> + return efx->type->update_stats_atomic(efx, full_stats, core_stats);
> + return efx->type->update_stats(efx, full_stats, core_stats);
> +}
>
> #define EFX_MAX_FLUSH_TIME 5000
>
--
Martin Habets <mhabets@solarflare.com>
next prev parent reply other threads:[~2020-09-29 9:46 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-27 19:48 [patch 00/35] net: in_interrupt() cleanup and fixes Thomas Gleixner
2020-09-27 19:48 ` [patch 01/35] net: enic: Cure the enic api locking trainwreck Thomas Gleixner
2020-09-27 19:48 ` [patch 02/35] net: caif: Remove unused caif SPI driver Thomas Gleixner
2020-09-27 19:48 ` [patch 03/35] net: Add netif_rx_any_context() Thomas Gleixner
2020-09-27 19:48 ` [patch 04/35] net: caif: Use netif_rx_any_context() Thomas Gleixner
2020-09-27 19:48 ` [patch 05/35] net: atheros: Remove WARN_ON(in_interrupt()) Thomas Gleixner
2020-09-27 19:48 ` [patch 06/35] net: cxgb3: Cleanup in_interrupt() usage Thomas Gleixner
2020-09-27 19:48 ` [patch 07/35] net: cxbg4: Remove pointless in_interrupt() check Thomas Gleixner
2020-09-27 19:48 ` [patch 08/35] net: e100: Remove in_interrupt() usage and pointless GFP_ATOMIC allocation Thomas Gleixner
2020-09-27 19:48 ` [patch 09/35] net: fec_mpc52xx: Replace in_interrupt() usage Thomas Gleixner
2020-09-27 19:48 ` [patch 10/35] net: intel: Remove in_interrupt() warnings Thomas Gleixner
2020-09-28 23:04 ` Alexander Duyck
2020-09-27 19:48 ` [patch 11/35] net: ionic: Replace in_interrupt() usage Thomas Gleixner
2020-09-28 17:24 ` Shannon Nelson
2020-09-28 19:51 ` Shannon Nelson
2020-09-29 14:37 ` Thomas Gleixner
2020-09-27 19:48 ` [patch 12/35] net: ionic: Remove WARN_ON(in_interrupt()) Thomas Gleixner
2020-09-28 17:26 ` Shannon Nelson
2020-09-27 19:48 ` [patch 13/35] net: mdiobus: Remove WARN_ON_ONCE(in_interrupt()) Thomas Gleixner
2020-09-27 23:00 ` Andrew Lunn
2020-09-27 19:49 ` [patch 14/35] net: natsemi: Replace in_interrupt() usage Thomas Gleixner
2020-09-27 19:49 ` [patch 15/35] net: sfc: " Thomas Gleixner
2020-09-28 19:03 ` Edward Cree
2020-09-28 20:05 ` [RFC PATCH net-next] sfc: replace " Edward Cree
2020-09-28 20:24 ` Thomas Gleixner
2020-09-29 15:15 ` Edward Cree
2020-09-29 19:27 ` Thomas Gleixner
2020-09-29 9:39 ` Martin Habets [this message]
2020-09-27 19:49 ` [patch 16/35] net: sunbmac: Replace " Thomas Gleixner
2020-09-27 19:49 ` [patch 17/35] net: sun3lance: Remove redundant checks in interrupt handler Thomas Gleixner
2020-09-27 19:49 ` [patch 18/35] net: vxge: Remove in_interrupt() conditionals Thomas Gleixner
2020-09-27 19:49 ` [patch 19/35] net: zd1211rw: Remove ZD_ASSERT(in_interrupt()) Thomas Gleixner
2020-09-27 19:49 ` [patch 20/35] net: usb: kaweth: Replace kaweth_control() with usb_control_msg() Thomas Gleixner
2020-09-27 19:49 ` [patch 21/35] net: usb: kaweth: Remove last user of kaweth_control() Thomas Gleixner
2020-09-28 6:50 ` Greg Kroah-Hartman
2020-09-27 19:49 ` [patch 22/35] net: usb: net1080: Remove in_interrupt() comment Thomas Gleixner
2020-09-27 19:49 ` [patch 23/35] net: wan/lmc: Remove lmc_trace() Thomas Gleixner
2020-09-27 19:49 ` [patch 24/35] net: brcmfmac: Replace in_interrupt() Thomas Gleixner
2020-09-28 7:35 ` Arend Van Spriel
2020-09-28 9:19 ` Ulf Hansson
2020-09-28 9:37 ` Arend Van Spriel
2020-09-28 9:40 ` Arend Van Spriel
2020-09-27 19:49 ` [patch 25/35] net: brcmfmac: Use netif_rx_any_context() Thomas Gleixner
2020-09-28 8:03 ` Arend Van Spriel
2020-09-27 19:49 ` [patch 26/35] net: brcmfmac: Convey allocation mode as argument Thomas Gleixner
2020-09-28 9:34 ` Arend Van Spriel
2020-09-27 19:49 ` [patch 27/35] net: ipw2x00,iwlegacy,iwlwifi: Remove in_interrupt() from debug macros Thomas Gleixner
2020-09-27 19:49 ` [patch 28/35] net: iwlwifi: Remove in_interrupt() from tracing macro Thomas Gleixner
2020-09-28 6:13 ` Coelho, Luciano
2020-09-27 19:49 ` [patch 29/35] net: hostap: Remove in_interrupt() usage Thomas Gleixner
2020-09-27 19:49 ` [patch 30/35] net: mwifiex: Use netif_rx_any_context() Thomas Gleixner
2020-09-27 19:49 ` [patch 31/35] net: libertas libertas_tf: Remove in_interrupt() from debug macro Thomas Gleixner
2020-09-27 19:49 ` [patch 32/35] net: libertas: Use netif_rx_any_context() Thomas Gleixner
2020-09-27 19:49 ` [patch 33/35] net: rtlwifi: Remove void* casts related to delayed work Thomas Gleixner
2020-09-27 19:49 ` [patch 34/35] net: rtlwifi: Remove in_interrupt() from debug macro Thomas Gleixner
2020-09-27 19:49 ` [patch 35/35] net: rtlwifi: Replace in_interrupt() for context detection Thomas Gleixner
2020-09-27 20:22 ` [patch 00/35] net: in_interrupt() cleanup and fixes Joe Perches
2020-09-27 20:57 ` David Miller
2020-09-28 10:25 ` Thomas Gleixner
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=20200929093900.GA744783@mh-desktop \
--to=mhabets@solarflare.com \
--cc=ecree@solarflare.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-net-drivers@solarflare.com \
--cc=netdev@vger.kernel.org \
--cc=tglx@linutronix.de \
/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;
as well as URLs for NNTP newsgroup(s).