Skip to content

Commit

Permalink
vringh: add 'iotlb_lock' to synchronize iotlb accesses
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefano Garzarella authored and Michael S. Tsirkin committed May 3, 2021
1 parent 4080fc1 commit f53d991
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
3 changes: 2 additions & 1 deletion drivers/vdpa/vdpa_sim/vdpa_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr)
goto err_iommu;

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();
if (ret)
Expand Down
9 changes: 8 additions & 1 deletion drivers/vhost/vringh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,8 @@ static int iotlb_translate(const struct vringh *vrh,
int ret = 0;
u64 s = 0;

spin_lock(vrh->iotlb_lock);

while (len > s) {
u64 size, pa, pfn;

Expand Down Expand Up @@ -1103,6 +1105,8 @@ static int iotlb_translate(const struct vringh *vrh,
++ret;
}

spin_unlock(vrh->iotlb_lock);

return ret;
}

Expand Down Expand Up @@ -1262,10 +1266,13 @@ EXPORT_SYMBOL(vringh_init_iotlb);
* vringh_set_iotlb - initialize a vringh for a ring with IOTLB.
* @vrh: the 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_lock = iotlb_lock;
}
EXPORT_SYMBOL(vringh_set_iotlb);

Expand Down
6 changes: 5 additions & 1 deletion include/linux/vringh.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ struct vringh {
/* IOTLB for this vring */
struct vhost_iotlb *iotlb;

/* spinlock to synchronize IOTLB accesses */
spinlock_t *iotlb_lock;

/* The function to call to notify the guest about added buffers */
void (*notify)(struct vringh *);
};
Expand Down Expand Up @@ -258,7 +261,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)

#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,
unsigned int num, bool weak_barriers,
Expand Down

0 comments on commit f53d991

Please sign in to comment.