Eliminate excessive CPU consumption when redirecting UART over SSH
Redirecting the external UART via SSH caused the console-server,
console-client, and dropbear to consume ~30% of the available CPU each
when a large amount of data was being written to the UART output.
Buffering all of the small 16550 FIFO bytes into a larger packet and
then sending that to the SSH SW allows more efficient transmission
over the ethernet connection.
Tested this by "ssh root@<bmc.ip.addr> -p 2200" on a system running a
CentOS distribution. Using a BASH console run a large binary file
through "od -t x1 <fname>" to create a large amount of traffic. At
the BMC console run "top" to review the CPU usage. My experience is
after this change is applied:
console-server: ~25% CPU
dropbear: ~3% CPU
console-client: ~1% CPU
Change-Id: Ibabfd285e97a487e7ff040e1cb3159fbff360328
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
diff --git a/ringbuffer.c b/ringbuffer.c
index 3edab0d..964ab43 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -108,7 +108,7 @@
free(rbc);
}
-static size_t ringbuffer_len(struct ringbuffer_consumer *rbc)
+size_t ringbuffer_len(struct ringbuffer_consumer *rbc)
{
if (rbc->pos <= rbc->rb->tail)
return rbc->rb->tail - rbc->pos;
@@ -148,6 +148,9 @@
if (len >= rb->size)
return -1;
+ if (len == 0)
+ return 0;
+
/* Ensure there is at least len bytes of space available.
*
* If a client doesn't have sufficient space, perform a blocking write
@@ -176,6 +179,7 @@
memcpy(rb->buf, data, len);
rb->tail += len;
+
/* Inform consumers of new data in non-blocking mode, by calling
* ->poll_fn with 0 force_len */
for (i = 0; i < rb->n_consumers; i++) {