public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: maarten.lankhorst@linux.intel.com
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v3 13/22] drm/i915: Swap planes on each crtc separately.
Date: Thu, 28 May 2015 17:56:35 -0700	[thread overview]
Message-ID: <20150529005635.GD15716@intel.com> (raw)
In-Reply-To: <1432137874-20543-4-git-send-email-maarten.lankhorst@linux.intel.com>

On Wed, May 20, 2015 at 06:04:25PM +0200, maarten.lankhorst@linux.intel.com wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> Repeated calls to begin_crtc_commit can cause warnings like this:
> [  169.127746] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:616
> [  169.127835] in_atomic(): 0, irqs_disabled(): 1, pid: 1947, name: kms_flip
> [  169.127840] 3 locks held by kms_flip/1947:
> [  169.127843]  #0:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffff814774bc>] __drm_modeset_lock_all+0x9c/0x130
> [  169.127860]  #1:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffff814774cd>] __drm_modeset_lock_all+0xad/0x130
> [  169.127870]  #2:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffff81477178>] drm_modeset_lock+0x38/0x110
> [  169.127879] irq event stamp: 665690
> [  169.127882] hardirqs last  enabled at (665689): [<ffffffff817ffdb5>] _raw_spin_unlock_irqrestore+0x55/0x70
> [  169.127889] hardirqs last disabled at (665690): [<ffffffffc0197a23>] intel_pipe_update_start+0x113/0x5c0 [i915]
> [  169.127936] softirqs last  enabled at (665470): [<ffffffff8108a766>] __do_softirq+0x236/0x650
> [  169.127942] softirqs last disabled at (665465): [<ffffffff8108ae75>] irq_exit+0xc5/0xd0
> [  169.127951] CPU: 1 PID: 1947 Comm: kms_flip Not tainted 4.1.0-rc4-patser+ #4039
> [  169.127954] Hardware name: LENOVO 2349AV8/2349AV8, BIOS G1ETA5WW (2.65 ) 04/15/2014
> [  169.127957]  ffff8800c49036f0 ffff8800cde5fa28 ffffffff817f6907 0000000080000001
> [  169.127964]  0000000000000000 ffff8800cde5fa58 ffffffff810aebed 0000000000000046
> [  169.127970]  ffffffff81c5d518 0000000000000268 0000000000000000 ffff8800cde5fa88
> [  169.127981] Call Trace:
> [  169.127992]  [<ffffffff817f6907>] dump_stack+0x4f/0x7b
> [  169.128001]  [<ffffffff810aebed>] ___might_sleep+0x16d/0x270
> [  169.128008]  [<ffffffff810aed38>] __might_sleep+0x48/0x90
> [  169.128017]  [<ffffffff817fc359>] mutex_lock_nested+0x29/0x410
> [  169.128073]  [<ffffffffc01635f0>] ? vgpu_write64+0x220/0x220 [i915]
> [  169.128138]  [<ffffffffc017fddf>] ? ironlake_update_primary_plane+0x2ff/0x410 [i915]
> [  169.128198]  [<ffffffffc0190e75>] intel_frontbuffer_flush+0x25/0x70 [i915]
> [  169.128253]  [<ffffffffc01831ac>] intel_finish_crtc_commit+0x4c/0x180 [i915]
> [  169.128279]  [<ffffffffc00784ac>] drm_atomic_helper_commit_planes+0x12c/0x240 [drm_kms_helper]
> [  169.128338]  [<ffffffffc0184264>] __intel_set_mode+0x684/0x830 [i915]
> [  169.128378]  [<ffffffffc018a84a>] intel_crtc_set_config+0x49a/0x620 [i915]
> [  169.128385]  [<ffffffff817fdd39>] ? mutex_unlock+0x9/0x10
> [  169.128391]  [<ffffffff81467b69>] drm_mode_set_config_internal+0x69/0x120
> [  169.128398]  [<ffffffff8119b547>] ? might_fault+0x57/0xb0
> [  169.128403]  [<ffffffff8146bf93>] drm_mode_setcrtc+0x253/0x620
> [  169.128409]  [<ffffffff8145c600>] drm_ioctl+0x1a0/0x6a0
> [  169.128415]  [<ffffffff810b3b41>] ? get_parent_ip+0x11/0x50
> [  169.128424]  [<ffffffff811e9ab8>] do_vfs_ioctl+0x2f8/0x530
> [  169.128429]  [<ffffffff810d0fcd>] ? trace_hardirqs_on+0xd/0x10
> [  169.128435]  [<ffffffff812e7676>] ? selinux_file_ioctl+0x56/0x100
> [  169.128439]  [<ffffffff811e9d71>] SyS_ioctl+0x81/0xa0
> [  169.128445]  [<ffffffff81800697>] system_call_fastpath+0x12/0x6f
> 
> Solve it by using the newly introduced drm_atomic_helper_commit_planes_on_crtc.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

This commit looks good, but I think you might want to elaborate on the
commit message a bit for people not super familiar with the atomic work.
The problem here was that the drm_atomic_helper_commit_planes() helper
we were using was basically designed to do

    begin_crtc_commit(crtc #1)
    begin_crtc_commit(crtc #2)
    ...
    commit all planes
    finish_crtc_commit(crtc #1)
    finish_crtc_commit(crtc #2)

The problem here is that since our hardware relies on vblank evasion,
our CRTC 'begin' function waits until we're out of the danger zone in
which register writes might wind up straddling the vblank, then disables
interrupts; our 'finish' function re-enables interrupts after the
registers have been written.  The expectation is that the operations between
'begin' and 'end' must be performed without sleeping (since interrupts
are disabled) and should happen as quickly as possible.  By clumping all
of the 'begin' calls together, we introducing a couple problems:
 * Subsequent 'begin' invocations might sleep (which is illegal)
 * The first 'begin' ensured that we were far enough from the vblank that
   we could write our registers safely and ensure they all fell within
   the same frame.  Adding extra delay waiting for subsequent CRTC's
   wasn't accounted for and could put us back into the 'danger zone' for
   CRTC #1.

This commit solves the problem by using a new helper that allows an
order of operations like:

   for each crtc {
        begin_crtc_commit(crtc)  // sleep (maybe), then disable interrupts
        commit planes for this specific CRTC
        end_crtc_commit(crtc)    // reenable interrupts
   }

so that sleeps will only be performed while interrupts are enabled and
we can be sure that registers for a CRTC will be written immediately
once we know we're in the safe zone.


The only other thing I noted is that the CRTC backpointer update in
intel_modeset_readout_hw_state() seems somewhat unrelated that might
have fit better in one of the earlier patches (but is necessary at this
point since otherwise the helper will dereference NULL).  You might want
to make a quick note about that.

Matt

> ---
>  drivers/gpu/drm/i915/intel_atomic.c  | 13 +++----------
>  drivers/gpu/drm/i915/intel_display.c |  5 +++--
>  2 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index e93aade0f2dc..83078763ba14 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -151,18 +151,11 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		if (INTEL_INFO(dev)->gen >= 9)
>  			skl_detach_scalers(to_intel_crtc(crtc));
> +
> +		drm_atomic_helper_commit_planes_on_crtc(crtc_state);
>  	}
>  
> -	/*
> -	 * FIXME:  The proper sequence here will eventually be:
> -	 *
> -	 * drm_atomic_helper_commit_modeset_disables(dev, state);
> -	 * drm_atomic_helper_commit_planes(dev, state);
> -	 * drm_atomic_helper_commit_modeset_enables(dev, state);
> -	 *
> -	 * once we have full atomic modeset.
> -	 */
> -	drm_atomic_helper_commit_planes(dev, state);
> +	/* FIXME: This function should eventually call __intel_set_mode when needed */
>  
>  	drm_atomic_helper_wait_for_vblanks(dev, state);
>  	drm_atomic_helper_cleanup_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index adb19c3c9172..81d5358efdde 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12225,10 +12225,10 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  
>  	modeset_update_crtc_power_domains(state);
>  
> -	drm_atomic_helper_commit_planes(dev, state);
> -
>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		drm_atomic_helper_commit_planes_on_crtc(crtc_state);
> +
>  		if (!needs_modeset(crtc->state) || !crtc->state->active)
>  			continue;
>  
> @@ -14572,6 +14572,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		struct intel_plane_state *plane_state;
>  
>  		memset(crtc->config, 0, sizeof(*crtc->config));
> +		crtc->config->base.crtc = &crtc->base;
>  
>  		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
>  
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2015-05-29  0:56 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-20 13:38 [PATCH v3 00/22] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 01/22] drm/i915: get rid of put_shared_dpll Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 02/22] drm/i915: get rid of intel_crtc_disable and related code, v2 Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 03/22] drm/i915: use intel_crtc_control everywhere, v2 Maarten Lankhorst
2015-05-21 12:33   ` [PATCH v3.5 02.5/22] drm/i915: add intel_display_suspend Maarten Lankhorst
2015-05-22 23:03     ` Matt Roper
2015-05-25  6:47       ` Maarten Lankhorst
2015-05-26  8:31       ` [PATCH v3.6 02.5/22] drm/i915: add intel_display_suspend, v2 Maarten Lankhorst
2015-05-21 12:34   ` [PATCH v3.5 03/22] drm/i915: use intel_crtc_control everywhere, v3 Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 04/22] drm/i915: Use drm_atomic_helper_update_legacy_modeset_state, v2 Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 05/22] drm/i915: Make __intel_set_mode() take only atomic state as argument Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 06/22] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config() Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 07/22] drm/i915: Use crtc_state->active instead of crtc_state->enable Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 08/22] drm/i915: Zap call to drm_plane_helper_disable Maarten Lankhorst
2015-05-28  1:37   ` Matt Roper
2015-05-28  7:22     ` Maarten Lankhorst
2015-05-20 13:38 ` [PATCH v3 09/22] drm/i915: calculate primary visibility changes instead of calling from set_config Maarten Lankhorst
2015-05-20 16:04 ` [PATCH v3 10/22] drm/i915: Support modeset across multiple pipes maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 11/22] drm/i915: Use global atomic state for staged pll config, v2 maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 12/22] drm/i915: Use drm_atomic_helper_swap_state in intel_atomic_commit maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 13/22] drm/i915: Swap planes on each crtc separately maarten.lankhorst
2015-05-29  0:56     ` Matt Roper [this message]
2015-05-20 16:04   ` [PATCH v3 14/22] drm/i915: Move cdclk and pll setup to intel_modeset_compute_config() maarten.lankhorst
2015-05-29  0:55     ` Matt Roper
2015-06-01  6:31       ` Maarten Lankhorst
2015-05-20 16:04   ` [PATCH v3 15/22] drm/i915: Read hw state into an atomic state struct maarten.lankhorst
2015-05-27  5:30     ` Maarten Lankhorst
2015-05-27 11:26       ` Daniel Vetter
2015-05-29  0:55     ` Matt Roper
2015-06-01  6:35       ` Maarten Lankhorst
2015-05-20 16:04   ` [PATCH v3 16/22] drm/i915: Implement intel_crtc_control using atomic state, v3 maarten.lankhorst
2015-05-21 12:40     ` [PATCH v3.5 16.5/22] drm/i915: Make intel_display_suspend atomic Maarten Lankhorst
2015-05-26  8:33       ` [PATCH v3.6 16.5/22] drm/i915: Make intel_display_suspend atomic, v2 Maarten Lankhorst
2015-05-26  8:35     ` [PATCH v3.6 16/22] drm/i915: Implement intel_crtc_control using atomic state, v4 Maarten Lankhorst
2015-05-29  0:57       ` Matt Roper
2015-06-01  6:39         ` Maarten Lankhorst
2015-05-20 16:04   ` [PATCH v3 17/22] drm/i915: move swap state to the right place maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 18/22] drm/i915: Use crtc->hwmode for vblanks, v2 maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 19/22] drm/i915: Remove use of crtc->config from i915_debugfs.c maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 20/22] drm/i915: Calculate haswell plane workaround, v3 maarten.lankhorst
2015-05-26  8:36     ` [PATCH v3.6 20/22] drm/i915: Calculate haswell plane workaround, v4 Maarten Lankhorst
2015-05-29  0:58       ` Matt Roper
2015-05-20 16:04   ` [PATCH v3 21/22] drm/i915: Use atomic state for calculating DVO_2X_MODE on i830 maarten.lankhorst
2015-05-20 16:04   ` [PATCH v3 22/22] drm/i915: use calculated state for vblank evasion maarten.lankhorst
2015-05-29  1:23 ` [PATCH v3 00/22] drm/i915: Convert to atomic, part 2 Matt Roper
2015-06-01  8:11 ` Ander Conselvan De Oliveira

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150529005635.GD15716@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=maarten.lankhorst@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox