[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xenstored: Fairly round-robin schedule work across all connections.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1185285050 -3600 # Node ID 2f22450e716d037aa654e0486f4fe7722ad6b2bb # Parent eff24408830c5356b130318565c4e7f8abf16070 xenstored: Fairly round-robin schedule work across all connections. Avoids total starvation under some workloads. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/xenstore/talloc.c | 18 ++++++- tools/xenstore/xenstored_core.c | 98 ++++++++++++++++++++-------------------- 2 files changed, 66 insertions(+), 50 deletions(-) diff -r eff24408830c -r 2f22450e716d tools/xenstore/talloc.c --- a/tools/xenstore/talloc.c Tue Jul 24 14:50:05 2007 +0100 +++ b/tools/xenstore/talloc.c Tue Jul 24 14:50:50 2007 +0100 @@ -97,6 +97,7 @@ struct talloc_chunk { struct talloc_chunk *next, *prev; struct talloc_chunk *parent, *child; struct talloc_reference_handle *refs; + unsigned int null_refs; /* references from null_context */ talloc_destructor_t destructor; const char *name; size_t size; @@ -189,6 +190,7 @@ void *_talloc(const void *context, size_ tc->child = NULL; tc->name = NULL; tc->refs = NULL; + tc->null_refs = 0; if (context) { struct talloc_chunk *parent = talloc_chunk_from_ptr(context); @@ -225,7 +227,11 @@ void talloc_set_destructor(const void *p */ void talloc_increase_ref_count(const void *ptr) { - talloc_reference(null_context, ptr); + struct talloc_chunk *tc; + if (ptr == NULL) return; + + tc = talloc_chunk_from_ptr(ptr); + tc->null_refs++; } /* @@ -285,6 +291,11 @@ static int talloc_unreference(const void if (context == NULL) { context = null_context; + } + + if ((context == null_context) && tc->null_refs) { + tc->null_refs--; + return 0; } for (h=tc->refs;h;h=h->next) { @@ -538,6 +549,11 @@ int talloc_free(void *ptr) } tc = talloc_chunk_from_ptr(ptr); + + if (tc->null_refs) { + tc->null_refs--; + return -1; + } if (tc->refs) { talloc_reference_destructor(tc->refs); diff -r eff24408830c -r 2f22450e716d tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Tue Jul 24 14:50:05 2007 +0100 +++ b/tools/xenstore/xenstored_core.c Tue Jul 24 14:50:50 2007 +0100 @@ -299,10 +299,14 @@ static void set_fd(int fd, fd_set *set, } -static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock) -{ - struct connection *i; +static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, + struct timeval **ptimeout) +{ + static struct timeval zero_timeout = { 0 }; + struct connection *conn; int max = -1; + + *ptimeout = NULL; FD_ZERO(inset); FD_ZERO(outset); @@ -314,13 +318,19 @@ static int initialize_set(fd_set *inset, if (xce_handle != -1) set_fd(xc_evtchn_fd(xce_handle), inset, &max); - list_for_each_entry(i, &connections, list) { - if (i->domain) - continue; - set_fd(i->fd, inset, &max); - if (!list_empty(&i->out_list)) - FD_SET(i->fd, outset); - } + list_for_each_entry(conn, &connections, list) { + if (conn->domain) { + if (domain_can_read(conn) || + (domain_can_write(conn) && + !list_empty(&conn->out_list))) + *ptimeout = &zero_timeout; + } else { + set_fd(conn->fd, inset, &max); + if (!list_empty(&conn->out_list)) + FD_SET(conn->fd, outset); + } + } + return max; } @@ -1709,6 +1719,7 @@ int main(int argc, char *argv[]) bool no_domain_init = false; const char *pidfile = NULL; int evtchn_fd = -1; + struct timeval *timeout; while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, NULL)) != -1) { @@ -1850,17 +1861,16 @@ int main(int argc, char *argv[]) evtchn_fd = xc_evtchn_fd(xce_handle); /* Get ready to listen to the tools. */ - max = initialize_set(&inset, &outset, *sock, *ro_sock); + max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout); /* Tell the kernel we're up and running. */ xenbus_notify_running(); /* Main loop. */ - /* FIXME: Rewrite so noone can starve. */ for (;;) { - struct connection *i; - - if (select(max+1, &inset, &outset, NULL, NULL) < 0) { + struct connection *conn, *old_conn; + + if (select(max+1, &inset, &outset, NULL, timeout) < 0) { if (errno == EINTR) continue; barf_perror("Select failed"); @@ -1882,41 +1892,31 @@ int main(int argc, char *argv[]) if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset)) handle_event(); - list_for_each_entry(i, &connections, list) { - if (i->domain) - continue; - - /* Operations can delete themselves or others - * (xs_release): list is not safe after input, - * so break. */ - if (FD_ISSET(i->fd, &inset)) { - handle_input(i); - break; + conn = list_entry(connections.next, typeof(*conn), list); + while (&conn->list != &connections) { + talloc_increase_ref_count(conn); + + if (conn->domain) { + if (domain_can_read(conn)) + handle_input(conn); + if (domain_can_write(conn) && + !list_empty(&conn->out_list)) + handle_output(conn); + } else { + if (FD_ISSET(conn->fd, &inset)) + handle_input(conn); + if (FD_ISSET(conn->fd, &outset)) + handle_output(conn); } - if (FD_ISSET(i->fd, &outset)) { - handle_output(i); - break; - } - } - - /* Handle all possible I/O for domain connections. */ - more: - list_for_each_entry(i, &connections, list) { - if (!i->domain) - continue; - - if (domain_can_read(i)) { - handle_input(i); - goto more; - } - - if (domain_can_write(i) && !list_empty(&i->out_list)) { - handle_output(i); - goto more; - } - } - - max = initialize_set(&inset, &outset, *sock, *ro_sock); + + old_conn = conn; + conn = list_entry(old_conn->list.next, + typeof(*conn), list); + talloc_free(old_conn); + } + + max = initialize_set(&inset, &outset, *sock, *ro_sock, + &timeout); } } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |