All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: dri-devel@lists.freedesktop.org
Cc: patches@linaro.org, daniel.vetter@ffwll.ch,
	Rob Clark <rob.clark@linaro.org>,
	bskeggs@redhat.com, gregkh@linuxfoundation.org,
	Rob Clark <rob@ti.com>
Subject: Re: [PATCH 01/11] drm: add drm_send_vblank_event() helper
Date: Thu, 11 Oct 2012 16:19:17 +0200	[thread overview]
Message-ID: <2521012.j15Ecn3JsI@avalon> (raw)
In-Reply-To: <1349725849-22433-2-git-send-email-rob.clark@linaro.org>

Hi Rob,

Thanks for the patch.

On Monday 08 October 2012 14:50:39 Rob Clark wrote:
> From: Rob Clark <rob@ti.com>
> 
> A helper that drivers can use to send vblank event after a pageflip.
> If the driver doesn't support proper vblank irq based time/seqn then
> just pass -1 for the pipe # to get do_gettimestamp() behavior (since
> there are a lot of drivers that don't use drm_vblank_count_and_time())
> 
> Also an internal send_vblank_event() helper for the various other code
> paths within drm_irq that also need to send vblank events.
> 
> Signed-off-by: Rob Clark <rob@ti.com>
> ---
>  drivers/gpu/drm/drm_irq.c |   65 +++++++++++++++++++++++++++---------------
>  include/drm/drmP.h        |    2 ++
>  2 files changed, 44 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 076c4a8..7a00d94 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -802,6 +802,43 @@ u32 drm_vblank_count_and_time(struct drm_device *dev,
> int crtc, }
>  EXPORT_SYMBOL(drm_vblank_count_and_time);
> 
> +static void send_vblank_event(struct drm_pending_vblank_event *e,
> +		unsigned long seq, struct timeval *now)
> +{
> +	e->event.sequence = seq;
> +	e->event.tv_sec = now->tv_sec;
> +	e->event.tv_usec = now->tv_usec;
> +
> +	list_add_tail(&e->base.link,
> +		      &e->base.file_priv->event_list);
> +	wake_up_interruptible(&e->base.file_priv->event_wait);
> +	trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> +					 e->event.sequence);
> +}
> +
> +/**
> + * drm_send_vblank_event - helper to send vblank event after pageflip
> + * @dev: DRM device
> + * @crtc: CRTC in question
> + * @e: the event to send
> + *
> + * Updates sequence # and timestamp on event, and sends it to userspace.

Due to the list_add_tail above, drm_send_vblank_event() requires locking. As 
you don't take any lock I expect the caller to be supposed to handle locking. 
That should be documented, along with the lock that the caller should take. 
Looking at the existing drivers that should be dev->event_lock, but not all 
drivers take it when calling the vblank functions below (for instance the i915 
and gma500 drivers call drm_vblank_off() without holding the event_lock 
spinlock). We thus seem to have a locking issue that should be fixed, either 
as part of this patch set or as a preliminary patches series.

I have no strong opinion on who takes the spinlock (the caller or the 
send_vblank_event() function) at the moment, but taking it in 
send_vblank_event() would allow calling drm_vblank_count_and_time() and 
do_gettimeofday() below outside of the locked region.

> + */
> +void drm_send_vblank_event(struct drm_device *dev, int crtc,
> +		struct drm_pending_vblank_event *e)
> +{
> +	struct timeval now;
> +	unsigned int seq;
> +	if (crtc >= 0) {
> +		seq = drm_vblank_count_and_time(dev, crtc, &now);
> +	} else {
> +		seq = 0;
> +		do_gettimeofday(&now);

Do you know why some drivers don't call drm_vblank_count_and_time() ? For 
instance nouveau sets the sequence to 0 and uses do_gettimeofday(), but it 
looks like it could just call drm_vblank_count_and_time().

> +	}
> +	send_vblank_event(e, seq, &now);
> +}
> +EXPORT_SYMBOL(drm_send_vblank_event);
> +
>  /**
>   * drm_update_vblank_count - update the master vblank counter
>   * @dev: DRM device
> @@ -955,15 +992,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
>  		DRM_DEBUG("Sending premature vblank event on disable: \
>  			  wanted %d, current %d\n",
>  			  e->event.sequence, seq);
> -
> -		e->event.sequence = seq;
> -		e->event.tv_sec = now.tv_sec;
> -		e->event.tv_usec = now.tv_usec;
> +		list_del(&e->base.link);
>  		drm_vblank_put(dev, e->pipe);
> -		list_move_tail(&e->base.link, &e->base.file_priv->event_list);
> -		wake_up_interruptible(&e->base.file_priv->event_wait);
> -		trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> -						 e->event.sequence);
> +		send_vblank_event(e, seq, &now);
>  	}
> 
>  	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> @@ -1107,15 +1138,8 @@ static int drm_queue_vblank_event(struct drm_device
> *dev, int pipe,
> 
>  	e->event.sequence = vblwait->request.sequence;
>  	if ((seq - vblwait->request.sequence) <= (1 << 23)) {
> -		e->event.sequence = seq;
> -		e->event.tv_sec = now.tv_sec;
> -		e->event.tv_usec = now.tv_usec;
>  		drm_vblank_put(dev, pipe);
> -		list_add_tail(&e->base.link, &e->base.file_priv->event_list);
> -		wake_up_interruptible(&e->base.file_priv->event_wait);
> -		vblwait->reply.sequence = seq;
> -		trace_drm_vblank_event_delivered(current->pid, pipe,
> -						 vblwait->request.sequence);
> +		send_vblank_event(e, seq, &now);
>  	} else {
>  		/* drm_handle_vblank_events will call drm_vblank_put */
>  		list_add_tail(&e->base.link, &dev->vblank_event_list);
> @@ -1256,14 +1280,9 @@ static void drm_handle_vblank_events(struct
> drm_device *dev, int crtc) DRM_DEBUG("vblank event on %d, current %d\n",
>  			  e->event.sequence, seq);
> 
> -		e->event.sequence = seq;
> -		e->event.tv_sec = now.tv_sec;
> -		e->event.tv_usec = now.tv_usec;
> +		list_del(&e->base.link);
>  		drm_vblank_put(dev, e->pipe);
> -		list_move_tail(&e->base.link, &e->base.file_priv->event_list);
> -		wake_up_interruptible(&e->base.file_priv->event_wait);
> -		trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> -						 e->event.sequence);
> +		send_vblank_event(e, seq, &now);
>  	}
> 
>  	spin_unlock_irqrestore(&dev->event_lock, flags);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 05af0e7..ee8f927 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1437,6 +1437,8 @@ extern int drm_vblank_wait(struct drm_device *dev,
> unsigned int *vbl_seq); extern u32 drm_vblank_count(struct drm_device *dev,
> int crtc);
>  extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
>  				     struct timeval *vblanktime);
> +extern void drm_send_vblank_event(struct drm_device *dev, int crtc,
> +				     struct drm_pending_vblank_event *e);
>  extern bool drm_handle_vblank(struct drm_device *dev, int crtc);
>  extern int drm_vblank_get(struct drm_device *dev, int crtc);
>  extern void drm_vblank_put(struct drm_device *dev, int crtc);

-- 
Regards,

Laurent Pinchart

  parent reply	other threads:[~2012-10-11 14:18 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-08 19:50 [PATCH 00/11] page-flip cleanups and fixes Rob Clark
2012-10-08 19:50 ` [PATCH 01/11] drm: add drm_send_vblank_event() helper Rob Clark
2012-10-08 21:26   ` Marcin Slusarz
2012-10-11 14:19   ` Laurent Pinchart [this message]
2012-10-11 14:43     ` Rob Clark
2012-10-13  0:28     ` Mario Kleiner
2012-10-16 12:53       ` Laurent Pinchart
2012-10-08 19:50 ` [PATCH 02/11] drm/i915: use " Rob Clark
2012-10-09  8:02   ` Daniel Vetter
2012-11-21 16:48   ` Daniel Vetter
2012-10-08 19:50 ` [PATCH 03/11] drm/nouveau: " Rob Clark
2012-10-08 19:50 ` [PATCH 04/11] drm/radeon: " Rob Clark
2012-10-08 19:50 ` [PATCH 05/11] drm/exynos: " Rob Clark
2013-05-21 23:19   ` Dave Airlie
2013-05-22  2:28     ` Inki Dae
2013-05-22  4:04   ` [PATCH] " Inki Dae
2013-05-22  4:51     ` Joonyoung Shim
2013-05-22  6:56       ` Inki Dae
2013-05-22  6:59     ` [PATCH RESEND] " Inki Dae
2012-10-08 19:50 ` [PATCH 06/11] drm/exynos: page flip fixes Rob Clark
2013-05-21 23:17   ` Dave Airlie
2013-05-22  2:36     ` Inki Dae
2012-10-08 19:50 ` [PATCH 07/11] drm/shmob: use drm_send_vblank_event() helper Rob Clark
2012-10-08 19:50 ` [PATCH 08/11] drm/imx: " Rob Clark
2012-10-08 19:50 ` [PATCH 09/11] drm/imx: page flip fixes Rob Clark
2013-05-21 23:18   ` Dave Airlie
2012-10-08 19:50 ` [PATCH 10/11] drm/omap: use drm_send_vblank_event() helper Rob Clark
2012-10-10  3:33   ` Mario Kleiner
2012-10-10 11:03     ` Rob Clark
2012-10-12 23:38       ` Mario Kleiner
2012-10-08 19:50 ` [PATCH 11/11] drm/omap: page-flip fixes Rob Clark
2012-10-09  9:35   ` Imre Deak
2012-10-09  9:38     ` Imre Deak
2012-10-08 20:51 ` [PATCH 00/11] page-flip cleanups and fixes Alex Deucher
2012-10-08 22:10 ` Marcin Slusarz
2012-10-09  5:17 ` Inki Dae
2012-10-22 22:39 ` Greg KH
2012-10-22 22:51   ` Rob Clark

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=2521012.j15Ecn3JsI@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=bskeggs@redhat.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=patches@linaro.org \
    --cc=rob.clark@linaro.org \
    --cc=rob@ti.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.