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>
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);