From: "Stephane Grosjean" <grosjean@iphase.com>
To: <linux-kernel@vger.kernel.org>
Subject: PROBLEM: tty_buffer_request_room() vs. ppp_sync_input(): a single buffer may contains several frames
Date: Thu, 9 Sep 2010 07:41:54 -0500 [thread overview]
Message-ID: <0D81855AB9880044B3FD8FE8A7B520595B040D@EXMAIL.interphase.iphase.com> (raw)
Hello,
Thank you to forward that mail to the team which maintains the
drivers/char tty interface.
This problem seems to be present in all versions of the Kernel, I
personnally use 2.6.21 but saw the same code in some newer versions...
I'm using ppp_sync line discipline with an internal char driver which
intends to interface between the kernel tty interface and our hardware.
In my isr, I use "tty_insert_flip_string()" when I just received a frame
from my hardware then, I call "tty_schedule_flip()" to ask that frame to
be pass to the ppp_sync ldisc receive callback.
My problem is that the "tty_buffer_request_room()" function may use the
same buffer (the tail) if it finds enough place to store the incoming
frame in.
But when such a case does occur, the buffer contains 2 (or more) frames
and nothing to separate them...
This is a problem when "ppp_sync_input()" is then called as it considers
a buffer as a SINGLE frame container (as it is written in the function
header:
/* called when the tty driver has data for us.
*
* Data is frame oriented: each call to ppp_sync_input is considered
* a whole frame. If the 1st flag byte is non-zero then the whole
* frame is considered to be in error and is tossed.
*/
static void
ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
char *flags, int count)
Running "pppd" with the "debug" option shows that it doesn't understand
some incoming frames and starts retransmission cycles (see below).
Since the "commit" field of a buffer object is set to the value of
"used" field when that buffer is pushed, one fix I found is to change
the condition used to search for a valid buffer in
"tty_buffer_request_room()":
/* OPTIMISATION: We could keep a per tty "zero" sized buffer to
remove this conditional if its worth it. This would be invisible
to the callers */
if ((b = tty->buf.tail) != NULL)
left = b->size - b->used;
else
left = 0;
-if (left < size) {
+if (left < size || (b->commit >= b->used)) {
/* This is the slow path - looking for new buffers to use */
if ((n = tty_buffer_find(tty, size)) != NULL) {
Please let me know if I'm right and if this fix is the only way to pass
synchronous frames to upper layers.
Local "pppd" debug ouput shows at least 2 received buffers which contain
2 PPP frames each (see ->):
pppd /dev/ttyDCC0 sync nolock 10.10.10.1:10.10.10.2 -detach debug
Thu Jan 1 03:54:13 UTC 1970
using channel 11
Using interface ppp0
Connect: ppp0 <--> /dev/ttyDCC0
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xd7da1d35> <pcomp>
<accomp>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xd7da1d35> <pcomp>
<accomp>]
rcvd [LCP ConfReq id=0x4b <asyncmap 0x0> <magic 0x767ed47a>
<pcomp> <accomp>]
sent [LCP ConfAck id=0x4b <asyncmap 0x0> <magic 0x767ed47a>
<pcomp> <accomp>]
sent [CCP ConfReq id=0x1 <deflate 15> <deflate(old#) 15> <bsd v1
15>]
sent [IPCP ConfReq id=0x1 <compress VJ 0f 01> <addr 10.10.10.1>]
-> rcvd [LCP EchoReq id=0x0 magic=0x767ed47a] 80 21 01 73 00 10 02 06
00 2d 0f 01 03 06 0a 0a 0a 02 80 fd 01 4b 00 04 80 fd 04 01 00 08 1a 04
...
sent [LCP EchoRep id=0x0 magic=0xd7da1d35]
rcvd [IPCP ConfAck id=0x1 <compress VJ 0f 01> <addr 10.10.10.1>]
-> rcvd [IPCP ConfReq id=0x73 <compress VJ 0f 01> <addr 10.10.10.2>]
80 fd 01 4b 00 04
sent [IPCP ConfAck id=0x73 <compress VJ 0f 01> <addr 10.10.10.2>]
local IP address 10.10.10.1
Thanks
next reply other threads:[~2010-09-09 12:54 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-09 12:41 Stephane Grosjean [this message]
2010-09-09 14:47 ` Alan Cox
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=0D81855AB9880044B3FD8FE8A7B520595B040D@EXMAIL.interphase.iphase.com \
--to=grosjean@iphase.com \
--cc=linux-kernel@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
all inboxes | Powered by JetHome®