ia64/xen-unstable
changeset 7373:40b4860f554a
Add memory barriers to console ring accesses. Similar to what
Rusty uses for xenbus messaging.
Signed-off-by: Keir Fraser <keir@xensource.com>
Rusty uses for xenbus messaging.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Wed Oct 12 21:10:14 2005 +0100 (2005-10-12) |
parents | d6e0eb8622cd |
children | 48f542f8d906 |
files | linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c tools/console/daemon/io.c |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Wed Oct 12 20:58:51 2005 +0100 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Wed Oct 12 21:10:14 2005 +0100 1.3 @@ -34,14 +34,18 @@ int xencons_ring_send(const char *data, 1.4 { 1.5 int sent = 0; 1.6 struct xencons_interface *intf = xencons_interface(); 1.7 + XENCONS_RING_IDX cons, prod; 1.8 1.9 - while ((sent < len) && 1.10 - (intf->out_prod - intf->out_cons) < sizeof(intf->out)) { 1.11 - intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] = 1.12 - data[sent]; 1.13 - intf->out_prod++; 1.14 - sent++; 1.15 - } 1.16 + cons = intf->out_cons; 1.17 + prod = intf->out_prod; 1.18 + mb(); 1.19 + BUG_ON((prod - cons) > sizeof(intf->out)); 1.20 + 1.21 + while ((sent < len) && ((prod - cons) < sizeof(intf->out))) 1.22 + intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; 1.23 + 1.24 + wmb(); 1.25 + intf->out_prod = prod; 1.26 1.27 /* Use evtchn: this is called early, before irq is set up. */ 1.28 notify_remote_via_evtchn(xen_start_info->console_evtchn); 1.29 @@ -52,16 +56,23 @@ int xencons_ring_send(const char *data, 1.30 static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) 1.31 { 1.32 struct xencons_interface *intf = xencons_interface(); 1.33 + XENCONS_RING_IDX cons, prod; 1.34 1.35 - while (intf->in_cons != intf->in_prod) { 1.36 + cons = intf->in_cons; 1.37 + prod = intf->in_prod; 1.38 + mb(); 1.39 + BUG_ON((prod - cons) > sizeof(intf->in)); 1.40 + 1.41 + while (cons != prod) { 1.42 if (xencons_receiver != NULL) 1.43 xencons_receiver( 1.44 - intf->in + MASK_XENCONS_IDX(intf->in_cons, 1.45 - intf->in), 1.46 + intf->in + MASK_XENCONS_IDX(cons++, intf->in), 1.47 1, regs); 1.48 - intf->in_cons++; 1.49 } 1.50 1.51 + wmb(); 1.52 + intf->in_cons = cons; 1.53 + 1.54 return IRQ_HANDLED; 1.55 } 1.56
2.1 --- a/tools/console/daemon/io.c Wed Oct 12 20:58:51 2005 +0100 2.2 +++ b/tools/console/daemon/io.c Wed Oct 12 21:10:14 2005 +0100 2.3 @@ -79,44 +79,43 @@ static void evtchn_notify(struct domain 2.4 static void buffer_append(struct domain *dom) 2.5 { 2.6 struct buffer *buffer = &dom->buffer; 2.7 - size_t size; 2.8 - XENCONS_RING_IDX oldcons; 2.9 - int notify = 0; 2.10 + XENCONS_RING_IDX cons, prod, size; 2.11 struct xencons_interface *intf = dom->interface; 2.12 2.13 - while ((size = (intf->out_prod - intf->out_cons)) != 0) { 2.14 - notify = 1; 2.15 - 2.16 - if ((buffer->capacity - buffer->size) < size) { 2.17 - buffer->capacity += (size + 1024); 2.18 - buffer->data = realloc(buffer->data, buffer->capacity); 2.19 - if (buffer->data == NULL) { 2.20 - dolog(LOG_ERR, "Memory allocation failed"); 2.21 - exit(ENOMEM); 2.22 - } 2.23 - } 2.24 + cons = intf->out_cons; 2.25 + prod = intf->out_prod; 2.26 + mb(); 2.27 2.28 - oldcons = intf->out_cons; 2.29 - while ((intf->out_cons - oldcons) < size) { 2.30 - buffer->data[buffer->size] = intf->out[ 2.31 - MASK_XENCONS_IDX(intf->out_cons, intf->out)]; 2.32 - buffer->size++; 2.33 - intf->out_cons++; 2.34 - } 2.35 + size = prod - cons; 2.36 + if ((size == 0) || (size > sizeof(intf->out))) 2.37 + return; 2.38 2.39 - if (buffer->max_capacity && 2.40 - buffer->size > buffer->max_capacity) { 2.41 - memmove(buffer->data + (buffer->size - 2.42 - buffer->max_capacity), 2.43 - buffer->data, buffer->max_capacity); 2.44 - buffer->data = realloc(buffer->data, 2.45 - buffer->max_capacity); 2.46 - buffer->capacity = buffer->max_capacity; 2.47 + if ((buffer->capacity - buffer->size) < size) { 2.48 + buffer->capacity += (size + 1024); 2.49 + buffer->data = realloc(buffer->data, buffer->capacity); 2.50 + if (buffer->data == NULL) { 2.51 + dolog(LOG_ERR, "Memory allocation failed"); 2.52 + exit(ENOMEM); 2.53 } 2.54 } 2.55 2.56 - if (notify) 2.57 - evtchn_notify(dom); 2.58 + while (cons != prod) 2.59 + buffer->data[buffer->size++] = intf->out[ 2.60 + MASK_XENCONS_IDX(cons++, intf->out)]; 2.61 + 2.62 + mb(); 2.63 + intf->out_cons = cons; 2.64 + evtchn_notify(dom); 2.65 + 2.66 + if (buffer->max_capacity && 2.67 + buffer->size > buffer->max_capacity) { 2.68 + memmove(buffer->data + (buffer->size - 2.69 + buffer->max_capacity), 2.70 + buffer->data, buffer->max_capacity); 2.71 + buffer->data = realloc(buffer->data, 2.72 + buffer->max_capacity); 2.73 + buffer->capacity = buffer->max_capacity; 2.74 + } 2.75 } 2.76 2.77 static bool buffer_empty(struct buffer *buffer) 2.78 @@ -419,10 +418,14 @@ static void handle_tty_read(struct domai 2.79 char msg[80]; 2.80 int i; 2.81 struct xencons_interface *intf = dom->interface; 2.82 - XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons; 2.83 + XENCONS_RING_IDX cons, prod; 2.84 2.85 - if (sizeof(intf->in) > filled) 2.86 - len = sizeof(intf->in) - filled; 2.87 + cons = intf->in_cons; 2.88 + prod = intf->in_prod; 2.89 + mb(); 2.90 + 2.91 + if (sizeof(intf->in) > (prod - cons)) 2.92 + len = sizeof(intf->in) - (prod - cons); 2.93 if (len > sizeof(msg)) 2.94 len = sizeof(msg); 2.95 2.96 @@ -441,10 +444,11 @@ static void handle_tty_read(struct domai 2.97 } 2.98 } else if (domain_is_valid(dom->domid)) { 2.99 for (i = 0; i < len; i++) { 2.100 - intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] = 2.101 + intf->in[MASK_XENCONS_IDX(prod++, intf->in)] = 2.102 msg[i]; 2.103 - intf->in_prod++; 2.104 } 2.105 + wmb(); 2.106 + intf->in_prod = prod; 2.107 evtchn_notify(dom); 2.108 } else { 2.109 close(dom->tty_fd);