diff mbox

[v11,2/3] drm/fence: add fence timeline to drm_crtc

Message ID 1479175056-28803-3-git-send-email-gustavo@padovan.org (mailing list archive)
State New, archived
Headers show

Commit Message

Gustavo Padovan Nov. 15, 2016, 1:57 a.m. UTC
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Create one timeline context for each CRTC to be able to handle out-fences
and signal them. It adds a few members to struct drm_crtc: fence_context,
where we store the context we get from fence_context_alloc(), the
fence seqno and the fence lock, that we pass in fence_init() to be
used by the fence.

v2: Comment by Daniel Stone:
	- add BUG_ON() to fence_to_crtc() macro

v3: Comment by Ville Syrjälä
	- Use more meaningful name as crtc timeline name

v4: Comments by Brian Starkey
	- Use even more meaninful name for the crtc timeline
	- add doc for timeline_name
    Comment by Daniel Vetter
	- use in-line style for comments

    - rebase after fence -> dma_fence rename

v5: Comment by Daniel Vetter
	- Add doc for drm_crtc_fence_ops

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Tested-by: Robert Foss <robert.foss@collabora.com>
---
 drivers/gpu/drm/drm_crtc.c | 31 +++++++++++++++++++++++++++++++
 include/drm/drm_crtc.h     | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

Comments

Chris Wilson Nov. 15, 2016, 8:25 a.m. UTC | #1
On Tue, Nov 15, 2016 at 10:57:35AM +0900, Gustavo Padovan wrote:
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 11780a9..0870de1 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -32,6 +32,8 @@
>  #include <linux/fb.h>
>  #include <linux/hdmi.h>
>  #include <linux/media-bus-format.h>
> +#include <linux/srcu.h>
> +#include <linux/dma-fence.h>
>  #include <uapi/drm/drm_mode.h>
>  #include <uapi/drm/drm_fourcc.h>
>  #include <drm/drm_modeset_lock.h>
> @@ -739,9 +741,52 @@ struct drm_crtc {
>  	 */
>  	struct drm_crtc_crc crc;
>  #endif
> +
> +	/**
> +	 * @fence_context:
> +	 *
> +	 * timeline context used for fence operations.
> +	 */
> +	unsigned int fence_context;
> +
> +	/**
> +	 * @fence_lock:
> +	 *
> +	 * spinlock to protect the fences in the fence_context.
> +	 */
> +
> +	spinlock_t fence_lock;
> +	/**
> +	 * @fence_seqno:
> +	 *
> +	 * Seqno variable used as monotonic counter for the fences
> +	 * created on the CRTC's timeline.
> +	 */
> +	unsigned long fence_seqno;
> +
> +	/**
> +	 * @timeline_name:
> +	 *
> +	 * The name of the CRTC's fence timeline.
> +	 */
> +	char timeline_name[32];
>  };
>  
>  /**
> + * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
> + *
> + * It contains the dma_fence_ops that should be called by the dma_fence
> + * code. CRTC core should use this ops when initializing fences.
> + */
> +extern const struct dma_fence_ops drm_crtc_fence_ops;
> +
> +static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
> +{
> +	BUG_ON(fence->ops != &drm_crtc_fence_ops);
> +	return container_of(fence->lock, struct drm_crtc, fence_lock);
> +}

If you are planning to export this for use by drivers, you are missing
the EXPORT_SYMBOL(drm_crtc_fence_ops).
-Chris
Chris Wilson Nov. 15, 2016, 8:39 a.m. UTC | #2
On Tue, Nov 15, 2016 at 08:25:55AM +0000, Chris Wilson wrote:
> On Tue, Nov 15, 2016 at 10:57:35AM +0900, Gustavo Padovan wrote:
> >  /**
> > + * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
> > + *
> > + * It contains the dma_fence_ops that should be called by the dma_fence
> > + * code. CRTC core should use this ops when initializing fences.
> > + */
> > +extern const struct dma_fence_ops drm_crtc_fence_ops;
> > +
> > +static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
> > +{
> > +	BUG_ON(fence->ops != &drm_crtc_fence_ops);
> > +	return container_of(fence->lock, struct drm_crtc, fence_lock);
> > +}
> 
> If you are planning to export this for use by drivers, you are missing
> the EXPORT_SYMBOL(drm_crtc_fence_ops).

My suggestion would not to have the BUG_ON() here (saves one
checkpatch.pl complaint in exchange for a slightly more mysterious GPF).
Also please consider calling this dma_fence_to_crtc() as otherwise it
conflicts with those with plans to use struct fences on their
crtc/states.
-Chris
Gustavo Padovan Nov. 15, 2016, 8:42 a.m. UTC | #3
2016-11-15 Chris Wilson <chris@chris-wilson.co.uk>:

> On Tue, Nov 15, 2016 at 10:57:35AM +0900, Gustavo Padovan wrote:
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index 11780a9..0870de1 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -32,6 +32,8 @@
> >  #include <linux/fb.h>
> >  #include <linux/hdmi.h>
> >  #include <linux/media-bus-format.h>
> > +#include <linux/srcu.h>
> > +#include <linux/dma-fence.h>
> >  #include <uapi/drm/drm_mode.h>
> >  #include <uapi/drm/drm_fourcc.h>
> >  #include <drm/drm_modeset_lock.h>
> > @@ -739,9 +741,52 @@ struct drm_crtc {
> >  	 */
> >  	struct drm_crtc_crc crc;
> >  #endif
> > +
> > +	/**
> > +	 * @fence_context:
> > +	 *
> > +	 * timeline context used for fence operations.
> > +	 */
> > +	unsigned int fence_context;
> > +
> > +	/**
> > +	 * @fence_lock:
> > +	 *
> > +	 * spinlock to protect the fences in the fence_context.
> > +	 */
> > +
> > +	spinlock_t fence_lock;
> > +	/**
> > +	 * @fence_seqno:
> > +	 *
> > +	 * Seqno variable used as monotonic counter for the fences
> > +	 * created on the CRTC's timeline.
> > +	 */
> > +	unsigned long fence_seqno;
> > +
> > +	/**
> > +	 * @timeline_name:
> > +	 *
> > +	 * The name of the CRTC's fence timeline.
> > +	 */
> > +	char timeline_name[32];
> >  };
> >  
> >  /**
> > + * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
> > + *
> > + * It contains the dma_fence_ops that should be called by the dma_fence
> > + * code. CRTC core should use this ops when initializing fences.
> > + */
> > +extern const struct dma_fence_ops drm_crtc_fence_ops;
> > +
> > +static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
> > +{
> > +	BUG_ON(fence->ops != &drm_crtc_fence_ops);
> > +	return container_of(fence->lock, struct drm_crtc, fence_lock);
> > +}
> 
> If you are planning to export this for use by drivers, you are missing
> the EXPORT_SYMBOL(drm_crtc_fence_ops).

Drivers should not be using this, at least for now.

Gustavo
Daniel Vetter Nov. 15, 2016, 8:52 a.m. UTC | #4
On Tue, Nov 15, 2016 at 05:42:35PM +0900, Gustavo Padovan wrote:
> 2016-11-15 Chris Wilson <chris@chris-wilson.co.uk>:
> 
> > On Tue, Nov 15, 2016 at 10:57:35AM +0900, Gustavo Padovan wrote:
> > > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > > index 11780a9..0870de1 100644
> > > --- a/include/drm/drm_crtc.h
> > > +++ b/include/drm/drm_crtc.h
> > > @@ -32,6 +32,8 @@
> > >  #include <linux/fb.h>
> > >  #include <linux/hdmi.h>
> > >  #include <linux/media-bus-format.h>
> > > +#include <linux/srcu.h>
> > > +#include <linux/dma-fence.h>
> > >  #include <uapi/drm/drm_mode.h>
> > >  #include <uapi/drm/drm_fourcc.h>
> > >  #include <drm/drm_modeset_lock.h>
> > > @@ -739,9 +741,52 @@ struct drm_crtc {
> > >  	 */
> > >  	struct drm_crtc_crc crc;
> > >  #endif
> > > +
> > > +	/**
> > > +	 * @fence_context:
> > > +	 *
> > > +	 * timeline context used for fence operations.
> > > +	 */
> > > +	unsigned int fence_context;
> > > +
> > > +	/**
> > > +	 * @fence_lock:
> > > +	 *
> > > +	 * spinlock to protect the fences in the fence_context.
> > > +	 */
> > > +
> > > +	spinlock_t fence_lock;
> > > +	/**
> > > +	 * @fence_seqno:
> > > +	 *
> > > +	 * Seqno variable used as monotonic counter for the fences
> > > +	 * created on the CRTC's timeline.
> > > +	 */
> > > +	unsigned long fence_seqno;
> > > +
> > > +	/**
> > > +	 * @timeline_name:
> > > +	 *
> > > +	 * The name of the CRTC's fence timeline.
> > > +	 */
> > > +	char timeline_name[32];
> > >  };
> > >  
> > >  /**
> > > + * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
> > > + *
> > > + * It contains the dma_fence_ops that should be called by the dma_fence
> > > + * code. CRTC core should use this ops when initializing fences.
> > > + */
> > > +extern const struct dma_fence_ops drm_crtc_fence_ops;
> > > +
> > > +static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
> > > +{
> > > +	BUG_ON(fence->ops != &drm_crtc_fence_ops);
> > > +	return container_of(fence->lock, struct drm_crtc, fence_lock);
> > > +}
> > 
> > If you are planning to export this for use by drivers, you are missing
> > the EXPORT_SYMBOL(drm_crtc_fence_ops).
> 
> Drivers should not be using this, at least for now.

Then please put it into drm_crtc_internal.h. We should only allow drivers
to use functions they're supposed to be using, and hide everything else.
-Daniel
Chris Wilson Nov. 15, 2016, 8:55 a.m. UTC | #5
On Tue, Nov 15, 2016 at 05:42:35PM +0900, Gustavo Padovan wrote:
> 2016-11-15 Chris Wilson <chris@chris-wilson.co.uk>:
> 
> > On Tue, Nov 15, 2016 at 10:57:35AM +0900, Gustavo Padovan wrote:
> > > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > > index 11780a9..0870de1 100644
> > > --- a/include/drm/drm_crtc.h
> > > +++ b/include/drm/drm_crtc.h
> > > @@ -32,6 +32,8 @@
> > >  #include <linux/fb.h>
> > >  #include <linux/hdmi.h>
> > >  #include <linux/media-bus-format.h>
> > > +#include <linux/srcu.h>
> > > +#include <linux/dma-fence.h>
> > >  #include <uapi/drm/drm_mode.h>
> > >  #include <uapi/drm/drm_fourcc.h>
> > >  #include <drm/drm_modeset_lock.h>
> > > @@ -739,9 +741,52 @@ struct drm_crtc {
> > >  	 */
> > >  	struct drm_crtc_crc crc;
> > >  #endif
> > > +
> > > +	/**
> > > +	 * @fence_context:
> > > +	 *
> > > +	 * timeline context used for fence operations.
> > > +	 */
> > > +	unsigned int fence_context;
> > > +
> > > +	/**
> > > +	 * @fence_lock:
> > > +	 *
> > > +	 * spinlock to protect the fences in the fence_context.
> > > +	 */
> > > +
> > > +	spinlock_t fence_lock;
> > > +	/**
> > > +	 * @fence_seqno:
> > > +	 *
> > > +	 * Seqno variable used as monotonic counter for the fences
> > > +	 * created on the CRTC's timeline.
> > > +	 */
> > > +	unsigned long fence_seqno;
> > > +
> > > +	/**
> > > +	 * @timeline_name:
> > > +	 *
> > > +	 * The name of the CRTC's fence timeline.
> > > +	 */
> > > +	char timeline_name[32];
> > >  };
> > >  
> > >  /**
> > > + * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
> > > + *
> > > + * It contains the dma_fence_ops that should be called by the dma_fence
> > > + * code. CRTC core should use this ops when initializing fences.
> > > + */
> > > +extern const struct dma_fence_ops drm_crtc_fence_ops;
> > > +
> > > +static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
> > > +{
> > > +	BUG_ON(fence->ops != &drm_crtc_fence_ops);
> > > +	return container_of(fence->lock, struct drm_crtc, fence_lock);
> > > +}
> > 
> > If you are planning to export this for use by drivers, you are missing
> > the EXPORT_SYMBOL(drm_crtc_fence_ops).
> 
> Drivers should not be using this, at least for now.

You've put into a central header, with kerneldoc on the ops, just inviting
people to use it...
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f6d1b38..20ddaff 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -165,6 +165,32 @@  static void drm_crtc_crc_fini(struct drm_crtc *crtc)
 #endif
 }
 
+static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
+{
+	struct drm_crtc *crtc = fence_to_crtc(fence);
+
+	return crtc->dev->driver->name;
+}
+
+static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
+{
+	struct drm_crtc *crtc = fence_to_crtc(fence);
+
+	return crtc->timeline_name;
+}
+
+static bool drm_crtc_fence_enable_signaling(struct dma_fence *fence)
+{
+	return true;
+}
+
+const struct dma_fence_ops drm_crtc_fence_ops = {
+	.get_driver_name = drm_crtc_fence_get_driver_name,
+	.get_timeline_name = drm_crtc_fence_get_timeline_name,
+	.enable_signaling = drm_crtc_fence_enable_signaling,
+	.wait = dma_fence_default_wait,
+};
+
 /**
  * drm_crtc_init_with_planes - Initialise a new CRTC object with
  *    specified primary and cursor planes.
@@ -222,6 +248,11 @@  int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 		return -ENOMEM;
 	}
 
+	crtc->fence_context = dma_fence_context_alloc(1);
+	spin_lock_init(&crtc->fence_lock);
+	snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
+		 "CRTC:%d-%s", crtc->base.id, crtc->name);
+
 	crtc->base.properties = &crtc->properties;
 
 	list_add_tail(&crtc->head, &config->crtc_list);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 11780a9..0870de1 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -32,6 +32,8 @@ 
 #include <linux/fb.h>
 #include <linux/hdmi.h>
 #include <linux/media-bus-format.h>
+#include <linux/srcu.h>
+#include <linux/dma-fence.h>
 #include <uapi/drm/drm_mode.h>
 #include <uapi/drm/drm_fourcc.h>
 #include <drm/drm_modeset_lock.h>
@@ -739,9 +741,52 @@  struct drm_crtc {
 	 */
 	struct drm_crtc_crc crc;
 #endif
+
+	/**
+	 * @fence_context:
+	 *
+	 * timeline context used for fence operations.
+	 */
+	unsigned int fence_context;
+
+	/**
+	 * @fence_lock:
+	 *
+	 * spinlock to protect the fences in the fence_context.
+	 */
+
+	spinlock_t fence_lock;
+	/**
+	 * @fence_seqno:
+	 *
+	 * Seqno variable used as monotonic counter for the fences
+	 * created on the CRTC's timeline.
+	 */
+	unsigned long fence_seqno;
+
+	/**
+	 * @timeline_name:
+	 *
+	 * The name of the CRTC's fence timeline.
+	 */
+	char timeline_name[32];
 };
 
 /**
+ * dma_crtc_fence_ops - fence ops for the drm_crtc timeline
+ *
+ * It contains the dma_fence_ops that should be called by the dma_fence
+ * code. CRTC core should use this ops when initializing fences.
+ */
+extern const struct dma_fence_ops drm_crtc_fence_ops;
+
+static inline struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
+{
+	BUG_ON(fence->ops != &drm_crtc_fence_ops);
+	return container_of(fence->lock, struct drm_crtc, fence_lock);
+}
+
+/**
  * struct drm_mode_set - new values for a CRTC config change
  * @fb: framebuffer to use for new config
  * @crtc: CRTC whose configuration we're about to change