From: Peter Hurley <peter@hurleysoftware.com>
To: Oliver Neukum <oneukum@suse.com>
Cc: Johan Hovold <johan@kernel.org>, Sven Brauch <mail@svenbrauch.de>,
One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>,
Toby Gray <toby.gray@realvnc.com>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
linux-serial@vger.kernel.org, linux-usb@vger.kernel.org
Subject: Re: [PATCH] Fix data loss in cdc-acm
Date: Wed, 21 Oct 2015 08:09:23 -0400 [thread overview]
Message-ID: <56278073.6030700@hurleysoftware.com> (raw)
In-Reply-To: <1445422352.2246.22.camel@suse.com>
On 10/21/2015 06:12 AM, Oliver Neukum wrote:
> On Tue, 2015-10-20 at 14:16 -0400, Peter Hurley wrote:
>> ECHO is on by default and the cdc-acm driver does not implement the
>> put_char() and flush_chars() tty driver methods, which made the
>> problem
>> _way worse_, since every echoed char is sent as it's own URB.
>
> That can be fixed. How can I test this?
I'm working on getting my tty tests organized for upstreaming, but it's
not there yet. Let me see if I can get you a standalone test for
accuracy, at least.
> Will the tty layer use write() and put_char()?
Echoing uses put_char() + flush_chars() for echoing, if the driver
supports it; otherwise, it uses write().
Be aware that while the N_TTY line discipline ensures that put_char()
and write() usage will not be interleaved without flush_chars(), other
line disciplines might not, so at least be sure that driver won't
crash if that happens.
Regards,
Peter Hurley
> From ac75a2c9ea67ec22c704a6bcaa30e6fc415d64d3 Mon Sep 17 00:00:00 2001
> From: Oliver Neukum <oneukum@suse.com>
> Date: Wed, 21 Oct 2015 12:10:07 +0200
> Subject: [PATCH] cdc-acm: implement put_char() and flush_chars()
>
> This should cut down latencies and waste if the tty layer writes single bytes.
>
> Signed-off-by: Oliver Neukum >oneukum@suse.com>
> ---
> drivers/usb/class/cdc-acm.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
> drivers/usb/class/cdc-acm.h | 1 +
> 2 files changed, 59 insertions(+)
>
> diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
> index b30e742..262f179 100644
> --- a/drivers/usb/class/cdc-acm.c
> +++ b/drivers/usb/class/cdc-acm.c
> @@ -725,6 +725,62 @@ static int acm_tty_write(struct tty_struct *tty,
> return count;
> }
>
> +static void acm_tty_flush_chars(struct tty_struct *tty)
> +{
> + struct acm *acm = tty->driver_data;
> + struct acm_wb *cur = acm->putbuffer;
> + int err;
> + unsigned long flags;
> +
> + acm->putbuffer = NULL;
> + err = usb_autopm_get_interface_async(acm->control);
> + spin_lock_irqsave(&acm->write_lock, flags);
> + if (err < 0) {
> + cur->use = 0;
> + goto out;
> + }
> +
> + if (acm->susp_count) {
> + usb_anchor_urb(cur->urb, &acm->delayed);
> + goto out;
> + }
> +
> + acm_start_wb(acm, cur);
> +out:
> + spin_unlock_irqrestore(&acm->write_lock, flags);
> + return;
> +}
> +
> +static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch)
> +{
> + struct acm *acm = tty->driver_data;
> + struct acm_wb *cur;
> + int wbn;
> + unsigned long flags;
> +
> +overflow:
> + cur = acm->putbuffer;
> + if (!cur) {
> + spin_lock_irqsave(&acm->write_lock, flags);
> + wbn = acm_wb_alloc(acm);
> + if (wbn >= 0) {
> + cur = &acm->wb[wbn];
> + acm->putbuffer = cur;
> + }
> + spin_unlock_irqrestore(&acm->write_lock, flags);
> + if (!cur)
> + return 0;
> + }
> +
> + if (cur->len == acm->writesize) {
> + acm_tty_flush_chars(tty);
> + goto overflow;
> + }
> +
> + cur->buf[cur->len++] = ch;
> + return 1;
> +}
> +
> static int acm_tty_write_room(struct tty_struct *tty)
> {
> struct acm *acm = tty->driver_data;
> @@ -1888,6 +1944,8 @@ static const struct tty_operations acm_ops = {
> .cleanup = acm_tty_cleanup,
> .hangup = acm_tty_hangup,
> .write = acm_tty_write,
> + .put_char = acm_tty_put_char,
> + .flush_chars = acm_tty_flush_chars,
> .write_room = acm_tty_write_room,
> .ioctl = acm_tty_ioctl,
> .throttle = acm_tty_throttle,
> diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
> index dd9af38..648a6f7 100644
> --- a/drivers/usb/class/cdc-acm.h
> +++ b/drivers/usb/class/cdc-acm.h
> @@ -94,6 +94,7 @@ struct acm {
> unsigned long read_urbs_free;
> struct urb *read_urbs[ACM_NR];
> struct acm_rb read_buffers[ACM_NR];
> + struct acm_wb *putbuffer; /* for acm_tty_put_char() */
> int rx_buflimit;
> int rx_endpoint;
> spinlock_t read_lock;
>
next prev parent reply other threads:[~2015-10-21 12:09 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-19 21:37 [PATCH] Fix data loss in cdc-acm Sven Brauch
2015-07-20 17:25 ` Johan Hovold
2015-07-20 18:07 ` Sven Brauch
2015-07-21 9:18 ` Johan Hovold
2015-07-21 16:45 ` Peter Hurley
2015-07-21 16:45 ` Peter Hurley
2015-07-22 8:40 ` Oliver Neukum
2015-07-22 14:30 ` Peter Hurley
2015-07-22 15:01 ` Oliver Neukum
[not found] ` <1437577303.5445.7.camel-IBi9RG/b67k@public.gmane.org>
2015-08-05 0:26 ` Peter Hurley
2015-08-05 0:26 ` Peter Hurley
2015-07-21 13:43 ` Oliver Neukum
[not found] ` <1437486195.3823.13.camel-IBi9RG/b67k@public.gmane.org>
2015-07-21 21:43 ` Sven Brauch
2015-07-21 21:43 ` Sven Brauch
2015-07-21 23:34 ` Peter Hurley
2015-07-22 0:47 ` Sven Brauch
2015-07-22 22:12 ` Peter Hurley
2015-07-22 22:53 ` Sven Brauch
2015-07-27 10:00 ` Peter Stuge
[not found] ` <55B01EDE.3050503-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-08-05 17:36 ` Peter Hurley
2015-08-05 17:36 ` Peter Hurley
[not found] ` <55C249A3.6030809-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
2015-10-20 18:16 ` Peter Hurley
2015-10-20 18:16 ` Peter Hurley
2015-10-21 10:12 ` Oliver Neukum
2015-10-21 12:09 ` Peter Hurley [this message]
2015-10-21 14:58 ` Peter Hurley
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=56278073.6030700@hurleysoftware.com \
--to=peter@hurleysoftware.com \
--cc=gnomes@lxorguk.ukuu.org.uk \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mail@svenbrauch.de \
--cc=oneukum@suse.com \
--cc=toby.gray@realvnc.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 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.