Commit 3c435c1e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm refcounting fixes from Dave Airlie:
 "Here is the complete set of i915 bug/warn/refcounting fixes"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: Fixup legacy plane->crtc link for initial fb config
  drm/i915: Fix atomic state when reusing the firmware fb
  drm/i915: Keep ring->active_list and ring->requests_list consistent
  drm/i915: Don't try to reference the fb in get_initial_plane_config()
  drm: Fixup racy refcounting in plane_force_disable
parents be8a9bc6 9822393d
...@@ -525,17 +525,6 @@ void drm_framebuffer_reference(struct drm_framebuffer *fb) ...@@ -525,17 +525,6 @@ void drm_framebuffer_reference(struct drm_framebuffer *fb)
} }
EXPORT_SYMBOL(drm_framebuffer_reference); EXPORT_SYMBOL(drm_framebuffer_reference);
static void drm_framebuffer_free_bug(struct kref *kref)
{
BUG();
}
static void __drm_framebuffer_unreference(struct drm_framebuffer *fb)
{
DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
kref_put(&fb->refcount, drm_framebuffer_free_bug);
}
/** /**
* drm_framebuffer_unregister_private - unregister a private fb from the lookup idr * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
* @fb: fb to unregister * @fb: fb to unregister
...@@ -1320,7 +1309,7 @@ void drm_plane_force_disable(struct drm_plane *plane) ...@@ -1320,7 +1309,7 @@ void drm_plane_force_disable(struct drm_plane *plane)
return; return;
} }
/* disconnect the plane from the fb and crtc: */ /* disconnect the plane from the fb and crtc: */
__drm_framebuffer_unreference(plane->old_fb); drm_framebuffer_unreference(plane->old_fb);
plane->old_fb = NULL; plane->old_fb = NULL;
plane->fb = NULL; plane->fb = NULL;
plane->crtc = NULL; plane->crtc = NULL;
......
...@@ -2737,24 +2737,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) ...@@ -2737,24 +2737,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
WARN_ON(i915_verify_lists(ring->dev)); WARN_ON(i915_verify_lists(ring->dev));
/* Move any buffers on the active list that are no longer referenced /* Retire requests first as we use it above for the early return.
* by the ringbuffer to the flushing/inactive lists as appropriate, * If we retire requests last, we may use a later seqno and so clear
* before we free the context associated with the requests. * the requests lists without clearing the active list, leading to
* confusion.
*/ */
while (!list_empty(&ring->active_list)) {
struct drm_i915_gem_object *obj;
obj = list_first_entry(&ring->active_list,
struct drm_i915_gem_object,
ring_list);
if (!i915_gem_request_completed(obj->last_read_req, true))
break;
i915_gem_object_move_to_inactive(obj);
}
while (!list_empty(&ring->request_list)) { while (!list_empty(&ring->request_list)) {
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
struct intel_ringbuffer *ringbuf; struct intel_ringbuffer *ringbuf;
...@@ -2789,6 +2776,23 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) ...@@ -2789,6 +2776,23 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
i915_gem_free_request(request); i915_gem_free_request(request);
} }
/* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate,
* before we free the context associated with the requests.
*/
while (!list_empty(&ring->active_list)) {
struct drm_i915_gem_object *obj;
obj = list_first_entry(&ring->active_list,
struct drm_i915_gem_object,
ring_list);
if (!i915_gem_request_completed(obj->last_read_req, true))
break;
i915_gem_object_move_to_inactive(obj);
}
if (unlikely(ring->trace_irq_req && if (unlikely(ring->trace_irq_req &&
i915_gem_request_completed(ring->trace_irq_req, true))) { i915_gem_request_completed(ring->trace_irq_req, true))) {
ring->irq_put(ring); ring->irq_put(ring);
......
...@@ -2438,8 +2438,15 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, ...@@ -2438,8 +2438,15 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
if (!intel_crtc->base.primary->fb) if (!intel_crtc->base.primary->fb)
return; return;
if (intel_alloc_plane_obj(intel_crtc, plane_config)) if (intel_alloc_plane_obj(intel_crtc, plane_config)) {
struct drm_plane *primary = intel_crtc->base.primary;
primary->state->crtc = &intel_crtc->base;
primary->crtc = &intel_crtc->base;
update_state_fb(primary);
return; return;
}
kfree(intel_crtc->base.primary->fb); kfree(intel_crtc->base.primary->fb);
intel_crtc->base.primary->fb = NULL; intel_crtc->base.primary->fb = NULL;
...@@ -2462,11 +2469,15 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, ...@@ -2462,11 +2469,15 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
continue; continue;
if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) { if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
struct drm_plane *primary = intel_crtc->base.primary;
if (obj->tiling_mode != I915_TILING_NONE) if (obj->tiling_mode != I915_TILING_NONE)
dev_priv->preserve_bios_swizzle = true; dev_priv->preserve_bios_swizzle = true;
drm_framebuffer_reference(c->primary->fb); drm_framebuffer_reference(c->primary->fb);
intel_crtc->base.primary->fb = c->primary->fb; primary->fb = c->primary->fb;
primary->state->crtc = &intel_crtc->base;
primary->crtc = &intel_crtc->base;
obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
break; break;
} }
...@@ -6663,7 +6674,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -6663,7 +6674,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
} }
static void chv_crtc_clock_get(struct intel_crtc *crtc, static void chv_crtc_clock_get(struct intel_crtc *crtc,
...@@ -7704,7 +7714,6 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7704,7 +7714,6 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
return; return;
error: error:
...@@ -7798,7 +7807,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7798,7 +7807,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
} }
static bool ironlake_get_pipe_config(struct intel_crtc *crtc, static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
......
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