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>
This commit is contained in:
Dave Gordon 2016-04-12 14:46:16 +01:00 committed by Tvrtko Ursulin
parent 86e06cc0c0
commit 8305216ff8
2 changed files with 13 additions and 8 deletions

View File

@ -3018,9 +3018,11 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
* pages and then returns a contiguous mapping of the backing storage into
* the kernel address space.
*
* The caller must hold the struct_mutex.
* The caller must hold the struct_mutex, and is responsible for calling
* i915_gem_object_unpin_map() when the mapping is no longer required.
*
* Returns the pointer through which to access the backing storage.
* Returns the pointer through which to access the mapped object, or an
* ERR_PTR() on error.
*/
void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj);

View File

@ -2088,6 +2088,7 @@ void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
i915_gem_object_unpin_map(ringbuf->obj);
else
iounmap(ringbuf->virtual_start);
ringbuf->virtual_start = NULL;
ringbuf->vma = NULL;
i915_gem_object_ggtt_unpin(ringbuf->obj);
}
@ -2100,6 +2101,7 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
struct drm_i915_gem_object *obj = ringbuf->obj;
/* Ring wraparound at offset 0 sometimes hangs. No idea why. */
unsigned flags = PIN_OFFSET_BIAS | 4096;
void *addr;
int ret;
if (HAS_LLC(dev_priv) && !obj->stolen) {
@ -2111,9 +2113,9 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
if (ret)
goto err_unpin;
ringbuf->virtual_start = i915_gem_object_pin_map(obj);
if (ringbuf->virtual_start == NULL) {
ret = -ENOMEM;
addr = i915_gem_object_pin_map(obj);
if (IS_ERR(addr)) {
ret = PTR_ERR(addr);
goto err_unpin;
}
} else {
@ -2129,14 +2131,15 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
/* Access through the GTT requires the device to be awake. */
assert_rpm_wakelock_held(dev_priv);
ringbuf->virtual_start = ioremap_wc(ggtt->mappable_base +
i915_gem_obj_ggtt_offset(obj), ringbuf->size);
if (ringbuf->virtual_start == NULL) {
addr = ioremap_wc(ggtt->mappable_base +
i915_gem_obj_ggtt_offset(obj), ringbuf->size);
if (addr == NULL) {
ret = -ENOMEM;
goto err_unpin;
}
}
ringbuf->virtual_start = addr;
ringbuf->vma = i915_gem_obj_to_ggtt(obj);
return 0;