Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Chris Wilson and committed by
Daniel Vetter
5cfacded 1f5d76db

+22 -19
+22 -19
drivers/gpu/drm/i915/i915_gem_dmabuf.c
··· 42 42 43 43 ret = i915_mutex_lock_interruptible(obj->base.dev); 44 44 if (ret) 45 - return ERR_PTR(ret); 45 + goto err; 46 46 47 47 ret = i915_gem_object_get_pages(obj); 48 - if (ret) { 49 - st = ERR_PTR(ret); 50 - goto out; 51 - } 48 + if (ret) 49 + goto err_unlock; 50 + 51 + i915_gem_object_pin_pages(obj); 52 52 53 53 /* Copy sg so that we make an independent mapping */ 54 54 st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); 55 55 if (st == NULL) { 56 - st = ERR_PTR(-ENOMEM); 57 - goto out; 56 + ret = -ENOMEM; 57 + goto err_unpin; 58 58 } 59 59 60 60 ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL); 61 - if (ret) { 62 - kfree(st); 63 - st = ERR_PTR(ret); 64 - goto out; 65 - } 61 + if (ret) 62 + goto err_free; 66 63 67 64 src = obj->pages->sgl; 68 65 dst = st->sgl; ··· 70 73 } 71 74 72 75 if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { 73 - sg_free_table(st); 74 - kfree(st); 75 - st = ERR_PTR(-ENOMEM); 76 - goto out; 76 + ret =-ENOMEM; 77 + goto err_free_sg; 77 78 } 78 79 79 - i915_gem_object_pin_pages(obj); 80 - 81 - out: 82 80 mutex_unlock(&obj->base.dev->struct_mutex); 83 81 return st; 82 + 83 + err_free_sg: 84 + sg_free_table(st); 85 + err_free: 86 + kfree(st); 87 + err_unpin: 88 + i915_gem_object_unpin_pages(obj); 89 + err_unlock: 90 + mutex_unlock(&obj->base.dev->struct_mutex); 91 + err: 92 + return ERR_PTR(ret); 84 93 } 85 94 86 95 static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,