Linux USB
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yaohan Li" <shunsheng1218@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH v3] usb: typec: tcpci: filter masked alerts and quiesce the IRQ
Date: Thu, 12 Nov 2026 08:56:34 +0000	[thread overview]
Message-ID: <sashiko-outbox-210802@kernel.org> (raw)
In-Reply-To: <20261112084014.2564834-1-shunsheng1218@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] usb: typec: tcpci: masking status before clearing TCPC_ALERT
  causes IRQ storm
- [Medium] usb: typec: tcpci: zeroing alert_mask before hardware mask
  write causes IRQ storm
--

commit 3b5f8c5cf280be1359b54eb345cc21c55eeb3247
Author: Yaohan Li <shunsheng1218@gmail.com>

usb: typec: tcpci: filter masked alerts and quiesce the IRQ

This commit filters TCPC_ALERT status bits with tcpci->alert_mask in
tcpci_irq() and adds an alerts_quiesced state and synchronize_irq() calls
to quiesce interrupts before unregistering the TCPM port on removal and
probe failure.

> diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> index c6165466c54b6..d413ebca75da2 100644
> --- a/drivers/usb/typec/tcpm/tcpci.c
> +++ b/drivers/usb/typec/tcpm/tcpci.c

[ ... ]

> @@ -722,8 +738,12 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
>  	int irq_ret;
>  	unsigned int raw;
>  
> +	if (!READ_ONCE(tcpci->alert_mask))
> +		return IRQ_NONE;
> +
>  	tcpci_read16(tcpci, TCPC_ALERT, &status);
> -	irq_ret = status & tcpci->alert_mask;
> +	status &= READ_ONCE(tcpci->alert_mask);
> +	irq_ret = status;
>  
>  process_status:
>  	/*

[Severity: High]
Can masking status with tcpci->alert_mask before writing TCPC_ALERT leave
hardware-enabled alerts latched and cause a level-triggered IRQ storm?

tcpci_init() never sets TCPC_ALERT_RX_BUF_OVF, TCPC_ALERT_FAULT or
TCPC_ALERT_VBUS_DISCNCT in tcpci->alert_mask, but vendor drivers that
delegate interrupt handling to tcpci_irq() unmask those bits in hardware:

drivers/usb/typec/tcpm/tcpci_rt1711h.c:rt1711h_probe() {
    ...
	const u16 alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED |
			       TCPC_ALERT_TX_FAILED | TCPC_ALERT_RX_HARD_RST |
			       TCPC_ALERT_RX_STATUS | TCPC_ALERT_POWER_STATUS |
			       TCPC_ALERT_CC_STATUS | TCPC_ALERT_RX_BUF_OVF |
			       TCPC_ALERT_FAULT;
    ...
	ret = rt1711h_write16(chip, TCPC_ALERT_MASK, alert_mask);
}

Previously, tcpci_write16(tcpci, TCPC_ALERT, status & ~TCPC_ALERT_RX_STATUS)
cleared any latched bit read from TCPC_ALERT.  With status masked by
tcpci->alert_mask first (and again after the re-read at the bottom of
tcpci_irq()), TCPC_ALERT_FAULT or TCPC_ALERT_RX_BUF_OVF is never written
back to TCPC_ALERT, so the active-low Alert# line stays asserted while
tcpci_irq() repeatedly returns IRQ_NONE until the spurious IRQ detector
disables the interrupt line.

[ ... ]

> @@ -988,10 +1013,19 @@ static void tcpci_remove(struct i2c_client *client)
>  	struct tcpci_chip *chip = i2c_get_clientdata(client);
>  	int err;
>  
> -	/* Disable chip interrupts before unregistering port */
> +	/*
> +	 * The port's kthread worker is destroyed by tcpci_unregister_port()
> +	 * below, while the threaded IRQ handler can still queue work on it.
> +	 * Publish a zero software mask first: tcpci_irq() then ignores any
> +	 * alert that is still latched, or asserted again on a shared IRQ,
> +	 * even if the hardware mask write fails.  synchronize_irq() waits
> +	 * for handlers that already read the old mask.
> +	 */
> +	tcpci_quiesce_alerts(chip->tcpci);
>  	err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
>  	if (err < 0)
>  		dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err));
> +	synchronize_irq(client->irq);
>  
>  	tcpci_unregister_port(chip->tcpci);
>  }

[Severity: Medium]
Can zeroing tcpci->alert_mask before masking TCPC_ALERT_MASK in hardware
trigger an unhandled IRQ storm if an alert fires during the I2C write?

CPU0                              irq/client->irq (SCHED_FIFO)
tcpci_remove()
  tcpci_quiesce_alerts()
    tcpci->alert_mask = 0
  tcpci_write16(..., TCPC_ALERT_MASK, 0)
    <blocks on I2C transfer>
                                  <Alert# asserted low>
                                  _tcpci_irq()
                                    tcpci_irq()
                                      if (!READ_ONCE(tcpci->alert_mask))
                                        return IRQ_NONE;
                                  irq_finalize_oneshot()
                                    <unmasks level-low IRQ line>
                                  <Alert# re-fires immediately>  <-- IRQ storm

While tcpci_write16() sleeps waiting for the I2C transfer, hardware
interrupts are still enabled in TCPC_ALERT_MASK.  Because tcpci_irq() now
returns IRQ_NONE immediately without sleeping on I2C or clearing
TCPC_ALERT, irq_finalize_oneshot() unmasks the level-triggered line with
Alert# still asserted low, spinning in the real-time IRQ thread until the
I2C write finishes or the spurious IRQ detector disables the shared IRQ.
Should TCPC_ALERT_MASK be cleared in hardware before calling
tcpci_quiesce_alerts()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261112084014.2564834-1-shunsheng1218@gmail.com?part=1

      reply	other threads:[~2026-11-12  8:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12  8:40 [PATCH v3] usb: typec: tcpci: filter masked alerts and quiesce the IRQ Yaohan Li
2026-11-12  8:56 ` sashiko-bot [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=sashiko-outbox-210802@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=shunsheng1218@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