All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michał Pecio" <michal.pecio@gmail.com>
To: quic_faisalh@quicinc.com
Cc: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
	linux-usb@vger.kernel.org, mathias.nyman@intel.com,
	stable@vger.kernel.org
Subject: Re: [PATCH] xhci: Fix Link TRB DMA in command ring stopped completion event
Date: Sat, 19 Oct 2024 09:20:23 +0200	[thread overview]
Message-ID: <20241019092023.5d987d7e@foxbook> (raw)
In-Reply-To: <20241018195953.12315-1-quic_faisalh@quicinc.com>

Hi,

> During the aborting of a command, the software receives a command
> completion event for the command ring stopped, with the TRB pointing
> to the next TRB after the aborted command.
>
> If the command we abort is located just before the Link TRB in the
> command ring, then during the 'command ring stopped' completion event,
> the xHC gives the Link TRB in the event's cmd DMA, which causes a
> mismatch in handling command completion event.
>
> To handle this situation, an additional check has been added to ignore
> the mismatch error and continue the operation.

Thanks, I remember having some issues with command aborts, but I blamed
them on my own bugs, although I never found what the problem was. I may
take a look at it later, but I'm currently busy with other things.

No comment about validity of this patch for now, but a few remarks:

>+static bool is_dma_link_trb(struct xhci_ring *ring, dma_addr_t dma)
>+{
>+	struct xhci_segment *seg;
>+	union xhci_trb *trb;
>+	dma_addr_t trb_dma;
>+	int i;
>+
>+	seg = ring->first_seg;
>+	do {
>+		for (i = 0; i < TRBS_PER_SEGMENT; i++) {
>+			trb = &seg->trbs[i];
>+			trb_dma = seg->dma + (i * sizeof(union xhci_trb));
>+
>+			if (trb_is_link(trb) && trb_dma == dma)
>+				return true;
>+		}

You don't need to iterate the array. Something like this should work:
do {
	if (in_range(dma, seg->dma, TRB_SEGMENT_SIZE)) {
		/* found the TRB, check if it's link */
		trb = &seg->trbs[(dma - seg->dma) / sizeof(*trb)];
		return trb_is_link(trb);
	}
	// try next seg, while (blah blah), return false

We should probably have a helper for (ring, dma)->trb lookups, but
for stable it may be sensible to do it without excess complication.

>+	if ((!cmd_dequeue_dma || cmd_dma != (u64)cmd_dequeue_dma) &&
>+	    !(cmd_comp_code == COMP_COMMAND_RING_STOPPED &&
>+	      is_dma_link_trb(xhci->cmd_ring, cmd_dma))) {

This if statement is quite complex now. I would be tempted to write
it this way instead:

/* original comment */
if (cmd_dma != dequeue_dma) {
	/* your new comment */
	if (! (RING_STOPPED && is_link)) {
		warn();
		return;
	}
}

Regards,
Michal

  parent reply	other threads:[~2024-10-19  7:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-18 19:59 [PATCH] xhci: Fix Link TRB DMA in command ring stopped completion event Faisal Hassan
2024-10-19  6:34 ` Greg Kroah-Hartman
2024-10-19 17:23   ` Faisal Hassan
2024-10-19  7:20 ` Michał Pecio [this message]
2024-10-19 17:52   ` Faisal Hassan

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=20241019092023.5d987d7e@foxbook \
    --to=michal.pecio@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=quic_faisalh@quicinc.com \
    --cc=stable@vger.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.