All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jesse Barnes <jbarnes@virtuousgeek.org>
To: ville.syrjala@linux.intel.com
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 2/5] drm: Make the vblank disable timer per-crtc
Date: Wed, 26 Feb 2014 11:32:04 -0800	[thread overview]
Message-ID: <20140226113204.35efdc58@jbarnes-desktop> (raw)
In-Reply-To: <1393009415-27651-3-git-send-email-ville.syrjala@linux.intel.com>

On Fri, 21 Feb 2014 21:03:32 +0200
ville.syrjala@linux.intel.com wrote:

> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Currently there's one per-device vblank disable timer, and it gets
> reset wheneven the vblank refcount for any crtc drops to zero. That
> means that one crtc could accidentally be keeping the vblank interrupts
> for other crtcs enabled even if there are no users for them. Make the
> disable timer per-crtc to avoid this issue.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/drm_irq.c | 40 +++++++++++++++++++++-------------------
>  include/drm/drmP.h        |  4 +++-
>  2 files changed, 24 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index baa12e7..3211158 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -167,33 +167,34 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
>  
>  static void vblank_disable_fn(unsigned long arg)
>  {
> -	struct drm_device *dev = (struct drm_device *)arg;
> +	struct drm_vblank_crtc *vblank = (void *)arg;
> +	struct drm_device *dev = vblank->dev;
>  	unsigned long irqflags;
> -	int i;
> +	int crtc = vblank->crtc;
>  
>  	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[i].refcount) == 0 &&
> -		    dev->vblank[i].enabled) {
> -			DRM_DEBUG("disabling vblank on crtc %d\n", i);
> -			vblank_disable_and_save(dev, i);
> -		}
> -		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> +	spin_lock_irqsave(&dev->vbl_lock, irqflags);
> +	if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
> +		DRM_DEBUG("disabling vblank on crtc %d\n", crtc);
> +		vblank_disable_and_save(dev, crtc);
>  	}
> +	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
>  }
>  
>  void drm_vblank_cleanup(struct drm_device *dev)
>  {
> +	int crtc;
> +
>  	/* Bail if the driver didn't call drm_vblank_init() */
>  	if (dev->num_crtcs == 0)
>  		return;
>  
> -	del_timer_sync(&dev->vblank_disable_timer);
> -
> -	vblank_disable_fn((unsigned long)dev);
> +	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
> +		del_timer_sync(&dev->vblank[crtc].disable_timer);
> +		vblank_disable_fn((unsigned long)&dev->vblank[crtc]);
> +	}
>  
>  	kfree(dev->vblank);
>  
> @@ -205,8 +206,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);
>  	spin_lock_init(&dev->vblank_time_lock);
>  
> @@ -216,8 +215,13 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
>  	if (!dev->vblank)
>  		goto err;
>  
> -	for (i = 0; i < num_crtcs; i++)
> +	for (i = 0; i < num_crtcs; i++) {
> +		dev->vblank[i].dev = dev;
> +		dev->vblank[i].crtc = i;
>  		init_waitqueue_head(&dev->vblank[i].queue);
> +		setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn,
> +			    (unsigned long)&dev->vblank[i]);
> +	}
>  
>  	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
>  
> @@ -934,7 +938,7 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
>  	/* Last user schedules interrupt disable */
>  	if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
>  	    (drm_vblank_offdelay > 0))
> -		mod_timer(&dev->vblank_disable_timer,
> +		mod_timer(&dev->vblank[crtc].disable_timer,
>  			  jiffies + ((drm_vblank_offdelay * HZ)/1000));
>  }
>  EXPORT_SYMBOL(drm_vblank_put);
> @@ -943,8 +947,6 @@ EXPORT_SYMBOL(drm_vblank_put);
>   * drm_vblank_off - disable vblank events on a CRTC
>   * @dev: DRM device
>   * @crtc: CRTC in question
> - *
> - * Caller must hold event lock.
>   */
>  void drm_vblank_off(struct drm_device *dev, int crtc)
>  {
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 04a7f31..f974da9 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1077,14 +1077,17 @@ struct drm_pending_vblank_event {
>  };
>  
>  struct drm_vblank_crtc {
> +	struct drm_device *dev;		/* pointer to the drm_device */
>  	wait_queue_head_t queue;	/**< VBLANK wait queue */
>  	struct timeval time[DRM_VBLANKTIME_RBSIZE];	/**< timestamp of current count */
> +	struct timer_list disable_timer;		/* delayed disable timer */
>  	atomic_t count;			/**< number of VBLANK interrupts */
>  	atomic_t refcount;		/* number of users of vblank interruptsper crtc */
>  	u32 last;			/* protected by dev->vbl_lock, used */
>  					/* for wraparound handling */
>  	u32 last_wait;			/* Last vblank seqno waited per CRTC */
>  	unsigned int inmodeset;		/* Display driver is setting mode */
> +	int crtc;			/* crtc index */
>  	bool enabled;			/* so we don't call enable more than
>  					   once per disable */
>  };
> @@ -1157,7 +1160,6 @@ struct drm_device {
>  
>  	spinlock_t vblank_time_lock;    /**< Protects vblank count and time updates during vblank enable/disable */
>  	spinlock_t vbl_lock;
> -	struct timer_list vblank_disable_timer;
>  
>  	u32 max_vblank_count;           /**< size of vblank counter register */
>  

Yeah this looks like a good fix.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2014-02-26 19:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-21 19:03 [PATCH 0/5] drm: Allow vblank interrupts during modeset and make the code less racy ville.syrjala
2014-02-21 19:03 ` [PATCH 1/5] drm: Use correct spinlock flavor in drm_vblank_get() ville.syrjala
2014-02-26 19:24   ` [Intel-gfx] " Jesse Barnes
2014-02-21 19:03 ` [PATCH 2/5] drm: Make the vblank disable timer per-crtc ville.syrjala
2014-02-26 19:32   ` Jesse Barnes [this message]
2014-02-21 19:03 ` [PATCH 3/5] drm: Allow the driver to reject vblank requests only when it really has the vblank interrupts disabled ville.syrjala
2014-02-26 19:41   ` Jesse Barnes
2014-03-04  9:24   ` Daniel Vetter
2014-03-05 12:38     ` Ville Syrjälä
2014-03-05 13:55       ` Daniel Vetter
2014-02-21 19:03 ` [PATCH 4/5] drm: Allow reenabling of vblank interrupts even if refcount>0 ville.syrjala
2014-02-26 19:44   ` Jesse Barnes
2014-03-04  9:16   ` Daniel Vetter
2014-03-05 12:33     ` Ville Syrjälä
2014-02-21 19:03 ` [PATCH 5/5] drm/i915: Allow vblank interrupts during modeset and eliminate some vblank races ville.syrjala
2014-02-24  3:48   ` Michel Dänzer
2014-02-24 12:11     ` Ville Syrjälä
2014-02-25  2:58       ` Michel Dänzer
2014-02-26 19:48         ` Jesse Barnes
2014-03-04  9:13         ` Daniel Vetter
2014-05-28  9:12           ` Michel Dänzer
2014-05-28 11:19             ` [Intel-gfx] " Ville Syrjälä
2014-05-29  4:11               ` Michel Dänzer
2014-05-29 10:56                 ` Daniel Vetter
2014-05-30  3:13                   ` Michel Dänzer
2014-02-28  8:56   ` Ville Syrjälä
2014-03-04  9:15     ` Daniel Vetter

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20140226113204.35efdc58@jbarnes-desktop \
    --to=jbarnes@virtuousgeek.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=ville.syrjala@linux.intel.com \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.