WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xenstored: Fairly round-robin schedule wo

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xenstored: Fairly round-robin schedule work across all connections.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Jul 2007 03:20:08 -0700
Delivery-date: Fri, 27 Jul 2007 03:18:30 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xenstored: Fairly round-robin schedule work across all connections., Xen patchbot-unstable <=