> > These variables are needed to be able to manage one of virtio devices > using both vhost library APIs and vhost PMD. > For example, if vhost PMD uses current callback handler and private data > provided by vhost library, A DPDK application that links vhost library > cannot use some of vhost library APIs. To avoid it, callback and private > data for vhost PMD are needed. > > Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp> > --- > lib/librte_vhost/rte_vhost_version.map | 6 +++ > lib/librte_vhost/rte_virtio_net.h | 3 ++ > lib/librte_vhost/vhost_user/virtio-net-user.c | 13 +++---- > lib/librte_vhost/virtio-net.c | 56 > +++++++++++++++++++++++++-- > lib/librte_vhost/virtio-net.h | 4 +- > 5 files changed, 70 insertions(+), 12 deletions(-) > > diff --git a/lib/librte_vhost/rte_vhost_version.map > b/lib/librte_vhost/rte_vhost_version.map > index 3d8709e..00a9ce5 100644 > --- a/lib/librte_vhost/rte_vhost_version.map > +++ b/lib/librte_vhost/rte_vhost_version.map > @@ -20,3 +20,9 @@ DPDK_2.1 { > rte_vhost_driver_unregister; > > } DPDK_2.0; > + > +DPDK_2.2 { > + global: > + > + rte_vhost_driver_pmd_callback_register; > +} DPDK_2.1; > diff --git a/lib/librte_vhost/rte_virtio_net.h > b/lib/librte_vhost/rte_virtio_net.h > index 426a70d..08e77af 100644 > --- a/lib/librte_vhost/rte_virtio_net.h > +++ b/lib/librte_vhost/rte_virtio_net.h > @@ -106,6 +106,7 @@ struct virtio_net { > char ifname[IF_NAME_SZ]; /**< Name of the tap > device or socket path. */ > uint32_t virt_qp_nb; /**< number of queue pair > we have allocated */ > void *priv; /**< private context */ > + void *pmd_priv; /**< private context for > vhost PMD */ > struct vhost_virtqueue > *virtqueue[VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX]; /**< Contains > all virtqueue information. */ > } __rte_cache_aligned; > > @@ -202,6 +203,8 @@ int rte_vhost_driver_unregister(const char > *dev_name); > > /* Register callbacks. */ > int rte_vhost_driver_callback_register(struct virtio_net_device_ops const * > const); > +/* Register callbacks for vhost PMD (Only for internal). */ > +int rte_vhost_driver_pmd_callback_register(struct virtio_net_device_ops > const * const); > /* Start vhost driver session blocking loop. */ > int rte_vhost_driver_session_start(void); > > diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.c > b/lib/librte_vhost/vhost_user/virtio-net-user.c > index 3e8dfea..dad083b 100644 > --- a/lib/librte_vhost/vhost_user/virtio-net-user.c > +++ b/lib/librte_vhost/vhost_user/virtio-net-user.c > @@ -111,7 +111,7 @@ user_set_mem_table(struct vhost_device_ctx ctx, > struct VhostUserMsg *pmsg) > > /* Remove from the data plane. */ > if (dev->flags & VIRTIO_DEV_RUNNING) > - notify_ops->destroy_device(dev); > + notify_destroy_device(dev); > > if (dev->mem) { > free_mem_region(dev); > @@ -272,7 +272,7 @@ user_set_vring_kick(struct vhost_device_ctx ctx, > struct VhostUserMsg *pmsg) > > if (virtio_is_ready(dev) && > !(dev->flags & VIRTIO_DEV_RUNNING)) > - notify_ops->new_device(dev); > + notify_new_device(dev); > } > > /* > @@ -307,7 +307,7 @@ user_get_vring_base(struct vhost_device_ctx ctx, > if ((dev->flags & VIRTIO_DEV_RUNNING) && > (dev->virtqueue[base_idx + VIRTIO_RXQ]->kickfd == > -1) && > (dev->virtqueue[base_idx + VIRTIO_TXQ]->kickfd == > -1)) > - notify_ops->destroy_device(dev); > + notify_destroy_device(dev); > > return 0; > } > @@ -328,10 +328,7 @@ user_set_vring_enable(struct vhost_device_ctx ctx, > "set queue enable: %d to qp idx: %d\n", > enable, state->index); > > - if (notify_ops->vring_state_changed) { > - notify_ops->vring_state_changed(dev, base_idx / > VIRTIO_QNUM, > - enable); > - } > + notify_vring_state_changed(dev, base_idx / VIRTIO_QNUM, > enable); > > dev->virtqueue[base_idx + VIRTIO_RXQ]->enabled = enable; > dev->virtqueue[base_idx + VIRTIO_TXQ]->enabled = enable; > @@ -345,7 +342,7 @@ user_destroy_device(struct vhost_device_ctx ctx) > struct virtio_net *dev = get_device(ctx); > > if (dev && (dev->flags & VIRTIO_DEV_RUNNING)) > - notify_ops->destroy_device(dev); > + notify_destroy_device(dev); > > if (dev && dev->mem) { > free_mem_region(dev); > diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c > index ee2e84d..de5d8ff 100644 > --- a/lib/librte_vhost/virtio-net.c > +++ b/lib/librte_vhost/virtio-net.c > @@ -65,6 +65,8 @@ struct virtio_net_config_ll { > > /* device ops to add/remove device to/from data core. */ > struct virtio_net_device_ops const *notify_ops; > +/* device ops for vhost PMD to add/remove device to/from data core. */ > +struct virtio_net_device_ops const *pmd_notify_ops; > /* root address of the linked list of managed virtio devices */ > static struct virtio_net_config_ll *ll_root; > > @@ -80,6 +82,43 @@ static struct virtio_net_config_ll *ll_root; > static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES; > > > +int > +notify_new_device(struct virtio_net *dev) > +{ > + if ((pmd_notify_ops != NULL) && (pmd_notify_ops->new_device != > NULL)) { > + int ret = pmd_notify_ops->new_device(dev); > + if (ret != 0) > + return ret; > + } > + if ((notify_ops != NULL) && (notify_ops->new_device != NULL)) > + return notify_ops->new_device(dev); > + > + return 0; > +} > + > +void > +notify_destroy_device(volatile struct virtio_net *dev) > +{ > + if ((pmd_notify_ops != NULL) && (pmd_notify_ops->destroy_device > != NULL)) > + pmd_notify_ops->destroy_device(dev); > + if ((notify_ops != NULL) && (notify_ops->destroy_device != NULL)) > + notify_ops->destroy_device(dev); > +} > + > +int > +notify_vring_state_changed(struct virtio_net *dev, uint16_t queue_id, int > enable) > +{ > + if ((pmd_notify_ops != NULL) && (pmd_notify_ops- > >vring_state_changed != NULL)) { > + int ret = pmd_notify_ops->vring_state_changed(dev, > queue_id, enable); > + if (ret != 0) > + return ret; > + } > + if ((notify_ops != NULL) && (notify_ops->vring_state_changed != > NULL)) > + return notify_ops->vring_state_changed(dev, queue_id, > enable); > + > + return 0; > +} > + > /* > * Converts QEMU virtual address to Vhost virtual address. This function is > * used to convert the ring addresses to our address space. > @@ -377,7 +416,7 @@ destroy_device(struct vhost_device_ctx ctx) > * the function to remove it from the data core. > */ > if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING)) > - notify_ops->destroy_device(&(ll_dev_cur- > >dev)); > + notify_destroy_device(&(ll_dev_cur->dev)); > ll_dev_cur = rm_config_ll_entry(ll_dev_cur, > ll_dev_last); > } else { > @@ -794,12 +833,12 @@ set_backend(struct vhost_device_ctx ctx, struct > vhost_vring_file *file) > if (!(dev->flags & VIRTIO_DEV_RUNNING)) { > if (((int)dev->virtqueue[base_idx + VIRTIO_RXQ]->backend > != VIRTIO_DEV_STOPPED) && > ((int)dev->virtqueue[base_idx + VIRTIO_TXQ]- > >backend != VIRTIO_DEV_STOPPED)) { > - return notify_ops->new_device(dev); > + return notify_new_device(dev); > } > /* Otherwise we remove it. */ > } else > if (file->fd == VIRTIO_DEV_STOPPED) > - notify_ops->destroy_device(dev); > + notify_destroy_device(dev); > return 0; > } > > @@ -883,3 +922,14 @@ rte_vhost_driver_callback_register(struct > virtio_net_device_ops const * const op > > return 0; > } > + > +/* > + * Register ops so that we can add/remove device to data core. > + */ > +int > +rte_vhost_driver_pmd_callback_register(struct virtio_net_device_ops > const * const ops) > +{ > + pmd_notify_ops = ops; > + > + return 0; > +} > diff --git a/lib/librte_vhost/virtio-net.h b/lib/librte_vhost/virtio-net.h > index 75fb57e..0816e71 100644 > --- a/lib/librte_vhost/virtio-net.h > +++ b/lib/librte_vhost/virtio-net.h > @@ -37,7 +37,9 @@ > #include "vhost-net.h" > #include "rte_virtio_net.h" > > -struct virtio_net_device_ops const *notify_ops; > struct virtio_net *get_device(struct vhost_device_ctx ctx); > > +int notify_new_device(struct virtio_net *dev); > +void notify_destroy_device(volatile struct virtio_net *dev); > +int notify_vring_state_changed(struct virtio_net *dev, uint16_t queue_id, > int enable); > #endif > -- > 2.1.4
Hi Tetsuya, Thanks for implementing this. I haven't had a chance to actually test it, but if these changes allow users of the PMD to implement their own new_ and destroy_ device functions etc, that's good news. Thanks, Ciara