[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |