From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48362) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W3NOW-0007NI-AY for qemu-devel@nongnu.org; Wed, 15 Jan 2014 05:08:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W3NOR-0004Ua-0z for qemu-devel@nongnu.org; Wed, 15 Jan 2014 05:08:20 -0500 Received: from mx1.redhat.com ([209.132.183.28]:11446) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W3NOQ-0004UP-Mz for qemu-devel@nongnu.org; Wed, 15 Jan 2014 05:08:14 -0500 Date: Wed, 15 Jan 2014 12:08:06 +0200 From: "Michael S. Tsirkin" Message-ID: <20140115100806.GA2199@redhat.com> References: <1389623119-15863-1-git-send-email-a.motakis@virtualopensystems.com> <1389623119-15863-7-git-send-email-a.motakis@virtualopensystems.com> <20140114112128.GE27922@redhat.com> <20140115091414.GD1719@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: <20140115091414.GD1719@redhat.com> Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v6 6/8] Add vhost-user calls implementation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Antonios Motakis Cc: Luke Gorrie , snabb-devel@googlegroups.com, Nikolay Nikolaev , qemu-devel qemu-devel , VirtualOpenSystems Technical Team On Wed, Jan 15, 2014 at 11:14:14AM +0200, Michael S. Tsirkin wrote: > On Tue, Jan 14, 2014 at 07:14:53PM +0100, Antonios Motakis wrote: > >=20 > >=20 > >=20 > > On Tue, Jan 14, 2014 at 12:21 PM, Michael S. Tsirkin = wrote: > >=20 > > On Mon, Jan 13, 2014 at 03:25:17PM +0100, Antonios Motakis wrote: > > > Each ioctl request of vhost-kernel has a vhost-user message equ= ivalent, > > > which is sent over the control socket. > > > > > > The general approach is to copy the data from the supplied argu= ment > > > pointer to a designated field in the message. If a file descrip= tor is > > > to be passed it will be placed in the fds array for inclusion i= n > > > the sendmsd control header. > > > > > > VHOST_SET_MEM_TABLE ignores the supplied vhost_memory structure= and scans > > > the global ram_list for ram blocks with a valid fd field set. T= his would > > > be set when the -mem-path option with shared=3Don property is u= sed. > > > > > > Signed-off-by: Antonios Motakis > > > Signed-off-by: Nikolay Nikolaev > >=20 > > the name vhost-backend and vhost-user is unfortunate as you let s= ome > > net specific stuff get in there. > >=20 > >=20 > > The vhost-net stuff here is not strictly necessary, so it can be remo= ved. We > > don't need to set a TAP backend when using vhost-user. > > =A0 >=20 > Weird. It does not need a tap backend? > Why did you make this a tap option then? Oh I didn't read what you wrote carefully. You are saying you don't use the VHOST_USER_NET_SET_BACKEND option to pass tap fd at all, so it can be removed? Pls ignore this last question then. >=20 > >=20 > > > --- > > > =A0hw/virtio/vhost-backend.c | 147 > > ++++++++++++++++++++++++++++++++++++++++++++-- > > > =A01 file changed, 143 insertions(+), 4 deletions(-) > > > > > > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backen= d.c > > > index 460ee02..8f98562 100644 > > > --- a/hw/virtio/vhost-backend.c > > > +++ b/hw/virtio/vhost-backend.c > > > @@ -81,6 +81,39 @@ static VhostUserMsg m __attribute__ ((unused= )); > > > =A0/* The version of the protocol we support */ > > > =A0#define VHOST_USER_VERSION =A0 =A0(0x1) > > > > > > +static unsigned long int ioctl_to_vhost_user_request[VHOST_USE= R_MAX] =3D { > > > + =A0 =A0-1, /* VHOST_USER_NONE */ > > > + =A0 =A0VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */ > > > + =A0 =A0VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */ > > > + =A0 =A0VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */ > > > + =A0 =A0VHOST_RESET_OWNER, /* VHOST_USER_RESET_OWNER */ > > > + =A0 =A0VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */ > > > + =A0 =A0VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */ > > > + =A0 =A0VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */ > > > + =A0 =A0VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */ > > > + =A0 =A0VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */ > > > + =A0 =A0VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */ > > > + =A0 =A0VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */ > > > + =A0 =A0VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */ > > > + =A0 =A0VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */ > > > + =A0 =A0VHOST_SET_VRING_ERR, /* VHOST_USER_SET_VRING_ERR */ > > > + =A0 =A0VHOST_NET_SET_BACKEND, /* VHOST_USER_NET_SET_BACKEND *= / > > > + =A0 =A0-1 /* VHOST_USER_ECHO */ > > > +}; > > > + > > > +static VhostUserRequest vhost_user_request_translate(unsigned = long int > > request) > > > +{ > > > + =A0 =A0VhostUserRequest idx; > > > + > > > + =A0 =A0for (idx =3D 0; idx < VHOST_USER_MAX; idx++) { > > > + =A0 =A0 =A0 =A0if (ioctl_to_vhost_user_request[idx] =3D=3D re= quest) { > > > + =A0 =A0 =A0 =A0 =A0 =A0break; > > > + =A0 =A0 =A0 =A0} > > > + =A0 =A0} > > > + > > > + =A0 =A0return (idx =3D=3D VHOST_USER_MAX) ? VHOST_USER_NONE := idx; > > > +} > > > + > > > =A0static int vhost_user_recv(int fd, VhostUserMsg *msg) > > > =A0{ > > > =A0 =A0 =A0ssize_t r; > > > @@ -235,7 +268,10 @@ static int vhost_user_call(struct vhost_de= v *dev, > > unsigned long int request, > > > =A0{ > > > =A0 =A0 =A0int fd =3D dev->control; > > > =A0 =A0 =A0VhostUserMsg msg; > > > - =A0 =A0int result =3D 0; > > > + =A0 =A0VhostUserRequest msg_request; > > > + =A0 =A0RAMBlock *block =3D 0; > > > + =A0 =A0struct vhost_vring_file *file =3D 0; > > > + =A0 =A0int need_reply =3D 0; > > > =A0 =A0 =A0int fds[VHOST_MEMORY_MAX_NREGIONS]; > > > =A0 =A0 =A0size_t fd_num =3D 0; > > > > > > @@ -245,20 +281,123 @@ static int vhost_user_call(struct vhost_= dev *dev, > > unsigned long int request, > > > =A0 =A0 =A0 =A0 =A0return 0; > > > =A0 =A0 =A0} > > > > > > - =A0 =A0msg.request =3D VHOST_USER_NONE; > > > + =A0 =A0msg_request =3D vhost_user_request_translate(request); > > > + =A0 =A0msg.request =3D msg_request; > > > =A0 =A0 =A0msg.flags =3D VHOST_USER_VERSION; > > > =A0 =A0 =A0msg.size =3D 0; > > > > > > =A0 =A0 =A0switch (request) { > > > + =A0 =A0case VHOST_GET_FEATURES: > > > + =A0 =A0case VHOST_GET_VRING_BASE: > > > + =A0 =A0 =A0 =A0need_reply =3D 1; > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_FEATURES: > > > + =A0 =A0case VHOST_SET_LOG_BASE: > > > + =A0 =A0 =A0 =A0msg.u64 =3D *((__u64 *) arg); > > > + =A0 =A0 =A0 =A0msg.size =3D sizeof(m.u64); > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_OWNER: > > > + =A0 =A0case VHOST_RESET_OWNER: > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_MEM_TABLE: > > > + =A0 =A0 =A0 =A0QTAILQ_FOREACH(block, &ram_list.blocks, next) > > > + =A0 =A0 =A0 =A0{ > > > + =A0 =A0 =A0 =A0 =A0 =A0if (block->fd > 0) { > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msg.memory.regions[fd_num].use= rspace_addr =3D (__u64) > > block->host; > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msg.memory.regions[fd_num].mem= ory_size =3D block->length; > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msg.memory.regions[fd_num].gue= st_phys_addr =3D block-> > > offset; > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0fds[fd_num++] =3D block->fd; > > > + =A0 =A0 =A0 =A0 =A0 =A0} > > > + =A0 =A0 =A0 =A0} > > > + > > > + =A0 =A0 =A0 =A0msg.memory.nregions =3D fd_num; > > > + > > > + =A0 =A0 =A0 =A0if (!fd_num) { > > > + =A0 =A0 =A0 =A0 =A0 =A0error_report("Failed initializing vhos= t-user memory map\n" > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"consider using -mem-p= ath option\n"); > > > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0} > > > + > > > + =A0 =A0 =A0 =A0msg.size =3D sizeof(m.memory.nregions); > > > + =A0 =A0 =A0 =A0msg.size +=3D sizeof(m.memory.padding); > > > + =A0 =A0 =A0 =A0msg.size +=3D fd_num * sizeof(VhostUserMemoryR= egion); > > > + > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_LOG_FD: > > > + =A0 =A0 =A0 =A0fds[fd_num++] =3D *((int *) arg); > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_VRING_NUM: > > > + =A0 =A0case VHOST_SET_VRING_BASE: > > > + =A0 =A0 =A0 =A0memcpy(&msg.state, arg, sizeof(struct vhost_vr= ing_state)); > > > + =A0 =A0 =A0 =A0msg.size =3D sizeof(m.state); > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_VRING_ADDR: > > > + =A0 =A0 =A0 =A0memcpy(&msg.addr, arg, sizeof(struct vhost_vri= ng_addr)); > > > + =A0 =A0 =A0 =A0msg.size =3D sizeof(m.addr); > > > + =A0 =A0 =A0 =A0break; > > > + > > > + =A0 =A0case VHOST_SET_VRING_KICK: > > > + =A0 =A0case VHOST_SET_VRING_CALL: > > > + =A0 =A0case VHOST_SET_VRING_ERR: > > > + =A0 =A0case VHOST_NET_SET_BACKEND: > > > + =A0 =A0 =A0 =A0file =3D arg; > > > + =A0 =A0 =A0 =A0msg.u64 =3D file->index; > > > + =A0 =A0 =A0 =A0msg.size =3D sizeof(m.u64); > > > + =A0 =A0 =A0 =A0if (file->fd > 0) { > > > + =A0 =A0 =A0 =A0 =A0 =A0fds[fd_num++] =3D file->fd; > > > + =A0 =A0 =A0 =A0} > > > + =A0 =A0 =A0 =A0break; > > > =A0 =A0 =A0default: > > > =A0 =A0 =A0 =A0 =A0error_report("vhost-user trying to send unha= ndled ioctl\n"); > > > =A0 =A0 =A0 =A0 =A0return -1; > > > =A0 =A0 =A0 =A0 =A0break; > > > =A0 =A0 =A0} > > > > > > - =A0 =A0result =3D vhost_user_send_fds(fd, &msg, fds, fd_num); > > > + =A0 =A0if (vhost_user_send_fds(fd, &msg, fds, fd_num) < 0) { > > > + =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0} > > > > > > - =A0 =A0return result; > > > + =A0 =A0if (need_reply) { > > > + =A0 =A0 =A0 =A0if (vhost_user_recv(fd, &msg) < 0) { > > > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0} > > > + > > > + =A0 =A0 =A0 =A0if (msg_request !=3D msg.request) { > > > + =A0 =A0 =A0 =A0 =A0 =A0error_report("Received unexpected msg = type." > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 " Expected %d= received %d\n", > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 msg_request, = msg.request); > > > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0} > > > + > > > + =A0 =A0 =A0 =A0switch (msg_request) { > > > + =A0 =A0 =A0 =A0case VHOST_USER_GET_FEATURES: > > > + =A0 =A0 =A0 =A0 =A0 =A0if (msg.size !=3D sizeof(m.u64)) { > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0error_report("Received bad msg= size.\n"); > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0 =A0 =A0} > > > + =A0 =A0 =A0 =A0 =A0 =A0*((__u64 *) arg) =3D msg.u64; > > > + =A0 =A0 =A0 =A0 =A0 =A0break; > > > + =A0 =A0 =A0 =A0case VHOST_USER_GET_VRING_BASE: > > > + =A0 =A0 =A0 =A0 =A0 =A0if (msg.size !=3D sizeof(m.state)) { > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0error_report("Received bad msg= size.\n"); > > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0 =A0 =A0} > > > + =A0 =A0 =A0 =A0 =A0 =A0memcpy(arg, &msg.state, sizeof(struct = vhost_vring_state)); > > > + =A0 =A0 =A0 =A0 =A0 =A0break; > > > + =A0 =A0 =A0 =A0default: > > > + =A0 =A0 =A0 =A0 =A0 =A0error_report("Received unexpected msg = type.\n"); > > > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > > > + =A0 =A0 =A0 =A0 =A0 =A0break; > > > + =A0 =A0 =A0 =A0} > > > + =A0 =A0} > > > + > > > + =A0 =A0return 0; > > > =A0} > > > > > > =A0static int vhost_user_init(struct vhost_dev *dev, const char= *devpath) > > > -- > > > 1.8.3.2 > > > > >=20 > >=20