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

[Xen-changelog] Add memory barriers to console ring accesses. Similar to what



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 40b4860f554a91d537aeb021a038ffd4b335a221
# Parent  d6e0eb8622cdd514a1f15e23dccac979cd611d18
Add memory barriers to console ring accesses. Similar to what
Rusty uses for xenbus messaging.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r d6e0eb8622cd -r 40b4860f554a 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Wed Oct 12 
19:58:51 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Wed Oct 12 
20:10:14 2005
@@ -34,14 +34,18 @@
 {
        int sent = 0;
        struct xencons_interface *intf = xencons_interface();
+       XENCONS_RING_IDX cons, prod;
 
-       while ((sent < len) &&
-              (intf->out_prod - intf->out_cons) < sizeof(intf->out)) {
-               intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] =
-                       data[sent];
-               intf->out_prod++;
-               sent++;
-       }
+       cons = intf->out_cons;
+       prod = intf->out_prod;
+       mb();
+       BUG_ON((prod - cons) > sizeof(intf->out));
+
+       while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
+               intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
+
+       wmb();
+       intf->out_prod = prod;
 
        /* Use evtchn: this is called early, before irq is set up. */
        notify_remote_via_evtchn(xen_start_info->console_evtchn);
@@ -52,15 +56,22 @@
 static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
 {
        struct xencons_interface *intf = xencons_interface();
+       XENCONS_RING_IDX cons, prod;
 
-       while (intf->in_cons != intf->in_prod) {
+       cons = intf->in_cons;
+       prod = intf->in_prod;
+       mb();
+       BUG_ON((prod - cons) > sizeof(intf->in));
+
+       while (cons != prod) {
                if (xencons_receiver != NULL)
                        xencons_receiver(
-                               intf->in + MASK_XENCONS_IDX(intf->in_cons,
-                                                           intf->in),
+                               intf->in + MASK_XENCONS_IDX(cons++, intf->in),
                                1, regs);
-               intf->in_cons++;
        }
+
+       wmb();
+       intf->in_cons = cons;
 
        return IRQ_HANDLED;
 }
diff -r d6e0eb8622cd -r 40b4860f554a tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Wed Oct 12 19:58:51 2005
+++ b/tools/console/daemon/io.c Wed Oct 12 20:10:14 2005
@@ -79,44 +79,43 @@
 static void buffer_append(struct domain *dom)
 {
        struct buffer *buffer = &dom->buffer;
-       size_t size;
-       XENCONS_RING_IDX oldcons;
-       int notify = 0;
+       XENCONS_RING_IDX cons, prod, size;
        struct xencons_interface *intf = dom->interface;
 
-       while ((size = (intf->out_prod - intf->out_cons)) != 0) {
-               notify = 1;
-
-               if ((buffer->capacity - buffer->size) < size) {
-                       buffer->capacity += (size + 1024);
-                       buffer->data = realloc(buffer->data, buffer->capacity);
-                       if (buffer->data == NULL) {
-                               dolog(LOG_ERR, "Memory allocation failed");
-                               exit(ENOMEM);
-                       }
-               }
-
-               oldcons = intf->out_cons;
-               while ((intf->out_cons - oldcons) < size) {
-                       buffer->data[buffer->size] = intf->out[
-                               MASK_XENCONS_IDX(intf->out_cons, intf->out)];
-                       buffer->size++;
-                       intf->out_cons++;
-               }
-
-               if (buffer->max_capacity &&
-                   buffer->size > buffer->max_capacity) {
-                       memmove(buffer->data + (buffer->size -
-                                               buffer->max_capacity),
-                               buffer->data, buffer->max_capacity);
-                       buffer->data = realloc(buffer->data,
-                                              buffer->max_capacity);
-                       buffer->capacity = buffer->max_capacity;
-               }
-       }
-
-       if (notify)
-               evtchn_notify(dom);
+       cons = intf->out_cons;
+       prod = intf->out_prod;
+       mb();
+
+       size = prod - cons;
+       if ((size == 0) || (size > sizeof(intf->out)))
+               return;
+
+       if ((buffer->capacity - buffer->size) < size) {
+               buffer->capacity += (size + 1024);
+               buffer->data = realloc(buffer->data, buffer->capacity);
+               if (buffer->data == NULL) {
+                       dolog(LOG_ERR, "Memory allocation failed");
+                       exit(ENOMEM);
+               }
+       }
+
+       while (cons != prod)
+               buffer->data[buffer->size++] = intf->out[
+                       MASK_XENCONS_IDX(cons++, intf->out)];
+
+       mb();
+       intf->out_cons = cons;
+       evtchn_notify(dom);
+
+       if (buffer->max_capacity &&
+           buffer->size > buffer->max_capacity) {
+               memmove(buffer->data + (buffer->size -
+                                       buffer->max_capacity),
+                       buffer->data, buffer->max_capacity);
+               buffer->data = realloc(buffer->data,
+                                      buffer->max_capacity);
+               buffer->capacity = buffer->max_capacity;
+       }
 }
 
 static bool buffer_empty(struct buffer *buffer)
@@ -419,10 +418,14 @@
        char msg[80];
        int i;
        struct xencons_interface *intf = dom->interface;
-       XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons;
-
-       if (sizeof(intf->in) > filled)
-               len = sizeof(intf->in) - filled;
+       XENCONS_RING_IDX cons, prod;
+
+       cons = intf->in_cons;
+       prod = intf->in_prod;
+       mb();
+
+       if (sizeof(intf->in) > (prod - cons))
+               len = sizeof(intf->in) - (prod - cons);
        if (len > sizeof(msg))
                len = sizeof(msg);
 
@@ -441,10 +444,11 @@
                }
        } else if (domain_is_valid(dom->domid)) {
                for (i = 0; i < len; i++) {
-                       intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] =
+                       intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
                                msg[i];
-                       intf->in_prod++;
-               }
+               }
+               wmb();
+               intf->in_prod = prod;
                evtchn_notify(dom);
        } else {
                close(dom->tty_fd);

_______________________________________________
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®.