Linux USB
 help / color / mirror / Atom feed
From: Oliver Neukum <oneukum@suse.com>
To: Julian Oes <julian@oes.ch>, Johan Hovold <johan@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] USB: serial: generic: recover from a stalled bulk-in endpoint
Date: Tue, 1 Sep 2026 10:28:08 +0200	[thread overview]
Message-ID: <746c4df4-abd5-4e04-9edc-3ff8f17506bf@suse.com> (raw)
In-Reply-To: <20260901034949.118739-1-julian@oes.ch>

On 01.09.26 05:49, Julian Oes wrote:
> A USB serial port can go permanently silent when its bulk-in endpoint is
> halted: the read URBs complete with -EPIPE, which the generic read
> callback has always treated as fatal, and no further data arrives until
> user space closes and reopens the tty.

But why do you get a port stalling?
It seems your hardware is quite broken.

[..]
> Use a dedicated work item rather than the existing per-port work. The
> latter is scheduled from every write completion and must not be
> cancelled on close, as the line discipline depends on it. Stall
> recovery resubmits the read URBs and must therefore be cancelled
> wherever the reads are stopped, that is, on close, suspend and
> disconnect.

Well, I am sorry, but no.

Your conceptual mistake is seeing the recovery from stall
as an indivisible process. It is not, as it has two parts.
Once your port is in a stall, you should send the feature
request to unblock the halt. There is no reason to cancel the
feature request if you close a port. You just need to refrain
from resubmitting the read URB.
In fact, if you were to be really comprehensive you need
to wait for the result of a feature request on the way
when you reopen a port.

> @@ -128,8 +144,16 @@ void usb_serial_generic_close(struct usb_serial_port *port)
>   		spin_unlock_irqrestore(&port->lock, flags);
>   	}
>   	if (port->bulk_in_size) {
> -		for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
> -			usb_kill_urb(port->read_urbs[i]);
> +		usb_serial_generic_kill_read_urbs(port);
> +		/*
> +		 * The read URBs are dead now so no further stall can be
> +		 * reported, but stall recovery may already be running and may
> +		 * have resubmitted them. Wait for it to finish before killing
> +		 * the URBs for good.
> +		 */
> +		cancel_delayed_work_sync(&port->stall_work);
> +		usb_serial_generic_kill_read_urbs(port);

And that is a race condition. Rekilling does not help reliably.
If your timing is unlucky enough any subsequent operation can be a nop.
A correct sequence would be something like

poison URBs -> cancel the works -> unpoison the URBs

	Regards
		Oliver


  parent reply	other threads:[~2026-09-01  8:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01  3:49 [PATCH v2] USB: serial: generic: recover from a stalled bulk-in endpoint Julian Oes
2026-09-01  4:33 ` Greg Kroah-Hartman
2026-09-01 22:44   ` Julian Oes
2026-09-01  8:28 ` Oliver Neukum [this message]
2026-09-01 23:13   ` Julian Oes
2026-09-02  4:42     ` Michal Pecio
2026-09-02  8:40       ` Oliver Neukum
2026-09-02 14:33       ` Alan Stern

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=746c4df4-abd5-4e04-9edc-3ff8f17506bf@suse.com \
    --to=oneukum@suse.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=johan@kernel.org \
    --cc=julian@oes.ch \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox