linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Robert White <rwhite@pobox.com>
To: Ed Vance <EdV@macrolink.com>
Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	"'Russell King'" <rmk@arm.linux.org.uk>,
	"'Theodore Tso'" <tytso@mit.edu>
Subject: Re: n_tty.c driver patch (semantic and performance correction) (a ll recent versions)
Date: Mon, 17 Jun 2002 19:00:03 -0700	[thread overview]
Message-ID: <200206171900.03955.rwhite@pobox.com> (raw)
In-Reply-To: <11E89240C407D311958800A0C9ACF7D13A7881@EXCHANGE>

Can you cite a single example of where the standard explicitly states that the 
a read of fewer bytes than VMIN should, none the less, block for the receipt 
of characters that can not be returned by the read?

You will find the standard is silent on the matter.  While it does say that 
the read will block until VMIN characters have been received it has no 
statement on what to do if less than VMIN characters have been requested in 
the particular read.  If I recall correctly (but it has been a while), Sun's 
implementation will return less than VMIN characters without waiting for the 
"extra" characters to be received.

Reguardless, the revise-down part can not possibly affect application 
portability.

Simply put, the patch provided is vanishingly close to* 100% user-space 
compatable with the stated intent of VMIN (and VTIME) as an upper limit on 
how long to wait for a read.  In particular, the downward revision behaviour 
will break absolutely no code.  (I haven't even been able to find an example 
of code where VMIN is greater than 1 and not explicitly reset to the expected 
packet read size).  [ *I use "vanishingly close to" instead of "is" because 
of a single case where VMIN is 255 and VTIME is 0, see below. ]

Since the entire purpose of the VMIN and VTIME is to allow reads to complete 
based on certain minimums.  If the minimum to receive is greater than the 
minimum that *can be returned" waiting for the extra, returnable characters 
is pointless.

When you read the manual pages it is clear the presumption is that the 
read-buffer-size is/would be bigger than the value of MIN.

===== Begin Quote (from sun termio(7i) since that's what I can cite ===== 

     MIN represents the minimum number of characters that  should
     be  received  when  the read is satisfied (that is, when the
     characters are returned to the user).  TIME is  a  timer  of
     0.10-second  granularity  that is used to timeout bursty and
     short-term data transmissions.  The four possible values for
     MIN and TIME and their interactions are described below.

     Case A: MIN > 0, TIME > 0
          In this case, TIME serves as  an  intercharacter  timer
          and is activated after the first character is received.
          Since it is an intercharacter timer, it is reset  after
          a  character  is received.  The interaction between MIN
          and TIME is as follows:  as soon as  one  character  is
          received,  the intercharacter timer is started.  If MIN
          characters are received before the intercharacter timer
          expires  (note  that the timer is reset upon receipt of
          each character), the read is satisfied.  If  the  timer
          expires before MIN characters are received, the charac-
          ters received to that point are returned to  the  user.
          Note  that if TIME expires, at least one character will
          be returned because  the  timer  would  not  have  been
          enabled  unless a character was received.  In this case
          (MIN > 0, TIME > 0), the read sleeps until the MIN  and
          TIME  mechanisms  are  activated  by the receipt of the
          first character.  If the number of characters  read  is
          less than the number of characters available, the timer
          is not reactivated and the subsequent read is satisfied
          immediately.
 
     Case B: MIN > 0, TIME = 0
          In this case, since the value  of  TIME  is  zero,  the
          timer  plays  no  role  and  only MIN is significant. A
          pending read is not satisfied until MIN characters  are
          received  (the pending read sleeps until MIN characters
          are received).  A program that uses this case  to  read
          record based terminal I/O may block indefinitely in the
          read operation.

     Case C: MIN = 0, TIME > 0
          In this case, since MIN = 0, TIME no longer  represents
          an intercharacter timer:  it now serves as a read timer
          that is activated as soon as a read is done.  A read is
          satisfied  as soon as a single character is received or
          the read timer expires.  Note that, in  this  case,  if
          the  timer  expires,  no character is returned.  If the
          timer does not expire, the only way  the  read  can  be
          satisfied is if a character is received.  In this case,
          the read will not  block  indefinitely  waiting  for  a
          character;  if no character is received within TIME*.10
          seconds after the read is initiated, the  read  returns
          with zero characters.

     Case D: MIN = 0, TIME = 0
          In this case, return  is  immediate.   The  minimum  of
          either the number of characters requested or the number
          of characters currently available is  returned  without
          waiting for more characters to be input.

  Comparison of the different cases of MIN, TIME interaction
     Some points to note about MIN and TIME:

     1.   In the following explanations, note that  the  interac-
          tions  of  MIN and TIME are not symmetric. For example,
          when MIN > 0 and TIME = 0, TIME has  no  effect.   How-
          ever, in the opposite case, where MIN = 0 and TIME > 0,
          both MIN and TIME play a role in that MIN is  satisfied
          with the receipt of a single character.

     2.   Also note that in case A (MIN >  0,  TIME  >  0),  TIME
          represents  an  intercharacter timer, whereas in case C
          (MIN = 0, TIME > 0), TIME represents a read timer.

     These two points highlight the dual purpose of the  MIN/TIME
     feature.   Cases  A  and  B,  where MIN > 0, exist to handle
     burst mode activity (for example, file  transfer  programs),
     where  a  program would like to process at least MIN charac-
     ters at a time.  In case  A,  the  intercharacter  timer  is
     activated  by  a  user  as  a safety measure; in case B, the
     timer is turned off.

     Cases C and  D  exist  to  handle  single  character,  timed
     transfers.   These  cases  are  readily adaptable to screen-
     based applications that need  to  know  if  a  character  is
     present in the input queue before refreshing the screen.  In
     case C, the read is timed, whereas in case D, it is not.

     Another important note is that MIN is always just a minimum.
     It  does not denote a record length.  For example, if a pro-
     gram does a read of 20 bytes, MIN is 10, and  25  characters
     are  present,  then  20  characters  will be returned to the
     user.

===== End Quote =====

Once again, notice the presumption that read would always supply a buffer 
equal to or larger than VMIN.  Nowhere does it mention anything about "upper" 
and "lower" parts of drivers it only addresses single reads and timing and 
return conditions to that read.  Since it is "silent" on the matter of what 
to do when the read size in less than MIN and it is "kind of dumb" to wait to 
return characters that can't be returned.  The downward revision code is 
completely within the spirit and structure of the standard.  It is also 
essentially impossible to break existing code by adding this fix.  (Existing 
code would already be hanging, or already be in bounds, or be part of a 
streaming dataset, and so on.)

The "bad thing" in the way it has been implemented currently is that when the 
packet sizes varry it takes a lot of time repeatedly reseting VMIN or 
bouncing in and out of kernel context and copying buffers because VMIN is 
artifically small (see pppd etc).  I am "fairly certain" that no other 
implementation would wait for unreturnable characters anyway since there is 
no real way to deal with the unreturnd characters that would result in 
predictable code.

As for the enhancement part.  The mod "could" jam up code in the single 
spesific case where VMIN==255 and VTIME==0 and the read size was larger than 
the received data could ever be.  I have found zero such instances.  Granted 
I do not have a psychic line into every piece of code everywhere.  I havn't 
even found a single instance of VMIN==255 and VTIME==0 (which, I reiterate, 
is the only case where the enhancement could possibly break code that wasn't 
already broken).

Find me one instance of code in the wild where:
 VMIN==255 and VTIME==0;
or
 VMIN=255 and VTIME>0 and performance isn't improved by the patch;
or
 VMIN < 255 and performance isn't unchanged-or-improved by the patch
and I'll bow my head in shame and go away.  8-)

So the floating down is a hard fix, and is actually hugely useful when dealing 
with small-event protocols.  The floating up is also hugely useful but there 
is a diminishingly miniscule chance of boning something.  The float-down fix 
doesn't violate a single standard (unless I am missing something).  and 
finally, the utility of the floating-up enhancement greatly outweighs the 
chance of it messing something up.

As I type this I can see that a guardian case of not floating up if TIME==0 
might be a conservatively useful case, but I dout it has any real-world 
value.

(in case you care for an example)
The real-world project that started me down this road was dealing with SIM 
cards (a.k.a. "Java Cards", "Smart Cards" etc) which (for protocol "T=0") 
operate at about 9600 baud and which return frames (who's variable lengths 
are known before the read) of data between 2 and 258 bytes, which can be 
paded with any number of 0x60(s), and which signal an error by "becomming 
unresponsive."  Lets face it, any protocol with a frame that includes a 
length component with one-byte encoding will, perforce, tend to overflow the 
255 value inherant in the VMIN data type because any framing on the payload 
will be longer thant the maximum payload of 255.

Also consider that virutally every serial protocol in use today has a larger 
than 255 character maximum frame.

I have been using the patch on several production systems (actually full time 
development boxes, so "production in development environment" whatever the 
distinction may be worth) and have found zero cases where there was any 
problems and the applications being developed with the fixed behavior have 
had a several-fold improvement in performance.

I think you will find the patch worth it in the long run and I doubt that, 
should you use your greater-access to the code and user base, you would find  
a single case where it breaks, invalidates, or confuses a single person or 
program on the planet.

Rob White.


On Monday 17 June 2002 10:27, Ed Vance wrote:
> On Sat, June 15, 2002 at 9:01 PM, Robert White wrote:
> > Kernel Versions: 2.2, 2.4, 2.5 (all of them since 1996 really 8-)
> >
> > The n_tty line discipline module contains a "semantic error" that
> > limits its speed and usefulness in many uses.  The attached patch
> > directly addresses serial performance in a completely backwards-
> > compatible way.
> >
> > In particular, the current handling of VMIN hugely limits,
> > complicates, and/or slows down optimal serial use.  The most
> > obvious example is that if you call read(2) with a buffer size less
> > than the current value of VMIN, the line discipline will insist
> > that the read call wait for characters that can not be returned to
> > that call.  The POSIX standard is silent on the subject of whether
> > this is right or wrong.  Common sense says it is wrong.
>
> Hi,
>
> IIRC, the way VMIN>0,VTIME=0 is supposed to work is to make characters
> available to the top level queue to be read when the low level input
> queue contains VMIN or more characters. Until that moment, there are
> no characters available to a read of any buffer size regardless of how
> many characters have been received at the low level. This is why a
> single character read blocks when at least one character has been
> received but not yet VMIN characters. Only data in the top level queue
> can be read. If the line discipline has not yet released data to the
> top level queue because of VMIN, then no data can be read, but this is
> not an error.
>
> Many have been tempted to change the behavior of this part of the
> system. IMHO, it is not worth tossing away application portability.
>
> Standards compliance can feel a bit like vertigo while instrument
> flying. Sometimes one has to just stare at the artificial horizon and
> say "I believe it" to one's self until the gut is convinced.
>
> Best regards,
> Ed
>
> ----------------------------------------------------------------
> Ed Vance              edv@macrolink.com
> Macrolink, Inc.       1500 N. Kellogg Dr  Anaheim, CA  92807
> ----------------------------------------------------------------


  reply	other threads:[~2002-06-18  2:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-06-17 17:27 n_tty.c driver patch (semantic and performance correction) (a ll recent versions) Ed Vance
2002-06-18  2:00 ` Robert White [this message]
2002-06-18 13:05   ` Stuart MacDonald
2002-06-19  4:59     ` Anyone using NFSv4? Dax Kelson
2002-06-19 23:48       ` David Ford
2002-06-26 17:48 n_tty.c driver patch (semantic and performance correction) (a ll recent versions) Ed Vance
2002-06-26 20:42 ` Russell King
2002-06-27 16:37 ` Robert White
2002-07-26 14:17 ` Russell King
2002-07-27 22:07   ` Robert White
2002-07-27 23:11     ` Russell King
2002-07-27 23:21     ` Andries Brouwer
2002-07-28  2:34       ` Robert White
2002-07-28  3:01         ` Stevie O
2002-07-28 13:34         ` Andries Brouwer
2002-07-28 20:04         ` Alan Cox
2002-07-30  7:41           ` Robert White
2002-07-28  2:36       ` Robert White
2002-06-28 18:12 Ed Vance
2002-07-29 21:46 Ed Vance
2002-07-30  7:50 ` Robert White
2002-07-30 17:07 Ed Vance
2002-07-31 16:58 Ed Vance

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=200206171900.03955.rwhite@pobox.com \
    --to=rwhite@pobox.com \
    --cc=EdV@macrolink.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=rmk@arm.linux.org.uk \
    --cc=tytso@mit.edu \
    /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;
as well as URLs for NNTP newsgroup(s).