All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arthur Crepin Leblond <arthur@marmottus.net>
To: netdev-bot+sashiko@kernel.org
Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, arnd@arndb.de,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v9 3/3] w5100: detect carrier state using link status bit and optional interrupt
Date: Wed, 23 Sep 2026 11:36:49 +0200	[thread overview]
Message-ID: <20260923093649.GA120572@marmottus.net> (raw)
In-Reply-To: <179009180606.2160803.9423654885662355459@kernel.org>

On Tue, Sep 22, 2026 at 03:43:26PM +0000, netdev-bot+sashiko@kernel.org wrote:
>[Severity: Medium]
> ...
>What is the intended split here - should w5100_tx_timeout() always queue
>restart_work now that w5100_restart() can sleep, or should the irq
>masking and the carrier re-check be done only in the may_sleep path?

schedule_work() will always be called (see v10).

>
>[Severity: Medium]
>The link irq is requested below with IRQF_NO_AUTOEN and
>IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, so it stays masked until this
>enable_irq(). PHYCFGR is sampled first and edge detection is only turned on
>afterwards:
>
>	w5500_report_carrier_state(ndev);	/* reads PHYCFGR */
>	enable_irq(priv->link_irq);		/* edge detection starts */
>
>If the PHY link comes up between those two steps, can that transition be
>lost for good? On the BCM2835 controller used in the binding's own example,
>masking disables edge detection and also discards latched events:
>
>drivers/pinctrl/bcm/pinctrl-bcm2835.c:
>	bcm2835_gpio_irq_config(pc, gpio, false);
>	/* Clear events that were latched prior to clearing event sources */
>	bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
>
>so unmasking does not replay the missed edge, and with a now stable LINKLED
>level the driver keeps reporting carrier off until the next physical link
>change.
>
>w5100_restart() and w5100_resume() use the same order, and restart follows a
>chip reset with PHY re-negotiation. The changelog lists this ordering as
>intentional ("enable the link irq after checking PHYCFGR") - would enabling
>the irq first and then reading PHYCFGR close the window?

Probably very unlikely to happen and more of an edge case but I can
enable link irq first.

>[Severity: High]
>flush_work(&priv->rx_work) now runs while socket 0 is still open, because
>w5100_hw_close() is called after it.
>
>w5100_rx_work() drains without a budget or a shutdown test:
>
>	while ((skb = w5100_rx_skb(priv->ndev)))
>		netif_rx(skb);
>
>and w5100_rx_skb() only returns NULL once the hardware receive buffer is
>observed empty:
>
>	u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR(priv));
>
>	if (rx_buf_len == 0)
>		return NULL;
>
>disable_irq(priv->irq) masks the host interrupt but does not stop the
>controller from filling its receive buffer. Each frame is drained with
>several synchronous SPI transfers, which is slower than line rate, so can
>sustained incoming traffic keep RX_RSR non-zero and make this flush_work()
>never return?
>
>ndo_stop runs with rtnl held, so an ip link set down would then stall all
>network configuration in an unkillable wait. w5100_remove() reaches the same
>path through unregister_netdev().
>
>Would calling w5100_hw_close() before flushing rx_work avoid this?
>
>> -	netif_carrier_off(ndev);
>> +
>> +	if (priv->link_irq > 0)  {
>> +		mutex_lock(&priv->link_lock);
>> +		netif_carrier_off(ndev);
>> +		mutex_unlock(&priv->link_lock);
>> +	}
>> +
>>  	netif_stop_queue(ndev);
>>  	napi_disable(&priv->napi);
>>  	return 0;
>>  }
>

Agreed, w5100_hw_close() should be called earlier.

>[Severity: Medium]
>The changelog states:
>
>  w5100_remove(), w5100_stop() and w5100_suspend() call
>  cancel_work_sync()/flush_work() to make sure there is no pending
>  work
>
>but w5100_suspend() only cancels restart_work here. setrx_work (queued with
>schedule_work() from w5100_set_rx_mode()), rx_work (queued on priv->xfer_wq
>from w5100_interrupt()) and tx_work (queued from w5100_start_tx()) are
>neither cancelled nor flushed, while w5100_stop() drains all four. Should
>the changelog be narrowed, or the suspend path made to match stop()?
>
>[Severity: High]
>Independently of the changelog wording, can these work items still touch the
>hardware after suspend has closed it?
>
>disable_irq(priv->irq) waits for the threaded handler w5100_interrupt() to
>finish, but any rx_work it already queued is still pending, and
>priv->xfer_wq is created with WQ_MEM_RECLAIM | WQ_PERCPU (no WQ_FREEZABLE),
>so it keeps running during suspend. w5100_rx_work() does SPI register
>accesses (S0_RX_RD writes and S0_CR_RECV) and ends with:
>
>	w5100_enable_intr(priv);
>
>which re-arms the chip interrupt masks that w5100_hw_close() cleared, while
>the host irq stays masked.
>
>setrx_work runs on system_wq and calls w5100_hw_start(), re-issuing
>S0_CR_OPEN and w5100_enable_intr() after suspend closed socket 0. tx_work
>can still issue S0_CR_SEND. Any of these transfers issued after the suspend
>callback returns are rejected once the SPI controller itself is suspended.
>
>There is also a re-queue window: restart_work is cancelled here, before
>netif_device_detach() below. In between, dev_watchdog() can still fire
>(netif_device_present(), netif_running() and netif_carrier_ok() all hold,
>and carrier_ok() is permanently true on w5100/w5200 and on a W5500 without a
>link irq):
>
>w5100_tx_timeout()
>	if (priv->ops->may_sleep)
>		schedule_work(&priv->restart_work);
>
>The re-queued w5100_restart() then passes its own netif_running() /
>netif_device_present() test and runs w5100_hw_reset() plus w5100_hw_start()
>against the device suspend is closing.
>
>Should netif_device_detach() come before the cancel, and should setrx_work,
>rx_work and tx_work be drained here as they are in w5100_stop()?

suspend() and resume() will call w5100_stop() and w5100_open()
directly.
And yes, netif_device_detach() will be called before.

Arthur

      reply	other threads:[~2026-09-23  9:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18 15:13 [PATCH net-next v9 0/3] w5100: restore GPIO-based link detection Arthur Crepin Leblond
2026-09-18 15:13 ` [PATCH net-next v9 1/3] dt-bindings: net: wiznet,w5100: convert to DT schema Arthur Crepin Leblond
2026-09-22 15:43   ` netdev-bot+sashiko
2026-09-23  9:12     ` Arthur Crepin Leblond
2026-09-18 15:13 ` [PATCH net-next v9 2/3] dt-bindings: net: wiznet,w5100: add link status interrupt Arthur Crepin Leblond
2026-09-18 15:13 ` [PATCH net-next v9 3/3] w5100: detect carrier state using link status bit and optional interrupt Arthur Crepin Leblond
2026-09-19 15:14   ` sashiko-bot
2026-09-21  9:04     ` Arthur Crepin Leblond
2026-09-21 10:42       ` Arthur Crepin Leblond
2026-09-22 15:43   ` netdev-bot+sashiko
2026-09-23  9:36     ` Arthur Crepin Leblond [this message]

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=20260923093649.GA120572@marmottus.net \
    --to=arthur@marmottus.net \
    --cc=andrew+netdev@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    /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.