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

Re: [Xen-devel] [PATCH 4/5] xen: Add V4V implementation



>>> On 28.06.12 at 18:26, Jean Guyader <jean.guyader@xxxxxxxxxx> wrote:
> --- /dev/null
> +++ b/xen/include/public/v4v.h
> @@ -0,0 +1,240 @@
> +/******************************************************************************
> + * V4V
> + *
> + * Version 2 of v2v (Virtual-to-Virtual)
> + *
> + * Copyright (c) 2010, Citrix Systems
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#ifndef __XEN_PUBLIC_V4V_H__
> +#define __XEN_PUBLIC_V4V_H__
> +
> +#include "xen.h"
> +
> +/*
> + * Structure definitions
> + */
> +
> +#define V4V_PROTO_DGRAM              0x3c2c1db8
> +#define V4V_PROTO_STREAM     0x70f6a8e5
> +
> +#ifdef __i386__

How about ARM?

> +# define V4V_RING_MAGIC         0xdf6977f231abd910ULL
> +# define V4V_PFN_LIST_MAGIC     0x91dd6159045b302dULL

Is there any reason these can't be also used for 64-bit?

> +#else
> +# define V4V_RING_MAGIC         0xdf6977f231abd910
> +# define V4V_PFN_LIST_MAGIC     0x91dd6159045b302d
> +#endif
> +#define V4V_DOMID_INVALID       (0x7FFFU)

Any reason not to use DOMID_INVALID instead?

> +#define V4V_DOMID_NONE          V4V_DOMID_INVALID
> +#define V4V_DOMID_ANY           V4V_DOMID_INVALID
> +#define V4V_PORT_NONE           0
> +
> +/*
> + * struct v4v_iov
> + * {
> + *      64 bits: iov_base
> + *      64 bits: iov_len
> + * }
> + */

What's the point of not defining the types here?

> +
> +/*
> + * struct v4v_addr
> + * {
> + *      32 bits: port
> + *      16 bits: domid
> + * }
> + */
> +
> +/*
> + * v4v_ring_id
> + * {
> + *      struct v4v_addr: addr
> + *      16 bits: partner
> + * }
> + */
> +
> +/*
> + * v4v_ring
> + * {
> + *      64 bits: magic
> + *      v4v_rind_id: id
> + *      32 bits: len
> + *      32 bits: rx_ptr
> + *      32 bits: tx_ptr
> + *      64 bits: padding
> + *      ... : ring
> + * }
> + *
> + * id:
> + * xen only looks at this during register/unregister
> + * and will fill in id.addr.domain
> + *
> + * rx_ptr: rx pointer, modified by domain
> + * tx_ptr: tx pointer, modified by xen
> + */
> +
> +#ifdef __i386__
> +#define V4V_RING_DATA_MAGIC  0x4ce4d30fbc82e92aULL

Same here as above.

> +#else
> +#define V4V_RING_DATA_MAGIC  0x4ce4d30fbc82e92a
> +#endif
> +
> +#define V4V_RING_DATA_F_EMPTY       1U << 0 /* Ring is empty */
> +#define V4V_RING_DATA_F_EXISTS      1U << 1 /* Ring exists */
> +#define V4V_RING_DATA_F_PENDING     1U << 2 /* Pending interrupt exists - do 
> not
> +                                               rely on this field - for
> +                                               profiling only */
> +#define V4V_RING_DATA_F_SUFFICIENT  1U << 3 /* Sufficient space to queue
> +                                               space_required bytes exists */
> +
> +/*
> + * v4v_ring_data_ent
> + * {
> + *      v4v_addr: ring
> + *      16 bits: flags
> + *      16 bits: padding
> + *      32 bits: space_required
> + *      32 bits: max_message_size
> + * }
> + */
> +
> +/*
> + * v4v_ring_data
> + * {
> + *      64 bits: magic (V4V_RING_DATA_MAGIC)
> + *      32 bits: nent
> + *      32 bits: padding
> + *      256 bits: reserved
> + *      ... : v4v_ring_data_ent
> + * }
> + */
> +
> +
> +#define V4V_ROUNDUP(a) (((a) +0xf ) & ~0xf)
> +/*
> + * Messages on the ring are padded to 128 bits
> + * Len here refers to the exact length of the data not including the
> + * 128 bit header. The message uses
> + * ((len +0xf) & ~0xf) + sizeof(v4v_ring_message_header) bytes
> + */
> +
> +/*
> + * v4v_stream_header
> + * {
> + *      32 bits: flags
> + *      32 bits: conid
> + * }
> + */
> +
> +/*
> + * v4v_ring_message_header
> + * {
> + *      32 bits: len
> + *      v4v_addr: source
> + *      32 bits: protocol
> + *      ... : data
> + * }
> + */
> +
> +/*
> + * HYPERCALLS
> + */
> +
> +#define V4VOP_register_ring  1
> +/*
> + * Registers a ring with Xen, if a ring with the same v4v_ring_id exists,
> + * this ring takes its place, registration will not change tx_ptr
> + * unless it is invalid
> + *
> + * do_v4v_op(V4VOP_unregister_ring,
> + *           v4v_ring, XEN_GUEST_HANDLE(v4v_pfn),
> + *           NULL, npage, 0)
> + */
> +
> +
> +#define V4VOP_unregister_ring        2
> +/*
> + * Unregister a ring.
> + *
> + * v4v_hypercall(V4VOP_send, v4v_ring, NULL, NULL, 0, 0)

Assuming this and the earlier do_v4v_op() refer to the same
thing, please use a single name consistently.

> + */
> +
> +#define V4VOP_send           3
> +/*
> + * Sends len bytes of buf to dst, giving src as the source address (xen will
> + * ignore src->domain and put your domain in the actually message), xen
> + * first looks for a ring with id.addr==dst and id.partner==sending_domain
> + * if that fails it looks for id.addr==dst and id.partner==DOMID_ANY.
> + * protocol is the 32 bit protocol number used from the message
> + * most likely V4V_PROTO_DGRAM or STREAM. If insufficient space exists
> + * it will return -EAGAIN and xen will twing the V4V_INTERRUPT when
> + * sufficient space becomes available
> + *
> + * v4v_hypercall(V4VOP_send,
> + *               v4v_addr src,
> + *               v4v_addr dst,
> + *               void* buf,
> + *               uint32_t len,
> + *               uint32_t protocol)
> + */
> +
> +
> +#define V4VOP_notify                 4
> +/* Asks xen for information about other rings in the system
> + *
> + * ent->ring is the v4v_addr_t of the ring you want information on
> + * the same matching rules are used as for V4VOP_send.
> + *
> + * ent->space_required  if this field is not null xen will check
> + * that there is space in the destination ring for this many bytes
> + * of payload. If there is it will set the V4V_RING_DATA_F_SUFFICIENT
> + * and CANCEL any pending interrupt for that ent->ring, if insufficient
> + * space is available it will schedule an interrupt and the flag will
> + * not be set.
> + *
> + * The flags are set by xen when notify replies
> + * V4V_RING_DATA_F_EMPTY     ring is empty
> + * V4V_RING_DATA_F_PENDING   interrupt is pending - don't rely on this
> + * V4V_RING_DATA_F_SUFFICIENT        sufficient space for space_required is 
> there
> + * V4V_RING_DATA_F_EXISTS    ring exists
> + *
> + * v4v_hypercall(V4VOP_notify,
> + *               XEN_GUEST_HANDLE(v4v_ring_data_ent) ent,
> + *               NULL, NULL, nent, 0)
> + */
> +
> +
> +#define V4VOP_sendv          5
> +/*
> + * Identical to V4VOP_send except rather than buf and len it takes
> + * an array of v4v_iov and a length of the array.
> + *
> + * v4v_hypercall(V4VOP_sendv,
> + *               v4v_addr src,
> + *               v4v_addr dst,
> + *               v4v_iov iov,
> + *               uint32_t niov,
> + *               uint32_t protocol)
> + */
> +
> +#endif /* __XEN_PUBLIC_V4V_H__ */
> --- /dev/null
> +++ b/xen/include/xen/v4v.h
> @@ -0,0 +1,187 @@
> +/******************************************************************************
> + * V4V
> + *
> + * Version 2 of v2v (Virtual-to-Virtual)
> + *
> + * Copyright (c) 2010, Citrix Systems
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#ifndef __V4V_PRIVATE_H__
> +#define __V4V_PRIVATE_H__
> +
> +#include <xen/config.h>
> +#include <xen/types.h>
> +#include <xen/spinlock.h>
> +#include <xen/smp.h>
> +#include <xen/shared.h>
> +#include <xen/list.h>
> +#include <public/v4v.h>
> +
> +#define V4V_HTABLE_SIZE 32
> +
> +#define V4V_PACKED __attribute__ ((packed))
> +
> +/*
> + * Structures
> + */
> +
> +typedef struct v4v_iov
> +{
> +    uint64_t iov_base;
> +    uint64_t iov_len;
> +} V4V_PACKED v4v_iov_t;

While you moved this to a private header now, I continue to
think that none of the uses of V4V_PACKED are actually
warranted (and hence these can't serve as reason for moving
these public definitions into a private header). Use explicit
padding fields, and you ought to be fine.

> +DEFINE_XEN_GUEST_HANDLE (v4v_iov_t);
> +
> +typedef struct v4v_addr
> +{
> +    uint32_t port;
> +    domid_t domain;
> +} V4V_PACKED v4v_addr_t;
> +DEFINE_XEN_GUEST_HANDLE (v4v_addr_t);
> +
> +typedef struct v4v_ring_id
> +{
> +    struct v4v_addr addr;
> +    domid_t partner;
> +} V4V_PACKED v4v_ring_id_t;
> +
> +typedef uint64_t v4v_pfn_t;
> +DEFINE_XEN_GUEST_HANDLE (v4v_pfn_t);
> +
> +typedef struct v4v_ring
> +{
> +    uint64_t magic;
> +    struct v4v_ring_id id;
> +    uint32_t len;
> +    uint32_t rx_ptr;
> +    uint32_t tx_ptr;
> +    uint64_t reserved[4];
> +    uint8_t ring[0];
> +} V4V_PACKED v4v_ring_t;
> +DEFINE_XEN_GUEST_HANDLE (v4v_ring_t);

If moved into the public header (where they belong imo), apart
from this one none of the guest handle defines should actually be
there, as there's no guest interface that would make use of them
(they're used internally to v4v.c only).

Also, conventionally there's no space before the opening
parenthesis here.

Jan

> +
> +typedef struct v4v_ring_data_ent
> +{
> +    struct v4v_addr ring;
> +    uint16_t flags;
> +    uint16_t pad0;
> +    uint32_t space_required;
> +    uint32_t max_message_size;
> +} V4V_PACKED v4v_ring_data_ent_t;
> +DEFINE_XEN_GUEST_HANDLE (v4v_ring_data_ent_t);
> +
> +typedef struct v4v_ring_data
> +{
> +    uint64_t magic;
> +    uint32_t nent;
> +    uint32_t padding;
> +    uint64_t reserved[4];
> +    v4v_ring_data_ent_t ring[0];
> +} V4V_PACKED v4v_ring_data_t;
> +DEFINE_XEN_GUEST_HANDLE (v4v_ring_data_t);
> +
> +struct v4v_stream_header
> +{
> +    uint32_t flags;
> +    uint32_t conid;
> +} V4V_PACKED;
> +
> +struct v4v_ring_message_header
> +{
> +    uint32_t len;
> +    struct v4v_addr source;
> +    uint32_t protocol;
> +    uint8_t data[0];
> +} V4V_PACKED;
> +
> +/*
> + * Helper functions
> + */
> +
> +
> +static inline uint16_t
> +v4v_hash_fn (struct v4v_ring_id *id)
> +{
> +  uint16_t ret;
> +  ret = (uint16_t) (id->addr.port >> 16);
> +  ret ^= (uint16_t) id->addr.port;
> +  ret ^= id->addr.domain;
> +  ret ^= id->partner;
> +
> +  ret &= (V4V_HTABLE_SIZE-1);
> +
> +  return ret;
> +}
> +
> +struct v4v_pending_ent
> +{
> +  struct hlist_node node;
> +  domid_t id;
> +  uint32_t len;
> +} V4V_PACKED;
> +
> +
> +struct v4v_ring_info
> +{
> +  /* next node in the hash, protected by L2  */
> +  struct hlist_node node;
> +  /* this ring's id, protected by L2 */
> +  struct v4v_ring_id id;
> +  /* L3 */
> +  spinlock_t lock;
> +  /* cached length of the ring (from ring->len), protected by L3 */
> +  uint32_t len;
> +  uint32_t npage;
> +  /* cached tx pointer location, protected by L3 */
> +  uint32_t tx_ptr;
> +  /* guest ring, protected by L3 */
> +  XEN_GUEST_HANDLE(v4v_ring_t) ring;
> +  /* mapped ring pages protected by L3*/
> +  uint8_t **mfn_mapping;
> +  /* list of mfns of guest ring */
> +  mfn_t *mfns;
> +  /* list of struct v4v_pending_ent for this ring, L3 */
> +  struct hlist_head pending;
> +} V4V_PACKED;
> +
> +/*
> + * The value of the v4v element in a struct domain is
> + * protected by the global lock L1
> + */
> +struct v4v_domain
> +{
> +  /* L2 */
> +  rwlock_t lock;
> +  /* protected by L2 */
> +  struct hlist_head ring_hash[V4V_HTABLE_SIZE];
> +} V4V_PACKED;
> +
> +void v4v_destroy(struct domain *d);
> +int v4v_init(struct domain *d);
> +long do_v4v_op (int cmd,
> +                XEN_GUEST_HANDLE (void) arg1,
> +                XEN_GUEST_HANDLE (void) arg2,
> +                XEN_GUEST_HANDLE (void) arg3,
> +                uint32_t arg4,
> +                uint32_t arg5);
> +
> +#endif /* __V4V_PRIVATE_H__ */


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