* [PATCH] drm: Aggressively disable vblanks
@ 2010-12-20 19:00 Andy Lutomirski
2010-12-21 3:23 ` Keith Packard
0 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2010-12-20 19:00 UTC (permalink / raw)
To: Jesse Barnes, Chris Wilson, David Airlie
Cc: intel-gfx, Andy Lutomirski, dri-devel
Enabling and disabling the vblank interrupt (on devices that
support it) is cheap. So disable it quickly after each
interrupt.
To avoid constantly enabling and disabling vblank when
animations are running, after a predefined number (3) of
consecutive enabled vblanks that someone cared about, just
leave the interrupt on until an interrupt that no one cares
about.
The full heuristic is:
There's a per-CRTC counter called vblank_consecutive. It
starts at zero and counts consecutive useful vblanks. A
vblank is useful if the refcount is nonzero when the interrupt
comes in.
Whenever drm_vblank_get enables the interrupt, it stays on at
least until the next vblank (*). If drm_vblank_put is called
and vblank_consecutive is less than a threshold (currently 3),
then the interrupt is disabled. If a vblank interrupt happens
with refcount == 0, then the interrupt is disabled and
vblank_consecutive is reset to 0. If vblank_get is called
with the interrupt disabled and no interrupts were missed,
then vblank_consecutive is incremented.
(*) I tried letting it turn off before the next interrupt, but
compiz on my laptop seems to call drm_wait_vblank twice with
relative waits of 0 (!) before actually waiting.
Signed-off-by: Andy Lutomirski <luto@mit.edu>
---
Jesse, you asked for the deletion of the timer to be separate
from reducing the timeout, but that seemed silly because I'm ripping
out the entire old mechanism. If you're worried about the added time
spent in the interrupt handler, I could move it to a tasklet. That
being said, disable_vblank should be very fast (it's at most a couple
of register accesses in all in-tree drivers).
I've tested this on i915, where it works nicely and reduces my wakeups
with a second hand showing on the clock but an otherwise idle system.
This changes the requirements on enable_vblank, disable_vblank and
get_vblank_counter: they can now be called from an IRQ. They already
had to work with IRQs off and a spinlock held, but now a driver has to
watch out for recursive calls from drm_handle_vblank. The vbl_lock is
still held.
I've audited the in-tree drivers:
mga, r128: get_vblank_counter just reads an atomic_t. enable_vblank
just pokes registers without a lock. disable_vblank does nothing, so
turning off vblanks is pointless.
via: get_vblank_counter just returns a counter. enable_vblank and
disable_vblank just poke registers without locks. (This looks wrong:
get_vblank_count does the wrong thing and will confuse my heuristic,
but it should be any worse than it already is. I can comment out
enable_vblank if anyone prefers that approach.)
vmwgfx: get_vblank_counter does nothing and the other hooks aren't
implemented.
radeon: Everything looks safe.
i915: Looks good and tested!
nouveau: Not implemented at all. I'm not sure why either the old code
or my code doesn't try to call a null pointer, but it doesn't. That
being said, sync-to-vblank doesn't work on nouveau for me (glxgears
gets over 600fps while claiming to be synced to vblank).
As a future improvement, all of the vblank-disabling code could be
skipped if there is no disable_vblank callback.
drivers/gpu/drm/drm_irq.c | 103 +++++++++++++++++++++++++++++++++-----------
include/drm/drmP.h | 5 ++-
2 files changed, 81 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 9d3a503..2f107c5 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -77,45 +77,59 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
return 0;
}
-static void vblank_disable_fn(unsigned long arg)
+/* After VBLANK_CONSEC_THRESHOLD consecutive non-ignored vblank interrupts,
+ * vblanks will be left on. */
+#define VBLANK_CONSEC_THRESHOLD 3
+
+static void __vblank_disable_now(struct drm_device *dev, int crtc, int force)
+{
+ if (!dev->vblank_disable_allowed)
+ return;
+
+ if (atomic_read(&dev->vblank_refcount[crtc]) == 0 && dev->vblank_enabled[crtc] &&
+ (dev->vblank_consecutive[crtc] < VBLANK_CONSEC_THRESHOLD || force))
+ {
+ DRM_DEBUG("disabling vblank on crtc %d\n", crtc);
+ dev->last_vblank[crtc] =
+ dev->driver->get_vblank_counter(dev, crtc);
+ dev->driver->disable_vblank(dev, crtc);
+ dev->vblank_enabled[crtc] = 0;
+ if (force)
+ dev->vblank_consecutive[crtc] = 0;
+ }
+}
+
+static void vblank_disable_now(struct drm_device *dev, int crtc, int force)
{
- struct drm_device *dev = (struct drm_device *)arg;
unsigned long irqflags;
- int i;
if (!dev->vblank_disable_allowed)
return;
- for (i = 0; i < dev->num_crtcs; i++) {
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
- if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
- dev->vblank_enabled[i]) {
- DRM_DEBUG("disabling vblank on crtc %d\n", i);
- dev->last_vblank[i] =
- dev->driver->get_vblank_counter(dev, i);
- dev->driver->disable_vblank(dev, i);
- dev->vblank_enabled[i] = 0;
- }
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- }
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ __vblank_disable_now(dev, crtc, force);
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
void drm_vblank_cleanup(struct drm_device *dev)
{
+ int i;
+
/* Bail if the driver didn't call drm_vblank_init() */
if (dev->num_crtcs == 0)
return;
- del_timer(&dev->vblank_disable_timer);
-
- vblank_disable_fn((unsigned long)dev);
+ for (i = 0; i < dev->num_crtcs; i++)
+ vblank_disable_now(dev, i, 1);
kfree(dev->vbl_queue);
kfree(dev->_vblank_count);
kfree(dev->vblank_refcount);
kfree(dev->vblank_enabled);
kfree(dev->last_vblank);
+ kfree(dev->last_vblank_enable);
kfree(dev->last_vblank_wait);
+ kfree(dev->vblank_consecutive);
kfree(dev->vblank_inmodeset);
dev->num_crtcs = 0;
@@ -126,8 +140,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
{
int i, ret = -ENOMEM;
- setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
- (unsigned long)dev);
spin_lock_init(&dev->vbl_lock);
dev->num_crtcs = num_crtcs;
@@ -153,10 +165,18 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
if (!dev->last_vblank)
goto err;
+ dev->last_vblank_enable = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
+ if (!dev->last_vblank)
+ goto err;
+
dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
if (!dev->last_vblank_wait)
goto err;
+ dev->vblank_consecutive = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
+ if (!dev->vblank_consecutive)
+ goto err;
+
dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
if (!dev->vblank_inmodeset)
goto err;
@@ -387,10 +407,12 @@ EXPORT_SYMBOL(drm_vblank_count);
* Only necessary when going from off->on, to account for frames we
* didn't get an interrupt for.
*
+ * Returns the number of vblanks missed.
+ *
* Note: caller must hold dev->vbl_lock since this reads & writes
* device vblank fields.
*/
-static void drm_update_vblank_count(struct drm_device *dev, int crtc)
+static u32 drm_update_vblank_count(struct drm_device *dev, int crtc)
{
u32 cur_vblank, diff;
@@ -414,6 +436,17 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
crtc, diff);
atomic_add(diff, &dev->_vblank_count[crtc]);
+ return diff;
+}
+
+static void vblank_enabled_consecutively(struct drm_device *dev, int crtc)
+{
+ if (dev->vblank_consecutive[crtc] < VBLANK_CONSEC_THRESHOLD) {
+ dev->vblank_consecutive[crtc]++;
+ if (dev->vblank_consecutive[crtc] == VBLANK_CONSEC_THRESHOLD)
+ DRM_DEBUG("consecutive vblank usage on crtc %d\n", crtc);
+ }
+
}
/**
@@ -433,7 +466,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
int ret = 0;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
- /* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
if (!dev->vblank_enabled[crtc]) {
ret = dev->driver->enable_vblank(dev, crtc);
@@ -442,7 +474,12 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
atomic_dec(&dev->vblank_refcount[crtc]);
else {
dev->vblank_enabled[crtc] = 1;
- drm_update_vblank_count(dev, crtc);
+ if (drm_update_vblank_count(dev, crtc) == 0)
+ vblank_enabled_consecutively(dev, crtc);
+ else
+ dev->vblank_consecutive[crtc] = 0;
+ dev->last_vblank_enable[crtc] =
+ drm_vblank_count(dev, crtc);
}
}
} else {
@@ -467,11 +504,18 @@ EXPORT_SYMBOL(drm_vblank_get);
*/
void drm_vblank_put(struct drm_device *dev, int crtc)
{
+ unsigned long irqflags;
+
BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
- /* Last user schedules interrupt disable */
- if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
- mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) {
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ if (atomic_read(&dev->_vblank_count[crtc]) !=
+ dev->last_vblank_enable[crtc]
+ && dev->vblank_consecutive[crtc] < VBLANK_CONSEC_THRESHOLD)
+ __vblank_disable_now(dev, crtc, 0);
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ }
}
EXPORT_SYMBOL(drm_vblank_put);
@@ -780,11 +824,18 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc)
*/
void drm_handle_vblank(struct drm_device *dev, int crtc)
{
+ int vblank_refcount;
if (!dev->num_crtcs)
return;
+ vblank_refcount = atomic_read(&dev->vblank_refcount[crtc]);
atomic_inc(&dev->_vblank_count[crtc]);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
drm_handle_vblank_events(dev, crtc);
+
+ if (vblank_refcount == 0) {
+ /* This interrupt was unnecessary. */
+ vblank_disable_now(dev, crtc, 1);
+ }
}
EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 4c9461a..c15918b 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -997,11 +997,14 @@ struct drm_device {
atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
u32 *last_vblank; /* protected by dev->vbl_lock, used */
/* for wraparound handling */
+ u32 *last_vblank_enable; /* protected by dev->vbl_lock, used */
+ /* for early disable path */
int *vblank_enabled; /* so we don't call enable more than
once per disable */
int *vblank_inmodeset; /* Display driver is setting mode */
u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */
- struct timer_list vblank_disable_timer;
+ int *vblank_consecutive; /* protected by dev->vbl_lock, counts
+ consecutive interesting vblanks */
u32 max_vblank_count; /**< size of vblank counter register */
--
1.7.3.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] drm: Aggressively disable vblanks
2010-12-20 19:00 Andy Lutomirski
@ 2010-12-21 3:23 ` Keith Packard
2010-12-21 3:34 ` [Intel-gfx] " Andrew Lutomirski
0 siblings, 1 reply; 12+ messages in thread
From: Keith Packard @ 2010-12-21 3:23 UTC (permalink / raw)
To: Andy Lutomirski, Jesse Barnes, Chris Wilson, David Airlie
Cc: intel-gfx, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 626 bytes --]
On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU> wrote:
> Enabling and disabling the vblank interrupt (on devices that
> support it) is cheap. So disable it quickly after each
> interrupt.
So, the concern (and reason for the original design) was that you might
lose count of vblank interrupts as vblanks are counted differently while
off than while on. If vblank interrupts get enabled near the interrupt
time, is it possible that you'll end up off by one somehow?
Leaving them enabled for 'a while' was supposed to reduce the impact of
this potential error.
--
keith.packard@intel.com
[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm: Aggressively disable vblanks
2010-12-21 3:55 ` Andrew Lutomirski
@ 2010-12-21 4:03 ` Jesse Barnes
0 siblings, 0 replies; 12+ messages in thread
From: Jesse Barnes @ 2010-12-21 4:03 UTC (permalink / raw)
To: Andrew Lutomirski; +Cc: David Airlie, intel-gfx, dri-devel
On Mon, 20 Dec 2010 22:55:46 -0500
Andrew Lutomirski <luto@mit.edu> wrote:
> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard <keithp@keithp.com> wrote:
> > On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski <luto@mit.edu> wrote:
> >
> >> But five seconds is a *long* time, and anything short enough that the
> >> interrupt actually gets turned off in normal use risks the same race.
> >
> > Right, so eliminating any race seems like the basic requirement. Can
> > that be done?
>
> I'll give it a shot.
>
> Do you know if there's an existing tool to call drm_wait_vblank from
> userspace for testing? I know approximately nothing about libdrm or
> any userspace graphics stuff whatsoever.
Yeah, libdrm has a test program called vbltest; it should do what you
need.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
[not found] <mailman.28.1292917668.19577.dri-devel@lists.freedesktop.org>
@ 2010-12-22 4:36 ` Mario Kleiner
2010-12-22 17:23 ` Jesse Barnes
0 siblings, 1 reply; 12+ messages in thread
From: Mario Kleiner @ 2010-12-22 4:36 UTC (permalink / raw)
To: dri-devel
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Mon, 20 Dec 2010 19:23:40 -0800
> From: Keith Packard <keithp@keithp.com>
> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> To: Andy Lutomirski <luto@MIT.EDU>, Jesse Barnes
> <jbarnes@virtuousgeek.org>, Chris Wilson <chris@chris-wilson.co.uk>,
> David Airlie <airlied@linux.ie>
> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> Message-ID: <yunfwtrrepv.fsf@aiko.keithp.com>
> Content-Type: text/plain; charset="us-ascii"
>
> On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
> wrote:
>
>> Enabling and disabling the vblank interrupt (on devices that
>> support it) is cheap. So disable it quickly after each
>> interrupt.
>
> So, the concern (and reason for the original design) was that you
> might
> lose count of vblank interrupts as vblanks are counted differently
> while
> off than while on. If vblank interrupts get enabled near the interrupt
> time, is it possible that you'll end up off by one somehow?
>
> Leaving them enabled for 'a while' was supposed to reduce the
> impact of
> this potential error.
>
> --
> keith.packard@intel.com
> -------------- next part --------------
> A non-text attachment was scrubbed...
> Name: not available
> Type: application/pgp-signature
> Size: 189 bytes
> Desc: not available
> URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
> 20101220/105a9fb6/attachment-0001.pgp>
>
> ------------------------------
>
> Message: 2
> Date: Mon, 20 Dec 2010 22:34:12 -0500
> From: Andrew Lutomirski <luto@mit.edu>
> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> To: Keith Packard <keithp@keithp.com>
> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> Message-ID:
> <AANLkTik-1zni1DdS6i+1ARoenx6p=9jQAAiA6t5uGg_K@mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Mon, Dec 20, 2010 at 10:23 PM, Keith Packard <keithp@keithp.com>
> wrote:
>> On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
>> wrote:
>>
>>> Enabling and disabling the vblank interrupt (on devices that
>>> support it) is cheap. ?So disable it quickly after each
>>> interrupt.
>>
>> So, the concern (and reason for the original design) was that you
>> might
>> lose count of vblank interrupts as vblanks are counted differently
>> while
>> off than while on. If vblank interrupts get enabled near the
>> interrupt
>> time, is it possible that you'll end up off by one somehow?
>
> So the race is:
>
> 1. Vblank happens.
> 2. vblank_get runs, reads hardware counter, and enables the interrupt
> (and maybe not quite in that order)
> 3. Interrupt fires and increments the counter. Now the counter is
> one too high.
>
> What if we read the hardware counter from the IRQ the first time that
> it fires after being enabled? That way, if the hardware and software
> counters match (mod 2^23 or whatever the magic number is), we don't
> increment the counter.
>
>>
>> Leaving them enabled for 'a while' was supposed to reduce the
>> impact of
>> this potential error.
>>
>
> Fair enough,
>
> But five seconds is a *long* time, and anything short enough that the
> interrupt actually gets turned off in normal use risks the same race.
>
> --Andy
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 20 Dec 2010 19:47:11 -0800
> From: Keith Packard <keithp@keithp.com>
> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> To: Andrew Lutomirski <luto@mit.edu>
> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> Message-ID: <yunbp4frdmo.fsf@aiko.keithp.com>
> Content-Type: text/plain; charset="us-ascii"
>
> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
> <luto@mit.edu> wrote:
>
>> But five seconds is a *long* time, and anything short enough that the
>> interrupt actually gets turned off in normal use risks the same race.
>
> Right, so eliminating any race seems like the basic requirement. Can
> that be done?
>
> --
> keith.packard@intel.com
> -------------- next part --------------
> A non-text attachment was scrubbed...
> Name: not available
> Type: application/pgp-signature
> Size: 189 bytes
> Desc: not available
> URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
> 20101220/5ca3b674/attachment-0001.pgp>
>
> ------------------------------
>
> Message: 4
> Date: Mon, 20 Dec 2010 22:55:46 -0500
> From: Andrew Lutomirski <luto@mit.edu>
> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> To: Keith Packard <keithp@keithp.com>
> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> Message-ID:
> <AANLkTimk6RLkr8Lt76cR8ncLW_3kaX6Dqa+=id9_G-8C@mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard <keithp@keithp.com>
> wrote:
>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
>> <luto@mit.edu> wrote:
>>
>>> But five seconds is a *long* time, and anything short enough that
>>> the
>>> interrupt actually gets turned off in normal use risks the same
>>> race.
>>
>> Right, so eliminating any race seems like the basic requirement. Can
>> that be done?
>
> I'll give it a shot.
>
> Do you know if there's an existing tool to call drm_wait_vblank from
> userspace for testing? I know approximately nothing about libdrm or
> any userspace graphics stuff whatsoever.
>
> --Andy
>
>>
>> --
>> keith.packard@intel.com
>>
>
>
> ------------------------------
>
> Message: 5
> Date: Mon, 20 Dec 2010 20:03:53 -0800
> From: Jesse Barnes <jbarnes@virtuousgeek.org>
> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> To: Andrew Lutomirski <luto@mit.edu>
> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> Message-ID: <20101220200353.12479178@jbarnes-desktop>
> Content-Type: text/plain; charset=US-ASCII
>
> On Mon, 20 Dec 2010 22:55:46 -0500
> Andrew Lutomirski <luto@mit.edu> wrote:
>
>> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard
>> <keithp@keithp.com> wrote:
>>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
>>> <luto@mit.edu> wrote:
>>>
>>>> But five seconds is a *long* time, and anything short enough
>>>> that the
>>>> interrupt actually gets turned off in normal use risks the same
>>>> race.
>>>
>>> Right, so eliminating any race seems like the basic requirement. Can
>>> that be done?
>>
>> I'll give it a shot.
>>
>> Do you know if there's an existing tool to call drm_wait_vblank from
>> userspace for testing? I know approximately nothing about libdrm or
>> any userspace graphics stuff whatsoever.
>
> Yeah, libdrm has a test program called vbltest; it should do what you
> need.
>
Not so fast please! After a lot of review by Jesse, Dave and Chris
just merged a set of my patches into the drm-next (and the intel and
radeon kms drivers) to implement precise timestamping of vblank's and
pageflip completion and vblank counting for DRI2 and the
OML_sync_control extension. It also fixes (hopefully) almost all race-
conditions (that i could find or think of) related to vblank irq on/
off, a few of them surprising and due to "funny" behaviour of some
gpu's when you enable/disable vblanks (e.g., radeon's spontaneously
firing a vblank irq in the middle of a scanout cycle when vblank
irq's get enabled, or firing the irq sometimes shortly before a
vblank instead of in the vblank).
There's one tiny race left in the vblank off path, which i wanted to
address during the next weeks. Also i need to implement support for
nouveau. After that we could simply reduce the vblank off timeout to
something small like 50 msecs. Or use Andrew's heuristic on top of this.
In any case, please check against the drm-next branch. I think your
patches touch/conflict with most of the areas in drm that are
modified in drm-next. At least my users need a very high level of
precision and robustness in vblank counting and timestamping for
neuro-science applications and similar stuff.
thanks,
-mario
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-22 4:36 ` [Intel-gfx] [PATCH] drm: Aggressively disable vblanks Mario Kleiner
@ 2010-12-22 17:23 ` Jesse Barnes
2010-12-22 21:06 ` Mario Kleiner
0 siblings, 1 reply; 12+ messages in thread
From: Jesse Barnes @ 2010-12-22 17:23 UTC (permalink / raw)
To: Mario Kleiner; +Cc: dri-devel
On Wed, 22 Dec 2010 05:36:13 +0100
Mario Kleiner <mario.kleiner@tuebingen.mpg.de> wrote:
> > ----------------------------------------------------------------------
> >
> > Message: 1
> > Date: Mon, 20 Dec 2010 19:23:40 -0800
> > From: Keith Packard <keithp@keithp.com>
> > Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> > To: Andy Lutomirski <luto@MIT.EDU>, Jesse Barnes
> > <jbarnes@virtuousgeek.org>, Chris Wilson <chris@chris-wilson.co.uk>,
> > David Airlie <airlied@linux.ie>
> > Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> > Message-ID: <yunfwtrrepv.fsf@aiko.keithp.com>
> > Content-Type: text/plain; charset="us-ascii"
> >
> > On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
> > wrote:
> >
> >> Enabling and disabling the vblank interrupt (on devices that
> >> support it) is cheap. So disable it quickly after each
> >> interrupt.
> >
> > So, the concern (and reason for the original design) was that you
> > might
> > lose count of vblank interrupts as vblanks are counted differently
> > while
> > off than while on. If vblank interrupts get enabled near the interrupt
> > time, is it possible that you'll end up off by one somehow?
> >
> > Leaving them enabled for 'a while' was supposed to reduce the
> > impact of
> > this potential error.
> >
> > --
> > keith.packard@intel.com
> > -------------- next part --------------
> > A non-text attachment was scrubbed...
> > Name: not available
> > Type: application/pgp-signature
> > Size: 189 bytes
> > Desc: not available
> > URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
> > 20101220/105a9fb6/attachment-0001.pgp>
> >
> > ------------------------------
> >
> > Message: 2
> > Date: Mon, 20 Dec 2010 22:34:12 -0500
> > From: Andrew Lutomirski <luto@mit.edu>
> > Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> > To: Keith Packard <keithp@keithp.com>
> > Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> > Message-ID:
> > <AANLkTik-1zni1DdS6i+1ARoenx6p=9jQAAiA6t5uGg_K@mail.gmail.com>
> > Content-Type: text/plain; charset=ISO-8859-1
> >
> > On Mon, Dec 20, 2010 at 10:23 PM, Keith Packard <keithp@keithp.com>
> > wrote:
> >> On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
> >> wrote:
> >>
> >>> Enabling and disabling the vblank interrupt (on devices that
> >>> support it) is cheap. ?So disable it quickly after each
> >>> interrupt.
> >>
> >> So, the concern (and reason for the original design) was that you
> >> might
> >> lose count of vblank interrupts as vblanks are counted differently
> >> while
> >> off than while on. If vblank interrupts get enabled near the
> >> interrupt
> >> time, is it possible that you'll end up off by one somehow?
> >
> > So the race is:
> >
> > 1. Vblank happens.
> > 2. vblank_get runs, reads hardware counter, and enables the interrupt
> > (and maybe not quite in that order)
> > 3. Interrupt fires and increments the counter. Now the counter is
> > one too high.
> >
> > What if we read the hardware counter from the IRQ the first time that
> > it fires after being enabled? That way, if the hardware and software
> > counters match (mod 2^23 or whatever the magic number is), we don't
> > increment the counter.
> >
> >>
> >> Leaving them enabled for 'a while' was supposed to reduce the
> >> impact of
> >> this potential error.
> >>
> >
> > Fair enough,
> >
> > But five seconds is a *long* time, and anything short enough that the
> > interrupt actually gets turned off in normal use risks the same race.
> >
> > --Andy
> >
> >
> > ------------------------------
> >
> > Message: 3
> > Date: Mon, 20 Dec 2010 19:47:11 -0800
> > From: Keith Packard <keithp@keithp.com>
> > Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> > To: Andrew Lutomirski <luto@mit.edu>
> > Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> > Message-ID: <yunbp4frdmo.fsf@aiko.keithp.com>
> > Content-Type: text/plain; charset="us-ascii"
> >
> > On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
> > <luto@mit.edu> wrote:
> >
> >> But five seconds is a *long* time, and anything short enough that the
> >> interrupt actually gets turned off in normal use risks the same race.
> >
> > Right, so eliminating any race seems like the basic requirement. Can
> > that be done?
> >
> > --
> > keith.packard@intel.com
> > -------------- next part --------------
> > A non-text attachment was scrubbed...
> > Name: not available
> > Type: application/pgp-signature
> > Size: 189 bytes
> > Desc: not available
> > URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
> > 20101220/5ca3b674/attachment-0001.pgp>
> >
> > ------------------------------
> >
> > Message: 4
> > Date: Mon, 20 Dec 2010 22:55:46 -0500
> > From: Andrew Lutomirski <luto@mit.edu>
> > Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> > To: Keith Packard <keithp@keithp.com>
> > Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> > Message-ID:
> > <AANLkTimk6RLkr8Lt76cR8ncLW_3kaX6Dqa+=id9_G-8C@mail.gmail.com>
> > Content-Type: text/plain; charset=ISO-8859-1
> >
> > On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard <keithp@keithp.com>
> > wrote:
> >> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
> >> <luto@mit.edu> wrote:
> >>
> >>> But five seconds is a *long* time, and anything short enough that
> >>> the
> >>> interrupt actually gets turned off in normal use risks the same
> >>> race.
> >>
> >> Right, so eliminating any race seems like the basic requirement. Can
> >> that be done?
> >
> > I'll give it a shot.
> >
> > Do you know if there's an existing tool to call drm_wait_vblank from
> > userspace for testing? I know approximately nothing about libdrm or
> > any userspace graphics stuff whatsoever.
> >
> > --Andy
> >
> >>
> >> --
> >> keith.packard@intel.com
> >>
> >
> >
> > ------------------------------
> >
> > Message: 5
> > Date: Mon, 20 Dec 2010 20:03:53 -0800
> > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> > Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
> > To: Andrew Lutomirski <luto@mit.edu>
> > Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
> > Message-ID: <20101220200353.12479178@jbarnes-desktop>
> > Content-Type: text/plain; charset=US-ASCII
> >
> > On Mon, 20 Dec 2010 22:55:46 -0500
> > Andrew Lutomirski <luto@mit.edu> wrote:
> >
> >> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard
> >> <keithp@keithp.com> wrote:
> >>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
> >>> <luto@mit.edu> wrote:
> >>>
> >>>> But five seconds is a *long* time, and anything short enough
> >>>> that the
> >>>> interrupt actually gets turned off in normal use risks the same
> >>>> race.
> >>>
> >>> Right, so eliminating any race seems like the basic requirement. Can
> >>> that be done?
> >>
> >> I'll give it a shot.
> >>
> >> Do you know if there's an existing tool to call drm_wait_vblank from
> >> userspace for testing? I know approximately nothing about libdrm or
> >> any userspace graphics stuff whatsoever.
> >
> > Yeah, libdrm has a test program called vbltest; it should do what you
> > need.
> >
>
> Not so fast please! After a lot of review by Jesse, Dave and Chris
> just merged a set of my patches into the drm-next (and the intel and
> radeon kms drivers) to implement precise timestamping of vblank's and
> pageflip completion and vblank counting for DRI2 and the
> OML_sync_control extension. It also fixes (hopefully) almost all race-
> conditions (that i could find or think of) related to vblank irq on/
> off, a few of them surprising and due to "funny" behaviour of some
> gpu's when you enable/disable vblanks (e.g., radeon's spontaneously
> firing a vblank irq in the middle of a scanout cycle when vblank
> irq's get enabled, or firing the irq sometimes shortly before a
> vblank instead of in the vblank).
>
> There's one tiny race left in the vblank off path, which i wanted to
> address during the next weeks. Also i need to implement support for
> nouveau. After that we could simply reduce the vblank off timeout to
> something small like 50 msecs. Or use Andrew's heuristic on top of this.
>
> In any case, please check against the drm-next branch. I think your
> patches touch/conflict with most of the areas in drm that are
> modified in drm-next. At least my users need a very high level of
> precision and robustness in vblank counting and timestamping for
> neuro-science applications and similar stuff.
To preserve all of that, the easiest way to reduce the amount of time
the vblank remains enabled would probably be to reduce the vblank off
timeout. Just make it 100ms or so since that will make sure it stays
on for a few frames at least.
Mario, for cases where you have very intermittent waits, I think you
added a method to disable the timer altogether? That combined with a
reduced timeout seems like it could make everyone happy...
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-22 17:23 ` Jesse Barnes
@ 2010-12-22 21:06 ` Mario Kleiner
2010-12-26 14:53 ` Andrew Lutomirski
0 siblings, 1 reply; 12+ messages in thread
From: Mario Kleiner @ 2010-12-22 21:06 UTC (permalink / raw)
To: Jesse Barnes, luto, Keith Packard, airlied; +Cc: dri-devel
On Dec 22, 2010, at 6:23 PM, Jesse Barnes wrote:
> On Wed, 22 Dec 2010 05:36:13 +0100
> Mario Kleiner <mario.kleiner@tuebingen.mpg.de> wrote:
>
>>> --------------------------------------------------------------------
>>> --
>>>
>>> Message: 1
>>> Date: Mon, 20 Dec 2010 19:23:40 -0800
>>> From: Keith Packard <keithp@keithp.com>
>>> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
>>> To: Andy Lutomirski <luto@MIT.EDU>, Jesse Barnes
>>> <jbarnes@virtuousgeek.org>, Chris Wilson <chris@chris-
>>> wilson.co.uk>,
>>> David Airlie <airlied@linux.ie>
>>> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
>>> Message-ID: <yunfwtrrepv.fsf@aiko.keithp.com>
>>> Content-Type: text/plain; charset="us-ascii"
>>>
>>> On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
>>> wrote:
>>>
>>>> Enabling and disabling the vblank interrupt (on devices that
>>>> support it) is cheap. So disable it quickly after each
>>>> interrupt.
>>>
>>> So, the concern (and reason for the original design) was that you
>>> might
>>> lose count of vblank interrupts as vblanks are counted differently
>>> while
>>> off than while on. If vblank interrupts get enabled near the
>>> interrupt
>>> time, is it possible that you'll end up off by one somehow?
>>>
>>> Leaving them enabled for 'a while' was supposed to reduce the
>>> impact of
>>> this potential error.
>>>
>>> --
>>> keith.packard@intel.com
>>> -------------- next part --------------
>>> A non-text attachment was scrubbed...
>>> Name: not available
>>> Type: application/pgp-signature
>>> Size: 189 bytes
>>> Desc: not available
>>> URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
>>> 20101220/105a9fb6/attachment-0001.pgp>
>>>
>>> ------------------------------
>>>
>>> Message: 2
>>> Date: Mon, 20 Dec 2010 22:34:12 -0500
>>> From: Andrew Lutomirski <luto@mit.edu>
>>> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
>>> To: Keith Packard <keithp@keithp.com>
>>> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
>>> Message-ID:
>>> <AANLkTik-1zni1DdS6i+1ARoenx6p=9jQAAiA6t5uGg_K@mail.gmail.com>
>>> Content-Type: text/plain; charset=ISO-8859-1
>>>
>>> On Mon, Dec 20, 2010 at 10:23 PM, Keith Packard <keithp@keithp.com>
>>> wrote:
>>>> On Mon, 20 Dec 2010 14:00:54 -0500, Andy Lutomirski <luto@MIT.EDU>
>>>> wrote:
>>>>
>>>>> Enabling and disabling the vblank interrupt (on devices that
>>>>> support it) is cheap. ?So disable it quickly after each
>>>>> interrupt.
>>>>
>>>> So, the concern (and reason for the original design) was that you
>>>> might
>>>> lose count of vblank interrupts as vblanks are counted differently
>>>> while
>>>> off than while on. If vblank interrupts get enabled near the
>>>> interrupt
>>>> time, is it possible that you'll end up off by one somehow?
>>>
>>> So the race is:
>>>
>>> 1. Vblank happens.
>>> 2. vblank_get runs, reads hardware counter, and enables the
>>> interrupt
>>> (and maybe not quite in that order)
>>> 3. Interrupt fires and increments the counter. Now the counter is
>>> one too high.
>>>
>>> What if we read the hardware counter from the IRQ the first time
>>> that
>>> it fires after being enabled? That way, if the hardware and
>>> software
>>> counters match (mod 2^23 or whatever the magic number is), we don't
>>> increment the counter.
>>>
>>>>
>>>> Leaving them enabled for 'a while' was supposed to reduce the
>>>> impact of
>>>> this potential error.
>>>>
>>>
>>> Fair enough,
>>>
>>> But five seconds is a *long* time, and anything short enough that
>>> the
>>> interrupt actually gets turned off in normal use risks the same
>>> race.
>>>
>>> --Andy
>>>
>>>
>>> ------------------------------
>>>
>>> Message: 3
>>> Date: Mon, 20 Dec 2010 19:47:11 -0800
>>> From: Keith Packard <keithp@keithp.com>
>>> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
>>> To: Andrew Lutomirski <luto@mit.edu>
>>> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
>>> Message-ID: <yunbp4frdmo.fsf@aiko.keithp.com>
>>> Content-Type: text/plain; charset="us-ascii"
>>>
>>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
>>> <luto@mit.edu> wrote:
>>>
>>>> But five seconds is a *long* time, and anything short enough
>>>> that the
>>>> interrupt actually gets turned off in normal use risks the same
>>>> race.
>>>
>>> Right, so eliminating any race seems like the basic requirement. Can
>>> that be done?
>>>
>>> --
>>> keith.packard@intel.com
>>> -------------- next part --------------
>>> A non-text attachment was scrubbed...
>>> Name: not available
>>> Type: application/pgp-signature
>>> Size: 189 bytes
>>> Desc: not available
>>> URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/
>>> 20101220/5ca3b674/attachment-0001.pgp>
>>>
>>> ------------------------------
>>>
>>> Message: 4
>>> Date: Mon, 20 Dec 2010 22:55:46 -0500
>>> From: Andrew Lutomirski <luto@mit.edu>
>>> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
>>> To: Keith Packard <keithp@keithp.com>
>>> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
>>> Message-ID:
>>> <AANLkTimk6RLkr8Lt76cR8ncLW_3kaX6Dqa+=id9_G-8C@mail.gmail.com>
>>> Content-Type: text/plain; charset=ISO-8859-1
>>>
>>> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard <keithp@keithp.com>
>>> wrote:
>>>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
>>>> <luto@mit.edu> wrote:
>>>>
>>>>> But five seconds is a *long* time, and anything short enough that
>>>>> the
>>>>> interrupt actually gets turned off in normal use risks the same
>>>>> race.
>>>>
>>>> Right, so eliminating any race seems like the basic requirement.
>>>> Can
>>>> that be done?
>>>
>>> I'll give it a shot.
>>>
>>> Do you know if there's an existing tool to call drm_wait_vblank from
>>> userspace for testing? I know approximately nothing about libdrm or
>>> any userspace graphics stuff whatsoever.
>>>
>>> --Andy
>>>
>>>>
>>>> --
>>>> keith.packard@intel.com
>>>>
>>>
>>>
>>> ------------------------------
>>>
>>> Message: 5
>>> Date: Mon, 20 Dec 2010 20:03:53 -0800
>>> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>>> Subject: Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
>>> To: Andrew Lutomirski <luto@mit.edu>
>>> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
>>> Message-ID: <20101220200353.12479178@jbarnes-desktop>
>>> Content-Type: text/plain; charset=US-ASCII
>>>
>>> On Mon, 20 Dec 2010 22:55:46 -0500
>>> Andrew Lutomirski <luto@mit.edu> wrote:
>>>
>>>> On Mon, Dec 20, 2010 at 10:47 PM, Keith Packard
>>>> <keithp@keithp.com> wrote:
>>>>> On Mon, 20 Dec 2010 22:34:12 -0500, Andrew Lutomirski
>>>>> <luto@mit.edu> wrote:
>>>>>
>>>>>> But five seconds is a *long* time, and anything short enough
>>>>>> that the
>>>>>> interrupt actually gets turned off in normal use risks the same
>>>>>> race.
>>>>>
>>>>> Right, so eliminating any race seems like the basic
>>>>> requirement. Can
>>>>> that be done?
>>>>
>>>> I'll give it a shot.
>>>>
>>>> Do you know if there's an existing tool to call drm_wait_vblank
>>>> from
>>>> userspace for testing? I know approximately nothing about
>>>> libdrm or
>>>> any userspace graphics stuff whatsoever.
>>>
>>> Yeah, libdrm has a test program called vbltest; it should do what
>>> you
>>> need.
>>>
>>
>> Not so fast please! After a lot of review by Jesse, Dave and Chris
>> just merged a set of my patches into the drm-next (and the intel and
>> radeon kms drivers) to implement precise timestamping of vblank's and
>> pageflip completion and vblank counting for DRI2 and the
>> OML_sync_control extension. It also fixes (hopefully) almost all
>> race-
>> conditions (that i could find or think of) related to vblank irq on/
>> off, a few of them surprising and due to "funny" behaviour of some
>> gpu's when you enable/disable vblanks (e.g., radeon's spontaneously
>> firing a vblank irq in the middle of a scanout cycle when vblank
>> irq's get enabled, or firing the irq sometimes shortly before a
>> vblank instead of in the vblank).
>>
>> There's one tiny race left in the vblank off path, which i wanted to
>> address during the next weeks. Also i need to implement support for
>> nouveau. After that we could simply reduce the vblank off timeout to
>> something small like 50 msecs. Or use Andrew's heuristic on top of
>> this.
>>
>> In any case, please check against the drm-next branch. I think your
>> patches touch/conflict with most of the areas in drm that are
>> modified in drm-next. At least my users need a very high level of
>> precision and robustness in vblank counting and timestamping for
>> neuro-science applications and similar stuff.
>
> To preserve all of that, the easiest way to reduce the amount of time
> the vblank remains enabled would probably be to reduce the vblank off
> timeout. Just make it 100ms or so since that will make sure it stays
> on for a few frames at least.
>
> Mario, for cases where you have very intermittent waits, I think you
> added a method to disable the timer altogether? That combined with a
> reduced timeout seems like it could make everyone happy...
>
> --
> Jesse Barnes, Intel Open Source Technology Center
There's a new drm module parameter for selecting the timeout: echo 50
> /sys/module/drm/parameters/vblankoffdelay
would set the timeout to 50 msecs. A setting of zero will disable the
timer, so vblank irq's would stay on all the time.
The default setting is still 5000 msecs as before, but reducing this
to 100 msecs wouldn't be a real problem imho. At least i didn't
observe any miscounting during extensive testing with 100 msecs.
The patches in drm-next fix a couple of races that i observed on
intel and radeon during testing and a few that i didn't see but that
i could imagine happening. It tries to make sure that the saved final
count at vblank irq disable of the software vblank_count and the gpu
counter are consistent - no off by one errors. They also try to
detect and filter out spurious vblank interrupts at vblank enable
time, e.g., on the radeon.
There's still one possible race in the disable path which i will try
to fix: We don't know when exactly the hardware counter increments
wrt. the processing of the vblank interrupt - it could increment a
few (dozen/hundred) microseconds before or after the irq handler
runs, so if you happen to query the hardware counter while the gpu is
inside the vblank you can't be sure if you picked up the old count or
the new count for that vblank.
This only matters during vblank disable. For that reason it's not
such a good idea to disable vblank irq's from within the vblank irq
handler. I tried that and it didn't work well --> When doing it from
within irq you basically maximize the chance of hitting the time
window when the race can happen. Delaying within the irq handler by a
millisecond would fix that, but that's not what we want.
Having the disable in a function triggered by a timer like now is the
most simple solution i could come up with. There we can burn a few
dozen microseconds if neccessary to remove this race.
There could be other races that i couldn't think of and that i didn't
see during my testing with my 2 radeons and 1 intel gpu. Therefore i
think we should keep vblank irq's enabled for at least 2 or maybe 3
refresh cycles if they aren't used by anyone. Apps that want to
schedule swaps very precisely and the ddx/drm/kms-driver itself do
multiple queries in quick succession for a typical swapbuffers call,
i.e., drm_vblank_get() -> query -> drm_vblank_put(), so on an
otherwise idle graphics system the refcount will toggle between zero
and one multiple times during a swap, usually within a few
milliseconds. If the timeout is big enough so that irq's don't get
disabled within such a sequence of toggles, even if there's a bit of
scheduling delay for the x-server or client, then a client will see
at least consistent vblank count during a swap, even if there are
still some races hiding somewhere that we don't handle properly. That
should be good enough, and paranoid clients can always increase the
timeout value or set it to infinite.
E.g., my toolkit schedules a swap for a specific system time like this:
1. glXGetSyncValuesOML(... &base_msc, &base_ust);
2. calculate target_msc based on user provided swap deadline t and
(base_msc, base_ust) as a baseline.
3. glXSwapBuffersMscOML(...., target_msc,...);
4. glXWaitForSbcOML() or use Intel_swap_events for retrieving the
true msc and ust of swap completion.
=> Doesn't matter if there would be an off-by-one error in vblank
counting due to an unknown race, as long as it doesn't happen between
1. and 4. As long as there aren't any client/x-server scheduling
delays between step 1 and 3 of more than /sys/module/drm/parameters/
vblankoffdelay msecs, nothing can go wrong even if there are race
conditions left in that area.
=> 50-100 msecs as new default would be probably good enough and at
the same time prevent the "blinking cursor keeps vblank irq's on all
the time" problem.
I didn't reduce the timeout in the current patches because the
filtering for race-conditions and other gpu funkyness relies on
somewhat precise vblank timestamps and the timestamping hooks aren't
yet implemented in the nouveau kms. Maybe i manage to get this
working over christmas. Patches to nouveau would be simple, i just
don't know the mmio register addresses for crtc scanout position on
nvidia gpu's.
-mario
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-22 21:06 ` Mario Kleiner
@ 2010-12-26 14:53 ` Andrew Lutomirski
2010-12-26 23:58 ` Mario Kleiner
2010-12-27 10:52 ` Michel Dänzer
0 siblings, 2 replies; 12+ messages in thread
From: Andrew Lutomirski @ 2010-12-26 14:53 UTC (permalink / raw)
To: Mario Kleiner; +Cc: dri-devel
On Wed, Dec 22, 2010 at 4:06 PM, Mario Kleiner
<mario.kleiner@tuebingen.mpg.de> wrote:
>
> There's a new drm module parameter for selecting the timeout: echo 50 >
> /sys/module/drm/parameters/vblankoffdelay
> would set the timeout to 50 msecs. A setting of zero will disable the timer,
> so vblank irq's would stay on all the time.
>
> The default setting is still 5000 msecs as before, but reducing this to 100
> msecs wouldn't be a real problem imho. At least i didn't observe any
> miscounting during extensive testing with 100 msecs.
>
> The patches in drm-next fix a couple of races that i observed on intel and
> radeon during testing and a few that i didn't see but that i could imagine
> happening. It tries to make sure that the saved final count at vblank irq
> disable of the software vblank_count and the gpu counter are consistent - no
> off by one errors. They also try to detect and filter out spurious vblank
> interrupts at vblank enable time, e.g., on the radeon.
>
> There's still one possible race in the disable path which i will try to fix:
> We don't know when exactly the hardware counter increments wrt. the
> processing of the vblank interrupt - it could increment a few
> (dozen/hundred) microseconds before or after the irq handler runs, so if you
> happen to query the hardware counter while the gpu is inside the vblank you
> can't be sure if you picked up the old count or the new count for that
> vblank.
That's disgusting. Does this affect many GPUs? (I can't imagine why
any sensible implementation wouldn't guarantee that the counter
increments just before the IRQ.)
>
> This only matters during vblank disable. For that reason it's not such a
> good idea to disable vblank irq's from within the vblank irq handler. I
> tried that and it didn't work well --> When doing it from within irq you
> basically maximize the chance of hitting the time window when the race can
> happen. Delaying within the irq handler by a millisecond would fix that, but
> that's not what we want.
>
> Having the disable in a function triggered by a timer like now is the most
> simple solution i could come up with. There we can burn a few dozen
> microseconds if neccessary to remove this race.
Maybe I'm missing something, but other than the race above (which
seems like it shouldn't exist on sane hardware), the new code seems
more complicated than necessary.
Why not do nothing at all on vblank disable and, on enable, do this:
Call get_vblank_counter and declare the return value to be correct.
On each vblank IRQ (or maybe just the first one after enable), read
the counter again and if it matches the cached value, then assume we
raced on enable (i.e. we enabled right at the beginning of the vblank
interval, and this interrupt is redundant). In that case, do nothing.
Otherwise increment the cached value by one.
On hardware with the silly race where get_vblank_counter in the IRQ
can return a number one too low, use the scanout pos to fix it (i.e.
if the scanout position is at the end of the frame, assume we hit that
race and increment by 1).
This means that it would be safe to disable vblanks from any context
at all, because it has no effect other than turning off the interupt.
--Andy
>
> There could be other races that i couldn't think of and that i didn't see
> during my testing with my 2 radeons and 1 intel gpu. Therefore i think we
> should keep vblank irq's enabled for at least 2 or maybe 3 refresh cycles if
> they aren't used by anyone. Apps that want to schedule swaps very precisely
> and the ddx/drm/kms-driver itself do multiple queries in quick succession
> for a typical swapbuffers call, i.e., drm_vblank_get() -> query ->
> drm_vblank_put(), so on an otherwise idle graphics system the refcount will
> toggle between zero and one multiple times during a swap, usually within a
> few milliseconds. If the timeout is big enough so that irq's don't get
> disabled within such a sequence of toggles, even if there's a bit of
> scheduling delay for the x-server or client, then a client will see at least
> consistent vblank count during a swap, even if there are still some races
> hiding somewhere that we don't handle properly. That should be good enough,
> and paranoid clients can always increase the timeout value or set it to
> infinite.
>
> E.g., my toolkit schedules a swap for a specific system time like this:
>
> 1. glXGetSyncValuesOML(... &base_msc, &base_ust);
> 2. calculate target_msc based on user provided swap deadline t and
> (base_msc, base_ust) as a baseline.
> 3. glXSwapBuffersMscOML(...., target_msc,...);
> 4. glXWaitForSbcOML() or use Intel_swap_events for retrieving the true msc
> and ust of swap completion.
>
> => Doesn't matter if there would be an off-by-one error in vblank counting
> due to an unknown race, as long as it doesn't happen between 1. and 4. As
> long as there aren't any client/x-server scheduling delays between step 1
> and 3 of more than /sys/module/drm/parameters/vblankoffdelay msecs, nothing
> can go wrong even if there are race conditions left in that area.
>
> => 50-100 msecs as new default would be probably good enough and at the same
> time prevent the "blinking cursor keeps vblank irq's on all the time"
> problem.
>
> I didn't reduce the timeout in the current patches because the filtering for
> race-conditions and other gpu funkyness relies on somewhat precise vblank
> timestamps and the timestamping hooks aren't yet implemented in the nouveau
> kms. Maybe i manage to get this working over christmas. Patches to nouveau
> would be simple, i just don't know the mmio register addresses for crtc
> scanout position on nvidia gpu's.
>
> -mario
>
>
> *********************************************************************
> Mario Kleiner
> Max Planck Institute for Biological Cybernetics
> Spemannstr. 38
> 72076 Tuebingen
> Germany
>
> e-mail: mario.kleiner@tuebingen.mpg.de
> office: +49 (0)7071/601-1623
> fax: +49 (0)7071/601-616
> www: http://www.kyb.tuebingen.mpg.de/~kleinerm
> *********************************************************************
> "For a successful technology, reality must take precedence
> over public relations, for Nature cannot be fooled."
> (Richard Feynman)
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-26 14:53 ` Andrew Lutomirski
@ 2010-12-26 23:58 ` Mario Kleiner
2010-12-27 11:16 ` Ville Syrjälä
2011-01-10 2:24 ` Andrew Lutomirski
2010-12-27 10:52 ` Michel Dänzer
1 sibling, 2 replies; 12+ messages in thread
From: Mario Kleiner @ 2010-12-26 23:58 UTC (permalink / raw)
To: Andrew Lutomirski; +Cc: dri-devel
On Dec 26, 2010, at 3:53 PM, Andrew Lutomirski wrote:
> On Wed, Dec 22, 2010 at 4:06 PM, Mario Kleiner
> <mario.kleiner@tuebingen.mpg.de> wrote:
>>
>> There's a new drm module parameter for selecting the timeout: echo
>> 50 >
>> /sys/module/drm/parameters/vblankoffdelay
>> would set the timeout to 50 msecs. A setting of zero will disable
>> the timer,
>> so vblank irq's would stay on all the time.
>>
>> The default setting is still 5000 msecs as before, but reducing
>> this to 100
>> msecs wouldn't be a real problem imho. At least i didn't observe any
>> miscounting during extensive testing with 100 msecs.
>>
>> The patches in drm-next fix a couple of races that i observed on
>> intel and
>> radeon during testing and a few that i didn't see but that i could
>> imagine
>> happening. It tries to make sure that the saved final count at
>> vblank irq
>> disable of the software vblank_count and the gpu counter are
>> consistent - no
>> off by one errors. They also try to detect and filter out spurious
>> vblank
>> interrupts at vblank enable time, e.g., on the radeon.
>>
>> There's still one possible race in the disable path which i will
>> try to fix:
>> We don't know when exactly the hardware counter increments wrt. the
>> processing of the vblank interrupt - it could increment a few
>> (dozen/hundred) microseconds before or after the irq handler runs,
>> so if you
>> happen to query the hardware counter while the gpu is inside the
>> vblank you
>> can't be sure if you picked up the old count or the new count for
>> that
>> vblank.
>
> That's disgusting. Does this affect many GPUs? (I can't imagine why
> any sensible implementation wouldn't guarantee that the counter
> increments just before the IRQ.)
;-). I don't know, but at least on the tested R500 and R600 class
Radeon's, this was the case, so i assume it's at least this way on
many radeon gpu's (probably all avivo parts?) out there. We don't
have any evergreen gpu's yet in our lab so i don't know how the more
recent parts behave. Also it doesn't matter
I guess it's also a matter of definition when a new video frame
starts? Leading edge / trailing edge of vblank? Start of vsync?
Something else?
>>
>> This only matters during vblank disable. For that reason it's not
>> such a
>> good idea to disable vblank irq's from within the vblank irq
>> handler. I
>> tried that and it didn't work well --> When doing it from within
>> irq you
>> basically maximize the chance of hitting the time window when the
>> race can
>> happen. Delaying within the irq handler by a millisecond would fix
>> that, but
>> that's not what we want.
>>
>> Having the disable in a function triggered by a timer like now is
>> the most
>> simple solution i could come up with. There we can burn a few dozen
>> microseconds if neccessary to remove this race.
>
> Maybe I'm missing something, but other than the race above (which
> seems like it shouldn't exist on sane hardware), the new code seems
> more complicated than necessary.
I don't think it's more complicated than necessary for what it tries
to achieve, but of course i'm a bit biased. It also started off more
simple and grew a bit when i found new issues with the tested gpu's.
The aim is to fix a couple of real races and to make vblank counts
and timestamps as trustworthy and oml_sync_control spec-conformant
(see http://www.opengl.org/registry/specs/OML/glx_sync_control.txt)
as possible. It only consumes a few additional bytes of memory
(approx. 40 bytes) per crtc, doesn't use excessive time inside the
irq handler and tries to avoid taking locks that are shared between
irq and non-irq context to avoid delays in irq execution, also if
used with a kernel with the preempt_rt patch applied (important for
my use case and other hard realtime apps). It's pretty self-contained
and because most of it is driver-independent it can handle similar
issues on different gpu's and kms drivers without the need for us to
check each single gpu + driver combo if it has such issues or not.
1. There's the hardware vblank counter race, and it's there on lots
of existing hardware, regardless if this is sane or not, so it needs
to be handled.
2. There are gpu's firing spurious vblank irq's as soon as you enable
irq's -- you need to filter those out, otherwise counts and
timestamps will be wrong for at least one refresh cycle after vblank
irq enable. You don't know when these redundant ones get delivered or
if they get delivered at all because a real vblank irq enable gets
triggered by some userspace calls, not locked to the video refresh
cycle and because the enable code itself holds spin_lock_irqsave
locks and may or may not (depending on number of cores and irq
routing) prevent delivery of the vblank irq's concurrent to its own
execution -> a possible race between the drm_handle_vblank() routine
and the drm_update_vblank_count() routine each time you call
drm_vblank_get().
3. There's gpu's sometimes, but not on other times, firing the irq
too early (1-3 scanlines observed on radeon's) so you get your irq
before the associated vblank interval and need to do at least all
timestamping as if you are already in that vblank. This may be
dependent on both video mode and on the dispatch delay of the vblank
irq handler (e.g., due to some other unrelated code holding off
irq's, e.g., by holding spin_lock_irqsave() locks).
4. In the old code it could happen that the vblank counter gets
incremented after it was "disabled", e.g., because vblank irq's were
turned off in the gpu, but there was still a vblank irq pending
(e.g., due to some spin_lock_irqsave on the relevant core),
incrementing the counter after it was supposedly frozen. With the new
oml_sync_control timestamping in place, such off-by-ones would be
worse as they would also corrupt timestamps.
There were some more issues which i can't remember from the top of my
head which get handled by the current code (Note to myself: Take more
notes!).
>
> Why not do nothing at all on vblank disable and, on enable, do this:
>
> Call get_vblank_counter and declare the return value to be correct.
Because declaring it to be correct isn't the same as it being
correct. Also the code needs to handle wraparound of the hardware
counter and for that it needs correct start values from the vblank
disable routine, which is why the disable routine needs to work as
race-free as possible. The vblank count for a frame also needs to be
consistent with the vblank timestamp for that frame at all times,
otherwise the oml_sync_control extension becomes too unreliable to be
trustworthy and useful for serious applications.
> On each vblank IRQ (or maybe just the first one after enable), read
> the counter again and if it matches the cached value, then assume we
> raced on enable (i.e. we enabled right at the beginning of the vblank
> interval, and this interrupt is redundant). In that case, do nothing.
> Otherwise increment the cached value by one.
>
> On hardware with the silly race where get_vblank_counter in the IRQ
> can return a number one too low, use the scanout pos to fix it (i.e.
> if the scanout position is at the end of the frame, assume we hit that
> race and increment by 1).
>
See the other races above. Iirc i tried something similar already and
they made it fail/unreliable. The current patch uses the vblank
timestamp instead of the hardware vblank counter to detect and filter
redundant irq's, because with the timestamping patches at least on
intel and ati gpu's (and hopefully nouveau/nvidia and others asap)
these are well defined and accurate (to define the end of a vblank
interval) so they can serve as a reference point. The tbd fix for
race condition #1 will also use scanout position as a fixed reference.
The sample client code (below) for scheduling accurately timed
bufferswaps needs precise and trustworthy return values from
glXGetSyncValuesOML() for it to work. If vblank's are disabled at
time of invocation of glXGetSyncValuesOML() then that function will
trigger the real vblank irq enable path and use its return values for
swap scheduling - i.e. unless it is called within or close to a
vblank, it uses the vblank count and timestamp computed in
drm_update_vblank_count(), usually before the vblank irq had a chance
to run. For that reason it is important for my kind of applications
that it really delivers the right counts and timestamps especially in
the enable path.
This is the context in case you're interested why i'm so protective
of the current implementation: The toolkit i'm developing is probably
one of the currently most demanding clients of the new dri2 swap &
sync bits and it is used for neuroscience research. Many of the
experiments there require very precise visual timing and often sub-
millisecond accurate timestamping. Too many unhandled races in the
wrong places could really spoil the work of the scientists that are
my users. As long as we have a disable timeout of 5 seconds, vblank
irq's probably won't disable at all during most experiment sessions
and even if they do, the frequency of possible screwups is probably
small enough to be annoying but manageable with statistics (detecting/
discarding outliers in experimental results etc.). At a disable
timeout of around 50 msecs, the error rate would be unbearable.
That's why i would like to make sure that the implementation can
handle at least the already known quirks of a large number of the
gpu's out there if we go down to 50 msecs. But i assume races in that
code would affect the quality of "normal" media players as well, once
we choose such low timeouts.
Thanks and belated happy x-mas,
-mario
> This means that it would be safe to disable vblanks from any context
> at all, because it has no effect other than turning off the interupt.
>
> --Andy
>
>>
>> There could be other races that i couldn't think of and that i
>> didn't see
>> during my testing with my 2 radeons and 1 intel gpu. Therefore i
>> think we
>> should keep vblank irq's enabled for at least 2 or maybe 3 refresh
>> cycles if
>> they aren't used by anyone. Apps that want to schedule swaps very
>> precisely
>> and the ddx/drm/kms-driver itself do multiple queries in quick
>> succession
>> for a typical swapbuffers call, i.e., drm_vblank_get() -> query ->
>> drm_vblank_put(), so on an otherwise idle graphics system the
>> refcount will
>> toggle between zero and one multiple times during a swap, usually
>> within a
>> few milliseconds. If the timeout is big enough so that irq's don't
>> get
>> disabled within such a sequence of toggles, even if there's a bit of
>> scheduling delay for the x-server or client, then a client will
>> see at least
>> consistent vblank count during a swap, even if there are still
>> some races
>> hiding somewhere that we don't handle properly. That should be
>> good enough,
>> and paranoid clients can always increase the timeout value or set
>> it to
>> infinite.
>>
>> E.g., my toolkit schedules a swap for a specific system time like
>> this:
>>
>> 1. glXGetSyncValuesOML(... &base_msc, &base_ust);
>> 2. calculate target_msc based on user provided swap deadline t and
>> (base_msc, base_ust) as a baseline.
>> 3. glXSwapBuffersMscOML(...., target_msc,...);
>> 4. glXWaitForSbcOML() or use Intel_swap_events for retrieving the
>> true msc
>> and ust of swap completion.
>>
>> => Doesn't matter if there would be an off-by-one error in vblank
>> counting
>> due to an unknown race, as long as it doesn't happen between 1.
>> and 4. As
>> long as there aren't any client/x-server scheduling delays between
>> step 1
>> and 3 of more than /sys/module/drm/parameters/vblankoffdelay
>> msecs, nothing
>> can go wrong even if there are race conditions left in that area.
>>
>> => 50-100 msecs as new default would be probably good enough and
>> at the same
>> time prevent the "blinking cursor keeps vblank irq's on all the time"
>> problem.
>>
>> I didn't reduce the timeout in the current patches because the
>> filtering for
>> race-conditions and other gpu funkyness relies on somewhat precise
>> vblank
>> timestamps and the timestamping hooks aren't yet implemented in
>> the nouveau
>> kms. Maybe i manage to get this working over christmas. Patches to
>> nouveau
>> would be simple, i just don't know the mmio register addresses for
>> crtc
>> scanout position on nvidia gpu's.
>>
>> -mario
>>
>>
>> *********************************************************************
>> Mario Kleiner
>> Max Planck Institute for Biological Cybernetics
>> Spemannstr. 38
>> 72076 Tuebingen
>> Germany
>>
>> e-mail: mario.kleiner@tuebingen.mpg.de
>> office: +49 (0)7071/601-1623
>> fax: +49 (0)7071/601-616
>> www: http://www.kyb.tuebingen.mpg.de/~kleinerm
>> *********************************************************************
>> "For a successful technology, reality must take precedence
>> over public relations, for Nature cannot be fooled."
>> (Richard Feynman)
>>
>>
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm: Aggressively disable vblanks
2010-12-26 14:53 ` Andrew Lutomirski
2010-12-26 23:58 ` Mario Kleiner
@ 2010-12-27 10:52 ` Michel Dänzer
1 sibling, 0 replies; 12+ messages in thread
From: Michel Dänzer @ 2010-12-27 10:52 UTC (permalink / raw)
To: Andrew Lutomirski; +Cc: dri-devel, Mario Kleiner
On Son, 2010-12-26 at 09:53 -0500, Andrew Lutomirski wrote:
> On Wed, Dec 22, 2010 at 4:06 PM, Mario Kleiner
> <mario.kleiner@tuebingen.mpg.de> wrote:
> >
> > There's a new drm module parameter for selecting the timeout: echo 50 >
> > /sys/module/drm/parameters/vblankoffdelay
> > would set the timeout to 50 msecs. A setting of zero will disable the timer,
> > so vblank irq's would stay on all the time.
> >
> > The default setting is still 5000 msecs as before, but reducing this to 100
> > msecs wouldn't be a real problem imho. At least i didn't observe any
> > miscounting during extensive testing with 100 msecs.
> >
> > The patches in drm-next fix a couple of races that i observed on intel and
> > radeon during testing and a few that i didn't see but that i could imagine
> > happening. It tries to make sure that the saved final count at vblank irq
> > disable of the software vblank_count and the gpu counter are consistent - no
> > off by one errors. They also try to detect and filter out spurious vblank
> > interrupts at vblank enable time, e.g., on the radeon.
> >
> > There's still one possible race in the disable path which i will try to fix:
> > We don't know when exactly the hardware counter increments wrt. the
> > processing of the vblank interrupt - it could increment a few
> > (dozen/hundred) microseconds before or after the irq handler runs, so if you
> > happen to query the hardware counter while the gpu is inside the vblank you
> > can't be sure if you picked up the old count or the new count for that
> > vblank.
>
> That's disgusting. Does this affect many GPUs? (I can't imagine why
> any sensible implementation wouldn't guarantee that the counter
> increments just before the IRQ.)
Actually, while we want the interrupt to trigger at the beginning of
vblank (so we get a chance to do work within the vblank period), at
least on Radeons, the hardware frame counter increments at the beginning
of scanout, i.e. at the end of vblank.
At some point we tried to compensate for that by adding 1 to the
hardware frame counter while inside vblank, but IIRC that wasn't 100%
reliable either but would sometimes result in the counter being
considered too high by 1. So instead we've tried to keep the
infrastructure robust against the interrupt and hardware frame counter
increment not necessarily occurring at the same time.
(Even if both events always occurred at the same time on the GPU, we
might not be able to take advantage of that due to interrupt latencies)
--
Earthling Michel Dänzer | http://www.vmware.com
Libre software enthusiast | Debian, X and DRI developer
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-26 23:58 ` Mario Kleiner
@ 2010-12-27 11:16 ` Ville Syrjälä
2010-12-27 21:30 ` Mario Kleiner
2011-01-10 2:24 ` Andrew Lutomirski
1 sibling, 1 reply; 12+ messages in thread
From: Ville Syrjälä @ 2010-12-27 11:16 UTC (permalink / raw)
To: Mario Kleiner; +Cc: Andrew Lutomirski, dri-devel
On Mon, Dec 27, 2010 at 12:58:10AM +0100, Mario Kleiner wrote:
> 2. There are gpu's firing spurious vblank irq's as soon as you enable
> irq's
You're sure this isn't simply a matter of the driver forgetting to ack
the irq just before enabling it?
--
Ville Syrjälä
syrjala@sci.fi
http://www.sci.fi/~syrjala/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-27 11:16 ` Ville Syrjälä
@ 2010-12-27 21:30 ` Mario Kleiner
0 siblings, 0 replies; 12+ messages in thread
From: Mario Kleiner @ 2010-12-27 21:30 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Andrew Lutomirski, dri-devel
On Dec 27, 2010, at 12:16 PM, Ville Syrjälä wrote:
> On Mon, Dec 27, 2010 at 12:58:10AM +0100, Mario Kleiner wrote:
>
>> 2. There are gpu's firing spurious vblank irq's as soon as you enable
>> irq's
>
> You're sure this isn't simply a matter of the driver forgetting to ack
> the irq just before enabling it?
>
Good point. This was on radeon. I can't remember for certain if it
happened always, or only frequently. I can check that later this week
when i'm back at the test machine.
Anyway, it's good to be robust against such problems, regardless if
it is gpu quirks or driver bugs. The current implementation would
filter the redundant vblank irq and DRM_DEBUG a message if the
drm.debug parameter is set.
thanks,
-mario
> --
> Ville Syrjälä
> syrjala@sci.fi
> http://www.sci.fi/~syrjala/
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Intel-gfx] [PATCH] drm: Aggressively disable vblanks
2010-12-26 23:58 ` Mario Kleiner
2010-12-27 11:16 ` Ville Syrjälä
@ 2011-01-10 2:24 ` Andrew Lutomirski
1 sibling, 0 replies; 12+ messages in thread
From: Andrew Lutomirski @ 2011-01-10 2:24 UTC (permalink / raw)
To: Mario Kleiner; +Cc: dri-devel
On Mon, Dec 27, 2010 at 7:58 AM, Mario Kleiner
<mario.kleiner@tuebingen.mpg.de> wrote:
> On Dec 26, 2010, at 3:53 PM, Andrew Lutomirski wrote:
>
>> On Wed, Dec 22, 2010 at 4:06 PM, Mario Kleiner
>> <mario.kleiner@tuebingen.mpg.de> wrote:
>>>
>>> There's a new drm module parameter for selecting the timeout: echo 50 >
>>> /sys/module/drm/parameters/vblankoffdelay
>>> would set the timeout to 50 msecs. A setting of zero will disable the
>>> timer,
>>> so vblank irq's would stay on all the time.
>>>
>>> The default setting is still 5000 msecs as before, but reducing this to
>>> 100
>>> msecs wouldn't be a real problem imho. At least i didn't observe any
>>> miscounting during extensive testing with 100 msecs.
>>>
>>> The patches in drm-next fix a couple of races that i observed on intel
>>> and
>>> radeon during testing and a few that i didn't see but that i could
>>> imagine
>>> happening. It tries to make sure that the saved final count at vblank irq
>>> disable of the software vblank_count and the gpu counter are consistent -
>>> no
>>> off by one errors. They also try to detect and filter out spurious vblank
>>> interrupts at vblank enable time, e.g., on the radeon.
>>>
>>> There's still one possible race in the disable path which i will try to
>>> fix:
>>> We don't know when exactly the hardware counter increments wrt. the
>>> processing of the vblank interrupt - it could increment a few
>>> (dozen/hundred) microseconds before or after the irq handler runs, so if
>>> you
>>> happen to query the hardware counter while the gpu is inside the vblank
>>> you
>>> can't be sure if you picked up the old count or the new count for that
>>> vblank.
>>
>> That's disgusting. Does this affect many GPUs? (I can't imagine why
>> any sensible implementation wouldn't guarantee that the counter
>> increments just before the IRQ.)
>
> ;-). I don't know, but at least on the tested R500 and R600 class Radeon's,
> this was the case, so i assume it's at least this way on many radeon gpu's
> (probably all avivo parts?) out there. We don't have any evergreen gpu's yet
> in our lab so i don't know how the more recent parts behave. Also it doesn't
> matter
>
> I guess it's also a matter of definition when a new video frame starts?
> Leading edge / trailing edge of vblank? Start of vsync? Something else?
>
>>>
>>> This only matters during vblank disable. For that reason it's not such a
>>> good idea to disable vblank irq's from within the vblank irq handler. I
>>> tried that and it didn't work well --> When doing it from within irq you
>>> basically maximize the chance of hitting the time window when the race
>>> can
>>> happen. Delaying within the irq handler by a millisecond would fix that,
>>> but
>>> that's not what we want.
>>>
>>> Having the disable in a function triggered by a timer like now is the
>>> most
>>> simple solution i could come up with. There we can burn a few dozen
>>> microseconds if neccessary to remove this race.
>>
>> Maybe I'm missing something, but other than the race above (which
>> seems like it shouldn't exist on sane hardware), the new code seems
>> more complicated than necessary.
>
> I don't think it's more complicated than necessary for what it tries to
> achieve, but of course i'm a bit biased. It also started off more simple and
> grew a bit when i found new issues with the tested gpu's.
>
> The aim is to fix a couple of real races and to make vblank counts and
> timestamps as trustworthy and oml_sync_control spec-conformant (see
> http://www.opengl.org/registry/specs/OML/glx_sync_control.txt) as possible.
> It only consumes a few additional bytes of memory (approx. 40 bytes) per
> crtc, doesn't use excessive time inside the irq handler and tries to avoid
> taking locks that are shared between irq and non-irq context to avoid
> delays in irq execution, also if used with a kernel with the preempt_rt
> patch applied (important for my use case and other hard realtime apps). It's
> pretty self-contained and because most of it is driver-independent it can
> handle similar issues on different gpu's and kms drivers without the need
> for us to check each single gpu + driver combo if it has such issues or not.
>
OK, having read the glx_sync_control spec this makes a lot more sense.
I reread the code and I have two questions right off the bat:
1. What's the point of vblank_disable_and_save? AFAICT all that it
does (other than disabling vblanks) is to possibly increment
_vblank_count, ensuring that (barring races) it's correct as soon as
the call returns. But there are only three ways that
vblank_disable_and_save gets called: the disable timer, and two paths
in i915 that turn off vblanks when disabling crtcs. The latter two
shouldn't really care because the crtc is about to turn off, and the
former, being a timer, doesn't return into anything that cares about
the counter.
2. Why are the timestamps coming from do_gettimeofday instead of
ktime_get? Currently, if someone changes the system time, then weird
things could happen, I think.
--Andy
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-01-10 2:24 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <mailman.28.1292917668.19577.dri-devel@lists.freedesktop.org>
2010-12-22 4:36 ` [Intel-gfx] [PATCH] drm: Aggressively disable vblanks Mario Kleiner
2010-12-22 17:23 ` Jesse Barnes
2010-12-22 21:06 ` Mario Kleiner
2010-12-26 14:53 ` Andrew Lutomirski
2010-12-26 23:58 ` Mario Kleiner
2010-12-27 11:16 ` Ville Syrjälä
2010-12-27 21:30 ` Mario Kleiner
2011-01-10 2:24 ` Andrew Lutomirski
2010-12-27 10:52 ` Michel Dänzer
2010-12-20 19:00 Andy Lutomirski
2010-12-21 3:23 ` Keith Packard
2010-12-21 3:34 ` [Intel-gfx] " Andrew Lutomirski
2010-12-21 3:47 ` Keith Packard
2010-12-21 3:55 ` Andrew Lutomirski
2010-12-21 4:03 ` Jesse Barnes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).