Re: [ovs-dev] [PATCH RFC v6 2/2] netdev-dpdk: Add vHost User PMD
[snip] > > + > > +static int > > netdev_dpdk_vhost_construct(struct netdev *netdev) > > { > > struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > > @@ -904,7 +1051,7 @@ netdev_dpdk_vhost_construct(struct netdev > *netdev) > > /* '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 > > * acceptable in 'name'. */ > > -if (strchr(name, '/') || strchr(name, '\\')) { > > +if (strchr(name, '/') || strchr(name, '\\') || strchr(name, ',')) { > > VLOG_ERR("\"%s\" is not a valid name for a vhost-user port. " > > "A valid name must not include '/' or '\\'", > > name); > > @@ -917,18 +1064,26 @@ netdev_dpdk_vhost_construct(struct netdev > *netdev) > > */ > > snprintf(dev->vhost_id, sizeof dev->vhost_id, "%s/%s", > > dpdk_get_vhost_sock_dir(), name); > > +dev->port_id = -1; > > > > -dev->vhost_driver_flags &= ~RTE_VHOST_USER_CLIENT; > > -err = rte_vhost_driver_register(dev->vhost_id, dev- > >vhost_driver_flags); > > -if (err) { > > -VLOG_ERR("vhost-user socket device setup failure for socket %s\n", > > - dev->vhost_id); > > -} else { > > +err = dpdk_attach_vhost_pmd(dev, 0); > > + > > +if (!err) { > > 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 = netdev_dpdk_init(netdev, -1, DPDK_DEV_VHOST); > > +err = netdev_dpdk_init(netdev, dev->port_id, DPDK_DEV_VHOST); > > + > > +if (err) { > > I think, that callbacks are not registered at this point in case of failure. > Anyway, IMHO, 'netdev_dpdk_init' should be responsible for unregistering. Ok > > > +rte_eth_dev_callback_unregister(dev->port_id, > > +RTE_ETH_EVENT_QUEUE_STATE, > > +vring_state_changed_callback, > > NULL); > > +rte_eth_dev_callback_unregister(dev->port_id, > > +RTE_ETH_EVENT_INTR_LSC, > > +link_status_changed_callback, > > NULL); > > +rte_eth_dev_detach(dev->port_id, dev->vhost_id); > > +} > > > > ovs_mutex_unlock(_mutex); > > return err; > > @@ -940,7 +1095,7 @@ netdev_dpdk_vhost_client_construct(struct > netdev *netdev) > > int err; > > > > ovs_mutex_lock(_mutex); > > -err = netdev_dpdk_init(netdev, -1, DPDK_DEV_VHOST); > > +err = netdev_dpdk_init(netdev, -1, DPDK_DEV_VHOST_CLIENT); > > ovs_mutex_unlock(_mutex); > > return err; > > } > > @@ -964,13 +1119,10 @@ netdev_dpdk_construct(struct netdev *netdev) > > } > > > > static void > > -netdev_dpdk_destruct(struct netdev *netdev) > > +dpdk_destruct_helper(struct netdev_dpdk *dev) > > +OVS_REQUIRES(dpdk_mutex) > > +OVS_REQUIRES(dev->mutex) > > { > > -struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > > - > > -ovs_mutex_lock(_mutex); > > -ovs_mutex_lock(>mutex); > > - > > rte_eth_dev_stop(dev->port_id); > > free(ovsrcu_get_protected(struct ingress_policer *, > >>ingress_policer)); > > @@ -978,61 +1130,59 @@ netdev_dpdk_destruct(struct netdev *netdev) > > rte_free(dev->tx_q); > > ovs_list_remove(>list_node); > > dpdk_mp_put(dev->dpdk_mp); > > - > > -ovs_mutex_unlock(>mutex); > > -ovs_mutex_unlock(_mutex); > > } > > > > -/* rte_vhost_driver_unregister() can call back destroy_device(), which will > > - * try to acquire 'dpdk_mutex' and possibly 'dev->mutex'. To avoid a > > - * deadlock, none of the mutexes must be held while calling this function. > */ > > -static int > > -dpdk_vhost_driver_unregister(struct netdev_dpdk *dev OVS_UNUSED, > > - char *vhost_id) > > -OVS_EXCLUDED(dpdk_mutex) > > -OVS_EXCLUDED(dev->mutex) > > +static void > > +netdev_dpdk_destruct(struct netdev *netdev) > > { > > -return rte_vhost_driver_unregister(vhost_id); > > +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > > + > > +ovs_mutex_lock(_mutex); > > +ovs_mutex_lock(>mutex); > > + > > +dpdk_destruct_helper(dev); > > + > > +ovs_mutex_unlock(>mutex); > > +ovs_mutex_unlock(_mutex); > > } > > > > static void > > netdev_dpdk_vhost_destruct(struct netdev *netdev) > > { > > struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > > -char *vhost_id; > > > > ovs_mutex_lock(_mutex); > > ovs_mutex_lock(>mutex); > > > > -/* Guest becomes an orphan if still attached. */ > > -if (netdev_dpdk_get_vid(dev) >= 0 > > -&& !(dev->vhost_driver_flags & RTE_VHOST_USER_CLIENT)) { > > +check_link_status(dev); > > +if (dev->link.link_status == ETH_LINK_UP) { > > VLOG_ERR("Removing port '%s' while vhost device
Re: [ovs-dev] [PATCH RFC v6 2/2] netdev-dpdk: Add vHost User PMD
Still not a full review. Comments inline. Bet regards, Ilya Maximets. On 28.10.2016 16:03, Ciara Loftus wrote: > The vHost PMD allows vHost User ports to be controlled by the > librte_ether API, like physical 'dpdk' ports and IVSHM 'dpdkr' ports. > This commit integrates this PMD into OVS and removes direct calls to the > librte_vhost DPDK library. > > This commit requires DPDK v16.11 functionality that isn't available in > previous releases, and thus breaks compatibility with such releases. > > Signed-off-by: Ciara Loftus> > --- > v6: > * Unregister callbacks before detach > > v5: > * change vhost_pmd_id to signed int and use -1 value to indicate an > ID from the pool hasn't been alloced for it yet. > * free pool ID if rte_eth_dev_attach fails. > * check link status on destruct and print warning if the port is live. > * only free ID during destruct if it has been allocated. > > v4: > * Use id-pool implementation for allocating vHost PMD IDs > > v3: > * Added DPDK_DEV_VHOST_CLIENT netdev_dpdk "type" > * Reintroduced socket-id logic to correctly set client type sid > * Removed magic number & used var instead > * Remove race condition in netdev_dpdk_init by reordering code. > * Detach vHost PMD if netdev_dpdk_init fails > * Introduce "out" in client_reconfigure for when txq alloc fails > * Remove set_tx_multiq fn for vHost ports > --- > NEWS | 2 + > lib/dpdk.c| 10 + > lib/dpdk.h| 1 + > lib/netdev-dpdk.c | 977 > +- > 4 files changed, 388 insertions(+), 602 deletions(-) > > diff --git a/NEWS b/NEWS > index 037bcda..5f84b0b 100644 > --- a/NEWS > +++ b/NEWS > @@ -137,6 +137,8 @@ v2.6.0 - 27 Sep 2016 > * Remove dpdkvhostcuse port type. > * OVS client mode for vHost and vHost reconnect (Requires QEMU 2.7) > * 'dpdkvhostuserclient' port type. > + * vHost PMD integration brings vhost-user ports under control of the > + rte_ether DPDK API. > - Increase number of registers to 16. > - ovs-benchmark: This utility has been removed due to lack of use and > bitrot. > diff --git a/lib/dpdk.c b/lib/dpdk.c > index 49a589a..831257a 100644 > --- a/lib/dpdk.c > +++ b/lib/dpdk.c > @@ -29,6 +29,7 @@ > > #include "dirs.h" > #include "fatal-signal.h" > +#include "id-pool.h" > #include "netdev-dpdk.h" > #include "openvswitch/dynamic-string.h" > #include "openvswitch/vlog.h" > @@ -37,6 +38,7 @@ > VLOG_DEFINE_THIS_MODULE(dpdk); > > static char *vhost_sock_dir = NULL; /* Location of vhost-user sockets */ > +static struct id_pool *vhost_driver_ids; /* Pool of IDs for vHost PMDs */ > > static int > process_vhost_flags(char *flag, char *default_val, int size, > @@ -407,6 +409,8 @@ dpdk_init__(const struct smap *ovs_other_config) > } > #endif > > +vhost_driver_ids = id_pool_create(0, RTE_MAX_ETHPORTS - 1); > + > /* Finally, register the dpdk classes */ > netdev_dpdk_register(); > } > @@ -428,6 +432,12 @@ dpdk_get_vhost_sock_dir(void) > return vhost_sock_dir; > } > > +struct id_pool * > +dpdk_get_vhost_id_pool(void) > +{ > +return vhost_driver_ids; > +} > + > void > dpdk_set_lcore_id(unsigned cpu) > { > diff --git a/lib/dpdk.h b/lib/dpdk.h > index 673a1f1..fb85c06 100644 > --- a/lib/dpdk.h > +++ b/lib/dpdk.h > @@ -35,5 +35,6 @@ struct smap; > void dpdk_init(const struct smap *ovs_other_config); > void dpdk_set_lcore_id(unsigned cpu); > const char *dpdk_get_vhost_sock_dir(void); > +struct id_pool *dpdk_get_vhost_id_pool(void); > > #endif /* dpdk.h */ > diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c > index 7c1523e..0b1af1d 100644 > --- a/lib/netdev-dpdk.c > +++ b/lib/netdev-dpdk.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -38,6 +39,7 @@ > #include "dpdk.h" > #include "dpif-netdev.h" > #include "fatal-signal.h" > +#include "id-pool.h" > #include "netdev-provider.h" > #include "netdev-vport.h" > #include "odp-util.h" > @@ -122,6 +124,7 @@ BUILD_ASSERT_DECL((MAX_NB_MBUF / > ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF)) > #define XSTAT_RX_BROADCAST_PACKETS "rx_broadcast_packets" > #define XSTAT_TX_BROADCAST_PACKETS "tx_broadcast_packets" > #define XSTAT_RX_UNDERSIZED_ERRORS "rx_undersized_errors" > +#define XSTAT_RX_UNDERSIZE_PACKETS "rx_undersize_packets" > #define XSTAT_RX_OVERSIZE_ERRORS "rx_oversize_errors" > #define XSTAT_RX_FRAGMENTED_ERRORS "rx_fragmented_errors" > #define XSTAT_RX_JABBER_ERRORS "rx_jabber_errors" > @@ -171,6 +174,7 @@ enum { DRAIN_TSC = 20ULL }; > enum dpdk_dev_type { > DPDK_DEV_ETH = 0, > DPDK_DEV_VHOST = 1, > +DPDK_DEV_VHOST_CLIENT = 2, > }; > > /* Quality of Service */ > @@ -343,15 +347,12 @@ struct netdev_dpdk { > struct rte_eth_link link; > int link_reset_cnt; > > -/* virtio identifier for vhost devices */ > -
[ovs-dev] [PATCH RFC v6 2/2] netdev-dpdk: Add vHost User PMD
The vHost PMD allows vHost User ports to be controlled by the librte_ether API, like physical 'dpdk' ports and IVSHM 'dpdkr' ports. This commit integrates this PMD into OVS and removes direct calls to the librte_vhost DPDK library. This commit requires DPDK v16.11 functionality that isn't available in previous releases, and thus breaks compatibility with such releases. Signed-off-by: Ciara Loftus--- v6: * Unregister callbacks before detach v5: * change vhost_pmd_id to signed int and use -1 value to indicate an ID from the pool hasn't been alloced for it yet. * free pool ID if rte_eth_dev_attach fails. * check link status on destruct and print warning if the port is live. * only free ID during destruct if it has been allocated. v4: * Use id-pool implementation for allocating vHost PMD IDs v3: * Added DPDK_DEV_VHOST_CLIENT netdev_dpdk "type" * Reintroduced socket-id logic to correctly set client type sid * Removed magic number & used var instead * Remove race condition in netdev_dpdk_init by reordering code. * Detach vHost PMD if netdev_dpdk_init fails * Introduce "out" in client_reconfigure for when txq alloc fails * Remove set_tx_multiq fn for vHost ports --- NEWS | 2 + lib/dpdk.c| 10 + lib/dpdk.h| 1 + lib/netdev-dpdk.c | 977 +- 4 files changed, 388 insertions(+), 602 deletions(-) diff --git a/NEWS b/NEWS index 037bcda..5f84b0b 100644 --- a/NEWS +++ b/NEWS @@ -137,6 +137,8 @@ v2.6.0 - 27 Sep 2016 * Remove dpdkvhostcuse port type. * OVS client mode for vHost and vHost reconnect (Requires QEMU 2.7) * 'dpdkvhostuserclient' port type. + * vHost PMD integration brings vhost-user ports under control of the + rte_ether DPDK API. - Increase number of registers to 16. - ovs-benchmark: This utility has been removed due to lack of use and bitrot. diff --git a/lib/dpdk.c b/lib/dpdk.c index 49a589a..831257a 100644 --- a/lib/dpdk.c +++ b/lib/dpdk.c @@ -29,6 +29,7 @@ #include "dirs.h" #include "fatal-signal.h" +#include "id-pool.h" #include "netdev-dpdk.h" #include "openvswitch/dynamic-string.h" #include "openvswitch/vlog.h" @@ -37,6 +38,7 @@ VLOG_DEFINE_THIS_MODULE(dpdk); static char *vhost_sock_dir = NULL; /* Location of vhost-user sockets */ +static struct id_pool *vhost_driver_ids; /* Pool of IDs for vHost PMDs */ static int process_vhost_flags(char *flag, char *default_val, int size, @@ -407,6 +409,8 @@ dpdk_init__(const struct smap *ovs_other_config) } #endif +vhost_driver_ids = id_pool_create(0, RTE_MAX_ETHPORTS - 1); + /* Finally, register the dpdk classes */ netdev_dpdk_register(); } @@ -428,6 +432,12 @@ dpdk_get_vhost_sock_dir(void) return vhost_sock_dir; } +struct id_pool * +dpdk_get_vhost_id_pool(void) +{ +return vhost_driver_ids; +} + void dpdk_set_lcore_id(unsigned cpu) { diff --git a/lib/dpdk.h b/lib/dpdk.h index 673a1f1..fb85c06 100644 --- a/lib/dpdk.h +++ b/lib/dpdk.h @@ -35,5 +35,6 @@ struct smap; void dpdk_init(const struct smap *ovs_other_config); void dpdk_set_lcore_id(unsigned cpu); const char *dpdk_get_vhost_sock_dir(void); +struct id_pool *dpdk_get_vhost_id_pool(void); #endif /* dpdk.h */ diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 7c1523e..0b1af1d 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ #include "dpdk.h" #include "dpif-netdev.h" #include "fatal-signal.h" +#include "id-pool.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "odp-util.h" @@ -122,6 +124,7 @@ BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF)) #define XSTAT_RX_BROADCAST_PACKETS "rx_broadcast_packets" #define XSTAT_TX_BROADCAST_PACKETS "tx_broadcast_packets" #define XSTAT_RX_UNDERSIZED_ERRORS "rx_undersized_errors" +#define XSTAT_RX_UNDERSIZE_PACKETS "rx_undersize_packets" #define XSTAT_RX_OVERSIZE_ERRORS "rx_oversize_errors" #define XSTAT_RX_FRAGMENTED_ERRORS "rx_fragmented_errors" #define XSTAT_RX_JABBER_ERRORS "rx_jabber_errors" @@ -171,6 +174,7 @@ enum { DRAIN_TSC = 20ULL }; enum dpdk_dev_type { DPDK_DEV_ETH = 0, DPDK_DEV_VHOST = 1, +DPDK_DEV_VHOST_CLIENT = 2, }; /* Quality of Service */ @@ -343,15 +347,12 @@ struct netdev_dpdk { struct rte_eth_link link; int link_reset_cnt; -/* virtio identifier for vhost devices */ -ovsrcu_index vid; - -/* True if vHost device is 'up' and has been reconfigured at least once */ -bool vhost_reconfigured; - /* Identifier used to distinguish vhost devices from each other. */ char vhost_id[PATH_MAX]; +/* ID of vhost user port given to the PMD driver */ +int32_t vhost_pmd_id; + /* In dpdk_list. */ struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex); @@