From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Marco Tormento <mtormento80@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Alan Stern <stern@rowland.harvard.edu>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] usb: core: deattach child device from typec connector on port unbind
Date: Wed, 22 Jul 2026 19:02:28 +0300 [thread overview]
Message-ID: <amDplMXaf1JpxE0v@kuha> (raw)
In-Reply-To: <20260721202201.27442-1-mtormento80@gmail.com>
On Tue, Jul 21, 2026 at 10:22:01PM +0200, Marco Tormento wrote:
> connector_bind() tells the Type-C connector about a port's already
> attached child via typec_attach(), but connector_unbind() has no
> mirror image: it drops port_dev->connector without deattaching a
> still-present child first. When that happens, port->usb2_dev (or
> usb3_dev) in the Type-C port is left pointing at a device that is
> about to be torn down, and typec_partner_deattach() never runs for
> it.
>
> This shows up on hardware where a single Type-C connector's component
> aggregate spans ports on more than one USB root hub sharing an xHCI
> controller (e.g. a Thunderbolt-attached hub exposing both a USB-2 and
> a USB-3 root-hub port through the same connector). Unbinding the
> connector from one root hub's ports also unbinds it for the other's,
> even though the other root hub's child device is still attached and
> gets disconnected later, by which point the connector is already
> gone. The result is a "kernfs: can not remove 'typec', no directory"
> warning the first time, "sysfs: cannot create duplicate filename"
> the next time the device is reattached, and eventually a general
> protection fault in typec_unregister_partner() when it dereferences
> port->usb2_dev/usb3_dev after the device it points to has been freed.
>
> Fix connector_unbind() to mirror connector_bind(): deattach the
> child from the connector before dropping the reference to it. This
> closes the race regardless of which order the parent USB controllers
> happen to be torn down in.
>
> Reported on a Lenovo Thinkpad T480s (BenQ EX3501R monitor with an
> integrated USB hub, connected via the Thunderbolt-capable Type-C
> port, alongside a USB-C power delivery brick on the other Type-C
> port). Ran the reported plug/unplug sequence multiple times on that
> hardware with this patch applied and could not reproduce the failure;
> the same kernel build without the patch reproduced it on the first
> attempt. Supersedes an earlier attempt that reordered
> typec_deattach() in usb_disconnect() instead; that approach worked
> around the same race but only for one ordering of controller teardown,
> and inverted the normal teardown-mirrors-setup convention.
>
> The original investigation, including the v1 patch and the hardware
> reproduction that led to identifying this bug, is my own work. The
> connector_unbind() fix approach below was proposed by Claude (Anthropic,
> Sonnet 5) during code review of the v1 patch. Hardware reproduction and
> validation of this fix were carried out by me, on the same hardware, per
> the note above.
>
> Link: https://lore.kernel.org/r/20250720210847.30998-1-mtormento80@gmail.com
>
> Assisted-by: Claude:claude-sonnet-5
> Signed-off-by: Marco Tormento <mtormento80@gmail.com>
There is already a fix for this:
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/commit/?h=usb-linus&id=e0b291fe117964037e0ba382eff4bb365d531c3a
Thanks,
> ---
> drivers/usb/core/port.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
> index b1364f0c384c..3b258246bb3f 100644
> --- a/drivers/usb/core/port.c
> +++ b/drivers/usb/core/port.c
> @@ -738,6 +738,14 @@ static void connector_unbind(struct device *dev, struct device *connector, void
> {
> struct usb_port *port_dev = to_usb_port(dev);
>
> + /*
> + * If a USB device is still connected to the port, let the
> + * Type-C connector know it's going away before we drop our
> + * reference to it.
> + */
> + if (port_dev->child)
> + typec_deattach(data, &port_dev->child->dev);
> +
> sysfs_remove_link(&connector->kobj, dev_name(dev));
> sysfs_remove_link(&dev->kobj, "connector");
> port_dev->connector = NULL;
> --
> 2.55.0
--
heikki
next prev parent reply other threads:[~2026-07-22 16:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 20:22 [PATCH] usb: core: deattach child device from typec connector on port unbind Marco Tormento
2026-07-22 16:02 ` Heikki Krogerus [this message]
2026-07-22 16:25 ` Marco Tormento
2026-07-27 11:13 ` Heikki Krogerus
2026-07-27 16:51 ` Marco Tormento
2026-08-05 11:49 ` Heikki Krogerus
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=amDplMXaf1JpxE0v@kuha \
--to=heikki.krogerus@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mtormento80@gmail.com \
--cc=stern@rowland.harvard.edu \
/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.