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