[U-Boot] RFC - How to speed up multiplexed input between serial and network?

Wolfgang Denk wd at denx.de
Wed Oct 29 13:14:52 CET 2008


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.

> 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.



More information about the U-Boot mailing list