The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Johan Hovold <johan@kernel.org>
To: Crescent Hsieh <crescentcy.hsieh@moxa.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v1 2/4] usb: serial: mxuport: handle SEND_NEXT tx flow control
Date: Thu, 7 May 2026 16:40:03 +0200	[thread overview]
Message-ID: <afykQ7JeGOKc8sRO@hovoldconsulting.com> (raw)
In-Reply-To: <20260324035041.352190-3-crescentcy.hsieh@moxa.com>

On Tue, Mar 24, 2026 at 11:50:39AM +0800, Crescent Hsieh wrote:
> Track the transmitted payload size per port and stop queueing more data
> once a bulk-out transfer reaches the device buffer threshold.
> 
> Resume transmission when the device reports UPORT_EVENT_SEND_NEXT, and
> reset the TX flow-control state when the port is opened.
> 
> This prevents the driver from queueing more TX data until the device
> reports that it is ready to accept the next transfer.

This explains what the patch does but says nothing about why you think
this is needed (which is the more important part).

The currently supported devices seems to work fine without this and
introducing this scheme should impact throughput negatively.

> Signed-off-by: Crescent Hsieh <crescentcy.hsieh@moxa.com>
> ---
>  drivers/usb/serial/mxuport.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
> index 034b506322c2..4d29a431cefd 100644
> --- a/drivers/usb/serial/mxuport.c
> +++ b/drivers/usb/serial/mxuport.c
> @@ -179,6 +179,8 @@
>  
>  /* This structure holds all of the local port information */
>  struct mxuport_port {
> +	u32 sent_payload;
> +	u32 hold_reason;
>  	u8 mcr_state;		/* Last MCR state */
>  	u8 msr_state;		/* Last MSR state */
>  	struct mutex mutex;	/* Protects mcr_state */
> @@ -250,9 +252,13 @@ MODULE_DEVICE_TABLE(usb, mxuport_idtable);
>  static int mxuport_prepare_write_buffer(struct usb_serial_port *port,
>  					void *dest, size_t size)
>  {
> +	struct mxuport_port *mxport = usb_get_serial_port_data(port);
>  	u8 *buf = dest;
>  	int count;
>  
> +	if (mxport->hold_reason & MX_WAIT_FOR_SEND_NEXT)
> +		return 0;

The generic write implementation does not support drivers returning zero
here (and has already made sure that there is data in the fifo) so if
this is at all needed that may need to be addressed.

> +
>  	count = kfifo_out_locked(&port->write_fifo, buf + HEADER_SIZE,
>  				 size - HEADER_SIZE,
>  				 &port->lock);
> @@ -263,6 +269,13 @@ static int mxuport_prepare_write_buffer(struct usb_serial_port *port,
>  	dev_dbg(&port->dev, "%s - size %zd count %d\n", __func__,
>  		size, count);
>  
> +	mxport->sent_payload += count;
> +
> +	if (mxport->sent_payload >= port->bulk_out_size) {
> +		mxport->hold_reason |= MX_WAIT_FOR_SEND_NEXT;
> +		buf[0] |= 0x80;
> +	}
> +
>  	return count + HEADER_SIZE;
>  }
>  
> @@ -484,6 +497,9 @@ static void mxuport_lsr_event(struct usb_serial_port *port, u8 buf[4])
>  static void mxuport_process_read_urb_event(struct usb_serial_port *port,
>  					   u8 buf[4], u32 event)
>  {
> +	struct mxuport_port *mxport = usb_get_serial_port_data(port);
> +	unsigned long flags;
> +
>  	dev_dbg(&port->dev, "%s - receive event : %04x\n", __func__, event);
>  
>  	switch (event) {
> @@ -492,6 +508,13 @@ static void mxuport_process_read_urb_event(struct usb_serial_port *port,
>  		 * Sent as part of the flow control on device buffers.
>  		 * Not currently used.
>  		 */
> +		if (mxport->hold_reason & MX_WAIT_FOR_SEND_NEXT) {
> +			spin_lock_irqsave(&mxport->spinlock, flags);
> +			mxport->hold_reason &= ~MX_WAIT_FOR_SEND_NEXT;
> +			mxport->sent_payload = 0;
> +			usb_serial_generic_write_start(port, GFP_ATOMIC);
> +			spin_unlock_irqrestore(&mxport->spinlock, flags);
> +		}

The locking here looks questionable.

>  		break;
>  	case UPORT_EVENT_MSR:
>  		mxuport_msr_event(port, buf);
> @@ -1318,6 +1341,9 @@ static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)
>  	 * returns.
>  	 */
>  	mxport->msr_state = 0;
> +	mxport->sent_payload = 0;
> +	mxport->hold_reason = 0;
> +	kfifo_reset(&port->write_fifo);

The fifo is already cleared on close.

>  
>  	return err;
>  }

Johan

  parent reply	other threads:[~2026-05-07 14:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260324035041.352190-1-crescentcy.hsieh@moxa.com>
     [not found] ` <20260324035041.352190-2-crescentcy.hsieh@moxa.com>
2026-05-07 14:13   ` [PATCH v1 1/4] usb: serial: mxuport: add support for more MXU50U UART devices Johan Hovold
     [not found] ` <20260324035041.352190-3-crescentcy.hsieh@moxa.com>
2026-05-07 14:40   ` Johan Hovold [this message]
     [not found] ` <20260324035041.352190-4-crescentcy.hsieh@moxa.com>
2026-05-07 15:56   ` [PATCH v1 3/4] usb: serial: mxuport: support serial interface mode configuration Johan Hovold
     [not found] ` <20260324035041.352190-5-crescentcy.hsieh@moxa.com>
2026-05-07 15:59   ` [PATCH v1 4/4] usb: serial: mxuport: add sysfs control for UART FIFO Johan Hovold

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=afykQ7JeGOKc8sRO@hovoldconsulting.com \
    --to=johan@kernel.org \
    --cc=crescentcy.hsieh@moxa.com \
    --cc=gregkh@linuxfoundation.org \
    --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