mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
Fix 100% libvirt CPU usage when --timeout is set
This commit is contained in:
parent
31135bff29
commit
9a86716446
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
Fri Feb 6 14:43:10 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Fix 100% CPU bound loop when libvirtd --timeout is used
|
||||||
|
* qemud/event.c: Don't assume pthread_t is equivalent to an
|
||||||
|
int, explicitly track whether event loop is active with a
|
||||||
|
flag independantly of the threadLeader variable
|
||||||
|
* qemud/qemud.c: Don't register/unregister shutdown timer
|
||||||
|
on each loop. Register once, and activate/deactivate when
|
||||||
|
required
|
||||||
|
|
||||||
Thu Feb 5 19:28:10 GMT 2009 John Levon <john.levon@sun.com>
|
Thu Feb 5 19:28:10 GMT 2009 John Levon <john.levon@sun.com>
|
||||||
|
|
||||||
* src/domain_conf.c: Check the last error, not the last
|
* src/domain_conf.c: Check the last error, not the last
|
||||||
|
@ -68,6 +68,7 @@ struct virEventTimeout {
|
|||||||
/* State for the main event loop */
|
/* State for the main event loop */
|
||||||
struct virEventLoop {
|
struct virEventLoop {
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
|
int running;
|
||||||
pthread_t leader;
|
pthread_t leader;
|
||||||
int wakeupfd[2];
|
int wakeupfd[2];
|
||||||
int handlesCount;
|
int handlesCount;
|
||||||
@ -521,6 +522,7 @@ int virEventRunOnce(void) {
|
|||||||
int ret, timeout, nfds;
|
int ret, timeout, nfds;
|
||||||
|
|
||||||
virEventLock();
|
virEventLock();
|
||||||
|
eventLoop.running = 1;
|
||||||
eventLoop.leader = pthread_self();
|
eventLoop.leader = pthread_self();
|
||||||
if ((nfds = virEventMakePollFDs(&fds)) < 0) {
|
if ((nfds = virEventMakePollFDs(&fds)) < 0) {
|
||||||
virEventUnlock();
|
virEventUnlock();
|
||||||
@ -572,7 +574,7 @@ int virEventRunOnce(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
eventLoop.leader = 0;
|
eventLoop.running = 0;
|
||||||
virEventUnlock();
|
virEventUnlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -611,7 +613,9 @@ int virEventInit(void)
|
|||||||
static int virEventInterruptLocked(void)
|
static int virEventInterruptLocked(void)
|
||||||
{
|
{
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
if (pthread_self() == eventLoop.leader)
|
|
||||||
|
if (!eventLoop.running ||
|
||||||
|
pthread_self() == eventLoop.leader)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c))
|
if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c))
|
||||||
|
@ -2031,11 +2031,15 @@ static int qemudOneLoop(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemudInactiveTimer(int timer ATTRIBUTE_UNUSED, void *data) {
|
static void qemudInactiveTimer(int timerid, void *data) {
|
||||||
struct qemud_server *server = (struct qemud_server *)data;
|
struct qemud_server *server = (struct qemud_server *)data;
|
||||||
DEBUG0("Got inactive timer expiry");
|
|
||||||
if (!virStateActive()) {
|
if (virStateActive() ||
|
||||||
DEBUG0("No state active, shutting down");
|
server->clients) {
|
||||||
|
DEBUG0("Timer expired but still active, not shutting down");
|
||||||
|
virEventUpdateTimeoutImpl(timerid, -1);
|
||||||
|
} else {
|
||||||
|
DEBUG0("Timer expired and inactive, shutting down");
|
||||||
server->shutdown = 1;
|
server->shutdown = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2066,9 +2070,18 @@ static void qemudFreeClient(struct qemud_client *client) {
|
|||||||
static int qemudRunLoop(struct qemud_server *server) {
|
static int qemudRunLoop(struct qemud_server *server) {
|
||||||
int timerid = -1;
|
int timerid = -1;
|
||||||
int ret = -1, i;
|
int ret = -1, i;
|
||||||
|
int timerActive = 0;
|
||||||
|
|
||||||
virMutexLock(&server->lock);
|
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)
|
if (min_workers > max_workers)
|
||||||
max_workers = min_workers;
|
max_workers = min_workers;
|
||||||
|
|
||||||
@ -2089,11 +2102,21 @@ static int qemudRunLoop(struct qemud_server *server) {
|
|||||||
* if any drivers have active state, if not
|
* if any drivers have active state, if not
|
||||||
* shutdown after timeout seconds
|
* shutdown after timeout seconds
|
||||||
*/
|
*/
|
||||||
if (timeout > 0 && !virStateActive() && !server->clients) {
|
if (timeout > 0) {
|
||||||
timerid = virEventAddTimeoutImpl(timeout*1000,
|
if (timerActive) {
|
||||||
qemudInactiveTimer,
|
if (server->clients) {
|
||||||
server, NULL);
|
DEBUG("Deactivating shutdown timer %d", timerid);
|
||||||
DEBUG("Scheduling 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);
|
virMutexUnlock(&server->lock);
|
||||||
@ -2147,15 +2170,6 @@ static int qemudRunLoop(struct qemud_server *server) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unregister any timeout that's active, since we
|
|
||||||
* just had an event processed
|
|
||||||
*/
|
|
||||||
if (timerid != -1) {
|
|
||||||
DEBUG("Removing shutdown timer %d", timerid);
|
|
||||||
virEventRemoveTimeoutImpl(timerid);
|
|
||||||
timerid = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server->shutdown) {
|
if (server->shutdown) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user