Linux USB
 help / color / mirror / Atom feed
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

  reply	other threads:[~2026-07-22 16:02 UTC|newest]

Thread overview: 3+ 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox