diff options
author | Dave Gordon <david.s.gordon@intel.com> | 2016-04-12 09:46:16 -0400 |
---|---|---|
committer | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2016-04-20 11:59:03 -0400 |
commit | 8305216ff831ebc47d6335f577448e6c0453fc82 (patch) | |
tree | 5c4f2130dd75a4f120ad448bedcc194db060cbaf | |
parent | 86e06cc0c0ecf3fdfe04ff48fccb34891767d514 (diff) |
drm/i915: check for ERR_PTR from i915_gem_object_pin_map()
The newly-introduced function i915_gem_object_pin_map() returns an
ERR_PTR (not NULL) if the pin-and-map opertaion fails, so that's what we
must check for. And it's nicer not to assign such a pointer-or-error to
a structure being filled in until after it's been validated, so we
should keep it local and avoid exporting a bogus pointer. Also, for
clarity and symmetry, we should clear 'virtual_start' along with 'vma'
when unmapping a ringbuffer.
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 15 |
2 files changed, 13 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 85102ad75962..6f1e0f127c0a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -3018,9 +3018,11 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) | |||
3018 | * pages and then returns a contiguous mapping of the backing storage into | 3018 | * pages and then returns a contiguous mapping of the backing storage into |
3019 | * the kernel address space. | 3019 | * the kernel address space. |
3020 | * | 3020 | * |
3021 | * The caller must hold the struct_mutex. | 3021 | * The caller must hold the struct_mutex, and is responsible for calling |
3022 | * i915_gem_object_unpin_map() when the mapping is no longer required. | ||
3022 | * | 3023 | * |
3023 | * Returns the pointer through which to access the backing storage. | 3024 | * Returns the pointer through which to access the mapped object, or an |
3025 | * ERR_PTR() on error. | ||
3024 | */ | 3026 | */ |
3025 | void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj); | 3027 | void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj); |
3026 | 3028 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 978f0b676c68..245386e20c52 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -2088,6 +2088,7 @@ void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf) | |||
2088 | i915_gem_object_unpin_map(ringbuf->obj); | 2088 | i915_gem_object_unpin_map(ringbuf->obj); |
2089 | else | 2089 | else |
2090 | iounmap(ringbuf->virtual_start); | 2090 | iounmap(ringbuf->virtual_start); |
2091 | ringbuf->virtual_start = NULL; | ||
2091 | ringbuf->vma = NULL; | 2092 | ringbuf->vma = NULL; |
2092 | i915_gem_object_ggtt_unpin(ringbuf->obj); | 2093 | i915_gem_object_ggtt_unpin(ringbuf->obj); |
2093 | } | 2094 | } |
@@ -2100,6 +2101,7 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
2100 | struct drm_i915_gem_object *obj = ringbuf->obj; | 2101 | struct drm_i915_gem_object *obj = ringbuf->obj; |
2101 | /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ | 2102 | /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ |
2102 | unsigned flags = PIN_OFFSET_BIAS | 4096; | 2103 | unsigned flags = PIN_OFFSET_BIAS | 4096; |
2104 | void *addr; | ||
2103 | int ret; | 2105 | int ret; |
2104 | 2106 | ||
2105 | if (HAS_LLC(dev_priv) && !obj->stolen) { | 2107 | if (HAS_LLC(dev_priv) && !obj->stolen) { |
@@ -2111,9 +2113,9 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
2111 | if (ret) | 2113 | if (ret) |
2112 | goto err_unpin; | 2114 | goto err_unpin; |
2113 | 2115 | ||
2114 | ringbuf->virtual_start = i915_gem_object_pin_map(obj); | 2116 | addr = i915_gem_object_pin_map(obj); |
2115 | if (ringbuf->virtual_start == NULL) { | 2117 | if (IS_ERR(addr)) { |
2116 | ret = -ENOMEM; | 2118 | ret = PTR_ERR(addr); |
2117 | goto err_unpin; | 2119 | goto err_unpin; |
2118 | } | 2120 | } |
2119 | } else { | 2121 | } else { |
@@ -2129,14 +2131,15 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
2129 | /* Access through the GTT requires the device to be awake. */ | 2131 | /* Access through the GTT requires the device to be awake. */ |
2130 | assert_rpm_wakelock_held(dev_priv); | 2132 | assert_rpm_wakelock_held(dev_priv); |
2131 | 2133 | ||
2132 | ringbuf->virtual_start = ioremap_wc(ggtt->mappable_base + | 2134 | addr = ioremap_wc(ggtt->mappable_base + |
2133 | i915_gem_obj_ggtt_offset(obj), ringbuf->size); | 2135 | i915_gem_obj_ggtt_offset(obj), ringbuf->size); |
2134 | if (ringbuf->virtual_start == NULL) { | 2136 | if (addr == NULL) { |
2135 | ret = -ENOMEM; | 2137 | ret = -ENOMEM; |
2136 | goto err_unpin; | 2138 | goto err_unpin; |
2137 | } | 2139 | } |
2138 | } | 2140 | } |
2139 | 2141 | ||
2142 | ringbuf->virtual_start = addr; | ||
2140 | ringbuf->vma = i915_gem_obj_to_ggtt(obj); | 2143 | ringbuf->vma = i915_gem_obj_to_ggtt(obj); |
2141 | return 0; | 2144 | return 0; |
2142 | 2145 | ||