[libvirt] [PATCH 1/7] Reduce performance overhead of the global log buffer

Daniel P. Berrange berrange at redhat.com
Mon Mar 3 19:18:06 UTC 2014


With the vast number of log debug statements in the code, the
logging framework has a measurable performance impact on libvirt
code, particularly in the daemon event loop.

The global log buffer records every single log message triggered
whether anyone cares to see them or not. This makes it impossible
to eliminate the overhead of printf format expansions in any of
the logging code. It is possible to disable the global log buffer
in libvirtd itself, but this doesn't help client side library
code. Also even if disabled by the config file, the existance of
the feature makes other performance improvements in the logging
layer impossible.

Instead of logging every single message to the global buffer, only
log messages that pass the log filters. This if libvirtd is set
to have log_filters="1:libvirt 1:qemu" the global log buffer will
only get filled with those messages instead of everything. This
reduces the performance burden, as well as improving the signal
to noise ratio of the log buffer.

As a quick benchmark, a demo program that registers 500 file
descriptors with the event loop (eg equiv of 500 QEMU monitor
commands), creates pending read I/O on every FD, and then runs
virEventRunDefaultImpl() took 1 minute 40 seconds todo 51200
iterations with nearly all the time shown against the logging
code. After this optimization it only takes 4.6 seconds.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/util/virlog.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/util/virlog.c b/src/util/virlog.c
index 68af0f3..e9bd61b 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -833,7 +833,7 @@ virLogVMessage(virLogSource source,
         emit = false;
     }
 
-    if (!emit && ((virLogBuffer == NULL) || (virLogSize <= 0)))
+    if (!emit)
         goto cleanup;
 
     /*
@@ -862,11 +862,7 @@ virLogVMessage(virLogSource source,
     virLogStr(timestamp);
     virLogStr(": ");
     virLogStr(msg);
-    virLogUnlock();
-    if (!emit)
-        goto cleanup;
 
-    virLogLock();
     for (i = 0; i < virLogNbOutputs; i++) {
         if (priority >= virLogOutputs[i].priority) {
             if (virLogOutputs[i].logVersion) {
-- 
1.8.5.3




More information about the libvir-list mailing list