From: Denis Mukhin <[email protected]> Make console_init_ring() more efficient by using memcpy()'s, rather than copying the ring a byte at a time.
Suggested-by: Andrew Cooper <[email protected]> Signed-off-by: Denis Mukhin <[email protected]> --- 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
