[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvmloader: Properly block on xenstore daemon rather than merely yielding.



# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1287588992 -3600
# Node ID c7c972f91663a9bfef007a828e91653fe561b2c3
# Parent  ac7f64d5577bccc0d87c6c7b28d7845d0279a670
hvmloader: Properly block on xenstore daemon rather than merely yielding.

Signed-off-by: Keir Fraser <keir@xxxxxxx>
---
 tools/firmware/hvmloader/util.h   |   10 ++++++++++
 tools/firmware/hvmloader/xenbus.c |   34 ++++++++++++++++++++++------------
 2 files changed, 32 insertions(+), 12 deletions(-)

diff -r ac7f64d5577b -r c7c972f91663 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Wed Oct 20 09:56:36 2010 +0100
+++ b/tools/firmware/hvmloader/util.h   Wed Oct 20 16:36:32 2010 +0100
@@ -33,6 +33,16 @@ static inline int test_bit(unsigned int 
 static inline int test_bit(unsigned int b, void *p)
 {
     return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7)));
+}
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+    int oldbit;
+    asm volatile (
+        "lock ; btrl %2,%1 ; sbbl %0,%0"
+        : "=r" (oldbit), "=m" (*(volatile long *)addr)
+        : "Ir" (nr), "m" (*(volatile long *)addr) : "memory");
+    return oldbit;
 }
 
 /* MSR access */
diff -r ac7f64d5577b -r c7c972f91663 tools/firmware/hvmloader/xenbus.c
--- a/tools/firmware/hvmloader/xenbus.c Wed Oct 20 09:56:36 2010 +0100
+++ b/tools/firmware/hvmloader/xenbus.c Wed Oct 20 16:36:32 2010 +0100
@@ -25,9 +25,9 @@
 #include <xen/hvm/params.h>
 #include <xen/io/xs_wire.h>
 
-struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
-evtchn_port_t event;                     /* Event-channel to dom0 */
-char payload[XENSTORE_PAYLOAD_MAX + 1];  /* Unmarshalling area */
+static struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
+static evtchn_port_t event;                     /* Event-channel to dom0 */
+static char payload[XENSTORE_PAYLOAD_MAX + 1];  /* Unmarshalling area */
 
 /* Connect our xenbus client to the backend.
  * Call once, before any other xenbus actions. */
@@ -69,6 +69,19 @@ void xenbus_shutdown(void)
     rings = NULL;
 }
 
+static void ring_wait(void)
+{
+    struct shared_info *shinfo = get_shared_info();
+    struct sched_poll poll;
+
+    memset(&poll, 0, sizeof(poll));
+    set_xen_guest_handle(poll.ports, &event);
+    poll.nr_ports = 1;
+
+    while ( !test_and_clear_bit(event, shinfo->evtchn_pending) )
+        hypercall_sched_op(SCHEDOP_poll, &poll);
+}
+
 /* Helper functions: copy data in and out of the ring */
 static void ring_write(char *data, uint32_t len)
 {
@@ -79,8 +92,9 @@ static void ring_write(char *data, uint3
     while ( len )
     {
         /* Don't overrun the consumer pointer */
-        part = (XENSTORE_RING_SIZE - 1) -
-            MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons);
+        while ( (part = (XENSTORE_RING_SIZE - 1) -
+                 MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons)) == 0 )
+            ring_wait();
         /* Don't overrun the end of the ring */
         if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod)) )
             part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod);
@@ -92,9 +106,6 @@ static void ring_write(char *data, uint3
         barrier(); /* = wmb before prod write, rmb before next cons read */
         rings->req_prod += part;
         len -= part;
-
-        if ( len )
-            hypercall_sched_op(SCHEDOP_yield, NULL);
     }
 }
 
@@ -107,7 +118,9 @@ static void ring_read(char *data, uint32
     while ( len )
     {
         /* Don't overrun the producer pointer */
-        part = MASK_XENSTORE_IDX(rings->rsp_prod - rings->rsp_cons);
+        while ( (part = MASK_XENSTORE_IDX(rings->rsp_prod -
+                                          rings->rsp_cons)) == 0 )
+            ring_wait();
         /* Don't overrun the end of the ring */
         if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons)) )
             part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons);
@@ -119,9 +132,6 @@ static void ring_read(char *data, uint32
         barrier(); /* = wmb before cons write, rmb before next prod read */
         rings->rsp_cons += part;
         len -= part;
-        
-        if ( len )
-            hypercall_sched_op(SCHEDOP_yield, NULL);
     }
 }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.