mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Vidya Sagar <vidyas@nvidia.com>
To: bhelgaas@google.com, tglx@kernel.org, wangruikang@iscas.ac.cn,
	Frank.Li@nxp.com, lihaoxiang@isrc.iscas.ac.cn,
	18255117159@163.com, shawn.lin@rock-chips.com,
	xiangzao@linux.alibaba.com
Cc: vsethi@nvidia.com, sdonthineni@nvidia.com, kthota@nvidia.com,
	mmaddireddy@nvidia.com, kumarahul@nvidia.com, sagar.tv@gmail.com,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH V4] PCI/MSI: Skip MSI/MSI-X programming while the channel is offline
Date: Wed, 30 Sep 2026 18:27:06 +0530	[thread overview]
Message-ID: <20b95005-9fa4-4864-8eb6-f90baf98216e@nvidia.com> (raw)
In-Reply-To: <20260909164908.2562818-1-vidyas@nvidia.com>

On 09-09-2026 22:19, Vidya Sagar wrote:
> The MSI-X Table lives in device MMIO space behind a BAR and the MSI Mask
> register in Configuration Space, so neither is reachable while the Link
> is down. While a Downstream Port has the Link contained by DPC it
> completes these accesses with Unsupported Request, and reads return all
> ones.
> 
> If the upstream Root Port implements the RP Extensions for DPC, it
> additionally reports that UR completion as an RP PIO error and triggers a
> second containment event, this time at the Root Port, which contains
> every device below it. So a contained Link on one Downstream Port turns
> into a far wider outage that takes down unrelated devices.
> 
> pci_free_irq_vectors() is called from driver error_detected() and
> prepare-for-reset callbacks, i.e. while the Link is contained and before
> the reset and the pci_restore_state() that follows it, and it masks every
> descriptor. Skip the programming when pci_channel_offline(), which also
> covers surprise removal. The msix_ctrl and msi_mask caches are still
> updated, so the restore paths replay the intended state once the Link is
> back up, and report_slot_reset() clears the offline state before the
> driver callback runs, so recovery is unaffected.
> pci_msix_write_tph_tag() flushes its Vector Control update with an
> unconditional read, so return -EIO there rather than issue it for a write
> that was skipped; the caller disables TPH in response. error_state is
> only set once containment has occurred, so this covers the case where the
> kernel knows the Link is down; it is not mutual exclusion against a
> containment event that begins concurrently.
> 
> This does not attempt to make every Configuration Space access safe
> while the Link is contained.
> 
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> Changes in v4:
> - Drop the pci_msi_dev_inaccessible() helper and use the existing
>   pci_channel_offline() instead. It is the same predicate, and the
>   pci_dev_is_disconnected() half was redundant because error_state !=
>   pci_channel_io_normal already covers pci_channel_io_perm_failure.
> - Also skip the Mask register write in pci_msi_update_mask(), so legacy
>   MSI below a contained Downstream Port is covered and not just MSI-X.
>   Subject and log updated accordingly.
> 
> Changes in v3:
> - Move the pci_msi_dev_inaccessible() check in pci_msix_write_tph_tag()
>   under irq_desc::lock, next to the accesses it guards, instead of before
>   msi_descs_lock which can sleep (reported by Sashiko AI review).
> 
> Changes in v2:
> - Return -EIO from pci_msix_write_tph_tag() so its unconditional flush
>   read is not issued for a skipped write (reported by Sashiko AI review).
> - Rename pci_msix_mmio_unsafe() to pci_msi_dev_inaccessible(), since in
>   __pci_write_msi_msg() it also gates the Configuration Space MSI path.
> - Note in the log why MSI-X restore during recovery is unaffected.
> 
>  drivers/pci/msi/msi.c | 15 +++++++++++++--
>  drivers/pci/msi/msi.h |  8 ++++++++
>  2 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
> index 80a9db417dc8..8a0133a6a286 100644
> --- a/drivers/pci/msi/msi.c
> +++ b/drivers/pci/msi/msi.c
> @@ -133,7 +133,9 @@ void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set)
>  	raw_spin_lock_irqsave(lock, flags);
>  	desc->pci.msi_mask &= ~clear;
>  	desc->pci.msi_mask |= set;
> -	pci_write_config_dword(dev, desc->pci.mask_pos, desc->pci.msi_mask);
> +	/* Cached either way, for __pci_restore_msi_state() to replay */
> +	if (!pci_channel_offline(dev))
> +		pci_write_config_dword(dev, desc->pci.mask_pos, desc->pci.msi_mask);
>  	raw_spin_unlock_irqrestore(lock, flags);
>  }
>  
> @@ -249,7 +251,7 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>  {
>  	struct pci_dev *dev = msi_desc_to_pci_dev(entry);
>  
> -	if (dev->current_state != PCI_D0 || pci_dev_is_disconnected(dev)) {
> +	if (dev->current_state != PCI_D0 || pci_channel_offline(dev)) {
>  		/* Don't touch the hardware now */
>  	} else if (entry->pci.msi_attrib.is_msix) {
>  		pci_write_msg_msix(entry, msg);
> @@ -976,6 +978,15 @@ int pci_msix_write_tph_tag(struct pci_dev *pdev, unsigned int index, u16 tag)
>  	if (!msi_desc || msi_desc->pci.msi_attrib.is_virtual)
>  		return -ENXIO;
>  
> +	/*
> +	 * The tag update below is a write to the MSI-X Table followed by a
> +	 * flush read, neither of which can be completed while the Link is
> +	 * down. Check as late as possible, as the Link can go down at any
> +	 * point. Let the caller disable TPH.
> +	 */
> +	if (pci_channel_offline(pdev))
> +		return -EIO;
> +
>  	FIELD_MODIFY(PCI_MSIX_ENTRY_CTRL_ST, &msi_desc->pci.msix_ctrl, tag);
>  	pci_msix_write_vector_ctrl(msi_desc, msi_desc->pci.msix_ctrl);
>  	/* Flush the write */
> diff --git a/drivers/pci/msi/msi.h b/drivers/pci/msi/msi.h
> index 0b420b319f50..f987cf897264 100644
> --- a/drivers/pci/msi/msi.h
> +++ b/drivers/pci/msi/msi.h
> @@ -36,6 +36,10 @@ static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl)
>  {
>  	void __iomem *desc_addr = pci_msix_desc_addr(desc);
>  
> +	/* The Table is unreachable while the Link is down */
> +	if (pci_channel_offline(msi_desc_to_pci_dev(desc)))
> +		return;
> +
>  	if (desc->pci.msi_attrib.can_mask)
>  		writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
>  }
> @@ -43,6 +47,10 @@ static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl)
>  static inline void pci_msix_mask(struct msi_desc *desc)
>  {
>  	desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
> +
> +	if (pci_channel_offline(msi_desc_to_pci_dev(desc)))
> +		return;
> +
>  	pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl);
>  	/* Flush write to device */
>  	readl(desc->pci.mask_base);

Any further comments on this patch?

Thanks,
Vidya Sagar

      reply	other threads:[~2026-09-30 12:57 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 19:56 [PATCH V1] PCI/MSI: Don't touch the MSI-X table while the Link is contained Vidya Sagar
2026-08-25 14:09 ` [PATCH V2] " Vidya Sagar
2026-08-25 17:27   ` [PATCH V3] " Vidya Sagar
2026-09-09 16:49     ` [PATCH V4] PCI/MSI: Skip MSI/MSI-X programming while the channel is offline Vidya Sagar
2026-09-30 12:57       ` Vidya Sagar [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=20b95005-9fa4-4864-8eb6-f90baf98216e@nvidia.com \
    --to=vidyas@nvidia.com \
    --cc=18255117159@163.com \
    --cc=Frank.Li@nxp.com \
    --cc=bhelgaas@google.com \
    --cc=kthota@nvidia.com \
    --cc=kumarahul@nvidia.com \
    --cc=lihaoxiang@isrc.iscas.ac.cn \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mmaddireddy@nvidia.com \
    --cc=sagar.tv@gmail.com \
    --cc=sdonthineni@nvidia.com \
    --cc=shawn.lin@rock-chips.com \
    --cc=tglx@kernel.org \
    --cc=vsethi@nvidia.com \
    --cc=wangruikang@iscas.ac.cn \
    --cc=xiangzao@linux.alibaba.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

all inboxes | Powered by JetHome®