From: Oliver Neukum <oneukum@suse.com>
To: Peter Hurley <peter@hurleysoftware.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 12:12:32 +0200 [thread overview]
Message-ID: <1445422352.2246.22.camel@suse.com> (raw)
In-Reply-To: <562684F4.1020501@hurleysoftware.com>
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? Will the tty layer use write()
and put_char()?
Regards
Oliver
>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;
--
2.1.4
next prev parent reply other threads:[~2015-10-21 10:12 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 [this message]
2015-10-21 12:09 ` Peter Hurley
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=1445422352.2246.22.camel@suse.com \
--to=oneukum@suse.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=peter@hurleysoftware.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.