From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tiwei Bie Subject: Re: [PATCH v2] vhost: flush IOTLB cache on new mem table handling Date: Fri, 3 Aug 2018 10:30:14 +0800 Message-ID: <20180803023014.GA28910@debian> References: <20180802172122.25923-1-maxime.coquelin@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Cc: zhihong.wang@intel.com, jfreimann@redhat.com, dev@dpdk.org, stable@dpdk.org To: Maxime Coquelin Return-path: Content-Disposition: inline In-Reply-To: <20180802172122.25923-1-maxime.coquelin@redhat.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On Thu, Aug 02, 2018 at 07:21:22PM +0200, Maxime Coquelin wrote: > IOTLB entries contain the host virtual address of the guest > pages. When receiving a new VHOST_USER_SET_MEM_TABLE request, > the previous regions get unmapped, so the IOTLB entries, if any, > will be invalid. It does cause the vhost-user process to > segfault. > > This patch introduces a new function to flush the IOTLB cache, > and call it as soon as the backend handles a VHOST_USER_SET_MEM > request. > > Fixes: 69c90e98f483 ("vhost: enable IOMMU support") > Cc: stable@dpdk.org > > Signed-off-by: Maxime Coquelin > --- > Changes since v1: > - Fix indentation (Stephen) > - Fix double iotlb-lock lock > > lib/librte_vhost/iotlb.c | 10 ++++++++-- > lib/librte_vhost/iotlb.h | 2 +- > lib/librte_vhost/vhost_user.c | 5 +++++ > 3 files changed, 14 insertions(+), 3 deletions(-) > > diff --git a/lib/librte_vhost/iotlb.c b/lib/librte_vhost/iotlb.c > index c11ebcaac..c6354fef7 100644 > --- a/lib/librte_vhost/iotlb.c > +++ b/lib/librte_vhost/iotlb.c > @@ -303,6 +303,13 @@ vhost_user_iotlb_cache_find(struct vhost_virtqueue *vq, uint64_t iova, > return vva; > } > > +void > +vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq) > +{ > + vhost_user_iotlb_cache_remove_all(vq); > + vhost_user_iotlb_pending_remove_all(vq); > +} > + > int > vhost_user_iotlb_init(struct virtio_net *dev, int vq_index) > { > @@ -315,8 +322,7 @@ vhost_user_iotlb_init(struct virtio_net *dev, int vq_index) > * The cache has already been initialized, > * just drop all cached and pending entries. > */ > - vhost_user_iotlb_cache_remove_all(vq); > - vhost_user_iotlb_pending_remove_all(vq); > + vhost_user_iotlb_flush_all(vq); > } > > #ifdef RTE_LIBRTE_VHOST_NUMA > diff --git a/lib/librte_vhost/iotlb.h b/lib/librte_vhost/iotlb.h > index e7083e37b..60b9e4c57 100644 > --- a/lib/librte_vhost/iotlb.h > +++ b/lib/librte_vhost/iotlb.h > @@ -73,7 +73,7 @@ void vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq, uint64_t iova, > uint8_t perm); > void vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq, uint64_t iova, > uint64_t size, uint8_t perm); > - > +void vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq); > int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index); > > #endif /* _VHOST_IOTLB_H_ */ > diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c > index dc53ff712..a2d4c9ffc 100644 > --- a/lib/librte_vhost/vhost_user.c > +++ b/lib/librte_vhost/vhost_user.c > @@ -813,6 +813,11 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *pmsg) > dev->mem = NULL; > } > > + /* Flush IOTLB cache as previous HVAs are now invalid */ > + if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) > + for (i = 0; i < dev->nr_vring; i++) > + vhost_user_iotlb_flush_all(dev->virtqueue[i]); Why is the pending list also flushed? Thanks, Tiwei