Commit de472664 authored by Chris Wilson's avatar Chris Wilson Committed by Rodrigo Vivi

drm/i915: Allow i915_gem_object_get_page() on userptr as well

commit 033908ae
Author: Dave Gordon <david.s.gordon@intel.com>
Date:   Thu Dec 10 18:51:23 2015 +0000

    drm/i915: mark GEM object pages dirty when mapped & written by the CPU

introduced a check into i915_gem_object_get_dirty_pages() that returned
a NULL pointer when called with a bad object, one that was not backed by
shmemfs. This WARN was too strict as we can work on all struct page
backed objects, and resulted in a WARN + GPF for existing userspace. In
order to differentiate the various types of objects, add a new flags field
to the i915_gem_object_ops struct to describe their capabilities, with
the first flag being whether the object has struct pages.

v2: Drop silly const before an integer in the structure declaration.

Testcase: igt/gem_userptr_blits/relocations
Reported-and-tested-by: default avatarKristian Høgsberg Kristensen <krh@bitplanet.net>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Gordon <david.s.gordon@intel.com>
Cc: Kristian Høgsberg Kristensen <krh@bitplanet.net>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarDave Gordon <david.s.gordon@intel.com>
Reviewed-by: default avatarKristian Høgsberg Kristensen <krh@bitplanet.net>
Tested-by: default avatarMichal Winiarski <michal.winiarski@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1453487551-16799-1-git-send-email-chris@chris-wilson.co.uk
parent b2435692
...@@ -2038,6 +2038,9 @@ enum hdmi_force_audio { ...@@ -2038,6 +2038,9 @@ enum hdmi_force_audio {
#define I915_GTT_OFFSET_NONE ((u32)-1) #define I915_GTT_OFFSET_NONE ((u32)-1)
struct drm_i915_gem_object_ops { struct drm_i915_gem_object_ops {
unsigned int flags;
#define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1
/* Interface between the GEM object and its backing storage. /* Interface between the GEM object and its backing storage.
* get_pages() is called once prior to the use of the associated set * get_pages() is called once prior to the use of the associated set
* of pages before to binding them into the GTT, and put_pages() is * of pages before to binding them into the GTT, and put_pages() is
...@@ -2053,6 +2056,7 @@ struct drm_i915_gem_object_ops { ...@@ -2053,6 +2056,7 @@ struct drm_i915_gem_object_ops {
*/ */
int (*get_pages)(struct drm_i915_gem_object *); int (*get_pages)(struct drm_i915_gem_object *);
void (*put_pages)(struct drm_i915_gem_object *); void (*put_pages)(struct drm_i915_gem_object *);
int (*dmabuf_export)(struct drm_i915_gem_object *); int (*dmabuf_export)(struct drm_i915_gem_object *);
void (*release)(struct drm_i915_gem_object *); void (*release)(struct drm_i915_gem_object *);
}; };
......
...@@ -4465,6 +4465,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, ...@@ -4465,6 +4465,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
} }
static const struct drm_i915_gem_object_ops i915_gem_object_ops = { static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
.get_pages = i915_gem_object_get_pages_gtt, .get_pages = i915_gem_object_get_pages_gtt,
.put_pages = i915_gem_object_put_pages_gtt, .put_pages = i915_gem_object_put_pages_gtt,
}; };
...@@ -5309,7 +5310,7 @@ i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n) ...@@ -5309,7 +5310,7 @@ i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n)
struct page *page; struct page *page;
/* Only default objects have per-page dirty tracking */ /* Only default objects have per-page dirty tracking */
if (WARN_ON(obj->ops != &i915_gem_object_ops)) if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0))
return NULL; return NULL;
page = i915_gem_object_get_page(obj, n); page = i915_gem_object_get_page(obj, n);
......
...@@ -708,9 +708,10 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) ...@@ -708,9 +708,10 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj)
} }
static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
.dmabuf_export = i915_gem_userptr_dmabuf_export, .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
.get_pages = i915_gem_userptr_get_pages, .get_pages = i915_gem_userptr_get_pages,
.put_pages = i915_gem_userptr_put_pages, .put_pages = i915_gem_userptr_put_pages,
.dmabuf_export = i915_gem_userptr_dmabuf_export,
.release = i915_gem_userptr_release, .release = i915_gem_userptr_release,
}; };
......
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