All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Ouyang Changchun <changchun.ouyang@intel.com>
Cc: snabb-devel@googlegroups.com, thibaut.collet@6wind.com,
	qemu-devel@nongnu.org, n.nikolaev@virtualopensystems.com,
	luke@snabb.co, thomas.long@intel.com
Subject: Re: [Qemu-devel] [PATCH v6 1/2] vhost-user: add multi queue support
Date: Thu, 13 Aug 2015 12:18:38 +0300	[thread overview]
Message-ID: <20150813121013-mutt-send-email-mst@redhat.com> (raw)
In-Reply-To: <1439360742-2186-2-git-send-email-changchun.ouyang@intel.com>

On Wed, Aug 12, 2015 at 02:25:41PM +0800, Ouyang Changchun wrote:
> Based on patch by Nikolay Nikolaev:
> Vhost-user will implement the multi queue support in a similar way
> to what vhost already has - a separate thread for each queue.
> To enable the multi queue functionality - a new command line parameter
> "queues" is introduced for the vhost-user netdev.
> 
> The RESET_OWNER change is based on commit:
>    294ce717e0f212ed0763307f3eab72b4a1bdf4d0
> If it is reverted, the patch need update for it accordingly.
> 
> Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
> Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
> ---
> Changes since v5:
>  - fix the message descption for VHOST_RESET_OWNER in vhost-user txt
> 
> Changes since v4:
>  - remove the unnecessary trailing '\n'
> 
> Changes since v3:
>  - fix one typo and wrap one long line
> 
> Changes since v2:
>  - fix vq index issue for set_vring_call
>    When it is the case of VHOST_SET_VRING_CALL, The vq_index is not initialized before it is used,
>    thus it could be a random value. The random value leads to crash in vhost after passing down
>    to vhost, as vhost use this random value to index an array index.
>  - fix the typo in the doc and description
>  - address vq index for reset_owner
> 
> Changes since v1:
>  - use s->nc.info_str when bringing up/down the backend
> 
>  docs/specs/vhost-user.txt |  7 ++++++-
>  hw/net/vhost_net.c        |  3 ++-
>  hw/virtio/vhost-user.c    | 11 ++++++++++-
>  net/vhost-user.c          | 37 ++++++++++++++++++++++++-------------
>  qapi-schema.json          |  6 +++++-
>  qemu-options.hx           |  5 +++--
>  6 files changed, 50 insertions(+), 19 deletions(-)
> 
> diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
> index 70da3b1..9390f89 100644
> --- a/docs/specs/vhost-user.txt
> +++ b/docs/specs/vhost-user.txt
> @@ -135,6 +135,11 @@ As older slaves don't support negotiating protocol features,
>  a feature bit was dedicated for this purpose:
>  #define VHOST_USER_F_PROTOCOL_FEATURES 30
>  
> +Multi queue support
> +-------------------
> +The protocol supports multiple queues by setting all index fields in the sent
> +messages to a properly calculated value.
> +
>  Message types
>  -------------
>  
> @@ -198,7 +203,7 @@ Message types
>  
>        Id: 4
>        Equivalent ioctl: VHOST_RESET_OWNER
> -      Master payload: N/A
> +      Master payload: vring state description
>  
>        Issued when a new connection is about to be closed. The Master will no
>        longer own this connection (and will usually close it).

This is an interface change, isn't it?
We can't make it unconditionally, need to make it dependent
on a protocol flag.


> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 1f25cb3..9cd6c05 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -159,6 +159,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
>  
>      net->dev.nvqs = 2;
>      net->dev.vqs = net->vqs;
> +    net->dev.vq_index = net->nc->queue_index;
>  
>      r = vhost_dev_init(&net->dev, options->opaque,
>                         options->backend_type, options->force);
> @@ -269,7 +270,7 @@ static void vhost_net_stop_one(struct vhost_net *net,
>          for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
>              const VhostOps *vhost_ops = net->dev.vhost_ops;
>              int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_OWNER,
> -                                          NULL);
> +                                          &file);
>              assert(r >= 0);
>          }
>      }
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 27ba035..fb11d4c 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -219,7 +219,12 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
>          break;
>  
>      case VHOST_USER_SET_OWNER:
> +        break;
> +
>      case VHOST_USER_RESET_OWNER:
> +        memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> +        msg.state.index += dev->vq_index;
> +        msg.size = sizeof(m.state);
>          break;
>  
>      case VHOST_USER_SET_MEM_TABLE:
> @@ -262,17 +267,20 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
>      case VHOST_USER_SET_VRING_NUM:
>      case VHOST_USER_SET_VRING_BASE:
>          memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> +        msg.state.index += dev->vq_index;
>          msg.size = sizeof(m.state);
>          break;
>  
>      case VHOST_USER_GET_VRING_BASE:
>          memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
> +        msg.state.index += dev->vq_index;
>          msg.size = sizeof(m.state);
>          need_reply = 1;
>          break;
>  
>      case VHOST_USER_SET_VRING_ADDR:
>          memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
> +        msg.addr.index += dev->vq_index;
>          msg.size = sizeof(m.addr);
>          break;
>  
> @@ -280,7 +288,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
>      case VHOST_USER_SET_VRING_CALL:
>      case VHOST_USER_SET_VRING_ERR:
>          file = arg;
> -        msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
> +        msg.u64 = (file->index + dev->vq_index) & VHOST_USER_VRING_IDX_MASK;
>          msg.size = sizeof(m.u64);
>          if (ioeventfd_enabled() && file->fd > 0) {
>              fds[fd_num++] = file->fd;
> @@ -322,6 +330,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
>                  error_report("Received bad msg size.");
>                  return -1;
>              }
> +            msg.state.index -= dev->vq_index;
>              memcpy(arg, &msg.state, sizeof(struct vhost_vring_state));
>              break;
>          default:
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index 1d86a2b..904d8af 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -121,35 +121,39 @@ static void net_vhost_user_event(void *opaque, int event)
>      case CHR_EVENT_OPENED:
>          vhost_user_start(s);
>          net_vhost_link_down(s, false);
> -        error_report("chardev \"%s\" went up", s->chr->label);
> +        error_report("chardev \"%s\" went up", s->nc.info_str);
>          break;
>      case CHR_EVENT_CLOSED:
>          net_vhost_link_down(s, true);
>          vhost_user_stop(s);
> -        error_report("chardev \"%s\" went down", s->chr->label);
> +        error_report("chardev \"%s\" went down", s->nc.info_str);
>          break;
>      }
>  }
>  
>  static int net_vhost_user_init(NetClientState *peer, const char *device,
> -                               const char *name, CharDriverState *chr)
> +                               const char *name, CharDriverState *chr,
> +                               uint32_t queues)
>  {
>      NetClientState *nc;
>      VhostUserState *s;
> +    int i;
>  
> -    nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
> +    for (i = 0; i < queues; i++) {
> +        nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
>  
> -    snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user to %s",
> -             chr->label);
> +        snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
> +                 i, chr->label);
>  
> -    s = DO_UPCAST(VhostUserState, nc, nc);
> +        s = DO_UPCAST(VhostUserState, nc, nc);
>  
> -    /* We don't provide a receive callback */
> -    s->nc.receive_disabled = 1;
> -    s->chr = chr;
> -
> -    qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);
> +        /* We don't provide a receive callback */
> +        s->nc.receive_disabled = 1;
> +        s->chr = chr;
> +        s->nc.queue_index = i;
>  
> +        qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);
> +    }
>      return 0;
>  }
>  
> @@ -225,6 +229,7 @@ static int net_vhost_check_net(QemuOpts *opts, void *opaque)


There are two problems here:

1. we don't really know that the backend
   is able to support the requested number of queues.
   If not, everything will fail, silently.
   A new message to query the # of queues could help, though
   I'm not sure what can be done on failure. Fail connection?

2. each message (e.g. set memory table) is sent multiple times,
   on the same socket.



>  int net_init_vhost_user(const NetClientOptions *opts, const char *name,
>                          NetClientState *peer)
>  {
> +    uint32_t queues;
>      const NetdevVhostUserOptions *vhost_user_opts;
>      CharDriverState *chr;
>  
> @@ -243,6 +248,12 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name,
>          return -1;
>      }
>  
> +    /* number of queues for multiqueue */
> +    if (vhost_user_opts->has_queues) {
> +        queues = vhost_user_opts->queues;
> +    } else {
> +        queues = 1;
> +    }
>  
> -    return net_vhost_user_init(peer, "vhost_user", name, chr);
> +    return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
>  }
> diff --git a/qapi-schema.json b/qapi-schema.json
> index f97ffa1..51e40ce 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2444,12 +2444,16 @@
>  #
>  # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
>  #
> +# @queues: #optional number of queues to be created for multiqueue vhost-user
> +#          (default: 1) (Since 2.5)
> +#
>  # Since 2.1
>  ##
>  { 'struct': 'NetdevVhostUserOptions',
>    'data': {
>      'chardev':        'str',
> -    '*vhostforce':    'bool' } }
> +    '*vhostforce':    'bool',
> +    '*queues':        'uint32' } }
>  
>  ##
>  # @NetClientOptions
> diff --git a/qemu-options.hx b/qemu-options.hx
> index ec356f6..dad035e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1942,13 +1942,14 @@ The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
>  netdev.  @code{-net} and @code{-device} with parameter @option{vlan} create the
>  required hub automatically.
>  
> -@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off]
> +@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]
>  
>  Establish a vhost-user netdev, backed by a chardev @var{id}. The chardev should
>  be a unix domain socket backed one. The vhost-user uses a specifically defined
>  protocol to pass vhost ioctl replacement messages to an application on the other
>  end of the socket. On non-MSIX guests, the feature can be forced with
> -@var{vhostforce}.
> +@var{vhostforce}. Use 'queues=@var{n}' to specify the number of queues to
> +be created for multiqueue vhost-user.
>  
>  Example:
>  @example
> -- 
> 1.8.4.2
> 

  reply	other threads:[~2015-08-13  9:18 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-28  1:23 [Qemu-devel] [PATCH v5] vhost-user: add multi queue support Ouyang Changchun
2015-07-08 14:29 ` Michael S. Tsirkin
2015-07-08 22:00   ` Maxime Leroy
2015-07-09  1:29     ` [Qemu-devel] [snabb-devel] " Ouyang, Changchun
2015-07-09  7:31       ` Michael S. Tsirkin
2015-07-09  7:06     ` [Qemu-devel] " Michael S. Tsirkin
2015-07-09 12:00       ` Martin Kletzander
2015-07-09 12:24         ` Maxime Leroy
2015-07-09 12:33           ` Martin Kletzander
2015-07-09 12:54           ` Michael S. Tsirkin
2015-08-12  6:25 ` [Qemu-devel] [PATCH v6 0/2] vhost-user " Ouyang Changchun
2015-08-12  6:25   ` [Qemu-devel] [PATCH v6 1/2] vhost-user: add " Ouyang Changchun
2015-08-13  9:18     ` Michael S. Tsirkin [this message]
2015-08-13 10:24       ` Maxime Leroy
2015-08-13 10:55         ` Michael S. Tsirkin
2015-08-25  3:25       ` [Qemu-devel] [snabb-devel] " Ouyang, Changchun
2015-08-27 13:05         ` Michael S. Tsirkin
2015-08-28  1:53           ` Ouyang, Changchun
2015-08-30  6:16             ` Michael S. Tsirkin
2015-08-31  8:29               ` Ouyang, Changchun
2015-08-31 11:30                 ` Michael S. Tsirkin
2015-08-31 15:04                   ` Eric Blake
2015-09-01  9:20                   ` Yuanhan Liu
2015-09-01  9:41                     ` Michael S. Tsirkin
2015-09-01 12:16                       ` Yuanhan Liu
2015-09-01  9:13       ` [Qemu-devel] " Yuanhan Liu
2015-09-01 10:07         ` Michael S. Tsirkin
2015-09-01 12:15           ` Yuanhan Liu
2015-09-01 14:10             ` Michael S. Tsirkin
2015-09-02  5:45               ` Ouyang, Changchun
2015-09-02 12:10                 ` Michael S. Tsirkin
2015-09-07 11:07       ` Marcel Apfelbaum
2015-09-07 12:26         ` Michael S. Tsirkin
2015-09-07 13:08           ` Marcel Apfelbaum
2015-08-12  6:25   ` [Qemu-devel] [PATCH v6 2/2] vhost-user: new protocol feature for multi queue Ouyang Changchun
2015-08-13  9:22     ` Michael S. Tsirkin
2015-08-24  1:50       ` [Qemu-devel] [snabb-devel] " Ouyang, Changchun
2015-09-01  9:16       ` [Qemu-devel] " Yuanhan Liu
2015-09-01 10:09         ` Michael S. Tsirkin
2015-09-01 11:42           ` Yuanhan Liu
2015-08-30 15:28 ` [Qemu-devel] [PATCH v5] vhost-user: add multi queue support Marcel Apfelbaum
2015-08-31  5:28   ` Ouyang, Changchun
2015-08-31  5:42     ` Xu, Qian Q
2015-08-31  8:55       ` Marcel Apfelbaum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150813121013-mutt-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=changchun.ouyang@intel.com \
    --cc=luke@snabb.co \
    --cc=n.nikolaev@virtualopensystems.com \
    --cc=qemu-devel@nongnu.org \
    --cc=snabb-devel@googlegroups.com \
    --cc=thibaut.collet@6wind.com \
    --cc=thomas.long@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.