diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-20 11:40:46 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-08-21 14:34:11 +0200 |
commit | 6c085a728cf000ac1865d66f8c9b52935558b328 (patch) | |
tree | 416d56b284e9aba4da4aee1d6c6a8f5fa16a934e /drivers/gpu/drm/i915/i915_gem_dmabuf.c | |
parent | 225067eedf1f4d4065940232c9069fcb255206ee (diff) | |
download | talos-obmc-linux-6c085a728cf000ac1865d66f8c9b52935558b328.tar.gz talos-obmc-linux-6c085a728cf000ac1865d66f8c9b52935558b328.zip |
drm/i915: Track unbound pages
When dealing with a working set larger than the GATT, or even the
mappable aperture when touching through the GTT, we end up with evicting
objects only to rebind them at a new offset again later. Moving an
object into and out of the GTT requires clflushing the pages, thus
causing a double-clflush penalty for rebinding.
To avoid having to clflush on rebinding, we can track the pages as they
are evicted from the GTT and only relinquish those pages on memory
pressure.
As usual, if it were not for the handling of out-of-memory condition and
having to manually shrink our own bo caches, it would be a net reduction
of code. Alas.
Note: The patch also contains a few changes to the last-hope
evict_everything logic in i916_gem_execbuffer.c - we no longer try to
only evict the purgeable stuff in a first try (since that's superflous
and only helps in OOM corner-cases, not fragmented-gtt trashing
situations).
Also, the extraction of the get_pages retry loop from bind_to_gtt (and
other callsites) to get_pages should imo have been a separate patch.
v2: Ditch the newly added put_pages (for unbound objects only) in
i915_gem_reset. A quick irc discussion hasn't revealed any important
reason for this, so if we need this, I'd like to have a git blame'able
explanation for it.
v3: Undo the s/drm_malloc_ab/kmalloc/ in get_pages that Chris noticed.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: Split out code movements and rant a bit in the commit message
with a few Notes. Done v2]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_dmabuf.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_dmabuf.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index ceaad5af01a4..43c95307f99e 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -33,7 +33,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme struct drm_i915_gem_object *obj = attachment->dmabuf->priv; struct drm_device *dev = obj->base.dev; int npages = obj->base.size / PAGE_SIZE; - struct sg_table *sg = NULL; + struct sg_table *sg; int ret; int nents; @@ -41,10 +41,10 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme if (ret) return ERR_PTR(ret); - if (!obj->pages) { - ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN); - if (ret) - goto out; + ret = i915_gem_object_get_pages_gtt(obj); + if (ret) { + sg = ERR_PTR(ret); + goto out; } /* link the pages into an SG then map the sg */ @@ -89,12 +89,10 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) goto out_unlock; } - if (!obj->pages) { - ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ERR_PTR(ret); - } + ret = i915_gem_object_get_pages_gtt(obj); + if (ret) { + mutex_unlock(&dev->struct_mutex); + return ERR_PTR(ret); } obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL); |