A couple of bugs conspired to make libvirtd use 100% CPU usage when the --timeout option is used. This is the default for qemu:///session instance which are auto-spawned, so quite annoying! eg libvirt --timeout=30 - The qemudRunLoop() method was registering a timeout on every iteration of the loop, when it considered itself inactive, even if already registered - virEventInteruptLocked() was looking at eventLoop.leader and comparing to pthread_self() before anyone used the event loop. 'leader' was 0 at this point so it thought it had to wake someone up even though no one was waiting in the event loop. The latter bug conspired with the former, so the act of registering the timeout, caused it to immediately see a wakeup signal on the following poll. So it did another loop iteration, adding another timer, getting woken up again, etc 100% cpu follows. Another minor problem was that when completing an event loop iteration, we reset eventloop.leader to '0'. It is not safe to assume that pthread_t is an integer like this. The solution is to track when something is using the event loop explicitly, and not rely on the 'leader' variable, unless we know a thread is active. Finally we never de-registered the shutdown timeout if a new client turned up while we were counting down. This patch addresses all these flaws Daniel Index: qemud/event.c =================================================================== RCS file: /data/cvs/libvirt/qemud/event.c,v retrieving revision 1.17 diff -u -p -u -r1.17 event.c --- qemud/event.c 22 Dec 2008 12:55:47 -0000 1.17 +++ qemud/event.c 4 Feb 2009 14:40:09 -0000 @@ -68,6 +68,7 @@ struct virEventTimeout { /* State for the main event loop */ struct virEventLoop { pthread_mutex_t lock; + int running; pthread_t leader; int wakeupfd[2]; int handlesCount; @@ -521,6 +522,7 @@ int virEventRunOnce(void) { int ret, timeout, nfds; virEventLock(); + eventLoop.running = 1; eventLoop.leader = pthread_self(); if ((nfds = virEventMakePollFDs(&fds)) < 0) { virEventUnlock(); @@ -572,7 +574,7 @@ int virEventRunOnce(void) { return -1; } - eventLoop.leader = 0; + eventLoop.running = 0; virEventUnlock(); return 0; } @@ -611,7 +613,9 @@ int virEventInit(void) static int virEventInterruptLocked(void) { char c = '\0'; - if (pthread_self() == eventLoop.leader) + + if (!eventLoop.running || + pthread_self() == eventLoop.leader) return 0; if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c)) Index: qemud/qemud.c =================================================================== RCS file: /data/cvs/libvirt/qemud/qemud.c,v retrieving revision 1.138 diff -u -p -u -r1.138 qemud.c --- qemud/qemud.c 28 Jan 2009 11:31:39 -0000 1.138 +++ qemud/qemud.c 4 Feb 2009 14:40:09 -0000 @@ -2048,9 +2048,18 @@ static void qemudFreeClient(struct qemud static int qemudRunLoop(struct qemud_server *server) { int timerid = -1; int ret = -1, i; + int timerActive = 0; virMutexLock(&server->lock); + if (timeout > 0 && + (timerid = virEventAddTimeoutImpl(-1, + qemudInactiveTimer, + server, NULL)) < 0) { + VIR_ERROR0(_("Failed to register shutdown timeout")); + return -1; + } + if (min_workers > max_workers) max_workers = min_workers; @@ -2071,11 +2080,21 @@ static int qemudRunLoop(struct qemud_ser * if any drivers have active state, if not * shutdown after timeout seconds */ - if (timeout > 0 && !virStateActive() && !server->clients) { - timerid = virEventAddTimeoutImpl(timeout*1000, - qemudInactiveTimer, - server, NULL); - DEBUG("Scheduling shutdown timer %d", timerid); + if (timeout > 0) { + if (timerActive) { + if (server->clients) { + DEBUG("Deactivating shutdown timer %d", timerid); + virEventUpdateTimeoutImpl(timerid, -1); + timerActive = 0; + } + } else { + if (!virStateActive() && + !server->clients) { + DEBUG("Activating shutdown timer %d", timerid); + virEventUpdateTimeoutImpl(timerid, timeout * 1000); + timerActive = 1; + } + } } virMutexUnlock(&server->lock); -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list