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

Re: [Xen-devel] [PATCH RFC] tools/ocaml/xb: Correct calculations of data/space the ring



Andrew Cooper, le Wed 28 Oct 2015 16:05:36 +0000, a écrit :
> @@ -62,22 +62,32 @@ CAMLprim value ml_interface_read(value ml_interface,
>  
>       xen_mb();
>  
> -     if ((prod - cons) > XENSTORE_RING_SIZE)
> +     if (((prod - cons) > XENSTORE_RING_SIZE) ||
> +            ((cons - prod) < -XENSTORE_RING_SIZE))

prod and cons are uint32_t, so the difference will still be unsigned.
IIRC the test is not bogus even when prod wraps around, (prod - cons)
will still correctly be the difference between both, modulo 2^32.

Indeed, the read side also needs the same two-memcpy fix.

> +     /* Check for any pending data at all. */
> +     total_data = prod - cons;
> +     if (total_data == 0) {
...
> +     else if (total_data > len)
> +             /* Some data - make a partial read. */
> +             len = total_data;
> +
> +     /* Check whether data crosses the end of the ring. */
> +     data = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
> +     if (len <= data)
> +             /* Data within the remaining part of the ring. */
> +             memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), len);
> +     else {
> +             /* Data crosses the ring boundary. Read both halves. */
> +             memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), data);
> +             memcpy(buffer + data, intf->req, len - data);
> +     }
> +

That looks right and nice-looking to me.

>       xen_mb();
>       intf->req_cons += len;
>       result = len;
> @@ -100,7 +110,7 @@ CAMLprim value ml_interface_write(value ml_interface,
>  
>       struct xenstore_domain_interface *intf = interface->addr;
>       XENSTORE_RING_IDX cons, prod;
> -     int can_write;
> +     int total_space, space;
>       uint32_t connection;
>  
>       cons = *(volatile uint32_t*)&intf->rsp_cons;
> @@ -111,17 +121,33 @@ CAMLprim value ml_interface_write(value ml_interface,
>               caml_raise_constant(*caml_named_value("Xb.Reconnect"));
>  
>       xen_mb();
> -     if ( (prod - cons) >= XENSTORE_RING_SIZE ) {
> +
> +     if (((prod - cons) > XENSTORE_RING_SIZE) ||
> +            ((cons - prod) < -XENSTORE_RING_SIZE))

Ditto.

> +     /* Check for space to write the full message. */
> +     total_space = prod - cons;
> +     if (total_space == 0) {

Shouldn't that be total_space == XENSTORE_RING_SIZE?

> +             /* No space at all - exit having done nothing. */
>               result = 0;
>               goto exit;
>       }
> +     else if (total_space < len)
> +             /* Some space - make a partial write. */
> +             len = total_space;
> +
> +     /* Check for space until the ring wraps. */
> +     space = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
> +     if (len <= space )
> +             /* Message fits inside the remaining part of the ring. */
> +             memcpy(intf->rsp + MASK_XENSTORE_IDX(prod), buffer, len);
> +     else {
> +             /* Message wraps around the end of the ring. Write both halves. 
> */
> +             memcpy(intf->rsp + MASK_XENSTORE_IDX(prod), buffer, space);
> +             memcpy(intf->rsp, buffer + space, len - space);
> +     }

That looks right and nicer-looking than my attempt :)

Samuel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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