public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Gustavo Padovan <gustavo@padovan.org>
To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	"Daniel Stone" <daniels@collabora.com>,
	"Arve Hjønnevåg" <arve@android.com>,
	"Riley Andrews" <riandrews@android.com>,
	"Rob Clark" <robdclark@gmail.com>,
	"Greg Hackmann" <ghackmann@google.com>,
	"John Harrison" <John.C.Harrison@Intel.com>,
	laurent.pinchart@ideasonboard.com, seanpaul@google.com,
	marcheu@google.com, m.chehab@samsung.com,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Gustavo Padovan" <gustavo.padovan@collabora.co.uk>
Subject: Re: [RFC 8/8] drm/fence: add out-fences support
Date: Fri, 15 Apr 2016 12:15:48 -0700	[thread overview]
Message-ID: <20160415191548.GF23954@joana> (raw)
In-Reply-To: <20160415081808.GU2510@phenom.ffwll.local>

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

      reply	other threads:[~2016-04-15 19:15 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-15  1:29 [RFC 0/8] drm: explicit fencing support Gustavo Padovan
2016-04-15  1:29 ` [RFC 1/8] dma-buf/fence: add fence_collection fences Gustavo Padovan
2016-04-15  8:02   ` Daniel Vetter
2016-04-15  9:03     ` Christian König
2016-04-15 11:44       ` Daniel Vetter
2016-04-15 18:29         ` Gustavo Padovan
2016-04-15 19:23           ` Daniel Vetter
2016-04-15 18:27       ` Gustavo Padovan
2016-04-15 19:25         ` Daniel Vetter
2016-05-18  7:07           ` Christian König
2016-05-18 14:30             ` Gustavo Padovan
2016-04-15  1:29 ` [RFC 2/8] dma-buf/sync_file: add sync_file_fences_get() Gustavo Padovan
2016-04-15  7:56   ` Daniel Vetter
2016-04-15  1:29 ` [RFC 3/8] drm/fence: allow fence waiting to be interrupted by userspace Gustavo Padovan
2016-04-15  7:47   ` Daniel Vetter
2016-04-15  1:29 ` [RFC 4/8] drm/fence: add in-fences support Gustavo Padovan
2016-04-15  8:05   ` Daniel Vetter
2016-04-15 18:40     ` Gustavo Padovan
2016-04-15  8:11   ` Daniel Vetter
2016-04-15  1:29 ` [RFC 5/8] drm/fence: add fence to drm_pending_event Gustavo Padovan
2016-04-15  8:09   ` Daniel Vetter
2016-04-15 18:59     ` Gustavo Padovan
2016-04-15 19:31       ` Daniel Vetter
2016-04-15  1:29 ` [RFC 6/8] drm/fence: create DRM_MODE_ATOMIC_OUT_FENCE flag Gustavo Padovan
2016-04-15  1:40   ` Rob Clark
2016-04-15 19:05     ` Gustavo Padovan
2016-04-15  1:29 ` [RFC 7/8] drm/fence: create per-crtc sync_timeline Gustavo Padovan
2016-04-15  1:29 ` [RFC 8/8] drm/fence: add out-fences support Gustavo Padovan
2016-04-15  8:18   ` Daniel Vetter
2016-04-15 19:15     ` Gustavo Padovan [this message]

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=20160415191548.GF23954@joana \
    --to=gustavo@padovan.org \
    --cc=John.C.Harrison@Intel.com \
    --cc=arve@android.com \
    --cc=daniels@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ghackmann@google.com \
    --cc=gustavo.padovan@collabora.co.uk \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.chehab@samsung.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=marcheu@google.com \
    --cc=riandrews@android.com \
    --cc=robdclark@gmail.com \
    --cc=seanpaul@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox