Ciara Loftus <ciara.lof...@intel.com> writes: > A new other_config DB option has been added called 'vhost_driver_mode'. > By default this is set to 'server' which is the mode of operation OVS > with DPDK has used up until this point - whereby OVS creates and manages > vHost user sockets. > > If set to 'client', OVS will act as the vHost client and connect to > sockets created and managed by QEMU which acts as the server. This mode > allows for reconnect capability, which allows vHost ports to resume > normal connectivity in event of switch reset. > > QEMU v2.7.0+ is required when using OVS in client mode and QEMU in > server mode. > > Signed-off-by: Ciara Loftus <ciara.lof...@intel.com> > --- > INSTALL.DPDK-ADVANCED.md | 27 +++++++++++++++++++++++++++ > NEWS | 1 + > lib/netdev-dpdk.c | 37 ++++++++++++++++++++++++++----------- > vswitchd/vswitch.xml | 13 +++++++++++++ > 4 files changed, 67 insertions(+), 11 deletions(-) > > diff --git a/INSTALL.DPDK-ADVANCED.md b/INSTALL.DPDK-ADVANCED.md > index ec1de29..ad3e59e 100644 > --- a/INSTALL.DPDK-ADVANCED.md > +++ b/INSTALL.DPDK-ADVANCED.md > @@ -489,6 +489,33 @@ DPDK 16.07 supports two types of vhost: > where `-L`: Changes the numbers of channels of the specified network > device > and `combined`: Changes the number of multi-purpose channels. > > + 4. Enable OVS vHost client-mode & vHost reconnect (OPTIONAL) > + > + By default, OVS DPDK acts as the vHost socket server and QEMU the > + client. In QEMU v2.7 the option is available for QEMU to act as the > + server. In order for this to work, OVS DPDK must be switched to > 'client' > + mode. This is possible by setting the 'vhost_driver_mode' DB entry to > + 'client' like so: > + > + ``` > + ovs-vsctl set Open_vSwitch . other_config:vhost_driver_mode="client" > + ``` > + > + This must be done before the switch is launched. It cannot sucessfully > + be changed after switch has launched. > + > + One must also append ',server' to the 'chardev' arguments on the QEMU > + command line, to instruct QEMU to use vHost server mode, like so: > + > + ```` > + -chardev > socket,id=char0,path=/usr/local/var/run/openvswitch/vhost0,server > + ```` > + > + One benefit of using this mode is the ability for vHost ports to > + 'reconnect' in event of the switch crashing or being brought down. > Once > + it is brought back up, the vHost ports will reconnect automatically > and > + normal service will resume. > + > - VM Configuration with libvirt > > * change the user/group, access control policty and restart libvirtd. > diff --git a/NEWS b/NEWS > index f50b05e..08bac37 100644 > --- a/NEWS > +++ b/NEWS > @@ -53,6 +53,7 @@ Post-v2.5.0 > * PMD threads servicing vHost User ports can now come from the NUMA > node that device memory is located on if CONFIG_RTE_LIBRTE_VHOST_NUMA > is enabled in DPDK. > + * OVS client mode for vHost and vHost reconnect (Requires QEMU 2.7) > - ovs-benchmark: This utility has been removed due to lack of use and > bitrot. > - ovs-appctl: > diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c > index 9cf0b0c..6763039 100644 > --- a/lib/netdev-dpdk.c > +++ b/lib/netdev-dpdk.c > @@ -138,9 +138,11 @@ BUILD_ASSERT_DECL((MAX_NB_MBUF / > ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF)) > * yet mapped to another queue. */ > > #ifdef VHOST_CUSE > -static char *cuse_dev_name = NULL; /* Character device cuse_dev_name. */ > +static char *cuse_dev_name = NULL; /* Character device cuse_dev_name. */ > +#else > +static char *vhost_sock_dir = NULL; /* Location of vhost-user sockets */ > +static uint64_t vhost_driver_flags = 0; /* Denote whether client/server mode > */ > #endif > -static char *vhost_sock_dir = NULL; /* Location of vhost-user sockets */ > > #define VHOST_ENQ_RETRY_NUM 8 > > @@ -845,7 +847,6 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev) > struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > const char *name = netdev->name; > int err; > - uint64_t flags = 0; > > /* 'name' is appended to 'vhost_sock_dir' and used to create a socket in > * the file system. '/' or '\' would traverse directories, so they're not > @@ -868,14 +869,17 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev) > snprintf(dev->vhost_id, sizeof(dev->vhost_id), "%s/%s", > vhost_sock_dir, name); > > - err = rte_vhost_driver_register(dev->vhost_id, flags); > + err = rte_vhost_driver_register(dev->vhost_id, vhost_driver_flags); > if (err) { > VLOG_ERR("vhost-user socket device setup failure for socket %s\n", > dev->vhost_id); > } else { > - fatal_signal_add_file_to_unlink(dev->vhost_id); > - VLOG_INFO("Socket %s created for vhost-user port %s\n", > - dev->vhost_id, name); > + if (!(vhost_driver_flags & RTE_VHOST_USER_CLIENT)) { > + /* OVS server mode - OVS may delete the socket */ > + fatal_signal_add_file_to_unlink(dev->vhost_id); > + VLOG_INFO("Socket %s created for vhost-user port %s\n", > + dev->vhost_id, name); > + } > err = vhost_construct_helper(netdev); > } > > @@ -945,7 +949,8 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev) > > if (rte_vhost_driver_unregister(dev->vhost_id)) { > VLOG_ERR("Unable to remove vhost-user socket %s", dev->vhost_id); > - } else { > + } else if (!(vhost_driver_flags & RTE_VHOST_USER_CLIENT)) { > + /* OVS server mode - OVS may delete the socket */ > fatal_signal_remove_file_to_unlink(dev->vhost_id); > } > > @@ -3208,6 +3213,7 @@ dpdk_init__(const struct smap *ovs_other_config) > cpu_set_t cpuset; > #ifndef VHOST_CUSE > char *sock_dir_subcomponent; > + const char *val; > #endif > > if (!smap_get_bool(ovs_other_config, "dpdk-init", false)) { > @@ -3218,8 +3224,8 @@ dpdk_init__(const struct smap *ovs_other_config) > VLOG_INFO("DPDK Enabled, initializing"); > > #ifdef VHOST_CUSE > - if (process_vhost_flags("cuse-dev-name", xstrdup("vhost-net"), > - PATH_MAX, ovs_other_config, &cuse_dev_name)) { > + process_vhost_flags("cuse-dev-name", xstrdup("vhost-net"), > + PATH_MAX, ovs_other_config, &cuse_dev_name); > #else > if (process_vhost_flags("vhost-sock-dir", xstrdup(ovs_rundir()), > NAME_MAX, ovs_other_config, > @@ -3243,8 +3249,17 @@ dpdk_init__(const struct smap *ovs_other_config) > free(sock_dir_subcomponent); > } else { > vhost_sock_dir = sock_dir_subcomponent; > -#endif > } > + val = smap_get(ovs_other_config, "vhost_driver_mode"); > + if (val != NULL && strncmp(val, "client", strlen(val)) == 0) { > + vhost_driver_flags |= RTE_VHOST_USER_CLIENT; > + VLOG_INFO("OVS client mode (QEMU server mode) selected for vHost"); > + } else { > + /* default case */ > + vhost_driver_flags &= ~RTE_VHOST_USER_CLIENT; > + VLOG_INFO("OVS server mode (QEMU client mode) selected for vHost"); > + }
Is it possible to just use the process_vhost_flags call for this section instead? Do you think it would make sense for consistency? > +#endif > > argv = grow_argv(&argv, 0, 1); > argc = 1; > diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml > index fed6f56..66007e5 100644 > --- a/vswitchd/vswitch.xml > +++ b/vswitchd/vswitch.xml > @@ -311,6 +311,19 @@ > </p> > </column> > > + <column name="other_config" key="vhost_driver_mode" > + type='{"type": "string", "enum": ["set", ["server", > "client"]]}'> > + <p> > + Specifies which mode OVS will use for vHost. In 'server' mode, OVS > + creates and destroys the vHost User sockets. In 'client' mode, OVS > + attaches to sockets created by QEMU. > + </p> > + <p> > + Defaults to 'server' mode. Changing this value requires restarting > + the daemon. > + </p> > + </column> > + > <column name="other_config" key="n-handler-threads" > type='{"type": "integer", "minInteger": 1}'> > <p> _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev