All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Hovold <jhovold@gmail.com>
To: Toby Gray <toby.gray@realvnc.com>, Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Oliver Neukum <oliver@neukum.name>,
	Greg Kroah-Hartman <gregkh@suse.de>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] USB: cdc-acm: Prevent data loss when filling tty buffer.
Date: Tue, 22 Mar 2011 11:05:26 +0100	[thread overview]
Message-ID: <20110322100526.GB21343@localhost> (raw)
In-Reply-To: <1300730698-17099-1-git-send-email-toby.gray@realvnc.com>

On Mon, Mar 21, 2011 at 06:04:58PM +0000, Toby Gray wrote:
> When sending large quantities of data through a CDC ACM channel it is possible
> for data to be lost when attempting to copy the data to the tty buffer. This
> occurs due to the return value from tty_insert_flip_string not being checked.
> 
> This patch adds checking for how many bytes have been inserted into the tty
> buffer and returns any remaining bytes back to the filled read buffer list.

[...]

> @@ -392,6 +393,7 @@ static void acm_rx_tasklet(unsigned long _acm)

[...]

> -	spin_lock_irqsave(&acm->read_lock, flags);
> -	list_add(&buf->list, &acm->spare_read_bufs);
> -	spin_unlock_irqrestore(&acm->read_lock, flags);
> +	buf->head += copied;
> +	buf->size -= copied;
> +
> +	if (buf->size == 0) {
> +		spin_lock_irqsave(&acm->read_lock, flags);
> +		list_add(&buf->list, &acm->spare_read_bufs);
> +		spin_unlock_irqrestore(&acm->read_lock, flags);
> +	} else {
> +		tty_kref_put(tty);
> +		dbg("Partial buffer fill");
> +		spin_lock_irqsave(&acm->read_lock, flags);
> +		list_add(&buf->list, &acm->filled_read_bufs);
> +		spin_unlock_irqrestore(&acm->read_lock, flags);
> +		return;
> +	}
> +

Say you fill up the tty buffer using the last of the sixteen buffers and
return in the else clause above, how will the tasklet ever get
re-scheduled?

The problem is that the tasklet is only scheduled on urb completion and
unthrottle (after open), and if you return above no urb will get
re-submitted. So the only way this will work is if it can be guaranteed
that the line discipline will throttle and later unthrottle us. I
doubt that is the case, but perhaps Alan can give a more definite
answer?

[By the way, did you see Filippe Balbi's patch posted today claiming to
fix a bug in n_tty which could cause data loss at high speeds?]

I was just about to submit a patch series killing the rx tasklet and
heavily simplifying the cdc-acm driver when you posted last night. I
think that if this mechanism is needed it is more straight-forwardly
implemented on top of those as they removes a lot of complexity and
makes it easier to spot corner cases such as the one pointed out above.

I would also prefer a more generic solution to the problem so that we
don't need to re-introduce driver buffering again. Since we already have
the throttelling mechanism in place, if we could only be notified/find
out that the tty buffers are say half-full, we could throttle (from
within the driver) but still push the remaining buffer still on the wire
as they arrive. It would of course require a guarantee that such a
throttle-is-about-to-happen notification is actually followed by (a
throttle and) unthrottle. Thoughts on that?

Thanks,
Johan

  reply	other threads:[~2011-03-22 10:05 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-21 15:52 [PATCH] USB: cdc-acm: Prevent data loss when filling tty buffer Toby Gray
2011-03-21 16:56 ` Alan Cox
2011-03-21 17:58   ` Toby Gray
2011-03-22  8:07   ` Oliver Neukum
2011-03-22 11:07     ` Alan Cox
2011-03-21 18:04 ` [PATCH v2] " Toby Gray
2011-03-22 10:05   ` Johan Hovold [this message]
2011-03-22 10:35     ` Alan Cox
2011-03-22 11:34       ` Johan Hovold
2011-03-22 14:11     ` Toby Gray
2011-03-22 18:05       ` Alan Cox
2011-03-22  7:43 ` [PATCH] " Oliver Neukum
2011-03-23 12:15   ` Toby Gray

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=20110322100526.GB21343@localhost \
    --to=jhovold@gmail.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=oliver@neukum.name \
    --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.