All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Pecio <michal.pecio@gmail.com>
To: Niklas Neronin <niklas.neronin@linux.intel.com>
Cc: mathias.nyman@linux.intel.com, linux-usb@vger.kernel.org
Subject: Re: [PATCH 2/5] usb: xhci: correct num_active_eps accounting on allocation failure
Date: Tue, 6 Oct 2026 23:02:07 +0200	[thread overview]
Message-ID: <20261006230207.0faaac31.michal.pecio@gmail.com> (raw)
In-Reply-To: <20261006183301.7a1875c3.michal.pecio@gmail.com>

On Tue, 6 Oct 2026 18:33:01 +0200, Michal Pecio wrote:
> On Tue,  6 Oct 2026 17:24:24 +0200, Niklas Neronin wrote:
> > Some host controllers have a global endpoint limit across all slots,
> > tracked by 'xhci->num_active_eps' when XHCI_EP_LIMIT_QUIRK is set.
> > 
> > During device allocation, EP0 resources are reserved before
> > xhci_alloc_virt_device() is called, and 'num_active_eps' is
> > incremented accordingly. If xhci_alloc_virt_device() subsequently
> > fails, the slot is disabled but the reserved endpoint resource is
> > not released, leaving 'num_active_eps' permanently increased.
> > 
> > Decreasing 'num_active_eps' happens in
> > xhci_handle_cmd_disable_slot(), which is called upon a Disable Slot
> > completion command.  
> 
> Why is 'num_active_eps' not decremented if the slot is disabled and
> Disable Slot completion handler is supposed to decrement it?
> 
> Does this bug really exist? Can you reproduce it by forcing the quirk
> with module parameter and simulating vdev allocation failure here?

Never mind, the bug is real and reproducible. Still, commit message
could include a few words of explanation to prevent such questions.

I think it would be cleaner to fix this by allocating vdev before
ep0 reservation, because allocation is easier to undo:

1. we have a helper for this, no need to dig in xhci members manually
2. we are the only user of this slot_id, so locking is not required

Downside: larger diff. But less code in the end.

And there is another bug: disable_slot uses udev->slot_id, which is
uninitialized in this path. Should use the local slot_id variable.

So overall,

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e5b39be04b92..9beb8b4b485f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4308,27 +4308,29 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 
 	xhci_free_command(xhci, command);
 
+	/* Use GFP_NOIO, since this function can be called from
+	 * xhci_discover_or_reset_device(), which may be called as part of
+	 * mass storage driver error handling.
+	 */
+	if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) {
+		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
+		goto disable_slot;
+	}
+	vdev = xhci->devs[slot_id];
+
 	if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) {
 		spin_lock_irqsave(&xhci->lock, flags);
 		ret = xhci_reserve_host_control_ep_resources(xhci);
+		spin_unlock_irqrestore(&xhci->lock, flags);
 		if (ret) {
-			spin_unlock_irqrestore(&xhci->lock, flags);
 			xhci_warn(xhci, "Not enough host resources, "
 					"active endpoint contexts = %u\n",
 					xhci->num_active_eps);
+			xhci_free_virt_device(xhci, vdev, slot_id);
+			/* without vdev disable slot won't free ep0 resources */
 			goto disable_slot;
 		}
-		spin_unlock_irqrestore(&xhci->lock, flags);
 	}
-	/* Use GFP_NOIO, since this function can be called from
-	 * xhci_discover_or_reset_device(), which may be called as part of
-	 * mass storage driver error handling.
-	 */
-	if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) {
-		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-		goto disable_slot;
-	}
-	vdev = xhci->devs[slot_id];
 	slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
 	trace_xhci_alloc_dev(slot_ctx);
 
@@ -4348,7 +4350,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	return 1;
 
 disable_slot:
-	xhci_disable_and_free_slot(xhci, udev->slot_id);
+	xhci_disable_slot(xhci, slot_id);
 
 	return 0;
 }

  reply	other threads:[~2026-10-06 21:02 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06 15:24 [PATCH 0/5] usb: xhci: bandwidth accounting fixes and cleanup Niklas Neronin
2026-10-06 15:24 ` [PATCH 1/5] usb: xhci: clear stale bandwidth data after hibernation Niklas Neronin
2026-10-06 16:12   ` Michal Pecio
2026-10-06 16:22   ` sashiko-bot
2026-10-06 15:24 ` [PATCH 2/5] usb: xhci: correct num_active_eps accounting on allocation failure Niklas Neronin
2026-10-06 16:29   ` sashiko-bot
2026-10-06 16:33   ` Michal Pecio
2026-10-06 21:02     ` Michal Pecio [this message]
2026-10-07  9:28       ` Neronin, Niklas
2026-10-06 15:24 ` [PATCH 3/5] usb: xhci: remove redundant TT active EP update from xhci_free_virt_device() Niklas Neronin
2026-10-06 16:41   ` sashiko-bot
2026-10-06 15:24 ` [PATCH 4/5] usb: xhci: correct variable size conversion Niklas Neronin
2026-10-06 16:46   ` sashiko-bot
2026-10-06 15:24 ` [PATCH 5/5] usb: xhci: remove unused structs Niklas Neronin
2026-10-06 16:47   ` sashiko-bot

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=20261006230207.0faaac31.michal.pecio@gmail.com \
    --to=michal.pecio@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@linux.intel.com \
    --cc=niklas.neronin@linux.intel.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 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.