linux-pinenote/drivers/gpu/drm/i915
Daniel Vetter 9128b040eb drm/i915: Fix modeset state confusion in the load detect code
This is a tricky story of the new atomic state handling and the legacy
code fighting over each another. The bug at hand is an underrun of the
framebuffer reference with subsequent hilarity caused by the load
detect code. Which is peculiar since the the exact same code works
fine as the implementation of the legacy setcrtc ioctl.

Let's look at the ingredients:

- Currently our code is a crazy mix of legacy modeset interfaces to
  set the parameters and half-baked atomic state tracking underneath.
  While this transition is going we're using the transitional plane
  helpers to update the atomic side (drm_plane_helper_disable/update
  and friends), i.e. plane->state->fb. Since the state structure owns
  the fb those functions take care of that themselves.

  The legacy state (specifically crtc->primary->fb) is still managed
  by the old code (and mostly by the drm core), with the fb reference
  counting done by callers (core drm for the ioctl or the i915 load
  detect code). The relevant commit is

  commit ea2c67bb4a
  Author: Matt Roper <matthew.d.roper@intel.com>
  Date:   Tue Dec 23 10:41:52 2014 -0800

      drm/i915: Move to atomic plane helpers (v9)

- drm_plane_helper_disable has special code to handle multiple calls
  in a row - it checks plane->crtc == NULL and bails out. This is to
  match the proper atomic implementation which needs the crtc to get
  at the implied locking context atomic updates always need. See

  commit acf24a395c
  Author: Daniel Vetter <daniel.vetter@ffwll.ch>
  Date:   Tue Jul 29 15:33:05 2014 +0200

      drm/plane-helper: transitional atomic plane helpers

- The universal plane code split out the implicit primary plane from
  the CRTC into it's own full-blown drm_plane object. As part of that
  the setcrtc ioctl (which updated both the crtc mode and primary
  plane) learned to set crtc->primary->crtc on modeset to make sure
  the plane->crtc assignments statate up to date in

  commit e13161af80
  Author: Matt Roper <matthew.d.roper@intel.com>
  Date:   Tue Apr 1 15:22:38 2014 -0700

      drm: Add drm_crtc_init_with_planes() (v2)

  Unfortunately we've forgotten to update the load detect code. Which
  wasn't a problem since the load detect modeset is temporary and
  always undone before we drop the locks.

- Finally there is a organically grown history (i.e. don't ask) around
  who sets the legacy plane->fb for the various driver entry points.
  Originally updating that was the drivers duty, but for almost all
  places we've moved that (plus updating the refcounts) into the core.
  Again the exception is the load detect code.

Taking all together the following happens:
- The load detect code doesn't set crtc->primary->crtc. This is only
  really an issue on crtcs never before used or when userspace
  explicitly disabled the primary plane.

- The plane helper glue code short-circuits because of that and leaves
  a non-NULL fb behind in plane->state->fb and plane->fb. The state
  fb isn't a real problem (it's properly refcounted on its own), it's
  just the canary.

- Load detect code drops the reference for that fb, but doesn't set
  plane->fb = NULL. This is ok since it's still living in that old
  world where drivers had to clear the pointer but the core/callers
  handled the refcounting.

- On the next modeset the drm core notices plane->fb and takes care of
  refcounting it properly by doing another unref. This drops the
  refcount to zero, leaving state->plane now pointing at freed memory.

- intel_plane_duplicate_state still assume it owns a reference to that
  very state->fb and bad things start to happen.

Fix this all by applying the same duct-tape as for the legacy setcrtc
ioctl code and set crtc->primary->crtc properly.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Paulo Zanoni <przanoni@gmail.com>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reported-and-tested-by: Linus Torvalds <torvalds@linux-foundation.org>
Reported-by: Paul Bolle <pebolle@tiscali.nl>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-03-03 09:04:33 -08:00
..
dvo.h
dvo_ch7xxx.c
dvo_ch7017.c
dvo_ivch.c
dvo_ns2501.c
dvo_sil164.c
dvo_tfp410.c
i915_cmd_parser.c drm/i915: Add GPGPU_THREADS_DISPATCHED to the register whitelist 2014-12-16 10:39:10 +01:00
i915_debugfs.c drm/i915: Take runtime pm reference on hangcheck_info 2015-02-09 14:29:36 +02:00
i915_dma.c drm/i915: Remove nested work in gpu error handling 2015-01-29 18:03:07 +01:00
i915_drv.c Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2015-02-16 15:48:00 -08:00
i915_drv.h drm/i915: Fix a use after free, and unbalanced refcounting 2015-02-24 15:18:37 +02:00
i915_gem.c drm/i915: Fix a use after free, and unbalanced refcounting 2015-02-24 15:18:37 +02:00
i915_gem_batch_pool.c drm/i915: Mark shadow batch buffers as purgeable 2014-12-16 10:39:09 +01:00
i915_gem_context.c Merge tag 'topic/i915-hda-componentized-2015-01-12' into drm-intel-next-queued 2015-01-12 23:07:46 +01:00
i915_gem_debug.c
i915_gem_dmabuf.c
i915_gem_evict.c drm/i915: Add some extra guards in evict_vm 2015-01-06 09:07:59 +01:00
i915_gem_execbuffer.c drm/i915: Specify bsd rings through exec flag 2015-01-27 09:51:05 +01:00
i915_gem_gtt.c drm/i915: Organize bind_vma funcs 2014-12-17 18:23:12 +01:00
i915_gem_gtt.h drm/i915: Infrastructure for supporting different GGTT views per object 2014-12-15 11:25:04 +01:00
i915_gem_render_state.c drm/i915: Remove obsolete seqno parameter from 'i915_add_request' 2014-12-03 09:35:19 +01:00
i915_gem_render_state.h
i915_gem_stolen.c drm/i915: Align initial plane backing objects correctly 2015-02-24 15:51:19 +02:00
i915_gem_tiling.c drm/i915: Check obj->vma_list under the struct_mutex 2015-02-24 15:30:42 +02:00
i915_gem_userptr.c drm/i915: Prevent use-after-free in invalidate_range_start callback 2015-02-05 16:31:30 +02:00
i915_gpu_error.c drm/i915: Removed duplicate members from submit_request 2015-01-27 09:50:52 +01:00
i915_ioc32.c drm/i915: remove redundant #ifdef CONFIG_COMPAT 2014-10-24 16:34:07 +02:00
i915_irq.c drm/i915: avoid processing spurious/shared interrupts in low-power states 2015-02-24 15:47:17 +02:00
i915_params.c drm/i915: Add i915.nuclear_pageflip command line param to force atomic (v4) 2015-01-27 09:57:34 +01:00
i915_reg.h drm/i915/skl: Enabling PSR on Skylake 2015-01-28 17:22:29 +01:00
i915_suspend.c Merge tag 'topic/i915-hda-componentized-2015-01-12' into drm-intel-next-queued 2015-01-12 23:07:46 +01:00
i915_sysfs.c drm/i915: Use intel_gpu_freq() and intel_freq_opcode() 2015-01-27 09:51:17 +01:00
i915_trace.h drm/i915: Additional request structure tracing 2014-12-06 01:46:27 +01:00
i915_trace_points.c
i915_ums.c drm/i915: don't save/restore backlight hist ctl registers 2014-11-14 10:29:28 +01:00
intel_acpi.c
intel_atomic.c drm/i915: Add crtc state duplication/destruction functions 2015-01-27 09:57:18 +01:00
intel_atomic_plane.c drm/i915: Switch plane properties to full atomic helper. 2015-01-27 09:57:25 +01:00
intel_audio.c drm/i915: Make intel_crtc->config a pointer 2015-01-27 09:50:50 +01:00
intel_bios.c Revert "drm/i915: Parsing LFP brightness control from VBT" 2015-01-07 09:45:38 +01:00
intel_bios.h Revert "drm/i915: Parsing LFP brightness control from VBT" 2015-01-07 09:45:38 +01:00
intel_crt.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_ddi.c drm/i915: Use pipe_config's cpu_transcoder for reading encoder hw state 2015-01-30 19:38:43 +01:00
intel_display.c drm/i915: Fix modeset state confusion in the load detect code 2015-03-03 09:04:33 -08:00
intel_dp.c drm/i915: Really ignore long HPD pulses on eDP 2015-02-11 14:09:51 +02:00
intel_dp_mst.c drm/i915: Use pipe_config's cpu_transcoder for reading encoder hw state 2015-01-30 19:38:43 +01:00
intel_drv.h drm/i915: Add crtc state duplication/destruction functions 2015-01-27 09:57:18 +01:00
intel_dsi.c drm/i915: Correct the base value while updating LP_OUTPUT_HOLD in MIPI_PORT_CTRL 2015-02-09 20:21:08 +02:00
intel_dsi.h drm/i915/dsi: add drm mipi dsi host support 2015-01-29 16:51:39 +01:00
intel_dsi_cmd.h drm/i915/dsi: move dpi_send_cmd() to intel_dsi.c and make it static 2015-01-29 16:56:47 +01:00
intel_dsi_panel_vbt.c drm/i915/dsi: remove intel_dsi_cmd.c and the unused functions therein 2015-01-29 16:57:14 +01:00
intel_dsi_pll.c drm/i915: Use DSI Pll1 for enabling MIPI DSI on Port C 2014-12-10 17:47:21 +01:00
intel_dvo.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_fbc.c drm/i915: Move rotation from intel_plane to drm_plane_state 2015-01-27 09:51:18 +01:00
intel_fbdev.c drm/i915: Rename plane_config to initial_plane_config 2015-01-27 09:51:04 +01:00
intel_fifo_underrun.c drivers: gpu: drm: i915: intel_fifo_underrun.c: Fix a typo in comment 2015-01-27 10:30:01 +01:00
intel_frontbuffer.c drm/i915: DRRS calls based on frontbuffer 2015-01-27 09:51:15 +01:00
intel_hdmi.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_i2c.c
intel_lrc.c drm/i915: Fix a use after free, and unbalanced refcounting 2015-02-24 15:18:37 +02:00
intel_lrc.h drm/i915: Subsume intel_ctx_submit_request in to drm_i915_gem_request 2015-01-27 09:50:53 +01:00
intel_lvds.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_modes.c
intel_opregion.c ACPI / i915: Update the condition to ignore firmware backlight change request 2014-09-30 01:11:18 +02:00
intel_overlay.c drm/i915: Make intel_crtc->config a pointer 2015-01-27 09:50:50 +01:00
intel_panel.c Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2015-02-16 15:48:00 -08:00
intel_pm.c drm/i915: Clamp efficient frequency to valid range 2015-02-11 14:09:51 +02:00
intel_psr.c drm/i915/skl: Enabling PSR on Skylake 2015-01-28 17:22:29 +01:00
intel_renderstate.h drm/i915 Add golden context support for Gen9 2014-11-04 14:04:55 +01:00
intel_renderstate_gen6.c drm/i915: Add headers to the various render state 2014-12-10 17:47:23 +01:00
intel_renderstate_gen7.c drm/i915: Add headers to the various render state 2014-12-10 17:47:23 +01:00
intel_renderstate_gen8.c drm/i915: Add headers to the various render state 2014-12-10 17:47:23 +01:00
intel_renderstate_gen9.c drm/i915: Add headers to the various render state 2014-12-10 17:47:23 +01:00
intel_ringbuffer.c drm/i915: Insert a command barrier on BLT/BSD cache flushes 2015-02-09 20:03:15 +02:00
intel_ringbuffer.h drm/i915: Remove FIXME_lrc_ctx backpointer 2015-01-27 09:50:53 +01:00
intel_runtime_pm.c drm/i915/skl: Adding power domains for AUX controllers 2015-01-27 09:50:58 +01:00
intel_sdvo.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_sdvo_regs.h
intel_sideband.c drm/i915: Correct the IOSF Dev_FN field for IOSF transfers 2015-02-09 14:26:19 +02:00
intel_sprite.c drm/i915: Switch plane properties to full atomic helper. 2015-01-27 09:57:25 +01:00
intel_tv.c drm/i915: Add atomic_get_property entrypoint for connectors (v2) 2015-01-27 09:57:10 +01:00
intel_uncore.c drm/i915: Squelch overzealous uncore reset WARN_ON 2015-02-09 14:35:49 +02:00
Kconfig drm/i915/dsi: add drm mipi dsi host support 2015-01-29 16:51:39 +01:00
Makefile drm/i915/dsi: remove intel_dsi_cmd.c and the unused functions therein 2015-01-29 16:57:14 +01:00