vringh: add 'iotlb_lock' to synchronize iotlb accesses
Usually iotlb accesses are synchronized with a spinlock. Let's request it as a new parameter in vringh_set_iotlb() and hold it when we navigate the iotlb in iotlb_translate() to avoid race conditions with any new additions/deletions of ranges from the ioltb. Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://lore.kernel.org/r/20210315163450.254396-3-sgarzare@redhat.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
4080fc1067
commit
f53d9910d0
@ -284,7 +284,8 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr)
|
|||||||
goto err_iommu;
|
goto err_iommu;
|
||||||
|
|
||||||
for (i = 0; i < dev_attr->nvqs; i++)
|
for (i = 0; i < dev_attr->nvqs; i++)
|
||||||
vringh_set_iotlb(&vdpasim->vqs[i].vring, vdpasim->iommu);
|
vringh_set_iotlb(&vdpasim->vqs[i].vring, vdpasim->iommu,
|
||||||
|
&vdpasim->iommu_lock);
|
||||||
|
|
||||||
ret = iova_cache_get();
|
ret = iova_cache_get();
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1074,6 +1074,8 @@ static int iotlb_translate(const struct vringh *vrh,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
u64 s = 0;
|
u64 s = 0;
|
||||||
|
|
||||||
|
spin_lock(vrh->iotlb_lock);
|
||||||
|
|
||||||
while (len > s) {
|
while (len > s) {
|
||||||
u64 size, pa, pfn;
|
u64 size, pa, pfn;
|
||||||
|
|
||||||
@ -1103,6 +1105,8 @@ static int iotlb_translate(const struct vringh *vrh,
|
|||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock(vrh->iotlb_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,10 +1266,13 @@ EXPORT_SYMBOL(vringh_init_iotlb);
|
|||||||
* vringh_set_iotlb - initialize a vringh for a ring with IOTLB.
|
* vringh_set_iotlb - initialize a vringh for a ring with IOTLB.
|
||||||
* @vrh: the vring
|
* @vrh: the vring
|
||||||
* @iotlb: iotlb associated with this vring
|
* @iotlb: iotlb associated with this vring
|
||||||
|
* @iotlb_lock: spinlock to synchronize the iotlb accesses
|
||||||
*/
|
*/
|
||||||
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb)
|
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb,
|
||||||
|
spinlock_t *iotlb_lock)
|
||||||
{
|
{
|
||||||
vrh->iotlb = iotlb;
|
vrh->iotlb = iotlb;
|
||||||
|
vrh->iotlb_lock = iotlb_lock;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vringh_set_iotlb);
|
EXPORT_SYMBOL(vringh_set_iotlb);
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ struct vringh {
|
|||||||
/* IOTLB for this vring */
|
/* IOTLB for this vring */
|
||||||
struct vhost_iotlb *iotlb;
|
struct vhost_iotlb *iotlb;
|
||||||
|
|
||||||
|
/* spinlock to synchronize IOTLB accesses */
|
||||||
|
spinlock_t *iotlb_lock;
|
||||||
|
|
||||||
/* The function to call to notify the guest about added buffers */
|
/* The function to call to notify the guest about added buffers */
|
||||||
void (*notify)(struct vringh *);
|
void (*notify)(struct vringh *);
|
||||||
};
|
};
|
||||||
@ -258,7 +261,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
|
|||||||
|
|
||||||
#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
|
#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
|
||||||
|
|
||||||
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb);
|
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb,
|
||||||
|
spinlock_t *iotlb_lock);
|
||||||
|
|
||||||
int vringh_init_iotlb(struct vringh *vrh, u64 features,
|
int vringh_init_iotlb(struct vringh *vrh, u64 features,
|
||||||
unsigned int num, bool weak_barriers,
|
unsigned int num, bool weak_barriers,
|
||||||
|
Loading…
Reference in New Issue
Block a user