[PATCH 2/2] drm/i915/gvt: Fix inconsistent locks holding sequence
Chuanxiao Dong
chuanxiao.dong at intel.com
Mon Jun 19 09:04:11 UTC 2017
There are two kinds of locking sequence.
One is in the thread which is started by vfio ioctl to do
the iommu unmapping. The locking sequence is:
down_read(&group_lock) ----> mutex_lock(&cached_lock)
The other is in the vfio release thread which will unpin all
the cached pages. The lock sequence is:
mutex_lock(&cached_lock) ---> down_read(&group_lock)
And, the cache_lock is used to protect the rb tree of the cache
node and doing vfio unpin doesn't require this lock. Move the
vfio unpin out of the cache_lock protected region.
Fixes: f30437c5e7bf ("drm/i915/gvt: add KVMGT support")
Signed-off-by: Chuanxiao Dong <chuanxiao.dong at intel.com>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 88a4d8f..1405c60 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -192,13 +192,6 @@ static void gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
kfree(new);
}
-static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu,
- struct gvt_dma *entry)
-{
- rb_erase(&entry->node, &vgpu->vdev.cache);
- kfree(entry);
-}
-
static void intel_vgpu_unpin_work(struct work_struct *work)
{
struct intel_vgpu *vgpu = container_of(work, struct intel_vgpu,
@@ -260,16 +253,22 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
struct device *dev = mdev_dev(vgpu->vdev.mdev);
unsigned long gfn;
- mutex_lock(&vgpu->vdev.cache_lock);
- while ((node = rb_first(&vgpu->vdev.cache))) {
+ do {
+ mutex_lock(&vgpu->vdev.cache_lock);
+ node = rb_first(&vgpu->vdev.cache);
+ if (!node) {
+ mutex_unlock(&vgpu->vdev.cache_lock);
+ break;
+ }
dma = rb_entry(node, struct gvt_dma, node);
gvt_dma_unmap_iova(vgpu, dma->iova);
- gfn = dma->gfn;
+ rb_erase(&dma->node, &vgpu->vdev.cache);
+ mutex_unlock(&vgpu->vdev.cache_lock);
+ gfn = dma->gfn;
vfio_unpin_pages(dev, &gfn, 1);
- __gvt_cache_remove_entry(vgpu, dma);
- }
- mutex_unlock(&vgpu->vdev.cache_lock);
+ kfree(dma);
+ } while (1);
}
static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt,
--
2.7.4
More information about the intel-gvt-dev
mailing list