[U-Boot] RFC - How to speed up multiplexed input between serial and network?
Bigler, Stefan
Stefan.Bigler at keymile.com
Wed Oct 29 15:02:02 CET 2008
Dear Mr. Denk
Thank you for the detailed answer.
> Dear "Bigler, Stefan",
>
> In message
> <D839955AA28B9A42A61B9181506E27C4012E18DB at SRVCHBER1212.ch.keymile.net>
you
> wrote:
> >
> > In the file common/console.c we added hooks to measure the time for
> > tstc() execution.
> > The measured time are:
> > serial-driver 3 Microseconds
> > nc 15 Milliseconds
>
> Let's start asking ourself why there is such a big difference.
>
> The serial driver just checks that status bits in some hardware
> registers. This is pretty fast.
>
> The nc driver however actually runs a NetLoop() call, i. e. it
> performs some active polling. THis takes much more time.
This is true and all configuration e.g. ipaddr are reread again and
again.
>
> > There are 2 possibilities to solve the problem:
> > -----------------------------------------------
> > a) make the netconsole faster
> > b) make serial more "robust" and allow more latency
>
> There may be other options as well, like making the multiplexing a
> little more intelligent. See below for an idea or two.
>
> > The better solution is of course to make the netconsole faster. But
can
> > we reach 100 Microseconds?
>
> Probably not. But do we really have to?
>
> > We can reduce it (as already done e.g. accelerate the readout of
> > env-variables). To accelerate by factor 150 we need to do major
changes
> > e.g. read-out the env if changed so we need a mechanism to see this.
>
> Indeed environment variable handling could be accelerated a lot for
> example by using a has table for in-ram storage instead of the linear
> search list we use now.
>
> > On the other hand we can enhance the serial driver to "absorb" e.g.
one
> > line that allows you to copy/paste.
> > This is not a big code change but it needs more dp-ram.
>
> And it needs to be tested on many systems.
>
> I really hesitate to add more complexity into the serial driver. It
> is part of the very basic design ideas in U-Boot to have a serial
> console very, very soon in the initialization sequence. This is a
> very impartant feature during board bringup and U-Boot porting, and I
> will not give this up easily.
>
> Adding more complexity here is probably not a good idea unless there
> is really no other way around it.
>
> > a) So I tried to make the netconsole faster with the optimisation of
> > tstc()
> >
------------------------------------------------------------------------
> > ---
> > There is the possibility to do the getenv() only if the env is
changed.
> > I added a "transactionId" what is incremented after every write to
env.
> > So the user of env can check if the env changed and only read if
> > changed.
> > This reduced the tstc() of nc to 60 Microseconds. So the polling of
> > serial is done every 70 Microseconds.
>
> Ah, but that's excellent - you asked for 100 us above, so we're
> already much faster than needed now.
>
> > In principle this should be fast enough to be able to copy paste
> > copy paste
> > 0123456789 -> 013679 -> 50%
>
> > Why are we receiving only half of the character? This due to the
fact
> > that processing a character needs time. If we check how often we
call
> > getc() while copy/paste, this is every 180 Microsecond. The method
> > getc() do not need lot of time, but the received character is sent
over
> > nc before we get the next char. I think we cannot avoid this.
>
> Well, one very simple way to avoid it is to run the serial port at a
> lower baud rate. If you have a slow processor, you will be facing
> certain limits. The more features you add (like I/O multiplexing with
> a network driver) the more restrictive these limits will be.
>
> > I do not see how we can reduce this time even further.
>
> Then it's probably time to lean back and think about alternative
> approaches to implement the featrues you are looking for.
>
> > The measurement is also done without nc. There the getc() is called
> > every 80-90 Microseconds. So we see that is little headroom to do
> > additional processing!
>
> I don't want to doubt your measurements, but they don;t match my
> experience. You say you test on a 8xx at 66 MHz - I'm pretty sure
> that the 8xx can be used at 115200 bps reliably even when running
> with 33 MHz only.
>
> Unfortunately I cannot test this at the moment, but I will run such a
> test as soon as possible.
>
> > b) Make the serial driver more "robust" to absorb bursts
> > --------------------------------------------------------
> > I think it would make sense to be able to absorb the burst of one
line
> > e.g. 128 character.
>
> Who says this is sufficient?
>
> I don;t consider this as a real solution - you just push the limits a
> bit, so that it works in a few test cases now, but it will still
> fails in the same way as soon as somebody uses a little longer lines.
>
> > This can be done in 2 way:
> > b1) use more buffer descriptor with one character
> > b2) use the feature of smc to allow multi-character buffer
>
> I really do not want to add such complexity to the serial driver,
> especially since the current implementation matches what Linux uses
> for early console, too.
>
> > Conclusion:
> > -----------
> > I do not see a good chance to be able to reduce the processing time
in
> > the netconsole below 100 Microseconds.
> >
> > I expect copy/paste to work for a line (128 characters).
> >
> > So I propose to enhance the serial driver.
>
> I really do not like this approach.
>
>
> But - do we really need such a "fix"? Lets step back a bit.
>
> As I understand it, the problem results from the fact that you are
> trying to always alternate calls to polling the serial and the
> network console. This makes sense in the idle state, when we are
> waiting for input from any of the possible input devices. But does it
> still make sense to interrupt the serial code with network polling
> while a (high-speed) data transfer is going on on the serial line?
>
> I don't think so.
>
> From what I've gathered from the existing design, you don't really
> care about guaranteeing any deterministic behaviour in case both
> input channels transfer data at the same time. If such a simultaneous
> transaction happens, your input data stream (for both channels) is
> likely to get corrupted (without any error indication).
>
> I interpret the fact that your code does not care about this as an
> indication that such situations are very untypical for your mode of
> usage - but then why do we need to provide code that focuses on such
> a case?
>
> So my question is: does it really make sense to continue polling the
> network console while a serial data transfer is in progress? [*]
>
> I do not think so.
>
> [*] Of course the same is true for the other direction - but there
> situation is much easier becahuse (a) the serial driver is very
> fast and (b) the nc code already handles multi-byte data packets.
>
>
> My suggestion is to make the multiplexing more intelligent instead of
> making the serial driver more complex. The nice thing with this is
> that you probably still get the same results (actually even better
> ones as the artificial 128 byte line lengt limit can be avoided), and
> the changes are only in the new code, i. e. users who do not need
> such I/O multiplexing will not be affected.
>
> I think it should be fairly simple to implement something similar to
> the VTIME feature for non-canonical reads in the Unix serial drivers
> (see "man tcsetattr"):
>
> - In idle mode, all configured input devices are polled in a
> round-robin manner (as it is done now).
>
> - As soon as a character is received on the serial line, a timestamp
> is taken. As you calculated, one character at 115 kbps takes about
> 100 us on the wire. Within a window of (for exmaple) 500 us (or
> about 5 character times) now polling of all other I/O ports will be
> skipped.
>
> This should give you raw serial driver performacne while a serial
> data transfer is running, while keeping functionality for all other
> use cases.
>
> What do you think?
First we need to have a good and accepted solution to reduce the time in
NetLoop e.g. read only the env when changed. Then the polling is not
anymore critical path.
The main problem from my point of view is the echo of the received data
to serial and also to nc. This is done now immediately, character by
character and this takes time (more than we have).
Am I right when I say that between a read from character getc() until
the next call of getc() we have 100 Microseconds to do all the required
processing otherwise we lose data?
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
>
Best regards,
Stefan Bigler
More information about the U-Boot
mailing list