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

2008-10-30 Thread Bigler, Stefan
Dear Denk Wolfgang,

 In message
 [EMAIL PROTECTED]
you
 wrote:
 
   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.
 
 Hm... sorry, but I disagree. With my suggestion above, the time spent
 in NetLoop() does not matter any more at  all.  So  no  optimizations
 there will be needed to get your code working.

If you know how to implement the behaviour like VTIME I'm fine, but I
don't understand how it can work.
Is it correct to say: To check if data is received at our nc we have run
NetLoop(). If yes, one run cost me 15 Milliseconds, so 150 character are
potentially lost on the serial.
Of course when I'm on the serial I stay longer on the serial and read
more.

 
  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).
 
 Sorry. I don't get it. It seems you bring up a new topic here.
 
 Less than 6 hours before this you wrote: The polling of  the  serial
 driver  is  too  slow  to  get  all characters. ... we added hooks to
 measure the time for tstc() execution. The measured time are: ...  nc
 15 Milliseconds.
 
 My interpretation was (and is) that it's the *input* processing which
 is your major concern. And I showed a way to solve this problem ( at
 least I think that my suggestion will solve it).
 
 
 Now you bring up a  new  topic  -  the  time  needed  to  output  the
 characters. May be we should try and solve problems sequentially - if
 we  throw  all  isses we see into one big pot we might not be able to
 swallow this.

Sorry I did not tell you the full story (I also do not understand all).

 
 BTW: did you measure any times for the character output?

 
What I know is, that reducing the time spend in the functions for nc by
calling getenv() only when the env is changed is listed below:
nc tstc() before 15 Milliseconds  after 60 Microseconds
nc getc() before 5  Microseconds  after  5 Microseconds 
nc send_packet()  before 90 Microseconds  after 90 Microseconds

For the receiving the real job is done in tstc(), getc() only take it
from the input_buffer.
The sending do not run the NetLoop() in steady state. 
This explains that only the tstc() gets faster.

 
 BTW - reducing the console baud rate would be a trivial way to avoid
 most of these issues ;-)

Reducing the baud rate helps here the measurements (pasting a 200
character line)

with 57600 6% of the characters are lost
with 38400 0% of the characters are lost  -- this would work


  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?

 On average, yes. The time for a single character might be longer  (up
to   close  to  200  us) assumimg we are fast enough then to catch the
third 
 char. All this assuming a console baudrate of 115 kbps.

I agree with this when we assume that one character is received in the
buffer/bd and 2 can be held in the HW-FIFO.
When this would be the case then I should receive always the 3 first
characters and then we have losses. But this is not the case we already
loose the second. 
Do you have an explanation for this?


Best regards,
Stefan Bigler
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


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

2008-10-29 Thread Bigler, Stefan
Hi

We are trying to use U-Boot that it can be remote controlled over
netconsole and in locally over the serial terminal. 
We were quite successful but we saw some latency issues on the serial
terminal. The polling of the serial driver is too slow to get all
characters. This does not allow you to e.g. to copy/paste, most of the
characters are lost.

We analyzed the code and tried to speed it up, without the required
improvement.
The tests are done with an [EMAIL PROTECTED] and an MPC8247.
  
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

The result is, that the serial interface is polled only every 15
Millisecond.
On the serial interface with a line-rate of 115200 we receive aprox
10'000 Character every second. This is one character every 100
Microsecond.

The serial driver has one buffer-descriptor with the space for one
character. This results in a maximal polling period of 100 Microseconds.

The HW-FIFO for a MPC852T is 2 bytes.


There are 2 possibilities to solve the problem:
---
a) make the netconsole faster
b) make serial more robust and allow more latency

The better solution is of course to make the netconsole faster. But can
we reach 100 Microseconds?
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.

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.

The copy/paste test shows the following result
copy  paste   
0123456789 - 0 - first character 


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

I do not see how we can reduce this time even further.

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!


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.

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 

b1) driver with multi buffer descriptor
---
This is the possibility that is quite simple to implement, but needs
more resources. I have already sent this. The required dual-port-memory
is high
128 bd * 8 byte plus 128 byte for character = 1152 byte more.
(I also implemented this driver)

b2) driver with multi-character buffer
--
I have implemented this driver for MPC852T (SMC) and attached a patch.
The additional use of DP-RAM is the size the buffer (e.g. 128 bytes) and
4 bytes for an index to the next character to read. 
A define can be used to specify the size of the buffer. If undefined the
size is 1.


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.

Best regards,
Stefan Bigler

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] RFC - How to speed up multiplexed input between serial andnetwork?

2008-10-29 Thread Bigler, Stefan
;
 
up = (smc_uart_t *)cpmp-cp_dparam[PROFF_SMC];
 #ifdef CFG_SMC_UCODE_PATCH
up = (smc_uart_t *) cpmp-cp_dpmem[up-smc_rpbase];
 #endif
 
-   rbdf = (cbd_t *)cpmp-cp_dpmem[up-smc_rbase];
+rtx = (SerialBuffer *)cpmp-cp_dpmem[up-smc_rbase];
+   unsigned char  c;
 
/* Wait for character to show up.
*/
-   buf = (unsigned char *)rbdf-cbd_bufaddr;
-
-   while (rbdf-cbd_sc  BD_SC_EMPTY)
+   while (rtx-rxbd.cbd_sc  BD_SC_EMPTY)
WATCHDOG_RESET ();
 
-   c = *buf;
-   rbdf-cbd_sc |= BD_SC_EMPTY;
+#ifdef CONFIG_SMC_RXBUFLEN
+   /* the characters are read one by one, use the rxCharIndex to
know the next char to deliver */
+   c = *(unsigned char *) (rtx-rxbd.cbd_bufaddr+rtx-rxCharIndex);
+   rtx-rxCharIndex++;
+
+   /* check if all char are readout, then make prepare for next
receive */
+   if (rtx-rxCharIndex = rtx-rxbd.cbd_datlen)
+   {
+   rtx-rxCharIndex  = 0;
+   rtx-rxbd.cbd_sc |= BD_SC_EMPTY;
+   }
+#else
+   c = *(unsigned char *) (rtx-rxbd.cbd_bufaddr);
+   rtx-rxbd.cbd_sc |= BD_SC_EMPTY;
+#endif
 
return(c);
 }
@@ -363,19 +390,19 @@ smc_getc(void)
 static int
 smc_tstc(void)
 {
-   volatile cbd_t  *rbdf;
volatile smc_uart_t *up;
volatile immap_t*im = (immap_t *)CFG_IMMR;
volatile cpm8xx_t   *cpmp = (im-im_cpm);
+   SerialBuffer*rtx;
 
up = (smc_uart_t *)cpmp-cp_dparam[PROFF_SMC];
 #ifdef CFG_SMC_UCODE_PATCH
up = (smc_uart_t *) cpmp-cp_dpmem[up-smc_rpbase];
 #endif
 
-   rbdf = (cbd_t *)cpmp-cp_dpmem[up-smc_rbase];
+   rtx = (SerialBuffer *)cpmp-cp_dpmem[up-smc_rbase];
 
-   return(!(rbdf-cbd_sc  BD_SC_EMPTY));
+   return(!(rtx-rxbd.cbd_sc  BD_SC_EMPTY));
 }
 
 struct serial_device serial_smc_device =


 -Original Message-
 From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED]
 On Behalf Of Bigler, Stefan
 Sent: Wednesday, October 29, 2008 9:27 AM
 To: u-boot@lists.denx.de
 Subject: [U-Boot] RFC - How to speed up multiplexed input between
serial
 andnetwork?
 
 Hi
 
 We are trying to use U-Boot that it can be remote controlled over
 netconsole and in locally over the serial terminal.
 We were quite successful but we saw some latency issues on the serial
 terminal. The polling of the serial driver is too slow to get all
 characters. This does not allow you to e.g. to copy/paste, most of the
 characters are lost.
 
 We analyzed the code and tried to speed it up, without the required
 improvement.
 The tests are done with an [EMAIL PROTECTED] and an MPC8247.
 
 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
 
 The result is, that the serial interface is polled only every 15
 Millisecond.
 On the serial interface with a line-rate of 115200 we receive aprox
 10'000 Character every second. This is one character every 100
 Microsecond.
 
 The serial driver has one buffer-descriptor with the space for one
 character. This results in a maximal polling period of 100
Microseconds.
 
 The HW-FIFO for a MPC852T is 2 bytes.
 
 
 There are 2 possibilities to solve the problem:
 ---
 a) make the netconsole faster
 b) make serial more robust and allow more latency
 
 The better solution is of course to make the netconsole faster. But
can
 we reach 100 Microseconds?
 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.
 
 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.
 
 The copy/paste test shows the following result
 copy  paste
 0123456789 - 0 - first character
 
 
 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.
 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.
 
 I do not see how we can reduce this time even