Commit 5cfacded authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter

drm/i915: Pin pages whilst mapping the dma-buf

As we attempt to kmalloc after calling get_pages, there is a possibility
that the shrinker may reap the pages we just acquired. To prevent this
we need to increment the pages_pin_count early, so rearrange the code
and error paths to make it so.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 1f5d76db
...@@ -42,27 +42,24 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme ...@@ -42,27 +42,24 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
ret = i915_mutex_lock_interruptible(obj->base.dev); ret = i915_mutex_lock_interruptible(obj->base.dev);
if (ret) if (ret)
return ERR_PTR(ret); goto err;
ret = i915_gem_object_get_pages(obj); ret = i915_gem_object_get_pages(obj);
if (ret) { if (ret)
st = ERR_PTR(ret); goto err_unlock;
goto out;
} i915_gem_object_pin_pages(obj);
/* Copy sg so that we make an independent mapping */ /* Copy sg so that we make an independent mapping */
st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (st == NULL) { if (st == NULL) {
st = ERR_PTR(-ENOMEM); ret = -ENOMEM;
goto out; goto err_unpin;
} }
ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL); ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL);
if (ret) { if (ret)
kfree(st); goto err_free;
st = ERR_PTR(ret);
goto out;
}
src = obj->pages->sgl; src = obj->pages->sgl;
dst = st->sgl; dst = st->sgl;
...@@ -73,17 +70,23 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme ...@@ -73,17 +70,23 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
} }
if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
sg_free_table(st); ret =-ENOMEM;
kfree(st); goto err_free_sg;
st = ERR_PTR(-ENOMEM);
goto out;
} }
i915_gem_object_pin_pages(obj);
out:
mutex_unlock(&obj->base.dev->struct_mutex); mutex_unlock(&obj->base.dev->struct_mutex);
return st; return st;
err_free_sg:
sg_free_table(st);
err_free:
kfree(st);
err_unpin:
i915_gem_object_unpin_pages(obj);
err_unlock:
mutex_unlock(&obj->base.dev->struct_mutex);
err:
return ERR_PTR(ret);
} }
static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment