linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Johan Hovold <johan@kernel.org>,
	Corentin Labbe <clabbe@baylibre.com>,
	linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org,
	david@ixit.cz
Subject: Re: [PATCH v8 1/2] usb: serial: add support for CH348
Date: Wed, 16 Jul 2025 10:57:27 +0200	[thread overview]
Message-ID: <2025071613-ethics-component-e56d@gregkh> (raw)
In-Reply-To: <CAFBinCAMGR2f4M1ARKytOwG1z9ORcD-OMNLH2FqZHb+tOm0tEQ@mail.gmail.com>

On Wed, Jul 16, 2025 at 10:28:22AM +0200, Martin Blumenstingl wrote:
> On Wed, Jul 16, 2025 at 9:44 AM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Tue, Jul 15, 2025 at 11:20:33PM +0200, Martin Blumenstingl wrote:
> > > Hi Johan,
> > >
> > > I'm excluding comments that are clear to me in this reply.
> > >
> > > On Mon, May 12, 2025 at 12:03 PM Johan Hovold <johan@kernel.org> wrote:
> > > [...]
> > > > > +     if (ret) {
> > > > > +             dev_err(&port->serial->dev->dev,
> > > > > +                     "Failed to configure UART_MCR, err=%d\n", ret);
> > > > > +             return ret;
> > > > > +     }
> > > >
> > > > The read urbs should be submitted at first open and stopped at last
> > > > close to avoid wasting resources when no one is using the device.
> > > >
> > > > I know we have a few drivers that do not do this currently, but it
> > > > shouldn't be that hard to get this right from the start.
> > > If you're aware of an easy approach or you can recommend an existing
> > > driver that implements the desired behavior then please let me know.
> > >
> > > The speciality about ch348 is that all ports share the RX/TX URBs.
> > > My current idea is to implement this using a ref count (for the number
> > > of open ports) and mutex for locking.
> >
> > How do you know if a port is "open" or not and keep track of them all?
> > Trying to manage that is a pain and a refcount shouldn't need locking if
> > you use the proper refcount_t type in a sane way.
> >
> > Try to keep it simple please.
> I'm currently refcounting from usb_serial_driver.{open,close}
> The additional challenge is that I need to open two URBs at the right
> time to "avoid wasting resources". At least in my head I can't make it
> work without an additional lock.

Urbs really aren't all that large of a "resource", so don't worry about
that.  Get it working properly first before attempting to care about
small buffers like this :)

> The following is a simplified/pseudo-code version of what I have at
> the moment (which is called from my ch348_open):
> static int ch348_submit_urbs(struct usb_serial *serial)
> {
>   int ret = 0;
> 
>   mutex_lock(&ch348->manage_urbs_lock);
> 
>   if (refcount_read(&ch348->num_open_ports))
>     goto out_increment_refcount;
> 
>   ret = usb_serial_generic_open(NULL, serial_rx);
>   if (ret)
>     goto out_unlock;
> 
>   ret = usb_serial_generic_open(NULL, status);
>   if (ret) {
>     usb_serial_generic_close(serial_rx); /* undo the first
> usb_serial_generic_open */
>     goto out_unlock;
>   }

That's odd, why use NULL for a tty device?  Ah, we don't even use it for
anything anymore, maybe that should be fixed...

Anyway, just submit the urbs, why use usb_serial_generic_* at all for
the status urb?  That's not normal.

And are you trying to only have one set of urbs out for any port being
opened (i.e. you only have one control, one read, and one write urb for
the whole device, and the port info are multiplexed over these urbs?  Or
do you have one endpoint per port?)

If you are sharing endpoints, try looking at one of the other usb-serial
drivers that do this today, like io_edgeport.c, that has had shared
endpoints for 25 years, it's not a new thing :)

> out_increment_refcount:
>   refcount_inc(&ch348->num_open_ports);
> 
> out_unlock:
>   mutex_unlock(&ch348->manage_urbs_lock);
> 
>   return ret;
> }
> 
> My understanding is that usb-serial core does not provide any locking
> around .open/.close.

Nor should it, these are independent per-port.

> > > > With this implementation writing data continuously to one port will
> > > > starve the others.
> > > >
> > > > The vendor implementation appears to write to more than one port in
> > > > parallel and track THRE per port which would avoid the starvation issue
> > > > and should also be much more efficient.
> > > >
> > > > Just track THRE per port and only submit the write urb when it the
> > > > transmitter is empty or when it becomes empty.
> > > I'm trying as you suggest:
> > > - submit the URB synchronously for port N
> > > - submit the URB synchronously for port N + 1
> > > - ...
> > >
> > > This seems to work (using usb_bulk_msg). What doesn't work is
> > > submitting URBs in parallel (this is what the vendor driver prevents
> > > as well).
> >
> > Why would submitting urbs in parallel not work?  Is the device somehow
> > broken and can't accept multiple requests at the same time?
> I don't know the reason behind this.
> These are requests to the same bulk out endpoint. When submitting
> multiple serial TX requests at the same time then some of the data is
> lost / corrupted.
> 
> The vendor driver basically does this in their write function (very
> much simplified, see [0] for their original code):
>   spin_lock_irqsave(&ch9344->write_lock, flags);
>   usb_submit_urb(wb->urb, GFP_ATOMIC); /* part of ch9344_start_wb */
>   spin_unlock_irqrestore(&ch9344->write_lock, flags);

that's crazy, why the timeout logic in there?  This is a write function,
submit the data to the device and get out of the way, that's all that
should be needed here.

> If you have any suggestions: please tell me - I'm happy to try them out!

Try keeping it simple first, the vendor driver looks like it was written
by someone who was paid per line of code :)

good luck!

greg k-h

  reply	other threads:[~2025-07-16  8:57 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-04 13:58 [PATCH v8 0/2] usb: serial: add support for CH348 Corentin Labbe
2025-02-04 13:58 ` [PATCH v8 1/2] " Corentin Labbe
2025-03-20 12:56   ` David Heidelberg
2025-05-12 10:03   ` Johan Hovold
2025-07-15 21:20     ` Martin Blumenstingl
2025-07-16  7:44       ` Greg KH
2025-07-16  8:28         ` Martin Blumenstingl
2025-07-16  8:57           ` Greg KH [this message]
2025-07-16  9:31             ` Martin Blumenstingl
2025-07-16 10:00               ` Greg KH
2025-07-16 11:24                 ` Martin Blumenstingl
2025-07-25 10:14               ` Johan Hovold
2025-07-25 10:07       ` Johan Hovold
2025-07-26 14:54         ` Martin Blumenstingl
2025-07-29  9:43           ` Johan Hovold
2025-07-29 20:45             ` Martin Blumenstingl
2025-08-04 12:32               ` Johan Hovold
2025-08-04 21:35                 ` Martin Blumenstingl
2025-08-27 10:07                   ` Johan Hovold
2025-02-04 13:58 ` [PATCH v8 2/2] usb: serial: add Martin and myself as maintainers of CH348 Corentin Labbe
2025-03-30  1:24 ` [PATCH v8 1/2] usb: serial: add support for CH348 Nicolas Frattaroli
2025-03-30 22:11   ` David Heidelberg
     [not found] ` <CA+j61XMwrtRJhGiJu_T5tt3g14fseOqvOJZLbb2bQGduSJsmxQ@mail.gmail.com>
2025-05-04 21:26   ` [PATCH v8 0/2] " Martin Blumenstingl

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=2025071613-ethics-component-e56d@gregkh \
    --to=gregkh@linuxfoundation.org \
    --cc=clabbe@baylibre.com \
    --cc=david@ixit.cz \
    --cc=johan@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=martin.blumenstingl@googlemail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).