drm/i915: Implement end_cpu_access
authorTiago Vignatti <tiago.vignatti@intel.com>
Tue, 22 Dec 2015 21:36:47 +0000 (19:36 -0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 9 Feb 2016 10:21:03 +0000 (11:21 +0100)
This function is meant to be used with dma-buf mmap, when finishing the CPU
access of the mapped pointer.

The error case should be rare to happen though, requiring the buffer become
active during the sync period and for the end_cpu_access to be interrupted. So
we use a uninterruptible mutex_lock to spit out when it ever happens.

v2: disable interruption to make sure errors are reported.
v3: update to the new end_cpu_access API.
v7: use .write = false cause it doesn't need to know whether it's write.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1450820214-12509-5-git-send-email-tiago.vignatti@intel.com
drivers/gpu/drm/i915/i915_gem_dmabuf.c

index 65ab2bd54af5fb40a4058390274a49df26a7dbfa..8c9ed2a0a6bfaf6ccf69cacf412199412f16635e 100644 (file)
@@ -212,6 +212,27 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_dire
        return ret;
 }
 
+static void i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
+{
+       struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+       struct drm_device *dev = obj->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       bool was_interruptible;
+       int ret;
+
+       mutex_lock(&dev->struct_mutex);
+       was_interruptible = dev_priv->mm.interruptible;
+       dev_priv->mm.interruptible = false;
+
+       ret = i915_gem_object_set_to_gtt_domain(obj, false);
+
+       dev_priv->mm.interruptible = was_interruptible;
+       mutex_unlock(&dev->struct_mutex);
+
+       if (unlikely(ret))
+               DRM_ERROR("unable to flush buffer following CPU access; rendering may be corrupt\n");
+}
+
 static const struct dma_buf_ops i915_dmabuf_ops =  {
        .map_dma_buf = i915_gem_map_dma_buf,
        .unmap_dma_buf = i915_gem_unmap_dma_buf,
@@ -224,6 +245,7 @@ static const struct dma_buf_ops i915_dmabuf_ops =  {
        .vmap = i915_gem_dmabuf_vmap,
        .vunmap = i915_gem_dmabuf_vunmap,
        .begin_cpu_access = i915_gem_begin_cpu_access,
+       .end_cpu_access = i915_gem_end_cpu_access,
 };
 
 struct dma_buf *i915_gem_prime_export(struct drm_device *dev,