Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1379400 > unrolled thread

[RFC 0/8] drm: explicit fencing support

Started byGustavo Padovan <gustavo@padovan.org>
First post2016-04-15 03:30 +0200
Last post2016-04-15 03:40 +0200
Articles 7 on this page of 27 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [RFC 0/8] drm: explicit fencing support Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:30 +0200
    [RFC 1/8] dma-buf/fence: add fence_collection fences Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:30 +0200
      Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:10 +0200
        Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 13:50 +0200
          Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 20:30 +0200
            Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 21:30 +0200
        Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 20:30 +0200
          Re: [RFC 1/8] dma-buf/fence: add fence_collection fences Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 21:30 +0200
    [RFC 3/8] drm/fence: allow fence waiting to be interrupted by userspace Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:30 +0200
      Re: [RFC 3/8] drm/fence: allow fence waiting to be interrupted by  userspace Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 09:50 +0200
    [RFC 6/8] drm/fence: create DRM_MODE_ATOMIC_OUT_FENCE flag Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:30 +0200
      Re: [RFC 6/8] drm/fence: create DRM_MODE_ATOMIC_OUT_FENCE flag Rob Clark <robdclark@gmail.com> - 2016-04-15 03:50 +0200
        Re: [RFC 6/8] drm/fence: create DRM_MODE_ATOMIC_OUT_FENCE flag Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 21:10 +0200
    [RFC 2/8] dma-buf/sync_file: add sync_file_fences_get() Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:40 +0200
      Re: [RFC 2/8] dma-buf/sync_file: add sync_file_fences_get() Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:00 +0200
    [RFC 5/8] drm/fence: add fence to drm_pending_event Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:40 +0200
      Re: [RFC 5/8] drm/fence: add fence to drm_pending_event Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:20 +0200
        Re: [RFC 5/8] drm/fence: add fence to drm_pending_event Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 21:00 +0200
          Re: [RFC 5/8] drm/fence: add fence to drm_pending_event Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 21:40 +0200
    [RFC 8/8] drm/fence: add out-fences support Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:40 +0200
      Re: [RFC 8/8] drm/fence: add out-fences support Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:20 +0200
        Re: [RFC 8/8] drm/fence: add out-fences support Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 21:20 +0200
    [RFC 4/8] drm/fence: add in-fences support Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:40 +0200
      Re: [RFC 4/8] drm/fence: add in-fences support Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:10 +0200
        Re: [RFC 4/8] drm/fence: add in-fences support Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 20:50 +0200
      Re: [RFC 4/8] drm/fence: add in-fences support Daniel Vetter <daniel@ffwll.ch> - 2016-04-15 10:20 +0200
    [RFC 7/8] drm/fence: create per-crtc sync_timeline Gustavo Padovan <gustavo@padovan.org> - 2016-04-15 03:40 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1379534 — Re: [RFC 8/8] drm/fence: add out-fences support

FromDaniel Vetter <daniel@ffwll.ch>
Date2016-04-15 10:20 +0200
SubjectRe: [RFC 8/8] drm/fence: add out-fences support
Message-ID<ro78R-8qx-5@gated-at.bofh.it>
In reply to#1379409
On Thu, Apr 14, 2016 at 06:29:41PM -0700, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> Support DRM out-fences creating a sync_file with a fence for each crtc
> update with the DRM_MODE_ATOMIC_OUT_FENCE flag.
> 
> We then send an struct drm_out_fences array with the out-fences fds back in
> the drm_atomic_ioctl() as an out arg in the out_fences_ptr field.
> 
> struct drm_out_fences {
> 	__u32   crtc_id;
> 	__u32   fd;
> };
> 
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  drivers/gpu/drm/drm_atomic.c        | 109 +++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/drm_atomic_helper.c |   1 +
>  include/drm/drm_crtc.h              |   3 +
>  include/uapi/drm/drm_mode.h         |   7 +++
>  4 files changed, 119 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 0b95526..af6e051 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1560,6 +1560,103 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(drm_atomic_clean_old_fb);
>  
> +static int drm_atomic_get_out_fences(struct drm_device *dev,
> +				     struct drm_atomic_state *state,
> +				     uint32_t __user *out_fences_ptr,
> +				     uint64_t count_out_fences,
> +				     uint64_t user_data)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_out_fences *out_fences;
> +	struct sync_file **sync_file;
> +	int num_fences = 0;
> +	int i, ret;
> +
> +	out_fences = kcalloc(count_out_fences, sizeof(*out_fences),
> +			     GFP_KERNEL);
> +	if (!out_fences)
> +		return -ENOMEM;
> +
> +	sync_file = kcalloc(count_out_fences, sizeof(*sync_file),
> +			     GFP_KERNEL);
> +	if (!sync_file) {
> +		kfree(out_fences);
> +		return -ENOMEM;
> +	}
> +
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		struct drm_pending_vblank_event *e;
> +		struct fence *fence;
> +		char name[32];
> +		int fd;
> +
> +		fence = sync_timeline_create_fence(crtc->timeline,
> +						   crtc->fence_seqno);
> +		if (!fence) {
> +			ret = -ENOMEM;
> +			goto out;
> +		}
> +
> +		snprintf(name, sizeof(name), "crtc-%d_%lu",
> +			 drm_crtc_index(crtc), crtc->fence_seqno++);
> +
> +		sync_file[i] = sync_file_create(name, fence);
> +		if(!sync_file[i]) {
> +			ret = -ENOMEM;
> +			goto out;
> +		}
> +
> +		fd = get_unused_fd_flags(O_CLOEXEC);
> +		if (fd < 0) {
> +			ret = fd;
> +			goto out;
> +		}
> +
> +		sync_file_install(sync_file[i], fd);
> +
> +		if (crtc_state->event) {
> +			crtc_state->event->base.fence = fence;
> +		} else {
> +			e = create_vblank_event(dev, NULL, fence, user_data);
> +			if (!e) {
> +				put_unused_fd(fd);
> +				ret = -ENOMEM;
> +				goto out;
> +			}
> +
> +			crtc_state->event = e;
> +		}
> +		if (num_fences > count_out_fences) {
> +			put_unused_fd(fd);
> +			ret = -EINVAL;
> +			goto out;
> +		}
> +
> +		fence_get(fence);
> +
> +		out_fences[num_fences].crtc_id = crtc->base.id;
> +		out_fences[num_fences].fd = fd;
> +		num_fences++;
> +	}
> +
> +	if (copy_to_user(out_fences_ptr, out_fences,
> +			 num_fences * sizeof(*out_fences))) {
> +		ret = -EFAULT;
> +		goto out;
> +	}
> +
> +	return 0;
> +
> +out:
> +	for (i = 0 ; i < count_out_fences ; i++) {
> +		if (sync_file[i])
> +			sync_file_put(sync_file[i]);
> +	}
> +
> +	return ret;
> +}
> +
>  int drm_mode_atomic_ioctl(struct drm_device *dev,
>  			  void *data, struct drm_file *file_priv)
>  {
> @@ -1568,6 +1665,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
>  	uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
>  	uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
>  	uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
> +	uint32_t __user *out_fences_ptr = (uint32_t __user *)(unsigned long)(arg->out_fences_ptr);
>  	unsigned int copied_objs, copied_props;
>  	struct drm_atomic_state *state;
>  	struct drm_modeset_acquire_ctx ctx;
> @@ -1601,7 +1699,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
>  
>  	/* can't test and expect an event at the same time. */
>  	if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
> -			(arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
> +			(arg->flags & (DRM_MODE_PAGE_FLIP_EVENT
> +			 | DRM_MODE_ATOMIC_OUT_FENCE)))
>  		return -EINVAL;
>  
>  	drm_modeset_acquire_init(&ctx, 0);
> @@ -1693,6 +1792,14 @@ retry:
>  		}
>  	}
>  
> +	if (arg->flags & DRM_MODE_ATOMIC_OUT_FENCE) {

OUT_FENCE and TEST_ONLY probably don't make sense, and need to be
rejected. Needs a testcase, too.

> +		ret = drm_atomic_get_out_fences(dev, state, out_fences_ptr,
> +						arg->count_out_fences,
> +						arg->user_data);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
>  	if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {

If anything fails below this point we need to clean up the sync_file/fd
mess. Might be easier to first create sync_file objects only, and only
install the fd once atomic has succeeded. You probably want to reserve the
fd slots beforehand though.

That means a bunch more per-crtc state in drm_atomic_state. We should
probably take all the per-crtc pointers and throw them into a small
struct, to avoid allocating individual arrays for everything. So

struct drm_atomic_state_per_crtc {
	struct drm_crtc *crtc;
	struct drm_crtc_state *state;
	struct sync_file *sync_file;
	int fd;
};

Sorry if this means a bit a sprawling upfront refactor :(

Wrt testcase: Need evil ones that pass invalid pointer to out_fences_ptr
or too small array size in count_out_fences and all that ofc.
-Daniel

>  		/*
>  		 * Unlike commit, check_only does not clean up state.
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 6ed8339..15ba3a8 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -31,6 +31,7 @@
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <linux/fence.h>
> +#include <linux/sync_file.h>
>  
>  /**
>   * DOC: overview
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 7934178..53e4e71 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -717,6 +717,7 @@ struct drm_crtc_funcs {
>   * @properties: property tracking for this CRTC
>   * @state: current atomic state for this CRTC
>   * @timeline: sync timeline for fence sigalling
> + * @fence_seqno: seqno variable to create fences
>   * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
>   * 	legacy IOCTLs
>   *
> @@ -773,7 +774,9 @@ struct drm_crtc {
>  
>  	struct drm_crtc_state *state;
>  
> +	/* for out-fences */
>  	struct sync_timeline *timeline;
> +	unsigned long fence_seqno;
>  
>  	/*
>  	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 39905cc..4cdcd22 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -592,6 +592,11 @@ struct drm_mode_destroy_dumb {
>  		DRM_MODE_ATOMIC_ALLOW_MODESET |\
>  		DRM_MODE_ATOMIC_OUT_FENCE)
>  
> +struct drm_out_fences {
> +	__u32	crtc_id;
> +	__u32	fd;
> +};
> +
>  struct drm_mode_atomic {
>  	__u32 flags;
>  	__u32 count_objs;
> @@ -601,6 +606,8 @@ struct drm_mode_atomic {
>  	__u64 prop_values_ptr;
>  	__u64 reserved;
>  	__u64 user_data;
> +	__u64 count_out_fences;
> +	__u64 out_fences_ptr;
>  };
>  
>  /**
> -- 
> 2.5.5
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1380146 — Re: [RFC 8/8] drm/fence: add out-fences support

FromGustavo Padovan <gustavo@padovan.org>
Date2016-04-15 21:20 +0200
SubjectRe: [RFC 8/8] drm/fence: add out-fences support
Message-ID<rohrA-81o-27@gated-at.bofh.it>
In reply to#1379534
2016-04-15 Daniel Vetter <daniel@ffwll.ch>:

> On Thu, Apr 14, 2016 at 06:29:41PM -0700, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > Support DRM out-fences creating a sync_file with a fence for each crtc
> > update with the DRM_MODE_ATOMIC_OUT_FENCE flag.
> > 
> > We then send an struct drm_out_fences array with the out-fences fds back in
> > the drm_atomic_ioctl() as an out arg in the out_fences_ptr field.
> > 
> > struct drm_out_fences {
> > 	__u32   crtc_id;
> > 	__u32   fd;
> > };
> > 
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > ---
> >  drivers/gpu/drm/drm_atomic.c        | 109 +++++++++++++++++++++++++++++++++++-
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  include/drm/drm_crtc.h              |   3 +
> >  include/uapi/drm/drm_mode.h         |   7 +++
> >  4 files changed, 119 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 0b95526..af6e051 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1560,6 +1560,103 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(drm_atomic_clean_old_fb);
> >  
> > +static int drm_atomic_get_out_fences(struct drm_device *dev,
> > +				     struct drm_atomic_state *state,
> > +				     uint32_t __user *out_fences_ptr,
> > +				     uint64_t count_out_fences,
> > +				     uint64_t user_data)
> > +{
> > +	struct drm_crtc *crtc;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_out_fences *out_fences;
> > +	struct sync_file **sync_file;
> > +	int num_fences = 0;
> > +	int i, ret;
> > +
> > +	out_fences = kcalloc(count_out_fences, sizeof(*out_fences),
> > +			     GFP_KERNEL);
> > +	if (!out_fences)
> > +		return -ENOMEM;
> > +
> > +	sync_file = kcalloc(count_out_fences, sizeof(*sync_file),
> > +			     GFP_KERNEL);
> > +	if (!sync_file) {
> > +		kfree(out_fences);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> > +		struct drm_pending_vblank_event *e;
> > +		struct fence *fence;
> > +		char name[32];
> > +		int fd;
> > +
> > +		fence = sync_timeline_create_fence(crtc->timeline,
> > +						   crtc->fence_seqno);
> > +		if (!fence) {
> > +			ret = -ENOMEM;
> > +			goto out;
> > +		}
> > +
> > +		snprintf(name, sizeof(name), "crtc-%d_%lu",
> > +			 drm_crtc_index(crtc), crtc->fence_seqno++);
> > +
> > +		sync_file[i] = sync_file_create(name, fence);
> > +		if(!sync_file[i]) {
> > +			ret = -ENOMEM;
> > +			goto out;
> > +		}
> > +
> > +		fd = get_unused_fd_flags(O_CLOEXEC);
> > +		if (fd < 0) {
> > +			ret = fd;
> > +			goto out;
> > +		}
> > +
> > +		sync_file_install(sync_file[i], fd);
> > +
> > +		if (crtc_state->event) {
> > +			crtc_state->event->base.fence = fence;
> > +		} else {
> > +			e = create_vblank_event(dev, NULL, fence, user_data);
> > +			if (!e) {
> > +				put_unused_fd(fd);
> > +				ret = -ENOMEM;
> > +				goto out;
> > +			}
> > +
> > +			crtc_state->event = e;
> > +		}
> > +		if (num_fences > count_out_fences) {
> > +			put_unused_fd(fd);
> > +			ret = -EINVAL;
> > +			goto out;
> > +		}
> > +
> > +		fence_get(fence);
> > +
> > +		out_fences[num_fences].crtc_id = crtc->base.id;
> > +		out_fences[num_fences].fd = fd;
> > +		num_fences++;
> > +	}
> > +
> > +	if (copy_to_user(out_fences_ptr, out_fences,
> > +			 num_fences * sizeof(*out_fences))) {
> > +		ret = -EFAULT;
> > +		goto out;
> > +	}
> > +
> > +	return 0;
> > +
> > +out:
> > +	for (i = 0 ; i < count_out_fences ; i++) {
> > +		if (sync_file[i])
> > +			sync_file_put(sync_file[i]);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> >  int drm_mode_atomic_ioctl(struct drm_device *dev,
> >  			  void *data, struct drm_file *file_priv)
> >  {
> > @@ -1568,6 +1665,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
> >  	uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
> >  	uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
> >  	uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
> > +	uint32_t __user *out_fences_ptr = (uint32_t __user *)(unsigned long)(arg->out_fences_ptr);
> >  	unsigned int copied_objs, copied_props;
> >  	struct drm_atomic_state *state;
> >  	struct drm_modeset_acquire_ctx ctx;
> > @@ -1601,7 +1699,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
> >  
> >  	/* can't test and expect an event at the same time. */
> >  	if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
> > -			(arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
> > +			(arg->flags & (DRM_MODE_PAGE_FLIP_EVENT
> > +			 | DRM_MODE_ATOMIC_OUT_FENCE)))
> >  		return -EINVAL;
> >  
> >  	drm_modeset_acquire_init(&ctx, 0);
> > @@ -1693,6 +1792,14 @@ retry:
> >  		}
> >  	}
> >  
> > +	if (arg->flags & DRM_MODE_ATOMIC_OUT_FENCE) {
> 
> OUT_FENCE and TEST_ONLY probably don't make sense, and need to be
> rejected. Needs a testcase, too.

I've added the check for this above. But a test case is still missing.

> 
> > +		ret = drm_atomic_get_out_fences(dev, state, out_fences_ptr,
> > +						arg->count_out_fences,
> > +						arg->user_data);
> > +		if (ret < 0)
> > +			goto out;
> > +	}
> > +
> >  	if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
> 
> If anything fails below this point we need to clean up the sync_file/fd
> mess. Might be easier to first create sync_file objects only, and only
> install the fd once atomic has succeeded. You probably want to reserve the
> fd slots beforehand though.
> 
> That means a bunch more per-crtc state in drm_atomic_state. We should
> probably take all the per-crtc pointers and throw them into a small
> struct, to avoid allocating individual arrays for everything. So
> 
> struct drm_atomic_state_per_crtc {
> 	struct drm_crtc *crtc;
> 	struct drm_crtc_state *state;
> 	struct sync_file *sync_file;
> 	int fd;
> };

That is good idea. I've left the clean up out for this RFC because I
didn't had any good approach on how to do it.

Thanks for this suggestion and all the other comments in the patches.
They were really helpful to improve this work.

	Gustavo

[toc] | [prev] | [next] | [standalone]


#1379410 — [RFC 4/8] drm/fence: add in-fences support

FromGustavo Padovan <gustavo@padovan.org>
Date2016-04-15 03:40 +0200
Subject[RFC 4/8] drm/fence: add in-fences support
Message-ID<ro0TM-3bX-11@gated-at.bofh.it>
In reply to#1379400
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

There is now a new property called FENCE_FD attached to every plane
state that receives the sync_file fd from userspace via the atomic commit
IOCTL.

The fd is then translated to a fence (that may be a fence_collection
subclass or just a normal fence) and then used by DRM to fence_wait() for
all fences in the sync_file to signal. So it only commits when all
framebuffers are ready to scanout.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/Kconfig             | 1 +
 drivers/gpu/drm/drm_atomic.c        | 8 ++++++++
 drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
 drivers/gpu/drm/drm_crtc.c          | 7 +++++++
 include/drm/drm_crtc.h              | 1 +
 5 files changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f2a74d0..3c987e3 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -12,6 +12,7 @@ menuconfig DRM
 	select I2C
 	select I2C_ALGOBIT
 	select DMA_SHARED_BUFFER
+	select SYNC_FILE
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8ee1db8..6702502 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -30,6 +30,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_mode.h>
 #include <drm/drm_plane_helper.h>
+#include <linux/sync_file.h>
 
 /**
  * drm_atomic_state_default_release -
@@ -680,6 +681,11 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
 		drm_atomic_set_fb_for_plane(state, fb);
 		if (fb)
 			drm_framebuffer_unreference(fb);
+	} else if (property == config->prop_fence_fd) {
+		state->fence = sync_file_fences_get(val);
+		if (!state->fence)
+			return -EINVAL;
+		fence_get(state->fence);
 	} else if (property == config->prop_crtc_id) {
 		struct drm_crtc *crtc = drm_crtc_find(dev, val);
 		return drm_atomic_set_crtc_for_plane(state, crtc);
@@ -737,6 +743,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
 
 	if (property == config->prop_fb_id) {
 		*val = (state->fb) ? state->fb->base.id : 0;
+	} else if (property == config->prop_fence_fd) {
+		*val = -1;
 	} else if (property == config->prop_crtc_id) {
 		*val = (state->crtc) ? state->crtc->base.id : 0;
 	} else if (property == config->prop_crtc_x) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index f85ef8c..6ed8339 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2687,6 +2687,11 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
 {
 	if (state->fb)
 		drm_framebuffer_unreference(state->fb);
+
+	if (state->fence) {
+		fence_put(state->fence);
+		state->fence = NULL;
+	}
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 55ffde5..65212ce 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1278,6 +1278,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
 
 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 		drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
+		drm_object_attach_property(&plane->base, config->prop_fence_fd, -1);
 		drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
 		drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
 		drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
@@ -1533,6 +1534,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.prop_fb_id = prop;
 
+	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
+			"FENCE_FD", -1, INT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.prop_fence_fd = prop;
+
 	prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
 			"CRTC_ID", DRM_MODE_OBJECT_CRTC);
 	if (!prop)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8cb377c..5ba3cda 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -2122,6 +2122,7 @@ struct drm_mode_config {
 	struct drm_property *prop_crtc_w;
 	struct drm_property *prop_crtc_h;
 	struct drm_property *prop_fb_id;
+	struct drm_property *prop_fence_fd;
 	struct drm_property *prop_crtc_id;
 	struct drm_property *prop_active;
 	struct drm_property *prop_mode_id;
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1379526 — Re: [RFC 4/8] drm/fence: add in-fences support

FromDaniel Vetter <daniel@ffwll.ch>
Date2016-04-15 10:10 +0200
SubjectRe: [RFC 4/8] drm/fence: add in-fences support
Message-ID<ro6Zb-8mQ-7@gated-at.bofh.it>
In reply to#1379410
On Thu, Apr 14, 2016 at 06:29:37PM -0700, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> There is now a new property called FENCE_FD attached to every plane
> state that receives the sync_file fd from userspace via the atomic commit
> IOCTL.
> 
> The fd is then translated to a fence (that may be a fence_collection
> subclass or just a normal fence) and then used by DRM to fence_wait() for
> all fences in the sync_file to signal. So it only commits when all
> framebuffers are ready to scanout.
> 
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  drivers/gpu/drm/Kconfig             | 1 +
>  drivers/gpu/drm/drm_atomic.c        | 8 ++++++++
>  drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
>  drivers/gpu/drm/drm_crtc.c          | 7 +++++++
>  include/drm/drm_crtc.h              | 1 +
>  5 files changed, 22 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index f2a74d0..3c987e3 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -12,6 +12,7 @@ menuconfig DRM
>  	select I2C
>  	select I2C_ALGOBIT
>  	select DMA_SHARED_BUFFER
> +	select SYNC_FILE
>  	help
>  	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
>  	  introduced in XFree86 4.0. If you say Y here, you need to select
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 8ee1db8..6702502 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -30,6 +30,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_mode.h>
>  #include <drm/drm_plane_helper.h>
> +#include <linux/sync_file.h>
>  
>  /**
>   * drm_atomic_state_default_release -
> @@ -680,6 +681,11 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
>  		drm_atomic_set_fb_for_plane(state, fb);
>  		if (fb)
>  			drm_framebuffer_unreference(fb);
> +	} else if (property == config->prop_fence_fd) {
> +		state->fence = sync_file_fences_get(val);
> +		if (!state->fence)
> +			return -EINVAL;
> +		fence_get(state->fence);

Yeah, this fence_get must be part of sync_file_fences_get, this code here
has a race (exercise for the reader to describe where things go wrong
here). Also, you need to explicitly filter out -1 here first I think.

Needs an atomic testcase to make sure setting FENCE_FD to -1 doesn't fall
over (since generic userspace might do this in an attempt to restore all
the state).

>  	} else if (property == config->prop_crtc_id) {
>  		struct drm_crtc *crtc = drm_crtc_find(dev, val);
>  		return drm_atomic_set_crtc_for_plane(state, crtc);
> @@ -737,6 +743,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>  
>  	if (property == config->prop_fb_id) {
>  		*val = (state->fb) ? state->fb->base.id : 0;
> +	} else if (property == config->prop_fence_fd) {
> +		*val = -1;
>  	} else if (property == config->prop_crtc_id) {
>  		*val = (state->crtc) ? state->crtc->base.id : 0;
>  	} else if (property == config->prop_crtc_x) {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index f85ef8c..6ed8339 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2687,6 +2687,11 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
>  {
>  	if (state->fb)
>  		drm_framebuffer_unreference(state->fb);
> +
> +	if (state->fence) {
> +		fence_put(state->fence);
> +		state->fence = NULL;

No need to set to NULL, we don't do that for ->fb either.

> +	}
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 55ffde5..65212ce 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1278,6 +1278,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
>  
>  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>  		drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
> +		drm_object_attach_property(&plane->base, config->prop_fence_fd, -1);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
> @@ -1533,6 +1534,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
>  		return -ENOMEM;
>  	dev->mode_config.prop_fb_id = prop;
>  
> +	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
> +			"FENCE_FD", -1, INT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	dev->mode_config.prop_fence_fd = prop;
> +
>  	prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
>  			"CRTC_ID", DRM_MODE_OBJECT_CRTC);
>  	if (!prop)
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 8cb377c..5ba3cda 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -2122,6 +2122,7 @@ struct drm_mode_config {
>  	struct drm_property *prop_crtc_w;
>  	struct drm_property *prop_crtc_h;
>  	struct drm_property *prop_fb_id;
> +	struct drm_property *prop_fence_fd;
>  	struct drm_property *prop_crtc_id;
>  	struct drm_property *prop_active;
>  	struct drm_property *prop_mode_id;
> -- 
> 2.5.5
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1380117 — Re: [RFC 4/8] drm/fence: add in-fences support

FromGustavo Padovan <gustavo@padovan.org>
Date2016-04-15 20:50 +0200
SubjectRe: [RFC 4/8] drm/fence: add in-fences support
Message-ID<rogYy-7wu-29@gated-at.bofh.it>
In reply to#1379526
2016-04-15 Daniel Vetter <daniel@ffwll.ch>:

> On Thu, Apr 14, 2016 at 06:29:37PM -0700, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > There is now a new property called FENCE_FD attached to every plane
> > state that receives the sync_file fd from userspace via the atomic commit
> > IOCTL.
> > 
> > The fd is then translated to a fence (that may be a fence_collection
> > subclass or just a normal fence) and then used by DRM to fence_wait() for
> > all fences in the sync_file to signal. So it only commits when all
> > framebuffers are ready to scanout.
> > 
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > ---
> >  drivers/gpu/drm/Kconfig             | 1 +
> >  drivers/gpu/drm/drm_atomic.c        | 8 ++++++++
> >  drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
> >  drivers/gpu/drm/drm_crtc.c          | 7 +++++++
> >  include/drm/drm_crtc.h              | 1 +
> >  5 files changed, 22 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> > index f2a74d0..3c987e3 100644
> > --- a/drivers/gpu/drm/Kconfig
> > +++ b/drivers/gpu/drm/Kconfig
> > @@ -12,6 +12,7 @@ menuconfig DRM
> >  	select I2C
> >  	select I2C_ALGOBIT
> >  	select DMA_SHARED_BUFFER
> > +	select SYNC_FILE
> >  	help
> >  	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
> >  	  introduced in XFree86 4.0. If you say Y here, you need to select
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 8ee1db8..6702502 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -30,6 +30,7 @@
> >  #include <drm/drm_atomic.h>
> >  #include <drm/drm_mode.h>
> >  #include <drm/drm_plane_helper.h>
> > +#include <linux/sync_file.h>
> >  
> >  /**
> >   * drm_atomic_state_default_release -
> > @@ -680,6 +681,11 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
> >  		drm_atomic_set_fb_for_plane(state, fb);
> >  		if (fb)
> >  			drm_framebuffer_unreference(fb);
> > +	} else if (property == config->prop_fence_fd) {
> > +		state->fence = sync_file_fences_get(val);
> > +		if (!state->fence)
> > +			return -EINVAL;
> > +		fence_get(state->fence);
> 
> Yeah, this fence_get must be part of sync_file_fences_get, this code here
> has a race (exercise for the reader to describe where things go wrong
> here). Also, you need to explicitly filter out -1 here first I think.

Right, I missed this race. Move it sync_file_fences_get() just fixes it.
I'll add the filter for -1 too and a testcase.

> 
> Needs an atomic testcase to make sure setting FENCE_FD to -1 doesn't fall
> over (since generic userspace might do this in an attempt to restore all
> the state).
> 
> >  	} else if (property == config->prop_crtc_id) {
> >  		struct drm_crtc *crtc = drm_crtc_find(dev, val);
> >  		return drm_atomic_set_crtc_for_plane(state, crtc);
> > @@ -737,6 +743,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> >  
> >  	if (property == config->prop_fb_id) {
> >  		*val = (state->fb) ? state->fb->base.id : 0;
> > +	} else if (property == config->prop_fence_fd) {
> > +		*val = -1;
> >  	} else if (property == config->prop_crtc_id) {
> >  		*val = (state->crtc) ? state->crtc->base.id : 0;
> >  	} else if (property == config->prop_crtc_x) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index f85ef8c..6ed8339 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -2687,6 +2687,11 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
> >  {
> >  	if (state->fb)
> >  		drm_framebuffer_unreference(state->fb);
> > +
> > +	if (state->fence) {
> > +		fence_put(state->fence);
> > +		state->fence = NULL;
> 
> No need to set to NULL, we don't do that for ->fb either.

Ok.

	Gustavo

[toc] | [prev] | [next] | [standalone]


#1379539 — Re: [RFC 4/8] drm/fence: add in-fences support

FromDaniel Vetter <daniel@ffwll.ch>
Date2016-04-15 10:20 +0200
SubjectRe: [RFC 4/8] drm/fence: add in-fences support
Message-ID<ro78S-8qx-19@gated-at.bofh.it>
In reply to#1379410
On Thu, Apr 14, 2016 at 06:29:37PM -0700, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> There is now a new property called FENCE_FD attached to every plane
> state that receives the sync_file fd from userspace via the atomic commit
> IOCTL.
> 
> The fd is then translated to a fence (that may be a fence_collection
> subclass or just a normal fence) and then used by DRM to fence_wait() for
> all fences in the sync_file to signal. So it only commits when all
> framebuffers are ready to scanout.
> 
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  drivers/gpu/drm/Kconfig             | 1 +
>  drivers/gpu/drm/drm_atomic.c        | 8 ++++++++
>  drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
>  drivers/gpu/drm/drm_crtc.c          | 7 +++++++
>  include/drm/drm_crtc.h              | 1 +
>  5 files changed, 22 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index f2a74d0..3c987e3 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -12,6 +12,7 @@ menuconfig DRM
>  	select I2C
>  	select I2C_ALGOBIT
>  	select DMA_SHARED_BUFFER
> +	select SYNC_FILE
>  	help
>  	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
>  	  introduced in XFree86 4.0. If you say Y here, you need to select
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 8ee1db8..6702502 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -30,6 +30,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_mode.h>
>  #include <drm/drm_plane_helper.h>
> +#include <linux/sync_file.h>
>  
>  /**
>   * drm_atomic_state_default_release -
> @@ -680,6 +681,11 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
>  		drm_atomic_set_fb_for_plane(state, fb);
>  		if (fb)
>  			drm_framebuffer_unreference(fb);
> +	} else if (property == config->prop_fence_fd) {

Need to fence_put if state->fence is non-NULL already. Could happen if
userspace sets FENCE_FD more than once (another case for your testcase I'd
say).
-Daniel

> +		state->fence = sync_file_fences_get(val);
> +		if (!state->fence)
> +			return -EINVAL;
> +		fence_get(state->fence);
>  	} else if (property == config->prop_crtc_id) {
>  		struct drm_crtc *crtc = drm_crtc_find(dev, val);
>  		return drm_atomic_set_crtc_for_plane(state, crtc);
> @@ -737,6 +743,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>  
>  	if (property == config->prop_fb_id) {
>  		*val = (state->fb) ? state->fb->base.id : 0;
> +	} else if (property == config->prop_fence_fd) {
> +		*val = -1;
>  	} else if (property == config->prop_crtc_id) {
>  		*val = (state->crtc) ? state->crtc->base.id : 0;
>  	} else if (property == config->prop_crtc_x) {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index f85ef8c..6ed8339 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2687,6 +2687,11 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
>  {
>  	if (state->fb)
>  		drm_framebuffer_unreference(state->fb);
> +
> +	if (state->fence) {
> +		fence_put(state->fence);
> +		state->fence = NULL;
> +	}
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 55ffde5..65212ce 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1278,6 +1278,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
>  
>  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>  		drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
> +		drm_object_attach_property(&plane->base, config->prop_fence_fd, -1);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
>  		drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
> @@ -1533,6 +1534,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
>  		return -ENOMEM;
>  	dev->mode_config.prop_fb_id = prop;
>  
> +	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
> +			"FENCE_FD", -1, INT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	dev->mode_config.prop_fence_fd = prop;
> +
>  	prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
>  			"CRTC_ID", DRM_MODE_OBJECT_CRTC);
>  	if (!prop)
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 8cb377c..5ba3cda 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -2122,6 +2122,7 @@ struct drm_mode_config {
>  	struct drm_property *prop_crtc_w;
>  	struct drm_property *prop_crtc_h;
>  	struct drm_property *prop_fb_id;
> +	struct drm_property *prop_fence_fd;
>  	struct drm_property *prop_crtc_id;
>  	struct drm_property *prop_active;
>  	struct drm_property *prop_mode_id;
> -- 
> 2.5.5
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1379412 — [RFC 7/8] drm/fence: create per-crtc sync_timeline

FromGustavo Padovan <gustavo@padovan.org>
Date2016-04-15 03:40 +0200
Subject[RFC 7/8] drm/fence: create per-crtc sync_timeline
Message-ID<ro0TM-3bX-17@gated-at.bofh.it>
In reply to#1379400
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Add one timeline per-crtc that will be use to handle fence signalling
to userspace via sync_files.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/drm_crtc.c | 9 +++++++++
 include/drm/drm_crtc.h     | 4 ++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 65212ce..e1204cf 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -709,6 +709,13 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 		return -ENOMEM;
 	}
 
+	crtc->timeline = sync_timeline_create(dev->driver->name, crtc->name);
+	if (!crtc->timeline) {
+		drm_mode_object_put(dev, &crtc->base);
+		kfree(crtc->name);
+		return -ENOMEM;
+	}
+
 	crtc->base.properties = &crtc->properties;
 
 	list_add_tail(&crtc->head, &config->crtc_list);
@@ -755,6 +762,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
 	if (crtc->state && crtc->funcs->atomic_destroy_state)
 		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 
+	sync_timeline_destroy(crtc->timeline);
+
 	kfree(crtc->name);
 
 	memset(crtc, 0, sizeof(*crtc));
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 5ba3cda..7934178 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -32,6 +32,7 @@
 #include <linux/fb.h>
 #include <linux/hdmi.h>
 #include <linux/media-bus-format.h>
+#include <linux/sync_timeline.h>
 #include <uapi/drm/drm_mode.h>
 #include <uapi/drm/drm_fourcc.h>
 #include <drm/drm_modeset_lock.h>
@@ -715,6 +716,7 @@ struct drm_crtc_funcs {
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
  * @state: current atomic state for this CRTC
+ * @timeline: sync timeline for fence sigalling
  * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
  * 	legacy IOCTLs
  *
@@ -771,6 +773,8 @@ struct drm_crtc {
 
 	struct drm_crtc_state *state;
 
+	struct sync_timeline *timeline;
+
 	/*
 	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
 	 * acquire context.
-- 
2.5.5

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web