Skip to content

Commit

Permalink
drm/i915: Convert the dmabuf object to use the new i915_gem_object_ops
Browse files Browse the repository at this point in the history
By providing a callback for when we need to bind the pages, and then
release them again later, we can shorten the amount of time we hold the
foreign pages mapped and pinned, and importantly the dmabuf objects then
behave as any other normal object with respect to the shrinker and
memory management.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Sep 20, 2012
1 parent 68d3472 commit 2f745ad
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,6 @@ struct drm_i915_gem_object {
int pages_pin_count;

/* prime dma-buf support */
struct sg_table *sg_table;
void *dma_buf_vmapping;
int vmapping_count;

Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1692,7 +1692,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
{
const struct drm_i915_gem_object_ops *ops = obj->ops;

if (obj->sg_table || obj->pages == NULL)
if (obj->pages == NULL)
return 0;

BUG_ON(obj->gtt_space);
Expand Down Expand Up @@ -1845,7 +1845,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
const struct drm_i915_gem_object_ops *ops = obj->ops;
int ret;

if (obj->sg_table || obj->pages)
if (obj->pages)
return 0;

BUG_ON(obj->pages_pin_count);
Expand Down Expand Up @@ -3738,9 +3738,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)

trace_i915_gem_object_destroy(obj);

if (gem_obj->import_attach)
drm_prime_gem_destroy(gem_obj, obj->sg_table);

if (obj->phys_obj)
i915_gem_detach_phys_object(dev, obj);

Expand All @@ -3762,6 +3759,9 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)

BUG_ON(obj->pages);

if (obj->base.import_attach)
drm_prime_gem_destroy(&obj->base, NULL);

drm_gem_object_release(&obj->base);
i915_gem_info_remove_obj(dev_priv, obj->base.size);

Expand Down
44 changes: 30 additions & 14 deletions drivers/gpu/drm/i915/i915_gem_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
}

static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
struct sg_table *sg, enum dma_data_direction dir)
struct sg_table *sg,
enum dma_data_direction dir)
{
dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
sg_free_table(sg);
Expand Down Expand Up @@ -228,11 +229,35 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, 0600);
}

static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
{
struct sg_table *sg;

sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL);
if (IS_ERR(sg))
return PTR_ERR(sg);

obj->pages = sg;
obj->has_dma_mapping = true;
return 0;
}

static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
{
dma_buf_unmap_attachment(obj->base.import_attach,
obj->pages, DMA_BIDIRECTIONAL);
obj->has_dma_mapping = false;
}

static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
.get_pages = i915_gem_object_get_pages_dmabuf,
.put_pages = i915_gem_object_put_pages_dmabuf,
};

struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf)
{
struct dma_buf_attachment *attach;
struct sg_table *sg;
struct drm_i915_gem_object *obj;
int ret;

Expand All @@ -251,34 +276,25 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
if (IS_ERR(attach))
return ERR_CAST(attach);

sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
if (IS_ERR(sg)) {
ret = PTR_ERR(sg);
goto fail_detach;
}

obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) {
ret = -ENOMEM;
goto fail_unmap;
goto fail_detach;
}

ret = drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
if (ret) {
kfree(obj);
goto fail_unmap;
goto fail_detach;
}

obj->has_dma_mapping = true;
obj->sg_table = sg;
i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
obj->base.import_attach = attach;

return &obj->base;

fail_unmap:
dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
fail_detach:
dma_buf_detach(dma_buf, attach);
return ERR_PTR(ret);
}

4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
}

i915_ppgtt_insert_sg_entries(ppgtt,
obj->sg_table ?: obj->pages,
obj->pages,
obj->gtt_space->start >> PAGE_SHIFT,
pte_flags);
}
Expand Down Expand Up @@ -325,7 +325,7 @@ void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
struct drm_device *dev = obj->base.dev;
unsigned int agp_type = cache_level_to_agp_type(dev, cache_level);

intel_gtt_insert_sg_entries(obj->sg_table ?: obj->pages,
intel_gtt_insert_sg_entries(obj->pages,
obj->gtt_space->start >> PAGE_SHIFT,
agp_type);
obj->has_global_gtt_mapping = 1;
Expand Down

0 comments on commit 2f745ad

Please sign in to comment.