All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Rework FBC schedule locking
@ 2018-03-16 15:01 Maarten Lankhorst
  2018-03-16 15:19 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Maarten Lankhorst @ 2018-03-16 15:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

Instead of taking fbc->lock inside the worker, don't take any lock
and cancel the work synchronously to prevent races. Since the worker
waits for a vblank before activating, wake up all vblank waiters after
signalling the cancel through unsetting work->scheduled_vblank. This
will make sure that we don't wait too long when cancelling the activation.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103167
---
 drivers/gpu/drm/i915/i915_debugfs.c |  4 +-
 drivers/gpu/drm/i915/i915_drv.h     |  3 +-
 drivers/gpu/drm/i915/intel_fbc.c    | 76 ++++++++++++++++---------------------
 3 files changed, 36 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 98e169636f86..cbf5504de183 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1643,9 +1643,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
 	else
 		seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
 
-	if (fbc->work.scheduled)
+	if (work_busy(&fbc->work.work))
 		seq_printf(m, "FBC worker scheduled on vblank %llu, now %llu\n",
-			   fbc->work.scheduled_vblank,
+			   (u64)atomic64_read(&fbc->work.scheduled_vblank),
 			   drm_crtc_vblank_count(&fbc->crtc->base));
 
 	if (intel_fbc_is_active(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9262cfb8aac2..a7a1b0453320 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -558,8 +558,7 @@ struct intel_fbc {
 	} params;
 
 	struct intel_fbc_work {
-		bool scheduled;
-		u64 scheduled_vblank;
+		atomic64_t scheduled_vblank;
 		struct work_struct work;
 	} work;
 
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 707d49c12638..20d45bcb6b6b 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -357,10 +357,6 @@ static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv)
 
 static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv)
 {
-	struct intel_fbc *fbc = &dev_priv->fbc;
-
-	fbc->active = true;
-
 	if (INTEL_GEN(dev_priv) >= 7)
 		gen7_fbc_activate(dev_priv);
 	else if (INTEL_GEN(dev_priv) >= 5)
@@ -407,16 +403,13 @@ static void intel_fbc_work_fn(struct work_struct *__work)
 	struct intel_fbc_work *work = &fbc->work;
 	struct intel_crtc *crtc = fbc->crtc;
 	struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe];
+	u64 vbl;
 
 	if (drm_crtc_vblank_get(&crtc->base)) {
 		/* CRTC is now off, leave FBC deactivated */
-		mutex_lock(&fbc->lock);
-		work->scheduled = false;
-		mutex_unlock(&fbc->lock);
 		return;
 	}
 
-retry:
 	/* Delay the actual enabling to let pageflipping cease and the
 	 * display to settle before starting the compression. Note that
 	 * this delay also serves a second purpose: it allows for a
@@ -425,34 +418,35 @@ static void intel_fbc_work_fn(struct work_struct *__work)
 	 *
 	 * WaFbcWaitForVBlankBeforeEnable:ilk,snb
 	 *
-	 * It is also worth mentioning that since work->scheduled_vblank can be
-	 * updated multiple times by the other threads, hitting the timeout is
-	 * not an error condition. We'll just end up hitting the "goto retry"
-	 * case below.
+	 * This may be killed by unsetting scheduled_vblank, in which
+	 * case we return early without activating.
 	 */
 	wait_event_timeout(vblank->queue,
-		drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank,
+		!(vbl = atomic64_read(&work->scheduled_vblank)) || vbl != drm_crtc_vblank_count(&crtc->base),
 		msecs_to_jiffies(50));
 
-	mutex_lock(&fbc->lock);
+	if (vbl)
+		intel_fbc_hw_activate(dev_priv);
 
-	/* Were we cancelled? */
-	if (!work->scheduled)
-		goto out;
+	drm_crtc_vblank_put(&crtc->base);
+}
 
-	/* Were we delayed again while this function was sleeping? */
-	if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) {
-		mutex_unlock(&fbc->lock);
-		goto retry;
-	}
+static void intel_fbc_cancel_activation(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_crtc *crtc;
+	struct drm_vblank_crtc *vblank;
 
-	intel_fbc_hw_activate(dev_priv);
+	if (!fbc->active)
+		return;
 
-	work->scheduled = false;
+	crtc = fbc->crtc;
+	vblank = &dev_priv->drm.vblank[crtc->pipe];
 
-out:
-	mutex_unlock(&fbc->lock);
-	drm_crtc_vblank_put(&crtc->base);
+	/* Kill FBC worker if it's waiting */
+	atomic64_set(&fbc->work.scheduled_vblank, 0);
+	wake_up_all(&vblank->queue);
+	cancel_work_sync(&fbc->work.work);
 }
 
 static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
@@ -471,12 +465,10 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
 		return;
 	}
 
-	/* It is useless to call intel_fbc_cancel_work() or cancel_work() in
-	 * this function since we're not releasing fbc.lock, so it won't have an
-	 * opportunity to grab it to discover that it was cancelled. So we just
-	 * update the expected jiffy count. */
-	work->scheduled = true;
-	work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base);
+	intel_fbc_cancel_activation(dev_priv);
+	fbc->active = true;
+
+	atomic64_set(&work->scheduled_vblank, drm_crtc_accurate_vblank_count(&crtc->base));
 	drm_crtc_vblank_put(&crtc->base);
 
 	schedule_work(&work->work);
@@ -489,13 +481,11 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv,
 
 	WARN_ON(!mutex_is_locked(&fbc->lock));
 
-	/* Calling cancel_work() here won't help due to the fact that the work
-	 * function grabs fbc->lock. Just set scheduled to false so the work
-	 * function can know it was cancelled. */
-	fbc->work.scheduled = false;
+	if (fbc->active) {
+		intel_fbc_cancel_activation(dev_priv);
 
-	if (fbc->active)
 		intel_fbc_hw_deactivate(dev_priv);
+	}
 
 	fbc->no_fbc_reason = reason;
 }
@@ -1222,11 +1212,11 @@ void intel_fbc_disable(struct intel_crtc *crtc)
 	WARN_ON(crtc->active);
 
 	mutex_lock(&fbc->lock);
+	intel_fbc_cancel_activation(dev_priv);
+
 	if (fbc->crtc == crtc)
 		__intel_fbc_disable(dev_priv);
 	mutex_unlock(&fbc->lock);
-
-	cancel_work_sync(&fbc->work.work);
 }
 
 /**
@@ -1243,13 +1233,13 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv)
 		return;
 
 	mutex_lock(&fbc->lock);
+	intel_fbc_cancel_activation(dev_priv);
+
 	if (fbc->enabled) {
 		WARN_ON(fbc->crtc->active);
 		__intel_fbc_disable(dev_priv);
 	}
 	mutex_unlock(&fbc->lock);
-
-	cancel_work_sync(&fbc->work.work);
 }
 
 static void intel_fbc_underrun_work_fn(struct work_struct *work)
@@ -1373,11 +1363,11 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
 	struct intel_fbc *fbc = &dev_priv->fbc;
 
 	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
+	atomic64_set(&fbc->work.scheduled_vblank, 0);
 	INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
 	mutex_init(&fbc->lock);
 	fbc->enabled = false;
 	fbc->active = false;
-	fbc->work.scheduled = false;
 
 	if (need_fbc_vtd_wa(dev_priv))
 		mkwrite_device_info(dev_priv)->has_fbc = false;
-- 
2.16.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Rework FBC schedule locking
  2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
@ 2018-03-16 15:19 ` Patchwork
  2018-03-16 15:43   ` Jani Nikula
  2018-03-16 15:36 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Patchwork @ 2018-03-16 15:19 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Rework FBC schedule locking
URL   : https://patchwork.freedesktop.org/series/40102/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
3bacd111d921 drm/i915: Rework FBC schedule locking
-:93: WARNING:LONG_LINE: line over 100 characters
#93: FILE: drivers/gpu/drm/i915/intel_fbc.c:425:
+		!(vbl = atomic64_read(&work->scheduled_vblank)) || vbl != drm_crtc_vblank_count(&crtc->base),

total: 0 errors, 1 warnings, 0 checks, 173 lines checked

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: Rework FBC schedule locking
  2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
  2018-03-16 15:19 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
@ 2018-03-16 15:36 ` Patchwork
  2018-03-16 18:10 ` ✓ Fi.CI.IGT: " Patchwork
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2018-03-16 15:36 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Rework FBC schedule locking
URL   : https://patchwork.freedesktop.org/series/40102/
State : success

== Summary ==

Series 40102v1 drm/i915: Rework FBC schedule locking
https://patchwork.freedesktop.org/api/1.0/series/40102/revisions/1/mbox/

---- Known issues:

Test debugfs_test:
        Subgroup read_all_entries:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713 +1
Test gem_exec_suspend:
        Subgroup basic-s3:
                incomplete -> PASS       (fi-cnl-y3) fdo#105086

fdo#103713 
fdo#105086 

fi-bdw-5557u     total:285  pass:264  dwarn:0   dfail:0   fail:0   skip:21  time:433s
fi-bdw-gvtdvm    total:285  pass:261  dwarn:0   dfail:0   fail:0   skip:24  time:439s
fi-blb-e6850     total:285  pass:220  dwarn:1   dfail:0   fail:0   skip:64  time:379s
fi-bsw-n3050     total:285  pass:239  dwarn:0   dfail:0   fail:0   skip:46  time:537s
fi-bwr-2160      total:285  pass:180  dwarn:0   dfail:0   fail:0   skip:105 time:296s
fi-bxt-dsi       total:285  pass:255  dwarn:0   dfail:0   fail:0   skip:30  time:513s
fi-bxt-j4205     total:285  pass:256  dwarn:0   dfail:0   fail:0   skip:29  time:511s
fi-byt-j1900     total:285  pass:250  dwarn:0   dfail:0   fail:0   skip:35  time:514s
fi-byt-n2820     total:285  pass:246  dwarn:0   dfail:0   fail:0   skip:39  time:505s
fi-cfl-8700k     total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:410s
fi-cfl-s2        total:285  pass:259  dwarn:0   dfail:0   fail:0   skip:26  time:579s
fi-cfl-u         total:285  pass:259  dwarn:0   dfail:0   fail:0   skip:26  time:512s
fi-cnl-drrs      total:285  pass:254  dwarn:3   dfail:0   fail:0   skip:28  time:521s
fi-cnl-y3        total:285  pass:258  dwarn:1   dfail:0   fail:0   skip:26  time:591s
fi-elk-e7500     total:285  pass:225  dwarn:1   dfail:0   fail:0   skip:59  time:426s
fi-gdg-551       total:285  pass:176  dwarn:0   dfail:0   fail:1   skip:108 time:313s
fi-glk-1         total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:543s
fi-hsw-4770      total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:401s
fi-ilk-650       total:285  pass:225  dwarn:0   dfail:0   fail:0   skip:60  time:419s
fi-ivb-3520m     total:285  pass:256  dwarn:0   dfail:0   fail:0   skip:29  time:471s
fi-ivb-3770      total:285  pass:252  dwarn:0   dfail:0   fail:0   skip:33  time:431s
fi-kbl-7500u     total:285  pass:260  dwarn:1   dfail:0   fail:0   skip:24  time:476s
fi-kbl-7567u     total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:471s
fi-kbl-r         total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:513s
fi-pnv-d510      total:285  pass:219  dwarn:1   dfail:0   fail:0   skip:65  time:657s
fi-skl-6260u     total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:440s
fi-skl-6600u     total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:540s
fi-skl-6700hq    total:285  pass:259  dwarn:0   dfail:0   fail:0   skip:26  time:541s
fi-skl-6700k2    total:285  pass:261  dwarn:0   dfail:0   fail:0   skip:24  time:504s
fi-skl-6770hq    total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:502s
fi-skl-guc       total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:428s
fi-skl-gvtdvm    total:285  pass:262  dwarn:0   dfail:0   fail:0   skip:23  time:449s
fi-snb-2520m     total:242  pass:208  dwarn:0   dfail:0   fail:0   skip:33 
fi-snb-2600      total:285  pass:245  dwarn:0   dfail:0   fail:0   skip:40  time:400s

8841c84f4467070d0007da3769508c3bfe3e0221 drm-tip: 2018y-03m-16d-14h-23m-11s UTC integration manifest
3bacd111d921 drm/i915: Rework FBC schedule locking

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8376/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Rework FBC schedule locking
  2018-03-16 15:19 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
@ 2018-03-16 15:43   ` Jani Nikula
  0 siblings, 0 replies; 7+ messages in thread
From: Jani Nikula @ 2018-03-16 15:43 UTC (permalink / raw)
  To: Patchwork, Maarten Lankhorst; +Cc: intel-gfx

On Fri, 16 Mar 2018, Patchwork <patchwork@emeril.freedesktop.org> wrote:
> == Series Details ==
>
> Series: drm/i915: Rework FBC schedule locking
> URL   : https://patchwork.freedesktop.org/series/40102/
> State : warning
>
> == Summary ==
>
> $ dim checkpatch origin/drm-tip

So I'll try to look at these reports a bit now that we've enabled them
with some filtering.

> 3bacd111d921 drm/i915: Rework FBC schedule locking
> -:93: WARNING:LONG_LINE: line over 100 characters
> #93: FILE: drivers/gpu/drm/i915/intel_fbc.c:425:
> +		!(vbl = atomic64_read(&work->scheduled_vblank)) || vbl != drm_crtc_vblank_count(&crtc->base),

I think this is a valid complaint. Please split the line after the ||.

BR,
Jani.

>
> total: 0 errors, 1 warnings, 0 checks, 173 lines checked
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: Rework FBC schedule locking
  2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
  2018-03-16 15:19 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
  2018-03-16 15:36 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-03-16 18:10 ` Patchwork
  2018-03-21 17:55 ` [PATCH] " Rodrigo Vivi
  2018-03-21 19:37 ` Paulo Zanoni
  4 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2018-03-16 18:10 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Rework FBC schedule locking
URL   : https://patchwork.freedesktop.org/series/40102/
State : success

== Summary ==

---- Possible new issues:

Test gem_eio:
        Subgroup suspend:
                fail       -> PASS       (shard-snb)

---- Known issues:

Test kms_flip:
        Subgroup 2x-plain-flip-fb-recreate:
                pass       -> FAIL       (shard-hsw) fdo#100368 +1
        Subgroup flip-vs-expired-vblank-interruptible:
                pass       -> FAIL       (shard-snb) fdo#102887
Test kms_frontbuffer_tracking:
        Subgroup fbc-1p-pri-indfb-multidraw:
                fail       -> PASS       (shard-snb) fdo#103167
Test perf:
        Subgroup polling:
                pass       -> FAIL       (shard-hsw) fdo#102252

fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887
fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252

shard-apl        total:3442 pass:1814 dwarn:1   dfail:0   fail:7   skip:1619 time:13101s
shard-hsw        total:3442 pass:1766 dwarn:1   dfail:0   fail:3   skip:1671 time:11856s
shard-snb        total:3442 pass:1354 dwarn:1   dfail:0   fail:4   skip:2082 time:7242s
Blacklisted hosts:
shard-kbl        total:3442 pass:1936 dwarn:1   dfail:0   fail:9   skip:1496 time:9847s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8376/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] drm/i915: Rework FBC schedule locking
  2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2018-03-16 18:10 ` ✓ Fi.CI.IGT: " Patchwork
@ 2018-03-21 17:55 ` Rodrigo Vivi
  2018-03-21 19:37 ` Paulo Zanoni
  4 siblings, 0 replies; 7+ messages in thread
From: Rodrigo Vivi @ 2018-03-21 17:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, Paulo Zanoni

On Fri, Mar 16, 2018 at 04:01:21PM +0100, Maarten Lankhorst wrote:
> Instead of taking fbc->lock inside the worker, don't take any lock
> and cancel the work synchronously to prevent races. Since the worker
> waits for a vblank before activating, wake up all vblank waiters after
> signalling the cancel through unsetting work->scheduled_vblank. This
> will make sure that we don't wait too long when cancelling the activation.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>

Overall I'm not comfortable with removing the locks on fbc activate
so I would deffer this to Paulo.

Also my own experience with atomic variables and vblank counters
weren't very positive on psr+dmc case. I always end up finding
a corner case :(

anyways few dummy questions below...

> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103167
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |  4 +-
>  drivers/gpu/drm/i915/i915_drv.h     |  3 +-
>  drivers/gpu/drm/i915/intel_fbc.c    | 76 ++++++++++++++++---------------------
>  3 files changed, 36 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 98e169636f86..cbf5504de183 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1643,9 +1643,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
>  	else
>  		seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
>  
> -	if (fbc->work.scheduled)
> +	if (work_busy(&fbc->work.work))
>  		seq_printf(m, "FBC worker scheduled on vblank %llu, now %llu\n",
> -			   fbc->work.scheduled_vblank,
> +			   (u64)atomic64_read(&fbc->work.scheduled_vblank),
>  			   drm_crtc_vblank_count(&fbc->crtc->base));
>  
>  	if (intel_fbc_is_active(dev_priv)) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 9262cfb8aac2..a7a1b0453320 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -558,8 +558,7 @@ struct intel_fbc {
>  	} params;
>  
>  	struct intel_fbc_work {
> -		bool scheduled;
> -		u64 scheduled_vblank;
> +		atomic64_t scheduled_vblank;

Why FBC is so tied with vblanks?

>  		struct work_struct work;
>  	} work;
>  
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index 707d49c12638..20d45bcb6b6b 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -357,10 +357,6 @@ static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv)
>  
>  static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_fbc *fbc = &dev_priv->fbc;
> -
> -	fbc->active = true;
> -
>  	if (INTEL_GEN(dev_priv) >= 7)
>  		gen7_fbc_activate(dev_priv);
>  	else if (INTEL_GEN(dev_priv) >= 5)
> @@ -407,16 +403,13 @@ static void intel_fbc_work_fn(struct work_struct *__work)
>  	struct intel_fbc_work *work = &fbc->work;
>  	struct intel_crtc *crtc = fbc->crtc;
>  	struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe];
> +	u64 vbl;

should we use something more descriptive here
like vbl_counter instead of "vbl" variable right before "vblank" one.

>  
>  	if (drm_crtc_vblank_get(&crtc->base)) {
>  		/* CRTC is now off, leave FBC deactivated */
> -		mutex_lock(&fbc->lock);
> -		work->scheduled = false;
> -		mutex_unlock(&fbc->lock);
>  		return;
>  	}
>  
> -retry:
>  	/* Delay the actual enabling to let pageflipping cease and the
>  	 * display to settle before starting the compression. Note that
>  	 * this delay also serves a second purpose: it allows for a
> @@ -425,34 +418,35 @@ static void intel_fbc_work_fn(struct work_struct *__work)
>  	 *
>  	 * WaFbcWaitForVBlankBeforeEnable:ilk,snb

why not a simple wait 1 vblank below?

>  	 *
> -	 * It is also worth mentioning that since work->scheduled_vblank can be
> -	 * updated multiple times by the other threads, hitting the timeout is
> -	 * not an error condition. We'll just end up hitting the "goto retry"
> -	 * case below.
> +	 * This may be killed by unsetting scheduled_vblank, in which
> +	 * case we return early without activating.
>  	 */
>  	wait_event_timeout(vblank->queue,
> -		drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank,
> +		!(vbl = atomic64_read(&work->scheduled_vblank)) || vbl != drm_crtc_vblank_count(&crtc->base),
>  		msecs_to_jiffies(50));
>  
> -	mutex_lock(&fbc->lock);
> +	if (vbl)
> +		intel_fbc_hw_activate(dev_priv);
>  
> -	/* Were we cancelled? */
> -	if (!work->scheduled)
> -		goto out;
> +	drm_crtc_vblank_put(&crtc->base);
> +}
>  
> -	/* Were we delayed again while this function was sleeping? */
> -	if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) {
> -		mutex_unlock(&fbc->lock);
> -		goto retry;
> -	}
> +static void intel_fbc_cancel_activation(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_fbc *fbc = &dev_priv->fbc;
> +	struct intel_crtc *crtc;
> +	struct drm_vblank_crtc *vblank;
>  
> -	intel_fbc_hw_activate(dev_priv);
> +	if (!fbc->active)
> +		return;
>  
> -	work->scheduled = false;
> +	crtc = fbc->crtc;
> +	vblank = &dev_priv->drm.vblank[crtc->pipe];
>  
> -out:
> -	mutex_unlock(&fbc->lock);
> -	drm_crtc_vblank_put(&crtc->base);
> +	/* Kill FBC worker if it's waiting */
> +	atomic64_set(&fbc->work.scheduled_vblank, 0);
> +	wake_up_all(&vblank->queue);
> +	cancel_work_sync(&fbc->work.work);
>  }
>  
>  static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
> @@ -471,12 +465,10 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
>  		return;
>  	}
>  
> -	/* It is useless to call intel_fbc_cancel_work() or cancel_work() in
> -	 * this function since we're not releasing fbc.lock, so it won't have an
> -	 * opportunity to grab it to discover that it was cancelled. So we just
> -	 * update the expected jiffy count. */
> -	work->scheduled = true;
> -	work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base);
> +	intel_fbc_cancel_activation(dev_priv);
> +	fbc->active = true;
> +
> +	atomic64_set(&work->scheduled_vblank, drm_crtc_accurate_vblank_count(&crtc->base));
>  	drm_crtc_vblank_put(&crtc->base);
>  
>  	schedule_work(&work->work);
> @@ -489,13 +481,11 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv,
>  
>  	WARN_ON(!mutex_is_locked(&fbc->lock));
>  
> -	/* Calling cancel_work() here won't help due to the fact that the work
> -	 * function grabs fbc->lock. Just set scheduled to false so the work
> -	 * function can know it was cancelled. */
> -	fbc->work.scheduled = false;
> +	if (fbc->active) {
> +		intel_fbc_cancel_activation(dev_priv);
>  
> -	if (fbc->active)
>  		intel_fbc_hw_deactivate(dev_priv);
> +	}
>  
>  	fbc->no_fbc_reason = reason;
>  }
> @@ -1222,11 +1212,11 @@ void intel_fbc_disable(struct intel_crtc *crtc)
>  	WARN_ON(crtc->active);
>  
>  	mutex_lock(&fbc->lock);
> +	intel_fbc_cancel_activation(dev_priv);
> +
>  	if (fbc->crtc == crtc)
>  		__intel_fbc_disable(dev_priv);
>  	mutex_unlock(&fbc->lock);
> -
> -	cancel_work_sync(&fbc->work.work);
>  }
>  
>  /**
> @@ -1243,13 +1233,13 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv)
>  		return;
>  
>  	mutex_lock(&fbc->lock);
> +	intel_fbc_cancel_activation(dev_priv);
> +
>  	if (fbc->enabled) {
>  		WARN_ON(fbc->crtc->active);
>  		__intel_fbc_disable(dev_priv);
>  	}
>  	mutex_unlock(&fbc->lock);
> -
> -	cancel_work_sync(&fbc->work.work);
>  }
>  
>  static void intel_fbc_underrun_work_fn(struct work_struct *work)
> @@ -1373,11 +1363,11 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
>  	struct intel_fbc *fbc = &dev_priv->fbc;
>  
>  	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
> +	atomic64_set(&fbc->work.scheduled_vblank, 0);
>  	INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
>  	mutex_init(&fbc->lock);
>  	fbc->enabled = false;
>  	fbc->active = false;
> -	fbc->work.scheduled = false;
>  
>  	if (need_fbc_vtd_wa(dev_priv))
>  		mkwrite_device_info(dev_priv)->has_fbc = false;
> -- 
> 2.16.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] drm/i915: Rework FBC schedule locking
  2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2018-03-21 17:55 ` [PATCH] " Rodrigo Vivi
@ 2018-03-21 19:37 ` Paulo Zanoni
  4 siblings, 0 replies; 7+ messages in thread
From: Paulo Zanoni @ 2018-03-21 19:37 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: Rodrigo Vivi

Em Sex, 2018-03-16 às 16:01 +0100, Maarten Lankhorst escreveu:
> Instead of taking fbc->lock inside the worker, don't take any lock
> and cancel the work synchronously to prevent races. Since the worker
> waits for a vblank before activating, wake up all vblank waiters
> after
> signalling the cancel through unsetting work->scheduled_vblank. This
> will make sure that we don't wait too long when cancelling the
> activation.
> 

Ok, so this patch changes stuff and above is a description of what is
changing, but why is this done and how does this solve the bug
referenced? What is the real problem here? Please improve the commit
message: it not only helps future git log readers, but it also helps
reviewers like me understand where you're trying to get. I'm lost here.


> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103167
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |  4 +-
>  drivers/gpu/drm/i915/i915_drv.h     |  3 +-
>  drivers/gpu/drm/i915/intel_fbc.c    | 76 ++++++++++++++++-----------
> ----------
>  3 files changed, 36 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 98e169636f86..cbf5504de183 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1643,9 +1643,9 @@ static int i915_fbc_status(struct seq_file *m,
> void *unused)
>  	else
>  		seq_printf(m, "FBC disabled: %s\n", fbc-
> >no_fbc_reason);
>  
> -	if (fbc->work.scheduled)
> +	if (work_busy(&fbc->work.work))
>  		seq_printf(m, "FBC worker scheduled on vblank %llu,
> now %llu\n",
> -			   fbc->work.scheduled_vblank,
> +			   (u64)atomic64_read(&fbc-
> >work.scheduled_vblank),
>  			   drm_crtc_vblank_count(&fbc->crtc->base));
>  
>  	if (intel_fbc_is_active(dev_priv)) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 9262cfb8aac2..a7a1b0453320 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -558,8 +558,7 @@ struct intel_fbc {
>  	} params;
>  
>  	struct intel_fbc_work {
> -		bool scheduled;
> -		u64 scheduled_vblank;
> +		atomic64_t scheduled_vblank;
>  		struct work_struct work;
>  	} work;
>  
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> b/drivers/gpu/drm/i915/intel_fbc.c
> index 707d49c12638..20d45bcb6b6b 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -357,10 +357,6 @@ static bool intel_fbc_hw_is_active(struct
> drm_i915_private *dev_priv)
>  
>  static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_fbc *fbc = &dev_priv->fbc;
> -
> -	fbc->active = true;
> -
>  	if (INTEL_GEN(dev_priv) >= 7)
>  		gen7_fbc_activate(dev_priv);
>  	else if (INTEL_GEN(dev_priv) >= 5)
> @@ -407,16 +403,13 @@ static void intel_fbc_work_fn(struct
> work_struct *__work)
>  	struct intel_fbc_work *work = &fbc->work;
>  	struct intel_crtc *crtc = fbc->crtc;
>  	struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc-
> >pipe];
> +	u64 vbl;
>  
>  	if (drm_crtc_vblank_get(&crtc->base)) {
>  		/* CRTC is now off, leave FBC deactivated */
> -		mutex_lock(&fbc->lock);
> -		work->scheduled = false;
> -		mutex_unlock(&fbc->lock);
>  		return;
>  	}
>  
> -retry:
>  	/* Delay the actual enabling to let pageflipping cease and
> the
>  	 * display to settle before starting the compression. Note
> that
>  	 * this delay also serves a second purpose: it allows for a
> @@ -425,34 +418,35 @@ static void intel_fbc_work_fn(struct
> work_struct *__work)
>  	 *
>  	 * WaFbcWaitForVBlankBeforeEnable:ilk,snb
>  	 *
> -	 * It is also worth mentioning that since work-
> >scheduled_vblank can be
> -	 * updated multiple times by the other threads, hitting the
> timeout is
> -	 * not an error condition. We'll just end up hitting the
> "goto retry"
> -	 * case below.
> +	 * This may be killed by unsetting scheduled_vblank, in
> which
> +	 * case we return early without activating.
>  	 */
>  	wait_event_timeout(vblank->queue,
> -		drm_crtc_vblank_count(&crtc->base) != work-
> >scheduled_vblank,
> +		!(vbl = atomic64_read(&work->scheduled_vblank)) ||
> vbl != drm_crtc_vblank_count(&crtc->base),
>  		msecs_to_jiffies(50));
>  
> -	mutex_lock(&fbc->lock);
> +	if (vbl)
> +		intel_fbc_hw_activate(dev_priv);
>  

We can't call this without fbc->lock locked.


> -	/* Were we cancelled? */
> -	if (!work->scheduled)
> -		goto out;
> +	drm_crtc_vblank_put(&crtc->base);
> +}
>  
> -	/* Were we delayed again while this function was sleeping?
> */
> -	if (drm_crtc_vblank_count(&crtc->base) == work-
> >scheduled_vblank) {
> -		mutex_unlock(&fbc->lock);
> -		goto retry;
> -	}
> +static void intel_fbc_cancel_activation(struct drm_i915_private
> *dev_priv)
> +{
> +	struct intel_fbc *fbc = &dev_priv->fbc;
> +	struct intel_crtc *crtc;
> +	struct drm_vblank_crtc *vblank;
>  
> -	intel_fbc_hw_activate(dev_priv);
> +	if (!fbc->active)
> +		return;
>  
> -	work->scheduled = false;
> +	crtc = fbc->crtc;
> +	vblank = &dev_priv->drm.vblank[crtc->pipe];
>  
> -out:
> -	mutex_unlock(&fbc->lock);
> -	drm_crtc_vblank_put(&crtc->base);
> +	/* Kill FBC worker if it's waiting */
> +	atomic64_set(&fbc->work.scheduled_vblank, 0);

Isn't 0 an actual valid vblank value in case we get enough vblanks to
wrap our counters?


> +	wake_up_all(&vblank->queue);
> +	cancel_work_sync(&fbc->work.work);
>  }
>  
>  static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
> @@ -471,12 +465,10 @@ static void
> intel_fbc_schedule_activation(struct intel_crtc *crtc)
>  		return;
>  	}
>  
> -	/* It is useless to call intel_fbc_cancel_work() or
> cancel_work() in
> -	 * this function since we're not releasing fbc.lock, so it
> won't have an
> -	 * opportunity to grab it to discover that it was cancelled.
> So we just
> -	 * update the expected jiffy count. */
> -	work->scheduled = true;
> -	work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base);
> +	intel_fbc_cancel_activation(dev_priv);
> +	fbc->active = true;
> +
> +	atomic64_set(&work->scheduled_vblank,
> drm_crtc_accurate_vblank_count(&crtc->base));
>  	drm_crtc_vblank_put(&crtc->base);
>  
>  	schedule_work(&work->work);
> @@ -489,13 +481,11 @@ static void intel_fbc_deactivate(struct
> drm_i915_private *dev_priv,
>  
>  	WARN_ON(!mutex_is_locked(&fbc->lock));
>  
> -	/* Calling cancel_work() here won't help due to the fact
> that the work
> -	 * function grabs fbc->lock. Just set scheduled to false so
> the work
> -	 * function can know it was cancelled. */
> -	fbc->work.scheduled = false;
> +	if (fbc->active) {
> +		intel_fbc_cancel_activation(dev_priv);
>  
> -	if (fbc->active)
>  		intel_fbc_hw_deactivate(dev_priv);
> +	}
>  
>  	fbc->no_fbc_reason = reason;
>  }
> @@ -1222,11 +1212,11 @@ void intel_fbc_disable(struct intel_crtc
> *crtc)
>  	WARN_ON(crtc->active);
>  
>  	mutex_lock(&fbc->lock);
> +	intel_fbc_cancel_activation(dev_priv);
> +
>  	if (fbc->crtc == crtc)
>  		__intel_fbc_disable(dev_priv);
>  	mutex_unlock(&fbc->lock);
> -
> -	cancel_work_sync(&fbc->work.work);
>  }
>  
>  /**
> @@ -1243,13 +1233,13 @@ void intel_fbc_global_disable(struct
> drm_i915_private *dev_priv)
>  		return;
>  
>  	mutex_lock(&fbc->lock);
> +	intel_fbc_cancel_activation(dev_priv);
> +
>  	if (fbc->enabled) {
>  		WARN_ON(fbc->crtc->active);
>  		__intel_fbc_disable(dev_priv);
>  	}
>  	mutex_unlock(&fbc->lock);
> -
> -	cancel_work_sync(&fbc->work.work);
>  }
>  
>  static void intel_fbc_underrun_work_fn(struct work_struct *work)
> @@ -1373,11 +1363,11 @@ void intel_fbc_init(struct drm_i915_private
> *dev_priv)
>  	struct intel_fbc *fbc = &dev_priv->fbc;
>  
>  	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
> +	atomic64_set(&fbc->work.scheduled_vblank, 0);
>  	INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
>  	mutex_init(&fbc->lock);
>  	fbc->enabled = false;
>  	fbc->active = false;
> -	fbc->work.scheduled = false;
>  
>  	if (need_fbc_vtd_wa(dev_priv))
>  		mkwrite_device_info(dev_priv)->has_fbc = false;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-03-21 19:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-16 15:01 [PATCH] drm/i915: Rework FBC schedule locking Maarten Lankhorst
2018-03-16 15:19 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
2018-03-16 15:43   ` Jani Nikula
2018-03-16 15:36 ` ✓ Fi.CI.BAT: success " Patchwork
2018-03-16 18:10 ` ✓ Fi.CI.IGT: " Patchwork
2018-03-21 17:55 ` [PATCH] " Rodrigo Vivi
2018-03-21 19:37 ` Paulo Zanoni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.