[PATCH v5 4/6] xen/console: use memcpy() in console_init_ring()

dmukhin@xen.org posted 6 patches 2 days, 3 hours ago
[PATCH v5 4/6] xen/console: use memcpy() in console_init_ring()
Posted by dmukhin@xen.org 2 days, 3 hours ago
From: Denis Mukhin <dmukhin@ford.com> 

Make console_init_ring() more efficient by using memcpy()'s, rather than
copying the ring a byte at a time.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v4:
- new patch
---
 xen/drivers/char/console.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index ef9131439bba..3ad86fd436e2 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -463,7 +463,7 @@ static void cf_check conring_dump_keyhandler(unsigned char key)
 void __init console_init_ring(void)
 {
     char *ring;
-    unsigned int i, order, memflags;
+    unsigned int start, size, chunk, order, memflags;
     unsigned long flags;
 
     if ( !opt_conring_size )
@@ -479,11 +479,23 @@ void __init console_init_ring(void)
     opt_conring_size = PAGE_SIZE << order;
 
     nrspin_lock_irqsave(&console_lock, flags);
-    for ( i = conringc ; i != conringp; i++ )
-        ring[i & (opt_conring_size - 1)] = conring[i & (conring_size - 1)];
+
+    start = conringc & (conring_size - 1);
+    size = min(conringp - conringc, conring_size);
+    chunk = min(size, conring_size - start);
+
+    memcpy(&ring[0], &conring[start], chunk);
+    if ( size > chunk )
+        memcpy(&ring[chunk], &conring[0], size - chunk);
+
+    /* Data is moved to [0..size), re-position conring pointers. */
+    conringc = 0;
+    conringp = size;
+
     conring = ring;
     smp_wmb(); /* Allow users of console_force_unlock() to see larger buffer. */
     conring_size = opt_conring_size;
+
     nrspin_unlock_irqrestore(&console_lock, flags);
 
     printk("Allocated console ring of %u KiB.\n", opt_conring_size >> 10);
-- 
2.52.0