All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] some stuff, and then connector_list locking
@ 2016-12-13 23:08 Daniel Vetter
  2016-12-13 23:08 ` [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls Daniel Vetter
                   ` (12 more replies)
  0 siblings, 13 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

I finally clued up about connector_list locking and here is a fix for that
little issue that's not totally horribly nightmare fuel. As usual I ended up
reading too much other code, so there's a few random bits in here too. Some of
the earlier randomness I submitted already and it's in drm-misc by now.

Anyway, core is all fixed up (and lost 2 FIXME and all unprotected
connector_list walkers). Helpers are converted (again all of it), plus i915 as
an example. Well, not all: The ones in intel_display.c look like (at least some)
that they should instead walk the connectors in some atomic update. An I just
couldn't be bothered to change the code in intel_sdvo.c since meh. Otherwise all
the existing connector_list walkers (whether drm_for_each_connector,
for_each_intel_connector or raw walk) are now all connected.

Seems to not immediately blow up, and even after a few nights of sleep I still
think this is correct.

Kerneldoc is also polished and updated.

Feedback and review highly welcome.

Cheers, Daniel

Daniel Vetter (13):
  drm/irq: drm_legacy_ prefix for legacy ioctls
  drm: Move atomic debugfs functions into drm_crtc_internal.h
  drm/radeon|amdgpu: Remove redundant num_connectors check
  drm: Drop locking cargo-cult from drm_mode_config_init
  drm: locking&new iterators for connector_list
  drm: Convert all helpers to drm_connector_list_iter
  drm: Clean up connectors by unreferencing them
  drm: prevent double-(un)registration for connectors
  drm: Tighten locking in drm_mode_getconnector
  drm/i915: Use drm_connector_list_iter in debugfs
  drm/i915: use drm_connector_list_iter in intel_hotplug.c
  drm/i915: use drm_connector_list_iter in intel_opregion.c
  drm/i915: Make intel_get_pipe_from_connector atomic

 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |   6 +-
 drivers/gpu/drm/drm_atomic.c            |  14 +-
 drivers/gpu/drm/drm_atomic_helper.c     |  39 ++++--
 drivers/gpu/drm/drm_connector.c         | 226 ++++++++++++++++++++++----------
 drivers/gpu/drm/drm_crtc_helper.c       |  49 +++++--
 drivers/gpu/drm/drm_crtc_internal.h     |   6 +
 drivers/gpu/drm/drm_debugfs.c           |   1 +
 drivers/gpu/drm/drm_encoder.c           |   6 +-
 drivers/gpu/drm/drm_fb_helper.c         |  12 +-
 drivers/gpu/drm/drm_internal.h          |   8 +-
 drivers/gpu/drm/drm_ioctl.c             |   4 +-
 drivers/gpu/drm/drm_irq.c               |  30 +----
 drivers/gpu/drm/drm_mode_config.c       |  51 +++----
 drivers/gpu/drm/drm_modeset_helper.c    |   2 +
 drivers/gpu/drm/drm_plane_helper.c      |   5 +-
 drivers/gpu/drm/drm_probe_helper.c      |  18 ++-
 drivers/gpu/drm/i915/i915_debugfs.c     |  62 ++++++---
 drivers/gpu/drm/i915/i915_drv.h         |   3 +
 drivers/gpu/drm/i915/intel_display.c    |   5 +-
 drivers/gpu/drm/i915/intel_hotplug.c    |  28 ++--
 drivers/gpu/drm/i915/intel_opregion.c   |  15 ++-
 drivers/gpu/drm/radeon/radeon_irq_kms.c |  12 +-
 include/drm/drm_atomic.h                |   6 -
 include/drm/drm_connector.h             |  73 ++++++++++-
 include/drm/drm_mode_config.h           |  12 +-
 25 files changed, 466 insertions(+), 227 deletions(-)

-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-16 15:02   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h Daniel Vetter
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Spotted while auditing our ioctl table. Also nuke the
not-really-kerneldoc comments, we don't document internals and
definitely don't want to mislead people with the old dragons.

I think with this all the legacy ioctls now have proper drm_legacy_
prefixes.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_internal.h |  8 ++++----
 drivers/gpu/drm/drm_ioctl.c    |  4 ++--
 drivers/gpu/drm/drm_irq.c      | 30 ++++--------------------------
 3 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index db80ec860e33..a6213f814345 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -58,10 +58,10 @@ extern unsigned int drm_timestamp_monotonic;
 /* IOCTLS */
 int drm_wait_vblank(struct drm_device *dev, void *data,
 		    struct drm_file *filp);
-int drm_control(struct drm_device *dev, void *data,
-		struct drm_file *file_priv);
-int drm_modeset_ctl(struct drm_device *dev, void *data,
-		    struct drm_file *file_priv);
+int drm_legacy_irq_control(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
+int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
 
 /* drm_auth.c */
 int drm_getmagic(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index e21a18ac968e..a16b6fbd1004 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -581,7 +581,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 
 #if IS_ENABLED(CONFIG_AGP)
 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -599,7 +599,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 
 	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_MASTER|DRM_UNLOCKED),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl, 0),
 
 	DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 273625a85036..feb091310ffe 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -579,19 +579,8 @@ int drm_irq_uninstall(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_irq_uninstall);
 
-/*
- * IRQ control ioctl.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_control structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls irq_install() or irq_uninstall() according to \p arg.
- */
-int drm_control(struct drm_device *dev, void *data,
-		struct drm_file *file_priv)
+int drm_legacy_irq_control(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
 {
 	struct drm_control *ctl = data;
 	int ret = 0, irq;
@@ -1442,19 +1431,8 @@ static void drm_legacy_vblank_post_modeset(struct drm_device *dev,
 	}
 }
 
-/*
- * drm_modeset_ctl - handle vblank event counter changes across mode switch
- * @DRM_IOCTL_ARGS: standard ioctl arguments
- *
- * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
- * ioctls around modesetting so that any lost vblank events are accounted for.
- *
- * Generally the counter will reset across mode sets.  If interrupts are
- * enabled around this call, we don't have to do anything since the counter
- * will have already been incremented.
- */
-int drm_modeset_ctl(struct drm_device *dev, void *data,
-		    struct drm_file *file_priv)
+int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
 {
 	struct drm_modeset_ctl *modeset = data;
 	unsigned int pipe;
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
  2016-12-13 23:08 ` [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-16 15:02   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check Daniel Vetter
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This is not driver interface stuff.

Fixes: 6559c901cb48 ("drm/atomic: add debugfs file to dump out atomic state")
Cc: Rob Clark <robdclark@gmail.com>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_crtc_internal.h | 6 ++++++
 drivers/gpu/drm/drm_debugfs.c       | 1 +
 include/drm/drm_atomic.h            | 6 ------
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index cdf6860c9d22..0b8454c7dc00 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -174,6 +174,12 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
 			   void *data, struct drm_file *file_priv);
 
 /* drm_atomic.c */
+#ifdef CONFIG_DEBUG_FS
+struct drm_minor;
+int drm_atomic_debugfs_init(struct drm_minor *minor);
+int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
+#endif
+
 int drm_atomic_get_property(struct drm_mode_object *obj,
 			    struct drm_property *property, uint64_t *val);
 int drm_mode_atomic_ioctl(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 2e3e46a53805..37fd612d57a6 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -38,6 +38,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_atomic.h>
 #include "drm_internal.h"
+#include "drm_crtc_internal.h"
 
 #if defined(CONFIG_DEBUG_FS)
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 01d02e1935b1..c35b4aba36b6 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -379,12 +379,6 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 
 void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
 
-#ifdef CONFIG_DEBUG_FS
-struct drm_minor;
-int drm_atomic_debugfs_init(struct drm_minor *minor);
-int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
-#endif
-
 #define for_each_connector_in_state(__state, connector, connector_state, __i) \
 	for ((__i) = 0;							\
 	     (__i) < (__state)->num_connector &&				\
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
  2016-12-13 23:08 ` [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls Daniel Vetter
  2016-12-13 23:08 ` [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-14 16:59   ` Alex Deucher
  2016-12-13 23:08 ` [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init Daniel Vetter
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development
  Cc: Alex Deucher, Daniel Vetter, Intel Graphics Development, Daniel Vetter

The list walk will shortcircuit anyway.

Cc: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |  6 ++----
 drivers/gpu/drm/radeon/radeon_irq_kms.c | 12 ++++--------
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index fb902932f571..e63ece049b05 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -61,10 +61,8 @@ static void amdgpu_hotplug_work_func(struct work_struct *work)
 	struct drm_connector *connector;
 
 	mutex_lock(&mode_config->mutex);
-	if (mode_config->num_connector) {
-		list_for_each_entry(connector, &mode_config->connector_list, head)
-			amdgpu_connector_hotplug(connector);
-	}
+	list_for_each_entry(connector, &mode_config->connector_list, head)
+		amdgpu_connector_hotplug(connector);
 	mutex_unlock(&mode_config->mutex);
 	/* Just fire off a uevent and let userspace tell us what to do */
 	drm_helper_hpd_irq_event(dev);
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index c084cadcbf21..1b7528df7f7f 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -85,10 +85,8 @@ static void radeon_hotplug_work_func(struct work_struct *work)
 		return;
 
 	mutex_lock(&mode_config->mutex);
-	if (mode_config->num_connector) {
-		list_for_each_entry(connector, &mode_config->connector_list, head)
-			radeon_connector_hotplug(connector);
-	}
+	list_for_each_entry(connector, &mode_config->connector_list, head)
+		radeon_connector_hotplug(connector);
 	mutex_unlock(&mode_config->mutex);
 	/* Just fire off a uevent and let userspace tell us what to do */
 	drm_helper_hpd_irq_event(dev);
@@ -103,10 +101,8 @@ static void radeon_dp_work_func(struct work_struct *work)
 	struct drm_connector *connector;
 
 	/* this should take a mutex */
-	if (mode_config->num_connector) {
-		list_for_each_entry(connector, &mode_config->connector_list, head)
-			radeon_connector_hotplug(connector);
-	}
+	list_for_each_entry(connector, &mode_config->connector_list, head)
+		radeon_connector_hotplug(connector);
 }
 /**
  * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (2 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-14  9:23   ` [Intel-gfx] " Daniel Stone
  2016-12-16 15:03   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
                   ` (8 subsequent siblings)
  12 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This is single-threaded setup code, no need for locks. And anyway,
all properties need to be set up before the driver is registered
anyway, they can't be hot-added.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_mode_config.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index b1e8bbceaf39..85a25fd9eff8 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -374,9 +374,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	idr_init(&dev->mode_config.tile_idr);
 	ida_init(&dev->mode_config.connector_ida);
 
-	drm_modeset_lock_all(dev);
 	drm_mode_create_standard_properties(dev);
-	drm_modeset_unlock_all(dev);
 
 	/* Just to be sure */
 	dev->mode_config.num_fb = 0;
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (3 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-14  8:35   ` Chris Wilson
                     ` (2 more replies)
  2016-12-13 23:08 ` [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter Daniel Vetter
                   ` (7 subsequent siblings)
  12 siblings, 3 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

The requirements for connector_list locking are a bit tricky:
- We need to be able to jump over zombie conectors (i.e. with refcount
  == 0, but not yet removed from the list). If instead we require that
  there's no zombies on the list then the final kref_put must happen
  under the list protection lock, which means that locking context
  leaks all over the place. Not pretty - better to deal with zombies
  and wrap the locking just around the list_del in the destructor.

- When we walk the list we must _not_ hold the connector list lock. We
  walk the connector list at an absolutely massive amounts of places,
  if all those places can't ever call drm_connector_unreference the
  code would get unecessarily complicated.

- connector_list needs it own lock, again too many places that walk it
  that we could reuse e.g. mode_config.mutex without resulting in
  inversions.

- Lots of code uses these loops to look-up a connector, i.e. they want
  to be able to call drm_connector_reference. But on the other hand we
  want connectors to stay on that list until they're dead (i.e.
  connector_list can't hold a full reference), which means despite the
  "can't hold lock for the loop body" rule we need to make sure a
  connector doesn't suddenly become a zombie.

At first Dave&I discussed various horror-show approaches using srcu,
but turns out it's fairly easy:

- For the loop body we always hold an additional reference to the
  current connector. That means it can't zombify, and it also means
  it'll stay on the list, which means we can use it as our iterator to
  find the next connector.

- When we try to find the next connector we only have to jump over
  zombies. To make sure we don't chase bad pointers that entire loop
  is protected with the new connect_list_lock spinlock. And because we
  know that we're starting out with a non-zombie (need to drop our
  reference for the old connector only after we have our new one),
  we're guranteed to still be on the connector_list and either find
  the next non-zombie or complete the iteration.

- Only downside is that we need to make sure that the temporary
  reference for the loop body doesn't leak. iter_get/put() functions +
  lockdep make sure that's the case.

- To avoid a flag day the new iterator macro has an _iter postfix. We
  can rename it back once all the users of the unsafe version are gone
  (there's about 100 list walkers for the connector_list).

For now this patch only converts all the list walking in the core,
leaving helpers and drivers for later patches. The nice thing is that
we can now finally remove 2 FIXME comments from the
register/unregister functions.

v2:
- use irqsafe spinlocks, so that we can use this in drm_state_dump
  too.
- nuke drm_modeset_lock_all from drm_connector_init, now entirely
  cargo-culted nonsense.

v3:
- do {} while (!kref_get_unless_zero), makes for a tidier loop (Dave).
- pretty kerneldoc
- add EXPORT_SYMBOL, helpers&drivers are supposed to use this.

v4: Change lockdep annotations to only check whether we release the
iter fake lock again (i.e. make sure that iter_put is called), but
not check any locking dependecies itself. That seams to require a
recursive read lock in trylock mode.

Cc: Dave Airlie <airlied@gmail.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c      |  14 ++++-
 drivers/gpu/drm/drm_connector.c   | 116 ++++++++++++++++++++++++++++++++------
 drivers/gpu/drm/drm_encoder.c     |   6 +-
 drivers/gpu/drm/drm_mode_config.c |  34 +++++------
 include/drm/drm_connector.h       |  38 +++++++++++++
 include/drm/drm_mode_config.h     |  12 +++-
 6 files changed, 177 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 60697482b94c..b23b4abd67be 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1417,6 +1417,7 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
 	struct drm_mode_config *config = &state->dev->mode_config;
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
+	struct drm_connector_list_iter conn_iter;
 	int ret;
 
 	ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
@@ -1430,14 +1431,18 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
 	 * Changed connectors are already in @state, so only need to look at the
 	 * current configuration.
 	 */
-	drm_for_each_connector(connector, state->dev) {
+	drm_connector_list_iter_get(state->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->state->crtc != crtc)
 			continue;
 
 		conn_state = drm_atomic_get_connector_state(state, connector);
-		if (IS_ERR(conn_state))
+		if (IS_ERR(conn_state)) {
+			drm_connector_list_iter_put(&conn_iter);
 			return PTR_ERR(conn_state);
+		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return 0;
 }
@@ -1692,6 +1697,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
 	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
 		return;
@@ -1702,8 +1708,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
 	list_for_each_entry(crtc, &config->crtc_list, head)
 		drm_atomic_crtc_print_state(p, crtc->state);
 
-	list_for_each_entry(connector, &config->connector_list, head)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		drm_atomic_connector_print_state(p, connector->state);
+	drm_connector_list_iter_put(&conn_iter);
 }
 EXPORT_SYMBOL(drm_state_dump);
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5a4526289392..b33334e09b00 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -189,13 +189,11 @@ int drm_connector_init(struct drm_device *dev,
 	struct ida *connector_ida =
 		&drm_connector_enum_list[connector_type].ida;
 
-	drm_modeset_lock_all(dev);
-
 	ret = drm_mode_object_get_reg(dev, &connector->base,
 				      DRM_MODE_OBJECT_CONNECTOR,
 				      false, drm_connector_free);
 	if (ret)
-		goto out_unlock;
+		return ret;
 
 	connector->base.properties = &connector->properties;
 	connector->dev = dev;
@@ -232,8 +230,10 @@ int drm_connector_init(struct drm_device *dev,
 
 	/* We should add connectors at the end to avoid upsetting the connector
 	 * index too much. */
+	spin_lock_irq(&config->connector_list_lock);
 	list_add_tail(&connector->head, &config->connector_list);
 	config->num_connector++;
+	spin_unlock_irq(&config->connector_list_lock);
 
 	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
 		drm_object_attach_property(&connector->base,
@@ -258,9 +258,6 @@ int drm_connector_init(struct drm_device *dev,
 	if (ret)
 		drm_mode_object_unregister(dev, &connector->base);
 
-out_unlock:
-	drm_modeset_unlock_all(dev);
-
 	return ret;
 }
 EXPORT_SYMBOL(drm_connector_init);
@@ -351,8 +348,10 @@ void drm_connector_cleanup(struct drm_connector *connector)
 	drm_mode_object_unregister(dev, &connector->base);
 	kfree(connector->name);
 	connector->name = NULL;
+	spin_lock_irq(&dev->mode_config.connector_list_lock);
 	list_del(&connector->head);
 	dev->mode_config.num_connector--;
+	spin_unlock_irq(&dev->mode_config.connector_list_lock);
 
 	WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
 	if (connector->state && connector->funcs->atomic_destroy_state)
@@ -431,30 +430,30 @@ EXPORT_SYMBOL(drm_connector_unregister);
 void drm_connector_unregister_all(struct drm_device *dev)
 {
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
-	/* FIXME: taking the mode config mutex ends up in a clash with sysfs */
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		drm_connector_unregister(connector);
+	drm_connector_list_iter_put(&conn_iter);
 }
 
 int drm_connector_register_all(struct drm_device *dev)
 {
 	struct drm_connector *connector;
-	int ret;
+	struct drm_connector_list_iter conn_iter;
+	int ret = 0;
 
-	/* FIXME: taking the mode config mutex ends up in a clash with
-	 * fbcon/backlight registration */
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		ret = drm_connector_register(connector);
 		if (ret)
-			goto err;
+			break;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
-	return 0;
-
-err:
-	mutex_unlock(&dev->mode_config.mutex);
-	drm_connector_unregister_all(dev);
+	if (ret)
+		drm_connector_unregister_all(dev);
 	return ret;
 }
 
@@ -476,6 +475,87 @@ const char *drm_get_connector_status_name(enum drm_connector_status status)
 }
 EXPORT_SYMBOL(drm_get_connector_status_name);
 
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map connector_list_iter_dep_map = {
+	.name = "drm_connector_list_iter"
+};
+#endif
+
+/**
+ * drm_connector_list_iter_get - initialize a connector_list iterator
+ * @dev: DRM device
+ * @iter: connector_list iterator
+ *
+ * Sets @iter up to walk the connector list in &drm_mode_config of @dev. @iter
+ * must always be cleaned up again by calling drm_connector_list_iter_put().
+ * Iteration itself happens using drm_connector_list_iter_next() or
+ * drm_for_each_connector_iter().
+ */
+void drm_connector_list_iter_get(struct drm_device *dev,
+				 struct drm_connector_list_iter *iter)
+{
+	iter->dev = dev;
+	iter->conn = NULL;
+	lock_acquire_shared_recursive(&connector_list_iter_dep_map, 0, 1, NULL, _RET_IP_);
+}
+EXPORT_SYMBOL(drm_connector_list_iter_get);
+
+/**
+ * drm_connector_list_iter_next - return next connector
+ * @iter: connectr_list iterator
+ *
+ * Returns the next connector for @iter, or NULL when the list walk has
+ * completed.
+ */
+struct drm_connector *
+drm_connector_list_iter_next(struct drm_connector_list_iter *iter)
+{
+	struct drm_connector *old_conn = iter->conn;
+	struct drm_mode_config *config = &iter->dev->mode_config;
+	struct list_head *lhead;
+	unsigned long flags;
+
+	spin_lock_irqsave(&config->connector_list_lock, flags);
+	lhead = old_conn ? &old_conn->head : &config->connector_list;
+
+	do {
+		if (lhead->next == &config->connector_list) {
+			iter->conn = NULL;
+			break;
+		}
+
+		lhead = lhead->next;
+		iter->conn = list_entry(lhead, struct drm_connector, head);
+
+		/* loop until it's not a zombie connector */
+	} while (!kref_get_unless_zero(&iter->conn->base.refcount));
+	spin_unlock_irqrestore(&config->connector_list_lock, flags);
+
+	if (old_conn)
+		drm_connector_unreference(old_conn);
+
+	return iter->conn;
+}
+EXPORT_SYMBOL(drm_connector_list_iter_next);
+
+/**
+ * drm_connector_list_iter_put - tear down a connector_list iterator
+ * @iter: connector_list iterator
+ *
+ * Tears down @iter and releases any resources (like &drm_connector references)
+ * acquired while walking the list. This must always be called, both when the
+ * iteration completes fully or when it was aborted without walking the entire
+ * list.
+ */
+void drm_connector_list_iter_put(struct drm_connector_list_iter *iter)
+{
+	iter->dev = NULL;
+	if (iter->conn)
+		drm_connector_unreference(iter->conn);
+	lock_release(&connector_list_iter_dep_map, 0, _RET_IP_);
+}
+EXPORT_SYMBOL(drm_connector_list_iter_put);
+
 static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
 	{ SubPixelUnknown, "Unknown" },
 	{ SubPixelHorizontalRGB, "Horizontal RGB" },
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 992879f15f23..989334a9f21c 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -173,10 +173,12 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
 	struct drm_connector *connector;
 	struct drm_device *dev = encoder->dev;
 	bool uses_atomic = false;
+	struct drm_connector_list_iter conn_iter;
 
 	/* For atomic drivers only state objects are synchronously updated and
 	 * protected by modeset locks, so check those first. */
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (!connector->state)
 			continue;
 
@@ -185,8 +187,10 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
 		if (connector->state->best_encoder != encoder)
 			continue;
 
+		drm_connector_list_iter_put(&conn_iter);
 		return connector->state->crtc;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* Don't return stale data (e.g. pending async disable). */
 	if (uses_atomic)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 85a25fd9eff8..747a26df0e90 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -93,6 +93,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	uint32_t __user *crtc_id;
 	uint32_t __user *connector_id;
 	uint32_t __user *encoder_id;
+	struct drm_connector_list_iter conn_iter;
 
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
@@ -112,9 +113,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	card_res->count_fbs = count;
 	mutex_unlock(&file_priv->fbs_lock);
 
-	/* mode_config.mutex protects the connector list against e.g. DP MST
-	 * connector hot-adding. CRTC/Plane lists are invariant. */
-	mutex_lock(&dev->mode_config.mutex);
 	card_res->max_height = dev->mode_config.max_height;
 	card_res->min_height = dev->mode_config.min_height;
 	card_res->max_width = dev->mode_config.max_width;
@@ -124,10 +122,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
 	drm_for_each_crtc(crtc, dev) {
 		if (count < card_res->count_crtcs &&
-		    put_user(crtc->base.id, crtc_id + count)) {
-			ret = -EFAULT;
-			goto out;
-		}
+		    put_user(crtc->base.id, crtc_id + count))
+			return -EFAULT;
 		count++;
 	}
 	card_res->count_crtcs = count;
@@ -136,28 +132,26 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
 	drm_for_each_encoder(encoder, dev) {
 		if (count < card_res->count_encoders &&
-		    put_user(encoder->base.id, encoder_id + count)) {
-			ret = -EFAULT;
-			goto out;
-		}
+		    put_user(encoder->base.id, encoder_id + count))
+			return -EFAULT;
 		count++;
 	}
 	card_res->count_encoders = count;
 
+	drm_connector_list_iter_get(dev, &conn_iter);
 	count = 0;
 	connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
-	drm_for_each_connector(connector, dev) {
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (count < card_res->count_connectors &&
 		    put_user(connector->base.id, connector_id + count)) {
-			ret = -EFAULT;
-			goto out;
+			drm_connector_list_iter_put(&conn_iter);
+			return -EFAULT;
 		}
 		count++;
 	}
 	card_res->count_connectors = count;
+	drm_connector_list_iter_put(&conn_iter);
 
-out:
-	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
 }
 
@@ -175,6 +169,7 @@ void drm_mode_config_reset(struct drm_device *dev)
 	struct drm_plane *plane;
 	struct drm_encoder *encoder;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
 	drm_for_each_plane(plane, dev)
 		if (plane->funcs->reset)
@@ -188,11 +183,11 @@ void drm_mode_config_reset(struct drm_device *dev)
 		if (encoder->funcs->reset)
 			encoder->funcs->reset(encoder);
 
-	mutex_lock(&dev->mode_config.mutex);
-	drm_for_each_connector(connector, dev)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		if (connector->funcs->reset)
 			connector->funcs->reset(connector);
-	mutex_unlock(&dev->mode_config.mutex);
+	drm_connector_list_iter_put(&conn_iter);
 }
 EXPORT_SYMBOL(drm_mode_config_reset);
 
@@ -373,6 +368,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	idr_init(&dev->mode_config.crtc_idr);
 	idr_init(&dev->mode_config.tile_idr);
 	ida_init(&dev->mode_config.connector_ida);
+	spin_lock_init(&dev->mode_config.connector_list_lock);
 
 	drm_mode_create_standard_properties(dev);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index a9b95246e26e..0e41a2e184a9 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -839,6 +839,11 @@ void drm_mode_put_tile_group(struct drm_device *dev,
  * @dev: the DRM device
  *
  * Iterate over all connectors of @dev.
+ *
+ * WARNING:
+ *
+ * This iterator is not safe against hotadd/removal of connectors and is
+ * deprecated. Use drm_for_each_connector_iter() instead.
  */
 #define drm_for_each_connector(connector, dev) \
 	for (assert_drm_connector_list_read_locked(&(dev)->mode_config),	\
@@ -847,4 +852,37 @@ void drm_mode_put_tile_group(struct drm_device *dev,
 	     &connector->head != (&(dev)->mode_config.connector_list);		\
 	     connector = list_next_entry(connector, head))
 
+/**
+ * struct drm_connector_list_iter - connector_list iterator
+ *
+ * This iterator tracks state needed to be able to walk the connector_list
+ * within struct drm_mode_config. Only use together with
+ * drm_connector_list_iter_get(), drm_connector_list_iter_put() and
+ * drm_connector_list_iter_next() respectively the convenience macro
+ * drm_for_each_connector_iter().
+ */
+struct drm_connector_list_iter {
+/* private: */
+	struct drm_device *dev;
+	struct drm_connector *conn;
+};
+
+void drm_connector_list_iter_get(struct drm_device *dev,
+				 struct drm_connector_list_iter *iter);
+struct drm_connector *
+drm_connector_list_iter_next(struct drm_connector_list_iter *iter);
+void drm_connector_list_iter_put(struct drm_connector_list_iter *iter);
+
+/**
+ * drm_for_each_connector_iter - connector_list iterator macro
+ * @connector: struct &drm_connector pointer used as cursor
+ * @iter: struct &drm_connector_list_iter
+ *
+ * Note that @connector is only valid within the list body, if you want to use
+ * @connector after calling drm_connector_list_iter_put() then you need to grab
+ * your own reference first using drm_connector_reference().
+ */
+#define drm_for_each_connector_iter(connector, iter) \
+	while ((connector = drm_connector_list_iter_next(iter)))
+
 #endif
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index bf9991b20611..5b735549bd51 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -365,7 +365,13 @@ struct drm_mode_config {
 	struct list_head fb_list;
 
 	/**
-	 * @num_connector: Number of connectors on this device.
+	 * @connector_list_lock: Protects @num_connector and
+	 * @connector_list.
+	 */
+	spinlock_t connector_list_lock;
+	/**
+	 * @num_connector: Number of connectors on this device. Protected by
+	 * @connector_list_lock.
 	 */
 	int num_connector;
 	/**
@@ -373,7 +379,9 @@ struct drm_mode_config {
 	 */
 	struct ida connector_ida;
 	/**
-	 * @connector_list: List of connector objects.
+	 * @connector_list: List of connector objects. Protected by
+	 * @connector_list_lock. Only use drm_for_each_connector_iter() and
+	 * struct &drm_connector_list_iter to walk this list.
 	 */
 	struct list_head connector_list;
 	int num_encoder;
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (4 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-15 14:34   ` Harry Wentland
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
  2016-12-13 23:08 ` [PATCH 07/13] drm: Clean up connectors by unreferencing them Daniel Vetter
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Mostly nothing special (except making sure that really all error paths
and friends call iter_put).

v2: Don't forget the raw connector_list walking in
drm_helper_move_panel_connectors_to_head. That one unfortunately can't
be converted to the iterator helpers, but since it's just some list
splicing best to just wrap the entire thing up in one critical
section.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic_helper.c  | 39 ++++++++++++++++++++--------
 drivers/gpu/drm/drm_crtc_helper.c    | 49 ++++++++++++++++++++++++++++--------
 drivers/gpu/drm/drm_fb_helper.c      | 12 ++++++---
 drivers/gpu/drm/drm_modeset_helper.c |  2 ++
 drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
 drivers/gpu/drm/drm_probe_helper.c   | 18 ++++++++-----
 6 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 23767df72615..e2e15a9903a9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 {
 	struct drm_connector_state *conn_state;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_encoder *encoder;
 	unsigned encoder_mask = 0;
-	int i, ret;
+	int i, ret = 0;
 
 	/*
 	 * First loop, find all newly assigned encoders from the connectors
@@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 	 * and the crtc is disabled if no encoder is left. This preserves
 	 * compatibility with the legacy set_config behavior.
 	 */
-	drm_for_each_connector(connector, state->dev) {
+	drm_connector_list_iter_get(state->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		struct drm_crtc_state *crtc_state;
 
 		if (drm_atomic_get_existing_connector_state(state, connector))
@@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 					 connector->state->crtc->base.id,
 					 connector->state->crtc->name,
 					 connector->base.id, connector->name);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 
 		conn_state = drm_atomic_get_connector_state(state, connector);
-		if (IS_ERR(conn_state))
-			return PTR_ERR(conn_state);
+		if (IS_ERR(conn_state)) {
+			ret = PTR_ERR(conn_state);
+			goto out;
+		}
 
 		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
 				 encoder->base.id, encoder->name,
@@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 
 		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
 		if (ret)
-			return ret;
+			goto out;
 
 		if (!crtc_state->connector_mask) {
 			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
 								NULL);
 			if (ret < 0)
-				return ret;
+				goto out;
 
 			crtc_state->active = false;
 		}
 	}
+out:
+	drm_connector_list_iter_put(&conn_iter);
 
-	return 0;
+	return ret;
 }
 
 static void
@@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 {
 	struct drm_atomic_state *state;
 	struct drm_connector *conn;
+	struct drm_connector_list_iter conn_iter;
 	int err;
 
 	state = drm_atomic_state_alloc(dev);
@@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
 	state->acquire_ctx = ctx;
 
-	drm_for_each_connector(conn, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(conn, &conn_iter) {
 		struct drm_crtc *crtc = conn->state->crtc;
 		struct drm_crtc_state *crtc_state;
 
@@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
 	err = drm_atomic_commit(state);
 free:
+	drm_connector_list_iter_put(&conn_iter);
 	drm_atomic_state_put(state);
 	return err;
 }
@@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 	struct drm_crtc_state *crtc_state;
 	struct drm_crtc *crtc;
 	struct drm_connector *tmp_connector;
+	struct drm_connector_list_iter conn_iter;
 	int ret;
 	bool active = false;
 	int old_mode = connector->dpms;
@@ -2867,7 +2878,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 
 	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
 
-	drm_for_each_connector(tmp_connector, connector->dev) {
+	drm_connector_list_iter_get(connector->dev, &conn_iter);
+	drm_for_each_connector_iter(tmp_connector, &conn_iter) {
 		if (tmp_connector->state->crtc != crtc)
 			continue;
 
@@ -2876,6 +2888,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 			break;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 	crtc_state->active = active;
 
 	ret = drm_atomic_commit(state);
@@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
 {
 	struct drm_atomic_state *state;
 	struct drm_connector *conn;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 	int err = 0;
@@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
 		}
 	}
 
-	drm_for_each_connector(conn, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(conn, &conn_iter) {
 		struct drm_connector_state *conn_state;
 
 		conn_state = drm_atomic_get_connector_state(state, conn);
 		if (IS_ERR(conn_state)) {
 			err = PTR_ERR(conn_state);
+			drm_connector_list_iter_put(&conn_iter);
 			goto free;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* clear the acquire context so that it isn't accidentally reused */
 	state->acquire_ctx = NULL;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 5d2cb138eba6..476e6d4b95f4 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -88,6 +88,7 @@
 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 {
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = encoder->dev;
 
 	/*
@@ -99,9 +100,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 	}
 
-	drm_for_each_connector(connector, dev)
-		if (connector->encoder == encoder)
+
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (connector->encoder == encoder) {
 			return true;
+			drm_connector_list_iter_put(&conn_iter);
+		}
+	}
+	drm_connector_list_iter_put(&conn_iter);
 	return false;
 }
 EXPORT_SYMBOL(drm_helper_encoder_in_use);
@@ -436,10 +443,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
 
 	/* Decouple all encoders and their attached connectors from this crtc */
 	drm_for_each_encoder(encoder, dev) {
+		struct drm_connector_list_iter conn_iter;
+
 		if (encoder->crtc != crtc)
 			continue;
 
-		drm_for_each_connector(connector, dev) {
+		drm_connector_list_iter_get(dev, &conn_iter);
+		drm_for_each_connector_iter(connector, &conn_iter) {
 			if (connector->encoder != encoder)
 				continue;
 
@@ -456,6 +466,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
 			/* we keep a reference while the encoder is bound */
 			drm_connector_unreference(connector);
 		}
+		drm_connector_list_iter_put(&conn_iter);
 	}
 
 	__drm_helper_disable_unused_functions(dev);
@@ -507,6 +518,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	bool mode_changed = false; /* if true do a full mode set */
 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int count = 0, ro, fail = 0;
 	const struct drm_crtc_helper_funcs *crtc_funcs;
 	struct drm_mode_set save_set;
@@ -571,9 +583,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		save_connector_encoders[count++] = connector->encoder;
-	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	save_set.crtc = set->crtc;
 	save_set.mode = &set->crtc->mode;
@@ -616,7 +629,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
 	/* a) traverse passed in connector list and get encoders for them */
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		const struct drm_connector_helper_funcs *connector_funcs =
 			connector->helper_private;
 		new_encoder = connector->encoder;
@@ -649,6 +663,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 			connector->encoder = new_encoder;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (fail) {
 		ret = -EINVAL;
@@ -656,7 +671,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (!connector->encoder)
 			continue;
 
@@ -674,6 +690,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		if (new_crtc &&
 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
 			ret = -EINVAL;
+			drm_connector_list_iter_put(&conn_iter);
 			goto fail;
 		}
 		if (new_crtc != connector->encoder->crtc) {
@@ -690,6 +707,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 				      connector->base.id, connector->name);
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* mode_set_base is not a required function */
 	if (fb_changed && !crtc_funcs->mode_set_base)
@@ -744,9 +762,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		connector->encoder = save_connector_encoders[count++];
-	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* after fail drop reference on all unbound connectors in set, let
 	 * bound connectors keep their reference
@@ -773,12 +792,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
 {
 	int dpms = DRM_MODE_DPMS_OFF;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = encoder->dev;
 
-	drm_for_each_connector(connector, dev)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		if (connector->encoder == encoder)
 			if (connector->dpms < dpms)
 				dpms = connector->dpms;
+	drm_connector_list_iter_put(&conn_iter);
+
 	return dpms;
 }
 
@@ -810,12 +833,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
 {
 	int dpms = DRM_MODE_DPMS_OFF;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = crtc->dev;
 
-	drm_for_each_connector(connector, dev)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		if (connector->encoder && connector->encoder->crtc == crtc)
 			if (connector->dpms < dpms)
 				dpms = connector->dpms;
+	drm_connector_list_iter_put(&conn_iter);
+
 	return dpms;
 }
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index e934b541feea..8f5937616f01 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 {
 	struct drm_device *dev = fb_helper->dev;
 	struct drm_connector *connector;
-	int i, ret;
+	struct drm_connector_list_iter conn_iter;
+	int i, ret = 0;
 
 	if (!drm_fbdev_emulation)
 		return 0;
 
 	mutex_lock(&dev->mode_config.mutex);
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		ret = drm_fb_helper_add_one_connector(fb_helper, connector);
 
 		if (ret)
 			goto fail;
 	}
-	mutex_unlock(&dev->mode_config.mutex);
-	return 0;
+	goto out;
+
 fail:
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_fb_helper_connector *fb_helper_connector =
@@ -145,6 +147,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 		fb_helper->connector_info[i] = NULL;
 	}
 	fb_helper->connector_count = 0;
+out:
+	drm_connector_list_iter_put(&conn_iter);
 	mutex_unlock(&dev->mode_config.mutex);
 
 	return ret;
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index cc232ac6c950..43789f606c37 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
 
 	INIT_LIST_HEAD(&panel_list);
 
+	spin_lock_irq(&dev->mode_config.connector_list_lock);
 	list_for_each_entry_safe(connector, tmp,
 				 &dev->mode_config.connector_list, head) {
 		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
@@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
 	}
 
 	list_splice(&panel_list, &dev->mode_config.connector_list);
+	spin_unlock_irq(&dev->mode_config.connector_list_lock);
 }
 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
 
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 7a7dddf604d7..bc9f97422cd1 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -74,6 +74,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int count = 0;
 
 	/*
@@ -83,7 +84,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 	 */
 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->encoder && connector->encoder->crtc == crtc) {
 			if (connector_list != NULL && count < num_connectors)
 				*(connector_list++) = connector;
@@ -91,6 +93,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 			count++;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return count;
 }
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index ac953f037be7..7cff91e7497f 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
 {
 	bool poll = false;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
 
 	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
@@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
 	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
 		return;
 
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
 					 DRM_CONNECTOR_POLL_DISCONNECT))
 			poll = true;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (dev->mode_config.delayed_event) {
 		poll = true;
@@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
 	struct delayed_work *delayed_work = to_delayed_work(work);
 	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	enum drm_connector_status old_status;
 	bool repoll = false, changed;
 
@@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
 		goto out;
 	}
 
-	drm_for_each_connector(connector, dev) {
-
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		/* Ignore forced connectors. */
 		if (connector->force)
 			continue;
@@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
 			changed = true;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	mutex_unlock(&dev->mode_config.mutex);
 
@@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 bool drm_helper_hpd_irq_event(struct drm_device *dev)
 {
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	enum drm_connector_status old_status;
 	bool changed = false;
 
@@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
 		return false;
 
 	mutex_lock(&dev->mode_config.mutex);
-	drm_for_each_connector(connector, dev) {
-
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		/* Only handle HPD capable connectors. */
 		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
 			continue;
@@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
 		if (old_status != connector->status)
 			changed = true;
 	}
-
+	drm_connector_list_iter_put(&conn_iter);
 	mutex_unlock(&dev->mode_config.mutex);
 
 	if (changed)
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 07/13] drm: Clean up connectors by unreferencing them
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (5 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-15 15:45   ` Harry Wentland
  2016-12-16 15:03   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 08/13] drm: prevent double-(un)registration for connectors Daniel Vetter
                   ` (5 subsequent siblings)
  12 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Only static connectors should be left at this point, and we should be
able to clean them out by simply dropping that last reference still
around from drm_connector_init.

If that leaves anything behind then we have a driver bug.

Doing the final cleanup this way also allows us to use
drm_connector_iter, removing the very last place where we walk
connector_list explicitly in drm core&helpers.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_mode_config.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 747a26df0e90..a942536abd60 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -397,7 +397,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
  */
 void drm_mode_config_cleanup(struct drm_device *dev)
 {
-	struct drm_connector *connector, *ot;
+	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_crtc *crtc, *ct;
 	struct drm_encoder *encoder, *enct;
 	struct drm_framebuffer *fb, *fbt;
@@ -410,10 +411,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 		encoder->funcs->destroy(encoder);
 	}
 
-	list_for_each_entry_safe(connector, ot,
-				 &dev->mode_config.connector_list, head) {
-		connector->funcs->destroy(connector);
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		/* drm_connector_list_iter holds an full reference to the
+		 * current connector itself, which means it is inherently safe
+		 * against unreferencing the current connector - but not against
+		 * deleting it right away. */
+		drm_connector_unreference(connector);
 	}
+	drm_connector_list_iter_put(&conn_iter);
+	WARN_ON(!list_empty(&dev->mode_config.connector_list));
 
 	list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
 				 head) {
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 08/13] drm: prevent double-(un)registration for connectors
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (6 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 07/13] drm: Clean up connectors by unreferencing them Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-13 23:52   ` Chris Wilson
  2016-12-16 15:03   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector Daniel Vetter
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

If we're unlucky then the registration from a hotplugged connector
might race with the final registration step on driver load. And since
MST topology discover is asynchronous that's even somewhat likely.

v2: Also update the kerneldoc for @registered!

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_connector.c | 18 +++++++++++++-----
 include/drm/drm_connector.h     | 12 +++++++++++-
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b33334e09b00..0d4728704099 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -223,6 +223,7 @@ int drm_connector_init(struct drm_device *dev,
 
 	INIT_LIST_HEAD(&connector->probed_modes);
 	INIT_LIST_HEAD(&connector->modes);
+	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
 
@@ -373,14 +374,15 @@ EXPORT_SYMBOL(drm_connector_cleanup);
  */
 int drm_connector_register(struct drm_connector *connector)
 {
-	int ret;
+	int ret = 0;
 
+	mutex_lock(&connector->mutex);
 	if (connector->registered)
-		return 0;
+		goto unlock;
 
 	ret = drm_sysfs_connector_add(connector);
 	if (ret)
-		return ret;
+		goto unlock;
 
 	ret = drm_debugfs_connector_add(connector);
 	if (ret) {
@@ -396,12 +398,14 @@ int drm_connector_register(struct drm_connector *connector)
 	drm_mode_object_register(connector->dev, &connector->base);
 
 	connector->registered = true;
-	return 0;
+	goto unlock;
 
 err_debugfs:
 	drm_debugfs_connector_remove(connector);
 err_sysfs:
 	drm_sysfs_connector_remove(connector);
+unlock:
+	mutex_unlock(&connector->mutex);
 	return ret;
 }
 EXPORT_SYMBOL(drm_connector_register);
@@ -414,8 +418,11 @@ EXPORT_SYMBOL(drm_connector_register);
  */
 void drm_connector_unregister(struct drm_connector *connector)
 {
-	if (!connector->registered)
+	mutex_lock(&connector->mutex);
+	if (!connector->registered) {
+		mutex_unlock(&connector->mutex);
 		return;
+	}
 
 	if (connector->funcs->early_unregister)
 		connector->funcs->early_unregister(connector);
@@ -424,6 +431,7 @@ void drm_connector_unregister(struct drm_connector *connector)
 	drm_debugfs_connector_remove(connector);
 
 	connector->registered = false;
+	mutex_unlock(&connector->mutex);
 }
 EXPORT_SYMBOL(drm_connector_unregister);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 0e41a2e184a9..a24559ef8bb7 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -559,7 +559,6 @@ struct drm_cmdline_mode {
  * @interlace_allowed: can this connector handle interlaced modes?
  * @doublescan_allowed: can this connector handle doublescan?
  * @stereo_allowed: can this connector handle stereo modes?
- * @registered: is this connector exposed (registered) with userspace?
  * @modes: modes available on this connector (from fill_modes() + user)
  * @status: one of the drm_connector_status enums (connected, not, or unknown)
  * @probed_modes: list of modes derived directly from the display
@@ -608,6 +607,13 @@ struct drm_connector {
 	char *name;
 
 	/**
+	 * @mutex: Lock for general connector state, but currently only protects
+	 * @registered. Most of the connector state is still protected by the
+	 * mutex in &drm_mode_config.
+	 */
+	struct mutex mutex;
+
+	/**
 	 * @index: Compacted connector index, which matches the position inside
 	 * the mode_config.list for drivers not supporting hot-add/removing. Can
 	 * be used as an array index. It is invariant over the lifetime of the
@@ -620,6 +626,10 @@ struct drm_connector {
 	bool interlace_allowed;
 	bool doublescan_allowed;
 	bool stereo_allowed;
+	/**
+	 * @registered: Is this connector exposed (registered) with userspace?
+	 * Protected by @mutex.
+	 */
 	bool registered;
 	struct list_head modes; /* list of modes on this connector */
 
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (7 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 08/13] drm: prevent double-(un)registration for connectors Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-16 15:03   ` Sean Paul
  2016-12-13 23:08 ` [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs Daniel Vetter
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

- Modeset state needs mode_config->connection mutex, that covers
  figuring out the encoder, and reading properties (since in the
  atomic case those need to look at connector->state).

- Don't hold any locks for stuff that's invariant (i.e. possible
  connectors).

- Same for connector lookup and unref, those don't need any locks.

- And finally the probe stuff is only protected by mode_config->mutex.

While at it updated the kerneldoc for these fields in drm_connector
and add docs explaining what's protected by which locks.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_connector.c | 92 ++++++++++++++++++++---------------------
 include/drm/drm_connector.h     | 23 +++++++++--
 2 files changed, 63 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 0d4728704099..44b556d5d40c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1160,43 +1160,65 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
 	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-	mutex_lock(&dev->mode_config.mutex);
-
 	connector = drm_connector_lookup(dev, out_resp->connector_id);
-	if (!connector) {
-		ret = -ENOENT;
-		goto out_unlock;
-	}
+	if (!connector)
+		return -ENOENT;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	encoder = drm_connector_get_encoder(connector);
+	if (encoder)
+		out_resp->encoder_id = encoder->base.id;
+	else
+		out_resp->encoder_id = 0;
+
+	ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
+			(uint32_t __user *)(unsigned long)(out_resp->props_ptr),
+			(uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
+			&out_resp->count_props);
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	if (ret)
+		goto out_unref;
 
 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
 		if (connector->encoder_ids[i] != 0)
 			encoders_count++;
 
+	if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
+		copied = 0;
+		encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
+		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+			if (connector->encoder_ids[i] != 0) {
+				if (put_user(connector->encoder_ids[i],
+					     encoder_ptr + copied)) {
+					ret = -EFAULT;
+					goto out_unref;
+				}
+				copied++;
+			}
+		}
+	}
+	out_resp->count_encoders = encoders_count;
+
+	out_resp->connector_id = connector->base.id;
+	out_resp->connector_type = connector->connector_type;
+	out_resp->connector_type_id = connector->connector_type_id;
+
+	mutex_lock(&dev->mode_config.mutex);
 	if (out_resp->count_modes == 0) {
 		connector->funcs->fill_modes(connector,
 					     dev->mode_config.max_width,
 					     dev->mode_config.max_height);
 	}
 
-	/* delayed so we get modes regardless of pre-fill_modes state */
-	list_for_each_entry(mode, &connector->modes, head)
-		if (drm_mode_expose_to_userspace(mode, file_priv))
-			mode_count++;
-
-	out_resp->connector_id = connector->base.id;
-	out_resp->connector_type = connector->connector_type;
-	out_resp->connector_type_id = connector->connector_type_id;
 	out_resp->mm_width = connector->display_info.width_mm;
 	out_resp->mm_height = connector->display_info.height_mm;
 	out_resp->subpixel = connector->display_info.subpixel_order;
 	out_resp->connection = connector->status;
 
-	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-	encoder = drm_connector_get_encoder(connector);
-	if (encoder)
-		out_resp->encoder_id = encoder->base.id;
-	else
-		out_resp->encoder_id = 0;
+	/* delayed so we get modes regardless of pre-fill_modes state */
+	list_for_each_entry(mode, &connector->modes, head)
+		if (drm_mode_expose_to_userspace(mode, file_priv))
+			mode_count++;
 
 	/*
 	 * This ioctl is called twice, once to determine how much space is
@@ -1219,36 +1241,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 		}
 	}
 	out_resp->count_modes = mode_count;
-
-	ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
-			(uint32_t __user *)(unsigned long)(out_resp->props_ptr),
-			(uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
-			&out_resp->count_props);
-	if (ret)
-		goto out;
-
-	if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
-		copied = 0;
-		encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
-		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
-			if (connector->encoder_ids[i] != 0) {
-				if (put_user(connector->encoder_ids[i],
-					     encoder_ptr + copied)) {
-					ret = -EFAULT;
-					goto out;
-				}
-				copied++;
-			}
-		}
-	}
-	out_resp->count_encoders = encoders_count;
-
 out:
-	drm_modeset_unlock(&dev->mode_config.connection_mutex);
-
-	drm_connector_unreference(connector);
-out_unlock:
 	mutex_unlock(&dev->mode_config.mutex);
+out_unref:
+	drm_connector_unreference(connector);
 
 	return ret;
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index a24559ef8bb7..9af4141165d3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -559,9 +559,6 @@ struct drm_cmdline_mode {
  * @interlace_allowed: can this connector handle interlaced modes?
  * @doublescan_allowed: can this connector handle doublescan?
  * @stereo_allowed: can this connector handle stereo modes?
- * @modes: modes available on this connector (from fill_modes() + user)
- * @status: one of the drm_connector_status enums (connected, not, or unknown)
- * @probed_modes: list of modes derived directly from the display
  * @funcs: connector control functions
  * @edid_blob_ptr: DRM property containing EDID if present
  * @properties: property tracking for this connector
@@ -631,11 +628,27 @@ struct drm_connector {
 	 * Protected by @mutex.
 	 */
 	bool registered;
+
+	/**
+	 * @modes:
+	 * Modes available on this connector (from fill_modes() + user).
+	 * Protected by dev->mode_config.mutex.
+	 */
 	struct list_head modes; /* list of modes on this connector */
 
+	/**
+	 * @status:
+	 * One of the drm_connector_status enums (connected, not, or unknown).
+	 * Protected by dev->mode_config.mutex.
+	 */
 	enum drm_connector_status status;
 
-	/* these are modes added by probing with DDC or the BIOS */
+	/**
+	 * @probed_modes:
+	 * These are modes added by probing with DDC or the BIOS, before
+	 * filtering is applied. Used by the probe helpers.Protected by
+	 * dev->mode_config.mutex.
+	 */
 	struct list_head probed_modes;
 
 	/**
@@ -644,6 +657,8 @@ struct drm_connector {
 	 * flat panels in embedded systems, the driver should initialize the
 	 * display_info.width_mm and display_info.height_mm fields with the
 	 * physical size of the display.
+	 *
+	 * Protected by dev->mode_config.mutex.
 	 */
 	struct drm_display_info display_info;
 	const struct drm_connector_funcs *funcs;
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (8 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-14 14:44   ` Jani Nikula
  2016-12-13 23:08 ` [PATCH 11/13] drm/i915: use drm_connector_list_iter in intel_hotplug.c Daniel Vetter
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

While at it also try to reduce the locking a bit to what's really just
needed instead of everything that we could possibly lock.

Added a new for_each_intel_connector_iter which includes the cast to
intel_connector.

Otherwise just plain transformation with nothing special going on.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 62 ++++++++++++++++++++++++-------------
 drivers/gpu/drm/i915/i915_drv.h     |  3 ++
 2 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7fca6b9fd10c..278509fd070d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2617,12 +2617,15 @@ static int i915_sink_crc(struct seq_file *m, void *data)
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct drm_device *dev = &dev_priv->drm;
 	struct intel_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct intel_dp *intel_dp = NULL;
 	int ret;
 	u8 crc[6];
 
-	drm_modeset_lock_all(dev);
-	for_each_intel_connector(dev, connector) {
+	/* connection mutex also gives us a read lock on the crtc */
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	drm_connector_list_iter_get(dev, &conn_iter);
+	for_each_intel_connector_iter(connector, &conn_iter) {
 		struct drm_crtc *crtc;
 
 		if (!connector->base.state->best_encoder)
@@ -2648,7 +2651,8 @@ static int i915_sink_crc(struct seq_file *m, void *data)
 	}
 	ret = -ENODEV;
 out:
-	drm_modeset_unlock_all(dev);
+	drm_connector_list_iter_put(&conn_iter);
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
 	return ret;
 }
 
@@ -3088,9 +3092,9 @@ static int i915_display_info(struct seq_file *m, void *unused)
 	struct drm_device *dev = &dev_priv->drm;
 	struct intel_crtc *crtc;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
 	intel_runtime_pm_get(dev_priv);
-	drm_modeset_lock_all(dev);
 	seq_printf(m, "CRTC info\n");
 	seq_printf(m, "---------\n");
 	for_each_intel_crtc(dev, crtc) {
@@ -3098,6 +3102,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
 		struct intel_crtc_state *pipe_config;
 		int x, y;
 
+		drm_modeset_lock(&crtc->base.mutex, NULL);
 		pipe_config = to_intel_crtc_state(crtc->base.state);
 
 		seq_printf(m, "CRTC %d: pipe: %c, active=%s, (size=%dx%d), dither=%s, bpp=%d\n",
@@ -3122,15 +3127,19 @@ static int i915_display_info(struct seq_file *m, void *unused)
 		seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
 			   yesno(!crtc->cpu_fifo_underrun_disabled),
 			   yesno(!crtc->pch_fifo_underrun_disabled));
+		drm_modeset_unlock(&crtc->base.mutex);
 	}
 
 	seq_printf(m, "\n");
 	seq_printf(m, "Connector info\n");
 	seq_printf(m, "--------------\n");
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+	mutex_lock(&dev->mode_config.mutex);
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		intel_connector_info(m, connector);
-	}
-	drm_modeset_unlock_all(dev);
+	drm_connector_list_iter_put(&conn_iter);
+	mutex_unlock(&dev->mode_config.mutex);
+
 	intel_runtime_pm_put(dev_priv);
 
 	return 0;
@@ -3451,13 +3460,16 @@ static void drrs_status_per_crtc(struct seq_file *m,
 	struct i915_drrs *drrs = &dev_priv->drrs;
 	int vrefresh = 0;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->state->crtc != &intel_crtc->base)
 			continue;
 
 		seq_printf(m, "%s:\n", connector->name);
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (dev_priv->vbt.drrs_type == STATIC_DRRS_SUPPORT)
 		seq_puts(m, "\tVBT: DRRS_type: Static");
@@ -3543,9 +3555,10 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused)
 	struct intel_encoder *intel_encoder;
 	struct intel_digital_port *intel_dig_port;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
-	drm_modeset_lock_all(dev);
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
 			continue;
 
@@ -3561,7 +3574,8 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused)
 			   port_name(intel_dig_port->port));
 		drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
 	}
-	drm_modeset_unlock_all(dev);
+	drm_connector_list_iter_put(&conn_iter);
+
 	return 0;
 }
 
@@ -3573,14 +3587,12 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
 	int status = 0;
 	struct drm_device *dev;
 	struct drm_connector *connector;
-	struct list_head *connector_list;
+	struct drm_connector_list_iter conn_iter;
 	struct intel_dp *intel_dp;
 	int val = 0;
 
 	dev = ((struct seq_file *)file->private_data)->private;
 
-	connector_list = &dev->mode_config.connector_list;
-
 	if (len == 0)
 		return 0;
 
@@ -3596,7 +3608,8 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
 	input_buffer[len] = '\0';
 	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
 
-	list_for_each_entry(connector, connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->connector_type !=
 		    DRM_MODE_CONNECTOR_DisplayPort)
 			continue;
@@ -3617,6 +3630,7 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
 				intel_dp->compliance.test_active = 0;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 out:
 	kfree(input_buffer);
 	if (status < 0)
@@ -3630,10 +3644,11 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
 	struct drm_connector *connector;
-	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct drm_connector_list_iter conn_iter;
 	struct intel_dp *intel_dp;
 
-	list_for_each_entry(connector, connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->connector_type !=
 		    DRM_MODE_CONNECTOR_DisplayPort)
 			continue;
@@ -3648,6 +3663,7 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)
 		} else
 			seq_puts(m, "0");
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return 0;
 }
@@ -3674,10 +3690,11 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
 	struct drm_connector *connector;
-	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct drm_connector_list_iter conn_iter;
 	struct intel_dp *intel_dp;
 
-	list_for_each_entry(connector, connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->connector_type !=
 		    DRM_MODE_CONNECTOR_DisplayPort)
 			continue;
@@ -3689,6 +3706,7 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
 		} else
 			seq_puts(m, "0");
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return 0;
 }
@@ -3713,10 +3731,11 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
 	struct drm_connector *connector;
-	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct drm_connector_list_iter conn_iter;
 	struct intel_dp *intel_dp;
 
-	list_for_each_entry(connector, connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->connector_type !=
 		    DRM_MODE_CONNECTOR_DisplayPort)
 			continue;
@@ -3728,6 +3747,7 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
 		} else
 			seq_puts(m, "0");
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 20bc04d5e617..7e25a7fffb1c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -481,6 +481,9 @@ struct i915_hotplug {
 			    &(dev)->mode_config.connector_list,	\
 			    base.head)
 
+#define for_each_intel_connector_iter(intel_connector, iter) \
+	while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter))))
+
 #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \
 	list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
 		for_each_if ((intel_encoder)->base.crtc == (__crtc))
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 11/13] drm/i915: use drm_connector_list_iter in intel_hotplug.c
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (9 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-13 23:08 ` [PATCH 12/13] drm/i915: use drm_connector_list_iter in intel_opregion.c Daniel Vetter
  2016-12-13 23:08 ` [PATCH 13/13] drm/i915: Make intel_get_pipe_from_connector atomic Daniel Vetter
  12 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Nothing special, just rote conversion.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_hotplug.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 3d546c019de0..2ddc9e5842ec 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -145,16 +145,17 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
 static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = &dev_priv->drm;
-	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct intel_connector *intel_connector;
 	struct intel_encoder *intel_encoder;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	enum hpd_pin pin;
 	bool hpd_disabled = false;
 
 	assert_spin_locked(&dev_priv->irq_lock);
 
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->polled != DRM_CONNECTOR_POLL_HPD)
 			continue;
 
@@ -177,6 +178,7 @@ static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv)
 			| DRM_CONNECTOR_POLL_DISCONNECT;
 		hpd_disabled = true;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* Enable polling and queue hotplug re-enabling. */
 	if (hpd_disabled) {
@@ -192,7 +194,6 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 		container_of(work, typeof(*dev_priv),
 			     hotplug.reenable_work.work);
 	struct drm_device *dev = &dev_priv->drm;
-	struct drm_mode_config *mode_config = &dev->mode_config;
 	int i;
 
 	intel_runtime_pm_get(dev_priv);
@@ -200,13 +201,15 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 	spin_lock_irq(&dev_priv->irq_lock);
 	for_each_hpd_pin(i) {
 		struct drm_connector *connector;
+		struct drm_connector_list_iter conn_iter;
 
 		if (dev_priv->hotplug.stats[i].state != HPD_DISABLED)
 			continue;
 
 		dev_priv->hotplug.stats[i].state = HPD_ENABLED;
 
-		list_for_each_entry(connector, &mode_config->connector_list, head) {
+		drm_connector_list_iter_get(dev, &conn_iter);
+		drm_for_each_connector_iter(connector, &conn_iter) {
 			struct intel_connector *intel_connector = to_intel_connector(connector);
 
 			if (intel_connector->encoder->hpd_pin == i) {
@@ -218,6 +221,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 					connector->polled = DRM_CONNECTOR_POLL_HPD;
 			}
 		}
+		drm_connector_list_iter_put(&conn_iter);
 	}
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev_priv);
@@ -303,14 +307,14 @@ static void i915_hotplug_work_func(struct work_struct *work)
 	struct drm_i915_private *dev_priv =
 		container_of(work, struct drm_i915_private, hotplug.hotplug_work);
 	struct drm_device *dev = &dev_priv->drm;
-	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct intel_connector *intel_connector;
 	struct intel_encoder *intel_encoder;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	bool changed = false;
 	u32 hpd_event_bits;
 
-	mutex_lock(&mode_config->mutex);
+	mutex_lock(&dev->mode_config.mutex);
 	DRM_DEBUG_KMS("running encoder hotplug functions\n");
 
 	spin_lock_irq(&dev_priv->irq_lock);
@@ -323,7 +327,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
 	spin_unlock_irq(&dev_priv->irq_lock);
 
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		intel_connector = to_intel_connector(connector);
 		if (!intel_connector->encoder)
 			continue;
@@ -337,7 +342,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
 				changed = true;
 		}
 	}
-	mutex_unlock(&mode_config->mutex);
+	drm_connector_list_iter_put(&conn_iter);
+	mutex_unlock(&dev->mode_config.mutex);
 
 	if (changed)
 		drm_kms_helper_hotplug_event(dev);
@@ -483,15 +489,16 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
 		container_of(work, struct drm_i915_private,
 			     hotplug.poll_init_work);
 	struct drm_device *dev = &dev_priv->drm;
-	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	bool enabled;
 
 	mutex_lock(&dev->mode_config.mutex);
 
 	enabled = READ_ONCE(dev_priv->hotplug.poll_enabled);
 
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		struct intel_connector *intel_connector =
 			to_intel_connector(connector);
 		connector->polled = intel_connector->polled;
@@ -509,6 +516,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
 				DRM_CONNECTOR_POLL_HPD;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (enabled)
 		drm_kms_helper_poll_enable_locked(dev);
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 12/13] drm/i915: use drm_connector_list_iter in intel_opregion.c
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (10 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 11/13] drm/i915: use drm_connector_list_iter in intel_hotplug.c Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  2016-12-13 23:08 ` [PATCH 13/13] drm/i915: Make intel_get_pipe_from_connector atomic Daniel Vetter
  12 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

One case where I nuked a now unecessary locking, otherwise all just
boring stuff.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_opregion.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index f4429f67a4e3..d586ff9a66ce 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -434,6 +434,7 @@ int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv,
 static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
 {
 	struct intel_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct opregion_asle *asle = dev_priv->opregion.asle;
 	struct drm_device *dev = &dev_priv->drm;
 
@@ -458,8 +459,10 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
 	 * only one).
 	 */
 	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
-	for_each_intel_connector(dev, connector)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	for_each_intel_connector_iter(connector, &conn_iter)
 		intel_panel_set_backlight_acpi(connector, bclp, 255);
+	drm_connector_list_iter_put(&conn_iter);
 	asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
 
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
@@ -701,6 +704,7 @@ static void intel_didl_outputs(struct drm_i915_private *dev_priv)
 {
 	struct intel_opregion *opregion = &dev_priv->opregion;
 	struct intel_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int i = 0, max_outputs;
 	int display_index[16] = {};
 
@@ -714,7 +718,8 @@ static void intel_didl_outputs(struct drm_i915_private *dev_priv)
 	max_outputs = ARRAY_SIZE(opregion->acpi->didl) +
 		ARRAY_SIZE(opregion->acpi->did2);
 
-	for_each_intel_connector(&dev_priv->drm, connector) {
+	drm_connector_list_iter_get(&dev_priv->drm, &conn_iter);
+	for_each_intel_connector_iter(connector, &conn_iter) {
 		u32 device_id, type;
 
 		device_id = acpi_display_type(connector);
@@ -729,6 +734,7 @@ static void intel_didl_outputs(struct drm_i915_private *dev_priv)
 			set_did(opregion, i, device_id);
 		i++;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	DRM_DEBUG_KMS("%d outputs detected\n", i);
 
@@ -745,6 +751,7 @@ static void intel_setup_cadls(struct drm_i915_private *dev_priv)
 {
 	struct intel_opregion *opregion = &dev_priv->opregion;
 	struct intel_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int i = 0;
 
 	/*
@@ -757,11 +764,13 @@ static void intel_setup_cadls(struct drm_i915_private *dev_priv)
 	 * Note that internal panels should be at the front of the connector
 	 * list already, ensuring they're not left out.
 	 */
-	for_each_intel_connector(&dev_priv->drm, connector) {
+	drm_connector_list_iter_get(&dev_priv->drm, &conn_iter);
+	for_each_intel_connector_iter(connector, &conn_iter) {
 		if (i >= ARRAY_SIZE(opregion->acpi->cadl))
 			break;
 		opregion->acpi->cadl[i++] = connector->acpi_device_id;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* If fewer than 8 active devices, the list must be null terminated */
 	if (i < ARRAY_SIZE(opregion->acpi->cadl))
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 13/13] drm/i915: Make intel_get_pipe_from_connector atomic
  2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
                   ` (11 preceding siblings ...)
  2016-12-13 23:08 ` [PATCH 12/13] drm/i915: use drm_connector_list_iter in intel_opregion.c Daniel Vetter
@ 2016-12-13 23:08 ` Daniel Vetter
  12 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-13 23:08 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Drive-by fixup while looking at all the connector_list walkers -
holding connection_mutex does actually _not_ give you locking to look
at the legacy drm_connector->encoder->crtc pointer chain. That one is
solely owned by the atomic commit workers. Instead we must inspect the
atomic state.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bc1af87789bc..b0ce4204631d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15424,15 +15424,14 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
 
 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
 {
-	struct drm_encoder *encoder = connector->base.encoder;
 	struct drm_device *dev = connector->base.dev;
 
 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
-	if (!encoder || WARN_ON(!encoder->crtc))
+	if (!connector->base.state->crtc)
 		return INVALID_PIPE;
 
-	return to_intel_crtc(encoder->crtc)->pipe;
+	return to_intel_crtc(connector->base.state->crtc)->pipe;
 }
 
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 08/13] drm: prevent double-(un)registration for connectors
  2016-12-13 23:08 ` [PATCH 08/13] drm: prevent double-(un)registration for connectors Daniel Vetter
@ 2016-12-13 23:52   ` Chris Wilson
  2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Chris Wilson @ 2016-12-13 23:52 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Dec 14, 2016 at 12:08:09AM +0100, Daniel Vetter wrote:
> If we're unlucky then the registration from a hotplugged connector
> might race with the final registration step on driver load. And since
> MST topology discover is asynchronous that's even somewhat likely.
> 
> v2: Also update the kerneldoc for @registered!
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c | 18 +++++++++++++-----
>  include/drm/drm_connector.h     | 12 +++++++++++-
>  2 files changed, 24 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index b33334e09b00..0d4728704099 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -223,6 +223,7 @@ int drm_connector_init(struct drm_device *dev,
>  
>  	INIT_LIST_HEAD(&connector->probed_modes);
>  	INIT_LIST_HEAD(&connector->modes);
> +	mutex_init(&connector->mutex);

There's a mutex_destroy() for drm_connector_free() for that extra bit of
debug icing.

> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 0e41a2e184a9..a24559ef8bb7 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -559,7 +559,6 @@ struct drm_cmdline_mode {
>   * @interlace_allowed: can this connector handle interlaced modes?
>   * @doublescan_allowed: can this connector handle doublescan?
>   * @stereo_allowed: can this connector handle stereo modes?
> - * @registered: is this connector exposed (registered) with userspace?
>   * @modes: modes available on this connector (from fill_modes() + user)
>   * @status: one of the drm_connector_status enums (connected, not, or unknown)
>   * @probed_modes: list of modes derived directly from the display
> @@ -608,6 +607,13 @@ struct drm_connector {
>  	char *name;
>  
>  	/**
> +	 * @mutex: Lock for general connector state, but currently only protects
> +	 * @registered. Most of the connector state is still protected by the
> +	 * mutex in &drm_mode_config.
> +	 */
> +	struct mutex mutex;
> +
> +	/**
>  	 * @index: Compacted connector index, which matches the position inside
>  	 * the mode_config.list for drivers not supporting hot-add/removing. Can
>  	 * be used as an array index. It is invariant over the lifetime of the
> @@ -620,6 +626,10 @@ struct drm_connector {
>  	bool interlace_allowed;
>  	bool doublescan_allowed;
>  	bool stereo_allowed;
> +	/**
> +	 * @registered: Is this connector exposed (registered) with userspace?
> +	 * Protected by @mutex.

early_unregister, late_register should also be documented as being
called under connector->mutex.

With those minor improvements,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
@ 2016-12-14  8:35   ` Chris Wilson
  2016-12-14 11:22   ` Jani Nikula
  2016-12-16 15:03   ` Sean Paul
  2 siblings, 0 replies; 41+ messages in thread
From: Chris Wilson @ 2016-12-14  8:35 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Dec 14, 2016 at 12:08:06AM +0100, Daniel Vetter wrote:
> The requirements for connector_list locking are a bit tricky:
> - We need to be able to jump over zombie conectors (i.e. with refcount
>   == 0, but not yet removed from the list). If instead we require that
>   there's no zombies on the list then the final kref_put must happen
>   under the list protection lock, which means that locking context
>   leaks all over the place. Not pretty - better to deal with zombies
>   and wrap the locking just around the list_del in the destructor.
> 
> - When we walk the list we must _not_ hold the connector list lock. We
>   walk the connector list at an absolutely massive amounts of places,
>   if all those places can't ever call drm_connector_unreference the
>   code would get unecessarily complicated.
> 
> - connector_list needs it own lock, again too many places that walk it
>   that we could reuse e.g. mode_config.mutex without resulting in
>   inversions.
> 
> - Lots of code uses these loops to look-up a connector, i.e. they want
>   to be able to call drm_connector_reference. But on the other hand we
>   want connectors to stay on that list until they're dead (i.e.
>   connector_list can't hold a full reference), which means despite the
>   "can't hold lock for the loop body" rule we need to make sure a
>   connector doesn't suddenly become a zombie.
> 
> At first Dave&I discussed various horror-show approaches using srcu,
> but turns out it's fairly easy:
> 
> - For the loop body we always hold an additional reference to the
>   current connector. That means it can't zombify, and it also means
>   it'll stay on the list, which means we can use it as our iterator to
>   find the next connector.
> 
> - When we try to find the next connector we only have to jump over
>   zombies. To make sure we don't chase bad pointers that entire loop
>   is protected with the new connect_list_lock spinlock. And because we
>   know that we're starting out with a non-zombie (need to drop our
>   reference for the old connector only after we have our new one),
>   we're guranteed to still be on the connector_list and either find
>   the next non-zombie or complete the iteration.
> 
> - Only downside is that we need to make sure that the temporary
>   reference for the loop body doesn't leak. iter_get/put() functions +
>   lockdep make sure that's the case.
> 
> - To avoid a flag day the new iterator macro has an _iter postfix. We
>   can rename it back once all the users of the unsafe version are gone
>   (there's about 100 list walkers for the connector_list).
> 
> For now this patch only converts all the list walking in the core,
> leaving helpers and drivers for later patches. The nice thing is that
> we can now finally remove 2 FIXME comments from the
> register/unregister functions.
> 
> v2:
> - use irqsafe spinlocks, so that we can use this in drm_state_dump
>   too.
> - nuke drm_modeset_lock_all from drm_connector_init, now entirely
>   cargo-culted nonsense.
> 
> v3:
> - do {} while (!kref_get_unless_zero), makes for a tidier loop (Dave).
> - pretty kerneldoc
> - add EXPORT_SYMBOL, helpers&drivers are supposed to use this.
> 
> v4: Change lockdep annotations to only check whether we release the
> iter fake lock again (i.e. make sure that iter_put is called), but
> not check any locking dependecies itself. That seams to require a
> recursive read lock in trylock mode.
> 
> Cc: Dave Airlie <airlied@gmail.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic.c      |  14 ++++-
>  drivers/gpu/drm/drm_connector.c   | 116 ++++++++++++++++++++++++++++++++------
>  drivers/gpu/drm/drm_encoder.c     |   6 +-
>  drivers/gpu/drm/drm_mode_config.c |  34 +++++------
>  include/drm/drm_connector.h       |  38 +++++++++++++
>  include/drm/drm_mode_config.h     |  12 +++-
>  6 files changed, 177 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 60697482b94c..b23b4abd67be 100644
>  int drm_connector_register_all(struct drm_device *dev)
>  {
>  	struct drm_connector *connector;
> -	int ret;
> +	struct drm_connector_list_iter conn_iter;
> +	int ret = 0;
>  
> -	/* FIXME: taking the mode config mutex ends up in a clash with
> -	 * fbcon/backlight registration */
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		ret = drm_connector_register(connector);
>  		if (ret)
> -			goto err;
> +			break;
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  
> -	return 0;
> -
> -err:
> -	mutex_unlock(&dev->mode_config.mutex);
> -	drm_connector_unregister_all(dev);
> +	if (ret)
> +		drm_connector_unregister_all(dev);

Just poked my head up here, because the thought of a hotplug connector
register vs an error here made my head hurt. I think the only way to
solve that (and general initialisation vs hpd) is to ensure/document no
hpd until after the registration phase.

The locking looks solid, the list is guarded by the spinlock, iterators
hold a reference, and the kref_unless_zero vs the list is guarded by the
spinlock inside connector release.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1417,6 +1417,7 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
>  	struct drm_mode_config *config = &state->dev->mode_config;
>  	struct drm_connector *connector;
>  	struct drm_connector_state *conn_state;
> +	struct drm_connector_list_iter conn_iter;
>  	int ret;
>  
>  	ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
> @@ -1430,14 +1431,18 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
>  	 * Changed connectors are already in @state, so only need to look at the
>  	 * current configuration.
>  	 */
> -	drm_for_each_connector(connector, state->dev) {
> +	drm_connector_list_iter_get(state->dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->state->crtc != crtc)
>  			continue;
>  
>  		conn_state = drm_atomic_get_connector_state(state, connector);
> -		if (IS_ERR(conn_state))
> +		if (IS_ERR(conn_state)) {
> +			drm_connector_list_iter_put(&conn_iter);
>  			return PTR_ERR(conn_state);

I wuold have gone with ret = PTR_ERR(conn_state); break; just because I
don't like have more paths through the critical section than necessary
(i.e. more than one unlock).
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Intel-gfx] [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init
  2016-12-13 23:08 ` [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init Daniel Vetter
@ 2016-12-14  9:23   ` Daniel Stone
  2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Daniel Stone @ 2016-12-14  9:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On 13 December 2016 at 23:08, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> This is single-threaded setup code, no need for locks. And anyway,
> all properties need to be set up before the driver is registered
> anyway, they can't be hot-added.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Reviewed-by: Daniel Stone <daniels@collabora.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
  2016-12-14  8:35   ` Chris Wilson
@ 2016-12-14 11:22   ` Jani Nikula
  2016-12-14 12:26     ` Daniel Vetter
  2016-12-16 15:03   ` Sean Paul
  2 siblings, 1 reply; 41+ messages in thread
From: Jani Nikula @ 2016-12-14 11:22 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

On Wed, 14 Dec 2016, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> The requirements for connector_list locking are a bit tricky:
> - We need to be able to jump over zombie conectors (i.e. with refcount
>   == 0, but not yet removed from the list). If instead we require that
>   there's no zombies on the list then the final kref_put must happen
>   under the list protection lock, which means that locking context
>   leaks all over the place. Not pretty - better to deal with zombies
>   and wrap the locking just around the list_del in the destructor.
>
> - When we walk the list we must _not_ hold the connector list lock. We
>   walk the connector list at an absolutely massive amounts of places,
>   if all those places can't ever call drm_connector_unreference the
>   code would get unecessarily complicated.
>
> - connector_list needs it own lock, again too many places that walk it
>   that we could reuse e.g. mode_config.mutex without resulting in
>   inversions.
>
> - Lots of code uses these loops to look-up a connector, i.e. they want
>   to be able to call drm_connector_reference. But on the other hand we
>   want connectors to stay on that list until they're dead (i.e.
>   connector_list can't hold a full reference), which means despite the
>   "can't hold lock for the loop body" rule we need to make sure a
>   connector doesn't suddenly become a zombie.
>
> At first Dave&I discussed various horror-show approaches using srcu,
> but turns out it's fairly easy:
>
> - For the loop body we always hold an additional reference to the
>   current connector. That means it can't zombify, and it also means
>   it'll stay on the list, which means we can use it as our iterator to
>   find the next connector.
>
> - When we try to find the next connector we only have to jump over
>   zombies. To make sure we don't chase bad pointers that entire loop
>   is protected with the new connect_list_lock spinlock. And because we
>   know that we're starting out with a non-zombie (need to drop our
>   reference for the old connector only after we have our new one),
>   we're guranteed to still be on the connector_list and either find
>   the next non-zombie or complete the iteration.
>
> - Only downside is that we need to make sure that the temporary
>   reference for the loop body doesn't leak. iter_get/put() functions +
>   lockdep make sure that's the case.
>
> - To avoid a flag day the new iterator macro has an _iter postfix. We
>   can rename it back once all the users of the unsafe version are gone
>   (there's about 100 list walkers for the connector_list).
>
> For now this patch only converts all the list walking in the core,
> leaving helpers and drivers for later patches. The nice thing is that
> we can now finally remove 2 FIXME comments from the
> register/unregister functions.
>
> v2:
> - use irqsafe spinlocks, so that we can use this in drm_state_dump
>   too.
> - nuke drm_modeset_lock_all from drm_connector_init, now entirely
>   cargo-culted nonsense.
>
> v3:
> - do {} while (!kref_get_unless_zero), makes for a tidier loop (Dave).
> - pretty kerneldoc
> - add EXPORT_SYMBOL, helpers&drivers are supposed to use this.
>
> v4: Change lockdep annotations to only check whether we release the
> iter fake lock again (i.e. make sure that iter_put is called), but
> not check any locking dependecies itself. That seams to require a
> recursive read lock in trylock mode.
>
> Cc: Dave Airlie <airlied@gmail.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic.c      |  14 ++++-
>  drivers/gpu/drm/drm_connector.c   | 116 ++++++++++++++++++++++++++++++++------
>  drivers/gpu/drm/drm_encoder.c     |   6 +-
>  drivers/gpu/drm/drm_mode_config.c |  34 +++++------
>  include/drm/drm_connector.h       |  38 +++++++++++++
>  include/drm/drm_mode_config.h     |  12 +++-
>  6 files changed, 177 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 60697482b94c..b23b4abd67be 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1417,6 +1417,7 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
>  	struct drm_mode_config *config = &state->dev->mode_config;
>  	struct drm_connector *connector;
>  	struct drm_connector_state *conn_state;
> +	struct drm_connector_list_iter conn_iter;
>  	int ret;
>  
>  	ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
> @@ -1430,14 +1431,18 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
>  	 * Changed connectors are already in @state, so only need to look at the
>  	 * current configuration.
>  	 */
> -	drm_for_each_connector(connector, state->dev) {
> +	drm_connector_list_iter_get(state->dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->state->crtc != crtc)
>  			continue;
>  
>  		conn_state = drm_atomic_get_connector_state(state, connector);
> -		if (IS_ERR(conn_state))
> +		if (IS_ERR(conn_state)) {
> +			drm_connector_list_iter_put(&conn_iter);
>  			return PTR_ERR(conn_state);
> +		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  
>  	return 0;
>  }
> @@ -1692,6 +1697,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
>  	struct drm_plane *plane;
>  	struct drm_crtc *crtc;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  
>  	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
>  		return;
> @@ -1702,8 +1708,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
>  	list_for_each_entry(crtc, &config->crtc_list, head)
>  		drm_atomic_crtc_print_state(p, crtc->state);
>  
> -	list_for_each_entry(connector, &config->connector_list, head)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		drm_atomic_connector_print_state(p, connector->state);
> +	drm_connector_list_iter_put(&conn_iter);
>  }
>  EXPORT_SYMBOL(drm_state_dump);
>  
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 5a4526289392..b33334e09b00 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -189,13 +189,11 @@ int drm_connector_init(struct drm_device *dev,
>  	struct ida *connector_ida =
>  		&drm_connector_enum_list[connector_type].ida;
>  
> -	drm_modeset_lock_all(dev);
> -
>  	ret = drm_mode_object_get_reg(dev, &connector->base,
>  				      DRM_MODE_OBJECT_CONNECTOR,
>  				      false, drm_connector_free);
>  	if (ret)
> -		goto out_unlock;
> +		return ret;
>  
>  	connector->base.properties = &connector->properties;
>  	connector->dev = dev;
> @@ -232,8 +230,10 @@ int drm_connector_init(struct drm_device *dev,
>  
>  	/* We should add connectors at the end to avoid upsetting the connector
>  	 * index too much. */
> +	spin_lock_irq(&config->connector_list_lock);
>  	list_add_tail(&connector->head, &config->connector_list);
>  	config->num_connector++;
> +	spin_unlock_irq(&config->connector_list_lock);
>  
>  	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
>  		drm_object_attach_property(&connector->base,
> @@ -258,9 +258,6 @@ int drm_connector_init(struct drm_device *dev,
>  	if (ret)
>  		drm_mode_object_unregister(dev, &connector->base);
>  
> -out_unlock:
> -	drm_modeset_unlock_all(dev);
> -
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_connector_init);
> @@ -351,8 +348,10 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  	drm_mode_object_unregister(dev, &connector->base);
>  	kfree(connector->name);
>  	connector->name = NULL;
> +	spin_lock_irq(&dev->mode_config.connector_list_lock);
>  	list_del(&connector->head);
>  	dev->mode_config.num_connector--;
> +	spin_unlock_irq(&dev->mode_config.connector_list_lock);
>  
>  	WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
>  	if (connector->state && connector->funcs->atomic_destroy_state)
> @@ -431,30 +430,30 @@ EXPORT_SYMBOL(drm_connector_unregister);
>  void drm_connector_unregister_all(struct drm_device *dev)
>  {
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  
> -	/* FIXME: taking the mode config mutex ends up in a clash with sysfs */
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		drm_connector_unregister(connector);
> +	drm_connector_list_iter_put(&conn_iter);
>  }
>  
>  int drm_connector_register_all(struct drm_device *dev)
>  {
>  	struct drm_connector *connector;
> -	int ret;
> +	struct drm_connector_list_iter conn_iter;
> +	int ret = 0;
>  
> -	/* FIXME: taking the mode config mutex ends up in a clash with
> -	 * fbcon/backlight registration */
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		ret = drm_connector_register(connector);
>  		if (ret)
> -			goto err;
> +			break;
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  
> -	return 0;
> -
> -err:
> -	mutex_unlock(&dev->mode_config.mutex);
> -	drm_connector_unregister_all(dev);
> +	if (ret)
> +		drm_connector_unregister_all(dev);
>  	return ret;
>  }
>  
> @@ -476,6 +475,87 @@ const char *drm_get_connector_status_name(enum drm_connector_status status)
>  }
>  EXPORT_SYMBOL(drm_get_connector_status_name);
>  
> +#ifdef CONFIG_LOCKDEP
> +static struct lockdep_map connector_list_iter_dep_map = {
> +	.name = "drm_connector_list_iter"
> +};
> +#endif
> +
> +/**
> + * drm_connector_list_iter_get - initialize a connector_list iterator
> + * @dev: DRM device
> + * @iter: connector_list iterator
> + *
> + * Sets @iter up to walk the connector list in &drm_mode_config of @dev. @iter
> + * must always be cleaned up again by calling drm_connector_list_iter_put().
> + * Iteration itself happens using drm_connector_list_iter_next() or
> + * drm_for_each_connector_iter().
> + */
> +void drm_connector_list_iter_get(struct drm_device *dev,
> +				 struct drm_connector_list_iter *iter)
> +{
> +	iter->dev = dev;
> +	iter->conn = NULL;
> +	lock_acquire_shared_recursive(&connector_list_iter_dep_map, 0, 1, NULL, _RET_IP_);
> +}
> +EXPORT_SYMBOL(drm_connector_list_iter_get);
> +
> +/**
> + * drm_connector_list_iter_next - return next connector
> + * @iter: connectr_list iterator
> + *
> + * Returns the next connector for @iter, or NULL when the list walk has
> + * completed.
> + */
> +struct drm_connector *
> +drm_connector_list_iter_next(struct drm_connector_list_iter *iter)
> +{
> +	struct drm_connector *old_conn = iter->conn;
> +	struct drm_mode_config *config = &iter->dev->mode_config;
> +	struct list_head *lhead;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&config->connector_list_lock, flags);
> +	lhead = old_conn ? &old_conn->head : &config->connector_list;
> +
> +	do {
> +		if (lhead->next == &config->connector_list) {
> +			iter->conn = NULL;
> +			break;
> +		}
> +
> +		lhead = lhead->next;
> +		iter->conn = list_entry(lhead, struct drm_connector, head);
> +
> +		/* loop until it's not a zombie connector */
> +	} while (!kref_get_unless_zero(&iter->conn->base.refcount));
> +	spin_unlock_irqrestore(&config->connector_list_lock, flags);
> +
> +	if (old_conn)
> +		drm_connector_unreference(old_conn);
> +
> +	return iter->conn;
> +}
> +EXPORT_SYMBOL(drm_connector_list_iter_next);
> +
> +/**
> + * drm_connector_list_iter_put - tear down a connector_list iterator
> + * @iter: connector_list iterator
> + *
> + * Tears down @iter and releases any resources (like &drm_connector references)
> + * acquired while walking the list. This must always be called, both when the
> + * iteration completes fully or when it was aborted without walking the entire
> + * list.
> + */
> +void drm_connector_list_iter_put(struct drm_connector_list_iter *iter)
> +{
> +	iter->dev = NULL;
> +	if (iter->conn)
> +		drm_connector_unreference(iter->conn);
> +	lock_release(&connector_list_iter_dep_map, 0, _RET_IP_);
> +}
> +EXPORT_SYMBOL(drm_connector_list_iter_put);
> +
>  static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
>  	{ SubPixelUnknown, "Unknown" },
>  	{ SubPixelHorizontalRGB, "Horizontal RGB" },
> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
> index 992879f15f23..989334a9f21c 100644
> --- a/drivers/gpu/drm/drm_encoder.c
> +++ b/drivers/gpu/drm/drm_encoder.c
> @@ -173,10 +173,12 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
>  	struct drm_connector *connector;
>  	struct drm_device *dev = encoder->dev;
>  	bool uses_atomic = false;
> +	struct drm_connector_list_iter conn_iter;
>  
>  	/* For atomic drivers only state objects are synchronously updated and
>  	 * protected by modeset locks, so check those first. */
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (!connector->state)
>  			continue;
>  
> @@ -185,8 +187,10 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
>  		if (connector->state->best_encoder != encoder)
>  			continue;
>  
> +		drm_connector_list_iter_put(&conn_iter);
>  		return connector->state->crtc;
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  
>  	/* Don't return stale data (e.g. pending async disable). */
>  	if (uses_atomic)
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 85a25fd9eff8..747a26df0e90 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -93,6 +93,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
>  	uint32_t __user *crtc_id;
>  	uint32_t __user *connector_id;
>  	uint32_t __user *encoder_id;
> +	struct drm_connector_list_iter conn_iter;
>  
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		return -EINVAL;
> @@ -112,9 +113,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
>  	card_res->count_fbs = count;
>  	mutex_unlock(&file_priv->fbs_lock);
>  
> -	/* mode_config.mutex protects the connector list against e.g. DP MST
> -	 * connector hot-adding. CRTC/Plane lists are invariant. */
> -	mutex_lock(&dev->mode_config.mutex);
>  	card_res->max_height = dev->mode_config.max_height;
>  	card_res->min_height = dev->mode_config.min_height;
>  	card_res->max_width = dev->mode_config.max_width;
> @@ -124,10 +122,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
>  	crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
>  	drm_for_each_crtc(crtc, dev) {
>  		if (count < card_res->count_crtcs &&
> -		    put_user(crtc->base.id, crtc_id + count)) {
> -			ret = -EFAULT;
> -			goto out;
> -		}
> +		    put_user(crtc->base.id, crtc_id + count))
> +			return -EFAULT;
>  		count++;
>  	}
>  	card_res->count_crtcs = count;
> @@ -136,28 +132,26 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
>  	encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
>  	drm_for_each_encoder(encoder, dev) {
>  		if (count < card_res->count_encoders &&
> -		    put_user(encoder->base.id, encoder_id + count)) {
> -			ret = -EFAULT;
> -			goto out;
> -		}
> +		    put_user(encoder->base.id, encoder_id + count))
> +			return -EFAULT;
>  		count++;
>  	}
>  	card_res->count_encoders = count;
>  
> +	drm_connector_list_iter_get(dev, &conn_iter);
>  	count = 0;
>  	connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
> -	drm_for_each_connector(connector, dev) {
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (count < card_res->count_connectors &&
>  		    put_user(connector->base.id, connector_id + count)) {
> -			ret = -EFAULT;
> -			goto out;
> +			drm_connector_list_iter_put(&conn_iter);
> +			return -EFAULT;
>  		}
>  		count++;
>  	}
>  	card_res->count_connectors = count;
> +	drm_connector_list_iter_put(&conn_iter);
>  
> -out:
> -	mutex_unlock(&dev->mode_config.mutex);
>  	return ret;
>  }
>  
> @@ -175,6 +169,7 @@ void drm_mode_config_reset(struct drm_device *dev)
>  	struct drm_plane *plane;
>  	struct drm_encoder *encoder;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  
>  	drm_for_each_plane(plane, dev)
>  		if (plane->funcs->reset)
> @@ -188,11 +183,11 @@ void drm_mode_config_reset(struct drm_device *dev)
>  		if (encoder->funcs->reset)
>  			encoder->funcs->reset(encoder);
>  
> -	mutex_lock(&dev->mode_config.mutex);
> -	drm_for_each_connector(connector, dev)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		if (connector->funcs->reset)
>  			connector->funcs->reset(connector);
> -	mutex_unlock(&dev->mode_config.mutex);
> +	drm_connector_list_iter_put(&conn_iter);
>  }
>  EXPORT_SYMBOL(drm_mode_config_reset);
>  
> @@ -373,6 +368,7 @@ void drm_mode_config_init(struct drm_device *dev)
>  	idr_init(&dev->mode_config.crtc_idr);
>  	idr_init(&dev->mode_config.tile_idr);
>  	ida_init(&dev->mode_config.connector_ida);
> +	spin_lock_init(&dev->mode_config.connector_list_lock);
>  
>  	drm_mode_create_standard_properties(dev);
>  
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a9b95246e26e..0e41a2e184a9 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -839,6 +839,11 @@ void drm_mode_put_tile_group(struct drm_device *dev,
>   * @dev: the DRM device
>   *
>   * Iterate over all connectors of @dev.
> + *
> + * WARNING:
> + *
> + * This iterator is not safe against hotadd/removal of connectors and is
> + * deprecated. Use drm_for_each_connector_iter() instead.
>   */
>  #define drm_for_each_connector(connector, dev) \
>  	for (assert_drm_connector_list_read_locked(&(dev)->mode_config),	\
> @@ -847,4 +852,37 @@ void drm_mode_put_tile_group(struct drm_device *dev,
>  	     &connector->head != (&(dev)->mode_config.connector_list);		\
>  	     connector = list_next_entry(connector, head))
>  
> +/**
> + * struct drm_connector_list_iter - connector_list iterator
> + *
> + * This iterator tracks state needed to be able to walk the connector_list
> + * within struct drm_mode_config. Only use together with
> + * drm_connector_list_iter_get(), drm_connector_list_iter_put() and
> + * drm_connector_list_iter_next() respectively the convenience macro
> + * drm_for_each_connector_iter().
> + */
> +struct drm_connector_list_iter {
> +/* private: */
> +	struct drm_device *dev;
> +	struct drm_connector *conn;
> +};
> +
> +void drm_connector_list_iter_get(struct drm_device *dev,
> +				 struct drm_connector_list_iter *iter);
> +struct drm_connector *
> +drm_connector_list_iter_next(struct drm_connector_list_iter *iter);
> +void drm_connector_list_iter_put(struct drm_connector_list_iter *iter);
> +
> +/**
> + * drm_for_each_connector_iter - connector_list iterator macro
> + * @connector: struct &drm_connector pointer used as cursor
> + * @iter: struct &drm_connector_list_iter
> + *
> + * Note that @connector is only valid within the list body, if you want to use
> + * @connector after calling drm_connector_list_iter_put() then you need to grab
> + * your own reference first using drm_connector_reference().
> + */
> +#define drm_for_each_connector_iter(connector, iter) \
> +	while ((connector = drm_connector_list_iter_next(iter)))
> +

Observe that in most, if not all, cases you lock over the for loop, but
not more. That means you always get/put right around the loop.

You could have a variant of get() that returns the first item, and a
variant of next() that does put() automatically when it's about to
return NULL, and implement most of the loops like this:

#define drm_for_each_connector_simple(dev, iter, connector) \
	for (connector = drm_connector_list_iter_get_first(dev, iter); \
	     connector != NULL; \
	     connector = drm_connector_list_iter_next_put(iter))

In the long run, that should be called just drm_for_each_connector.

The only case where you'd have to call put() explicitly is when you
break out of the loop early. Otherwise all looping would be dead simple,
without all the gets and puts, just like they are now. Perhaps the
naming of the functions should be such that this is the most common
case. Perhaps you don't actually need the versions with "manual" locking
at all.


BR,
Jani.


>  #endif
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index bf9991b20611..5b735549bd51 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -365,7 +365,13 @@ struct drm_mode_config {
>  	struct list_head fb_list;
>  
>  	/**
> -	 * @num_connector: Number of connectors on this device.
> +	 * @connector_list_lock: Protects @num_connector and
> +	 * @connector_list.
> +	 */
> +	spinlock_t connector_list_lock;
> +	/**
> +	 * @num_connector: Number of connectors on this device. Protected by
> +	 * @connector_list_lock.
>  	 */
>  	int num_connector;
>  	/**
> @@ -373,7 +379,9 @@ struct drm_mode_config {
>  	 */
>  	struct ida connector_ida;
>  	/**
> -	 * @connector_list: List of connector objects.
> +	 * @connector_list: List of connector objects. Protected by
> +	 * @connector_list_lock. Only use drm_for_each_connector_iter() and
> +	 * struct &drm_connector_list_iter to walk this list.
>  	 */
>  	struct list_head connector_list;
>  	int num_encoder;

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-14 11:22   ` Jani Nikula
@ 2016-12-14 12:26     ` Daniel Vetter
  2016-12-14 15:04       ` [Intel-gfx] " Jani Nikula
  0 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-14 12:26 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Wed, Dec 14, 2016 at 01:22:15PM +0200, Jani Nikula wrote:
> On Wed, 14 Dec 2016, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > +/**
> > + * drm_for_each_connector_iter - connector_list iterator macro
> > + * @connector: struct &drm_connector pointer used as cursor
> > + * @iter: struct &drm_connector_list_iter
> > + *
> > + * Note that @connector is only valid within the list body, if you want to use
> > + * @connector after calling drm_connector_list_iter_put() then you need to grab
> > + * your own reference first using drm_connector_reference().
> > + */
> > +#define drm_for_each_connector_iter(connector, iter) \
> > +	while ((connector = drm_connector_list_iter_next(iter)))
> > +
> 
> Observe that in most, if not all, cases you lock over the for loop, but
> not more. That means you always get/put right around the loop.
> 
> You could have a variant of get() that returns the first item, and a
> variant of next() that does put() automatically when it's about to
> return NULL, and implement most of the loops like this:
> 
> #define drm_for_each_connector_simple(dev, iter, connector) \
> 	for (connector = drm_connector_list_iter_get_first(dev, iter); \
> 	     connector != NULL; \
> 	     connector = drm_connector_list_iter_next_put(iter))
> 
> In the long run, that should be called just drm_for_each_connector.
> 
> The only case where you'd have to call put() explicitly is when you
> break out of the loop early. Otherwise all looping would be dead simple,
> without all the gets and puts, just like they are now. Perhaps the
> naming of the functions should be such that this is the most common
> case. Perhaps you don't actually need the versions with "manual" locking
> at all.

I had this in an earlier iteration of this patch series. The implemenation
was somewhat misguided (as in it used srcu and some other wizzardry that I
now managed to remove), but otherwise was exactly what you've asking for
here.

The amount of leaking was mindboggling.

And that was only me being sloppyin in converting the piles of existing
loop, not even ongoing maintenance of new loops additions done by people
who're not well versed in the finer details of connector_list walking and
the refcounting dance involved.

Given that I've concluded that hiding those details is a bad choice, and
to top it off the new code enforces matching get/put using lockdep. We do
pay a price in that simple loops become a bit more verbose, but
unfortunately there's no way to create something which is guarnateed to
get destructed when leaving a code block (unlike in C++). And without that
guarantee I don't think it'll be maintainable long-term.

I expect that drm_for_each_connector will stay around for a long time
(maybe even forever). As long as your driver doesn't hotplug connectors,
it's perfectly fine. Only core + helpers + any driver supporting mst
really need to switch over.

Overall not the prettiest thing, but still an acceptable tradeoff imo.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs
  2016-12-13 23:08 ` [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs Daniel Vetter
@ 2016-12-14 14:44   ` Jani Nikula
  2016-12-14 14:51     ` [Intel-gfx] " Daniel Vetter
  0 siblings, 1 reply; 41+ messages in thread
From: Jani Nikula @ 2016-12-14 14:44 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

On Wed, 14 Dec 2016, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 20bc04d5e617..7e25a7fffb1c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -481,6 +481,9 @@ struct i915_hotplug {
>  			    &(dev)->mode_config.connector_list,	\
>  			    base.head)
>  
> +#define for_each_intel_connector_iter(intel_connector, iter) \
> +	while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter))))

I occasionally worry about us relying on the base struct always being
the first member. We don't even document this requirement anywhere.


BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Intel-gfx] [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs
  2016-12-14 14:44   ` Jani Nikula
@ 2016-12-14 14:51     ` Daniel Vetter
  0 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-14 14:51 UTC (permalink / raw)
  To: Jani Nikula; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Dec 14, 2016 at 3:44 PM, Jani Nikula
<jani.nikula@linux.intel.com> wrote:
> On Wed, 14 Dec 2016, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 20bc04d5e617..7e25a7fffb1c 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -481,6 +481,9 @@ struct i915_hotplug {
>>                           &(dev)->mode_config.connector_list, \
>>                           base.head)
>>
>> +#define for_each_intel_connector_iter(intel_connector, iter) \
>> +     while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter))))
>
> I occasionally worry about us relying on the base struct always being
> the first member. We don't even document this requirement anywhere.

In the cases where we misplaced the base struct we fixed up our to_foo
cast macros to correctly cast NULL pointers. Anything else just goes
boom sooner or later ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Intel-gfx] [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-14 12:26     ` Daniel Vetter
@ 2016-12-14 15:04       ` Jani Nikula
  0 siblings, 0 replies; 41+ messages in thread
From: Jani Nikula @ 2016-12-14 15:04 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Wed, 14 Dec 2016, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Wed, Dec 14, 2016 at 01:22:15PM +0200, Jani Nikula wrote:
>> On Wed, 14 Dec 2016, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>> > +/**
>> > + * drm_for_each_connector_iter - connector_list iterator macro
>> > + * @connector: struct &drm_connector pointer used as cursor
>> > + * @iter: struct &drm_connector_list_iter
>> > + *
>> > + * Note that @connector is only valid within the list body, if you want to use
>> > + * @connector after calling drm_connector_list_iter_put() then you need to grab
>> > + * your own reference first using drm_connector_reference().
>> > + */
>> > +#define drm_for_each_connector_iter(connector, iter) \
>> > +	while ((connector = drm_connector_list_iter_next(iter)))
>> > +
>> 
>> Observe that in most, if not all, cases you lock over the for loop, but
>> not more. That means you always get/put right around the loop.
>> 
>> You could have a variant of get() that returns the first item, and a
>> variant of next() that does put() automatically when it's about to
>> return NULL, and implement most of the loops like this:
>> 
>> #define drm_for_each_connector_simple(dev, iter, connector) \
>> 	for (connector = drm_connector_list_iter_get_first(dev, iter); \
>> 	     connector != NULL; \
>> 	     connector = drm_connector_list_iter_next_put(iter))
>> 
>> In the long run, that should be called just drm_for_each_connector.
>> 
>> The only case where you'd have to call put() explicitly is when you
>> break out of the loop early. Otherwise all looping would be dead simple,
>> without all the gets and puts, just like they are now. Perhaps the
>> naming of the functions should be such that this is the most common
>> case. Perhaps you don't actually need the versions with "manual" locking
>> at all.
>
> I had this in an earlier iteration of this patch series. The implemenation
> was somewhat misguided (as in it used srcu and some other wizzardry that I
> now managed to remove), but otherwise was exactly what you've asking for
> here.
>
> The amount of leaking was mindboggling.
>
> And that was only me being sloppyin in converting the piles of existing
> loop, not even ongoing maintenance of new loops additions done by people
> who're not well versed in the finer details of connector_list walking and
> the refcounting dance involved.
>
> Given that I've concluded that hiding those details is a bad choice, and
> to top it off the new code enforces matching get/put using lockdep. We do
> pay a price in that simple loops become a bit more verbose, but
> unfortunately there's no way to create something which is guarnateed to
> get destructed when leaving a code block (unlike in C++). And without that
> guarantee I don't think it'll be maintainable long-term.
>
> I expect that drm_for_each_connector will stay around for a long time
> (maybe even forever). As long as your driver doesn't hotplug connectors,
> it's perfectly fine. Only core + helpers + any driver supporting mst
> really need to switch over.
>
> Overall not the prettiest thing, but still an acceptable tradeoff imo.

Fair enough.

Jani.


-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check
  2016-12-13 23:08 ` [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check Daniel Vetter
@ 2016-12-14 16:59   ` Alex Deucher
  0 siblings, 0 replies; 41+ messages in thread
From: Alex Deucher @ 2016-12-14 16:59 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> The list walk will shortcircuit anyway.
>
> Cc: Alex Deucher <alexdeucher@gmail.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |  6 ++----
>  drivers/gpu/drm/radeon/radeon_irq_kms.c | 12 ++++--------
>  2 files changed, 6 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index fb902932f571..e63ece049b05 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -61,10 +61,8 @@ static void amdgpu_hotplug_work_func(struct work_struct *work)
>         struct drm_connector *connector;
>
>         mutex_lock(&mode_config->mutex);
> -       if (mode_config->num_connector) {
> -               list_for_each_entry(connector, &mode_config->connector_list, head)
> -                       amdgpu_connector_hotplug(connector);
> -       }
> +       list_for_each_entry(connector, &mode_config->connector_list, head)
> +               amdgpu_connector_hotplug(connector);
>         mutex_unlock(&mode_config->mutex);
>         /* Just fire off a uevent and let userspace tell us what to do */
>         drm_helper_hpd_irq_event(dev);
> diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
> index c084cadcbf21..1b7528df7f7f 100644
> --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
> +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
> @@ -85,10 +85,8 @@ static void radeon_hotplug_work_func(struct work_struct *work)
>                 return;
>
>         mutex_lock(&mode_config->mutex);
> -       if (mode_config->num_connector) {
> -               list_for_each_entry(connector, &mode_config->connector_list, head)
> -                       radeon_connector_hotplug(connector);
> -       }
> +       list_for_each_entry(connector, &mode_config->connector_list, head)
> +               radeon_connector_hotplug(connector);
>         mutex_unlock(&mode_config->mutex);
>         /* Just fire off a uevent and let userspace tell us what to do */
>         drm_helper_hpd_irq_event(dev);
> @@ -103,10 +101,8 @@ static void radeon_dp_work_func(struct work_struct *work)
>         struct drm_connector *connector;
>
>         /* this should take a mutex */
> -       if (mode_config->num_connector) {
> -               list_for_each_entry(connector, &mode_config->connector_list, head)
> -                       radeon_connector_hotplug(connector);
> -       }
> +       list_for_each_entry(connector, &mode_config->connector_list, head)
> +               radeon_connector_hotplug(connector);
>  }
>  /**
>   * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
> --
> 2.11.0
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter
  2016-12-13 23:08 ` [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter Daniel Vetter
@ 2016-12-15 14:34   ` Harry Wentland
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
  1 sibling, 0 replies; 41+ messages in thread
From: Harry Wentland @ 2016-12-15 14:34 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Intel Graphics Development

On 2016-12-13 06:08 PM, Daniel Vetter wrote:
> Mostly nothing special (except making sure that really all error paths
> and friends call iter_put).
>
> v2: Don't forget the raw connector_list walking in
> drm_helper_move_panel_connectors_to_head. That one unfortunately can't
> be converted to the iterator helpers, but since it's just some list
> splicing best to just wrap the entire thing up in one critical
> section.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c  | 39 ++++++++++++++++++++--------
>  drivers/gpu/drm/drm_crtc_helper.c    | 49 ++++++++++++++++++++++++++++--------
>  drivers/gpu/drm/drm_fb_helper.c      | 12 ++++++---
>  drivers/gpu/drm/drm_modeset_helper.c |  2 ++
>  drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
>  drivers/gpu/drm/drm_probe_helper.c   | 18 ++++++++-----
>  6 files changed, 92 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 23767df72615..e2e15a9903a9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  {
>  	struct drm_connector_state *conn_state;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_encoder *encoder;
>  	unsigned encoder_mask = 0;
> -	int i, ret;
> +	int i, ret = 0;
>
>  	/*
>  	 * First loop, find all newly assigned encoders from the connectors
> @@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  	 * and the crtc is disabled if no encoder is left. This preserves
>  	 * compatibility with the legacy set_config behavior.
>  	 */
> -	drm_for_each_connector(connector, state->dev) {
> +	drm_connector_list_iter_get(state->dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		struct drm_crtc_state *crtc_state;
>
>  		if (drm_atomic_get_existing_connector_state(state, connector))
> @@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  					 connector->state->crtc->base.id,
>  					 connector->state->crtc->name,
>  					 connector->base.id, connector->name);
> -			return -EINVAL;
> +			ret = -EINVAL;
> +			goto out;
>  		}
>
>  		conn_state = drm_atomic_get_connector_state(state, connector);
> -		if (IS_ERR(conn_state))
> -			return PTR_ERR(conn_state);
> +		if (IS_ERR(conn_state)) {
> +			ret = PTR_ERR(conn_state);
> +			goto out;
> +		}
>
>  		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
>  				 encoder->base.id, encoder->name,
> @@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>
>  		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
>  		if (ret)
> -			return ret;
> +			goto out;
>
>  		if (!crtc_state->connector_mask) {
>  			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
>  								NULL);
>  			if (ret < 0)
> -				return ret;
> +				goto out;
>
>  			crtc_state->active = false;
>  		}
>  	}
> +out:
> +	drm_connector_list_iter_put(&conn_iter);
>
> -	return 0;
> +	return ret;
>  }
>
>  static void
> @@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>  {
>  	struct drm_atomic_state *state;
>  	struct drm_connector *conn;
> +	struct drm_connector_list_iter conn_iter;
>  	int err;
>
>  	state = drm_atomic_state_alloc(dev);
> @@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>  	state->acquire_ctx = ctx;
>
> -	drm_for_each_connector(conn, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(conn, &conn_iter) {
>  		struct drm_crtc *crtc = conn->state->crtc;
>  		struct drm_crtc_state *crtc_state;
>
> @@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>  	err = drm_atomic_commit(state);
>  free:
> +	drm_connector_list_iter_put(&conn_iter);
>  	drm_atomic_state_put(state);
>  	return err;
>  }
> @@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>  	struct drm_crtc_state *crtc_state;
>  	struct drm_crtc *crtc;
>  	struct drm_connector *tmp_connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int ret;
>  	bool active = false;
>  	int old_mode = connector->dpms;
> @@ -2867,7 +2878,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>
>  	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
>
> -	drm_for_each_connector(tmp_connector, connector->dev) {
> +	drm_connector_list_iter_get(connector->dev, &conn_iter);
> +	drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>  		if (tmp_connector->state->crtc != crtc)
>  			continue;
>
> @@ -2876,6 +2888,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>  			break;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  	crtc_state->active = active;
>
>  	ret = drm_atomic_commit(state);
> @@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>  {
>  	struct drm_atomic_state *state;
>  	struct drm_connector *conn;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_plane *plane;
>  	struct drm_crtc *crtc;
>  	int err = 0;
> @@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>  		}
>  	}
>
> -	drm_for_each_connector(conn, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(conn, &conn_iter) {
>  		struct drm_connector_state *conn_state;
>
>  		conn_state = drm_atomic_get_connector_state(state, conn);
>  		if (IS_ERR(conn_state)) {
>  			err = PTR_ERR(conn_state);
> +			drm_connector_list_iter_put(&conn_iter);
>  			goto free;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* clear the acquire context so that it isn't accidentally reused */
>  	state->acquire_ctx = NULL;
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 5d2cb138eba6..476e6d4b95f4 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -88,6 +88,7 @@
>  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>  {
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = encoder->dev;
>
>  	/*
> @@ -99,9 +100,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>  		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>  	}
>
> -	drm_for_each_connector(connector, dev)
> -		if (connector->encoder == encoder)
> +
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
> +		if (connector->encoder == encoder) {
>  			return true;
> +			drm_connector_list_iter_put(&conn_iter);

Probably should put the conn_iter before returning :)

With that fixed this is
Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry


> +		}
> +	}
> +	drm_connector_list_iter_put(&conn_iter);
>  	return false;
>  }
>  EXPORT_SYMBOL(drm_helper_encoder_in_use);
> @@ -436,10 +443,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>
>  	/* Decouple all encoders and their attached connectors from this crtc */
>  	drm_for_each_encoder(encoder, dev) {
> +		struct drm_connector_list_iter conn_iter;
> +
>  		if (encoder->crtc != crtc)
>  			continue;
>
> -		drm_for_each_connector(connector, dev) {
> +		drm_connector_list_iter_get(dev, &conn_iter);
> +		drm_for_each_connector_iter(connector, &conn_iter) {
>  			if (connector->encoder != encoder)
>  				continue;
>
> @@ -456,6 +466,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>  			/* we keep a reference while the encoder is bound */
>  			drm_connector_unreference(connector);
>  		}
> +		drm_connector_list_iter_put(&conn_iter);
>  	}
>
>  	__drm_helper_disable_unused_functions(dev);
> @@ -507,6 +518,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	bool mode_changed = false; /* if true do a full mode set */
>  	bool fb_changed = false; /* if true and !mode_changed just do a flip */
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int count = 0, ro, fail = 0;
>  	const struct drm_crtc_helper_funcs *crtc_funcs;
>  	struct drm_mode_set save_set;
> @@ -571,9 +583,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		save_connector_encoders[count++] = connector->encoder;
> -	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	save_set.crtc = set->crtc;
>  	save_set.mode = &set->crtc->mode;
> @@ -616,7 +629,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>
>  	/* a) traverse passed in connector list and get encoders for them */
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		const struct drm_connector_helper_funcs *connector_funcs =
>  			connector->helper_private;
>  		new_encoder = connector->encoder;
> @@ -649,6 +663,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  			connector->encoder = new_encoder;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	if (fail) {
>  		ret = -EINVAL;
> @@ -656,7 +671,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (!connector->encoder)
>  			continue;
>
> @@ -674,6 +690,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  		if (new_crtc &&
>  		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
>  			ret = -EINVAL;
> +			drm_connector_list_iter_put(&conn_iter);
>  			goto fail;
>  		}
>  		if (new_crtc != connector->encoder->crtc) {
> @@ -690,6 +707,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  				      connector->base.id, connector->name);
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* mode_set_base is not a required function */
>  	if (fb_changed && !crtc_funcs->mode_set_base)
> @@ -744,9 +762,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		connector->encoder = save_connector_encoders[count++];
> -	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* after fail drop reference on all unbound connectors in set, let
>  	 * bound connectors keep their reference
> @@ -773,12 +792,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
>  {
>  	int dpms = DRM_MODE_DPMS_OFF;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = encoder->dev;
>
> -	drm_for_each_connector(connector, dev)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		if (connector->encoder == encoder)
>  			if (connector->dpms < dpms)
>  				dpms = connector->dpms;
> +	drm_connector_list_iter_put(&conn_iter);
> +
>  	return dpms;
>  }
>
> @@ -810,12 +833,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
>  {
>  	int dpms = DRM_MODE_DPMS_OFF;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = crtc->dev;
>
> -	drm_for_each_connector(connector, dev)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		if (connector->encoder && connector->encoder->crtc == crtc)
>  			if (connector->dpms < dpms)
>  				dpms = connector->dpms;
> +	drm_connector_list_iter_put(&conn_iter);
> +
>  	return dpms;
>  }
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index e934b541feea..8f5937616f01 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>  {
>  	struct drm_device *dev = fb_helper->dev;
>  	struct drm_connector *connector;
> -	int i, ret;
> +	struct drm_connector_list_iter conn_iter;
> +	int i, ret = 0;
>
>  	if (!drm_fbdev_emulation)
>  		return 0;
>
>  	mutex_lock(&dev->mode_config.mutex);
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		ret = drm_fb_helper_add_one_connector(fb_helper, connector);
>
>  		if (ret)
>  			goto fail;
>  	}
> -	mutex_unlock(&dev->mode_config.mutex);
> -	return 0;
> +	goto out;
> +
>  fail:
>  	drm_fb_helper_for_each_connector(fb_helper, i) {
>  		struct drm_fb_helper_connector *fb_helper_connector =
> @@ -145,6 +147,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>  		fb_helper->connector_info[i] = NULL;
>  	}
>  	fb_helper->connector_count = 0;
> +out:
> +	drm_connector_list_iter_put(&conn_iter);
>  	mutex_unlock(&dev->mode_config.mutex);
>
>  	return ret;
> diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
> index cc232ac6c950..43789f606c37 100644
> --- a/drivers/gpu/drm/drm_modeset_helper.c
> +++ b/drivers/gpu/drm/drm_modeset_helper.c
> @@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>
>  	INIT_LIST_HEAD(&panel_list);
>
> +	spin_lock_irq(&dev->mode_config.connector_list_lock);
>  	list_for_each_entry_safe(connector, tmp,
>  				 &dev->mode_config.connector_list, head) {
>  		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
> @@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>  	}
>
>  	list_splice(&panel_list, &dev->mode_config.connector_list);
> +	spin_unlock_irq(&dev->mode_config.connector_list_lock);
>  }
>  EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
>
> diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
> index 7a7dddf604d7..bc9f97422cd1 100644
> --- a/drivers/gpu/drm/drm_plane_helper.c
> +++ b/drivers/gpu/drm/drm_plane_helper.c
> @@ -74,6 +74,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int count = 0;
>
>  	/*
> @@ -83,7 +84,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  	 */
>  	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->encoder && connector->encoder->crtc == crtc) {
>  			if (connector_list != NULL && count < num_connectors)
>  				*(connector_list++) = connector;
> @@ -91,6 +93,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  			count++;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	return count;
>  }
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index ac953f037be7..7cff91e7497f 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>  {
>  	bool poll = false;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
>
>  	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
> @@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>  	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
>  		return;
>
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
>  					 DRM_CONNECTOR_POLL_DISCONNECT))
>  			poll = true;
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	if (dev->mode_config.delayed_event) {
>  		poll = true;
> @@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
>  	struct delayed_work *delayed_work = to_delayed_work(work);
>  	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	enum drm_connector_status old_status;
>  	bool repoll = false, changed;
>
> @@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
>  		goto out;
>  	}
>
> -	drm_for_each_connector(connector, dev) {
> -
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		/* Ignore forced connectors. */
>  		if (connector->force)
>  			continue;
> @@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
>  			changed = true;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	mutex_unlock(&dev->mode_config.mutex);
>
> @@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
>  bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  {
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	enum drm_connector_status old_status;
>  	bool changed = false;
>
> @@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  		return false;
>
>  	mutex_lock(&dev->mode_config.mutex);
> -	drm_for_each_connector(connector, dev) {
> -
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		/* Only handle HPD capable connectors. */
>  		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
>  			continue;
> @@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  		if (old_status != connector->status)
>  			changed = true;
>  	}
> -
> +	drm_connector_list_iter_put(&conn_iter);
>  	mutex_unlock(&dev->mode_config.mutex);
>
>  	if (changed)
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 07/13] drm: Clean up connectors by unreferencing them
  2016-12-13 23:08 ` [PATCH 07/13] drm: Clean up connectors by unreferencing them Daniel Vetter
@ 2016-12-15 15:45   ` Harry Wentland
  2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Harry Wentland @ 2016-12-15 15:45 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

On 2016-12-13 06:08 PM, Daniel Vetter wrote:
> Only static connectors should be left at this point, and we should be
> able to clean them out by simply dropping that last reference still
> around from drm_connector_init.
>
> If that leaves anything behind then we have a driver bug.
>
> Doing the final cleanup this way also allows us to use
> drm_connector_iter, removing the very last place where we walk
> connector_list explicitly in drm core&helpers.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_mode_config.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 747a26df0e90..a942536abd60 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -397,7 +397,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
>   */
>  void drm_mode_config_cleanup(struct drm_device *dev)
>  {
> -	struct drm_connector *connector, *ot;
> +	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_crtc *crtc, *ct;
>  	struct drm_encoder *encoder, *enct;
>  	struct drm_framebuffer *fb, *fbt;
> @@ -410,10 +411,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>  		encoder->funcs->destroy(encoder);
>  	}
>
> -	list_for_each_entry_safe(connector, ot,
> -				 &dev->mode_config.connector_list, head) {
> -		connector->funcs->destroy(connector);
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
> +		/* drm_connector_list_iter holds an full reference to the
> +		 * current connector itself, which means it is inherently safe
> +		 * against unreferencing the current connector - but not against
> +		 * deleting it right away. */
> +		drm_connector_unreference(connector);
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
> +	WARN_ON(!list_empty(&dev->mode_config.connector_list));
>
>  	list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
>  				 head) {
>

Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-13 23:08 ` [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter Daniel Vetter
  2016-12-15 14:34   ` Harry Wentland
@ 2016-12-15 15:58   ` Daniel Vetter
  2016-12-15 16:32     ` Harry Wentland
                       ` (3 more replies)
  1 sibling, 4 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-15 15:58 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Harry Wentland

Mostly nothing special (except making sure that really all error paths
and friends call iter_put).

v2: Don't forget the raw connector_list walking in
drm_helper_move_panel_connectors_to_head. That one unfortunately can't
be converted to the iterator helpers, but since it's just some list
splicing best to just wrap the entire thing up in one critical
section.

v3: Bail out after iter_put (Harry).

Cc: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic_helper.c  | 39 ++++++++++++++++++++--------
 drivers/gpu/drm/drm_crtc_helper.c    | 49 ++++++++++++++++++++++++++++--------
 drivers/gpu/drm/drm_fb_helper.c      | 12 ++++++---
 drivers/gpu/drm/drm_modeset_helper.c |  2 ++
 drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
 drivers/gpu/drm/drm_probe_helper.c   | 18 ++++++++-----
 6 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 23767df72615..e2e15a9903a9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 {
 	struct drm_connector_state *conn_state;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_encoder *encoder;
 	unsigned encoder_mask = 0;
-	int i, ret;
+	int i, ret = 0;
 
 	/*
 	 * First loop, find all newly assigned encoders from the connectors
@@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 	 * and the crtc is disabled if no encoder is left. This preserves
 	 * compatibility with the legacy set_config behavior.
 	 */
-	drm_for_each_connector(connector, state->dev) {
+	drm_connector_list_iter_get(state->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		struct drm_crtc_state *crtc_state;
 
 		if (drm_atomic_get_existing_connector_state(state, connector))
@@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 					 connector->state->crtc->base.id,
 					 connector->state->crtc->name,
 					 connector->base.id, connector->name);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 
 		conn_state = drm_atomic_get_connector_state(state, connector);
-		if (IS_ERR(conn_state))
-			return PTR_ERR(conn_state);
+		if (IS_ERR(conn_state)) {
+			ret = PTR_ERR(conn_state);
+			goto out;
+		}
 
 		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
 				 encoder->base.id, encoder->name,
@@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 
 		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
 		if (ret)
-			return ret;
+			goto out;
 
 		if (!crtc_state->connector_mask) {
 			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
 								NULL);
 			if (ret < 0)
-				return ret;
+				goto out;
 
 			crtc_state->active = false;
 		}
 	}
+out:
+	drm_connector_list_iter_put(&conn_iter);
 
-	return 0;
+	return ret;
 }
 
 static void
@@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 {
 	struct drm_atomic_state *state;
 	struct drm_connector *conn;
+	struct drm_connector_list_iter conn_iter;
 	int err;
 
 	state = drm_atomic_state_alloc(dev);
@@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
 	state->acquire_ctx = ctx;
 
-	drm_for_each_connector(conn, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(conn, &conn_iter) {
 		struct drm_crtc *crtc = conn->state->crtc;
 		struct drm_crtc_state *crtc_state;
 
@@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
 	err = drm_atomic_commit(state);
 free:
+	drm_connector_list_iter_put(&conn_iter);
 	drm_atomic_state_put(state);
 	return err;
 }
@@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 	struct drm_crtc_state *crtc_state;
 	struct drm_crtc *crtc;
 	struct drm_connector *tmp_connector;
+	struct drm_connector_list_iter conn_iter;
 	int ret;
 	bool active = false;
 	int old_mode = connector->dpms;
@@ -2867,7 +2878,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 
 	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
 
-	drm_for_each_connector(tmp_connector, connector->dev) {
+	drm_connector_list_iter_get(connector->dev, &conn_iter);
+	drm_for_each_connector_iter(tmp_connector, &conn_iter) {
 		if (tmp_connector->state->crtc != crtc)
 			continue;
 
@@ -2876,6 +2888,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 			break;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 	crtc_state->active = active;
 
 	ret = drm_atomic_commit(state);
@@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
 {
 	struct drm_atomic_state *state;
 	struct drm_connector *conn;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 	int err = 0;
@@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
 		}
 	}
 
-	drm_for_each_connector(conn, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(conn, &conn_iter) {
 		struct drm_connector_state *conn_state;
 
 		conn_state = drm_atomic_get_connector_state(state, conn);
 		if (IS_ERR(conn_state)) {
 			err = PTR_ERR(conn_state);
+			drm_connector_list_iter_put(&conn_iter);
 			goto free;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* clear the acquire context so that it isn't accidentally reused */
 	state->acquire_ctx = NULL;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9d007f5f9732..ad154325a0fd 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -88,6 +88,7 @@
 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 {
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = encoder->dev;
 
 	/*
@@ -99,9 +100,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 	}
 
-	drm_for_each_connector(connector, dev)
-		if (connector->encoder == encoder)
+
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (connector->encoder == encoder) {
+			drm_connector_list_iter_put(&conn_iter);
 			return true;
+		}
+	}
+	drm_connector_list_iter_put(&conn_iter);
 	return false;
 }
 EXPORT_SYMBOL(drm_helper_encoder_in_use);
@@ -436,10 +443,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
 
 	/* Decouple all encoders and their attached connectors from this crtc */
 	drm_for_each_encoder(encoder, dev) {
+		struct drm_connector_list_iter conn_iter;
+
 		if (encoder->crtc != crtc)
 			continue;
 
-		drm_for_each_connector(connector, dev) {
+		drm_connector_list_iter_get(dev, &conn_iter);
+		drm_for_each_connector_iter(connector, &conn_iter) {
 			if (connector->encoder != encoder)
 				continue;
 
@@ -456,6 +466,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
 			/* we keep a reference while the encoder is bound */
 			drm_connector_unreference(connector);
 		}
+		drm_connector_list_iter_put(&conn_iter);
 	}
 
 	__drm_helper_disable_unused_functions(dev);
@@ -507,6 +518,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	bool mode_changed = false; /* if true do a full mode set */
 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int count = 0, ro, fail = 0;
 	const struct drm_crtc_helper_funcs *crtc_funcs;
 	struct drm_mode_set save_set;
@@ -571,9 +583,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		save_connector_encoders[count++] = connector->encoder;
-	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	save_set.crtc = set->crtc;
 	save_set.mode = &set->crtc->mode;
@@ -615,7 +628,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
 	/* a) traverse passed in connector list and get encoders for them */
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		const struct drm_connector_helper_funcs *connector_funcs =
 			connector->helper_private;
 		new_encoder = connector->encoder;
@@ -648,6 +662,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 			connector->encoder = new_encoder;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (fail) {
 		ret = -EINVAL;
@@ -655,7 +670,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (!connector->encoder)
 			continue;
 
@@ -673,6 +689,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		if (new_crtc &&
 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
 			ret = -EINVAL;
+			drm_connector_list_iter_put(&conn_iter);
 			goto fail;
 		}
 		if (new_crtc != connector->encoder->crtc) {
@@ -689,6 +706,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 				      connector->base.id, connector->name);
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* mode_set_base is not a required function */
 	if (fb_changed && !crtc_funcs->mode_set_base)
@@ -743,9 +761,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 
 	count = 0;
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		connector->encoder = save_connector_encoders[count++];
-	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	/* after fail drop reference on all unbound connectors in set, let
 	 * bound connectors keep their reference
@@ -772,12 +791,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
 {
 	int dpms = DRM_MODE_DPMS_OFF;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = encoder->dev;
 
-	drm_for_each_connector(connector, dev)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		if (connector->encoder == encoder)
 			if (connector->dpms < dpms)
 				dpms = connector->dpms;
+	drm_connector_list_iter_put(&conn_iter);
+
 	return dpms;
 }
 
@@ -809,12 +832,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
 {
 	int dpms = DRM_MODE_DPMS_OFF;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_device *dev = crtc->dev;
 
-	drm_for_each_connector(connector, dev)
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter)
 		if (connector->encoder && connector->encoder->crtc == crtc)
 			if (connector->dpms < dpms)
 				dpms = connector->dpms;
+	drm_connector_list_iter_put(&conn_iter);
+
 	return dpms;
 }
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index bee5e4149a1c..145d55fef69e 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 {
 	struct drm_device *dev = fb_helper->dev;
 	struct drm_connector *connector;
-	int i, ret;
+	struct drm_connector_list_iter conn_iter;
+	int i, ret = 0;
 
 	if (!drm_fbdev_emulation)
 		return 0;
 
 	mutex_lock(&dev->mode_config.mutex);
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		ret = drm_fb_helper_add_one_connector(fb_helper, connector);
 
 		if (ret)
 			goto fail;
 	}
-	mutex_unlock(&dev->mode_config.mutex);
-	return 0;
+	goto out;
+
 fail:
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_fb_helper_connector *fb_helper_connector =
@@ -145,6 +147,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 		fb_helper->connector_info[i] = NULL;
 	}
 	fb_helper->connector_count = 0;
+out:
+	drm_connector_list_iter_put(&conn_iter);
 	mutex_unlock(&dev->mode_config.mutex);
 
 	return ret;
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 5b051859b8d3..5d8fa791fff5 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
 
 	INIT_LIST_HEAD(&panel_list);
 
+	spin_lock_irq(&dev->mode_config.connector_list_lock);
 	list_for_each_entry_safe(connector, tmp,
 				 &dev->mode_config.connector_list, head) {
 		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
@@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
 	}
 
 	list_splice(&panel_list, &dev->mode_config.connector_list);
+	spin_unlock_irq(&dev->mode_config.connector_list_lock);
 }
 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
 
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 7a7dddf604d7..bc9f97422cd1 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -74,6 +74,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	int count = 0;
 
 	/*
@@ -83,7 +84,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 	 */
 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->encoder && connector->encoder->crtc == crtc) {
 			if (connector_list != NULL && count < num_connectors)
 				*(connector_list++) = connector;
@@ -91,6 +93,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 			count++;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	return count;
 }
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index ac953f037be7..7cff91e7497f 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
 {
 	bool poll = false;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
 
 	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
@@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
 	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
 		return;
 
-	drm_for_each_connector(connector, dev) {
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
 					 DRM_CONNECTOR_POLL_DISCONNECT))
 			poll = true;
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	if (dev->mode_config.delayed_event) {
 		poll = true;
@@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
 	struct delayed_work *delayed_work = to_delayed_work(work);
 	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	enum drm_connector_status old_status;
 	bool repoll = false, changed;
 
@@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
 		goto out;
 	}
 
-	drm_for_each_connector(connector, dev) {
-
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		/* Ignore forced connectors. */
 		if (connector->force)
 			continue;
@@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
 			changed = true;
 		}
 	}
+	drm_connector_list_iter_put(&conn_iter);
 
 	mutex_unlock(&dev->mode_config.mutex);
 
@@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 bool drm_helper_hpd_irq_event(struct drm_device *dev)
 {
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 	enum drm_connector_status old_status;
 	bool changed = false;
 
@@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
 		return false;
 
 	mutex_lock(&dev->mode_config.mutex);
-	drm_for_each_connector(connector, dev) {
-
+	drm_connector_list_iter_get(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		/* Only handle HPD capable connectors. */
 		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
 			continue;
@@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
 		if (old_status != connector->status)
 			changed = true;
 	}
-
+	drm_connector_list_iter_put(&conn_iter);
 	mutex_unlock(&dev->mode_config.mutex);
 
 	if (changed)
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
@ 2016-12-15 16:32     ` Harry Wentland
  2016-12-15 22:47     ` kbuild test robot
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 41+ messages in thread
From: Harry Wentland @ 2016-12-15 16:32 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Intel Graphics Development

Reviewed-by: Harry Wentland: <harry.wentland@amd.com>

On 2016-12-15 10:58 AM, Daniel Vetter wrote:
> Mostly nothing special (except making sure that really all error paths
> and friends call iter_put).
>
> v2: Don't forget the raw connector_list walking in
> drm_helper_move_panel_connectors_to_head. That one unfortunately can't
> be converted to the iterator helpers, but since it's just some list
> splicing best to just wrap the entire thing up in one critical
> section.
>
> v3: Bail out after iter_put (Harry).
>
> Cc: Harry Wentland <harry.wentland@amd.com>
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c  | 39 ++++++++++++++++++++--------
>  drivers/gpu/drm/drm_crtc_helper.c    | 49 ++++++++++++++++++++++++++++--------
>  drivers/gpu/drm/drm_fb_helper.c      | 12 ++++++---
>  drivers/gpu/drm/drm_modeset_helper.c |  2 ++
>  drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
>  drivers/gpu/drm/drm_probe_helper.c   | 18 ++++++++-----
>  6 files changed, 92 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 23767df72615..e2e15a9903a9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  {
>  	struct drm_connector_state *conn_state;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_encoder *encoder;
>  	unsigned encoder_mask = 0;
> -	int i, ret;
> +	int i, ret = 0;
>
>  	/*
>  	 * First loop, find all newly assigned encoders from the connectors
> @@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  	 * and the crtc is disabled if no encoder is left. This preserves
>  	 * compatibility with the legacy set_config behavior.
>  	 */
> -	drm_for_each_connector(connector, state->dev) {
> +	drm_connector_list_iter_get(state->dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		struct drm_crtc_state *crtc_state;
>
>  		if (drm_atomic_get_existing_connector_state(state, connector))
> @@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  					 connector->state->crtc->base.id,
>  					 connector->state->crtc->name,
>  					 connector->base.id, connector->name);
> -			return -EINVAL;
> +			ret = -EINVAL;
> +			goto out;
>  		}
>
>  		conn_state = drm_atomic_get_connector_state(state, connector);
> -		if (IS_ERR(conn_state))
> -			return PTR_ERR(conn_state);
> +		if (IS_ERR(conn_state)) {
> +			ret = PTR_ERR(conn_state);
> +			goto out;
> +		}
>
>  		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
>  				 encoder->base.id, encoder->name,
> @@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>
>  		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
>  		if (ret)
> -			return ret;
> +			goto out;
>
>  		if (!crtc_state->connector_mask) {
>  			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
>  								NULL);
>  			if (ret < 0)
> -				return ret;
> +				goto out;
>
>  			crtc_state->active = false;
>  		}
>  	}
> +out:
> +	drm_connector_list_iter_put(&conn_iter);
>
> -	return 0;
> +	return ret;
>  }
>
>  static void
> @@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>  {
>  	struct drm_atomic_state *state;
>  	struct drm_connector *conn;
> +	struct drm_connector_list_iter conn_iter;
>  	int err;
>
>  	state = drm_atomic_state_alloc(dev);
> @@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>  	state->acquire_ctx = ctx;
>
> -	drm_for_each_connector(conn, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(conn, &conn_iter) {
>  		struct drm_crtc *crtc = conn->state->crtc;
>  		struct drm_crtc_state *crtc_state;
>
> @@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>  	err = drm_atomic_commit(state);
>  free:
> +	drm_connector_list_iter_put(&conn_iter);
>  	drm_atomic_state_put(state);
>  	return err;
>  }
> @@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>  	struct drm_crtc_state *crtc_state;
>  	struct drm_crtc *crtc;
>  	struct drm_connector *tmp_connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int ret;
>  	bool active = false;
>  	int old_mode = connector->dpms;
> @@ -2867,7 +2878,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>
>  	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
>
> -	drm_for_each_connector(tmp_connector, connector->dev) {
> +	drm_connector_list_iter_get(connector->dev, &conn_iter);
> +	drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>  		if (tmp_connector->state->crtc != crtc)
>  			continue;
>
> @@ -2876,6 +2888,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>  			break;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>  	crtc_state->active = active;
>
>  	ret = drm_atomic_commit(state);
> @@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>  {
>  	struct drm_atomic_state *state;
>  	struct drm_connector *conn;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_plane *plane;
>  	struct drm_crtc *crtc;
>  	int err = 0;
> @@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>  		}
>  	}
>
> -	drm_for_each_connector(conn, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(conn, &conn_iter) {
>  		struct drm_connector_state *conn_state;
>
>  		conn_state = drm_atomic_get_connector_state(state, conn);
>  		if (IS_ERR(conn_state)) {
>  			err = PTR_ERR(conn_state);
> +			drm_connector_list_iter_put(&conn_iter);
>  			goto free;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* clear the acquire context so that it isn't accidentally reused */
>  	state->acquire_ctx = NULL;
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 9d007f5f9732..ad154325a0fd 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -88,6 +88,7 @@
>  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>  {
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = encoder->dev;
>
>  	/*
> @@ -99,9 +100,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>  		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>  	}
>
> -	drm_for_each_connector(connector, dev)
> -		if (connector->encoder == encoder)
> +
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
> +		if (connector->encoder == encoder) {
> +			drm_connector_list_iter_put(&conn_iter);
>  			return true;
> +		}
> +	}
> +	drm_connector_list_iter_put(&conn_iter);
>  	return false;
>  }
>  EXPORT_SYMBOL(drm_helper_encoder_in_use);
> @@ -436,10 +443,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>
>  	/* Decouple all encoders and their attached connectors from this crtc */
>  	drm_for_each_encoder(encoder, dev) {
> +		struct drm_connector_list_iter conn_iter;
> +
>  		if (encoder->crtc != crtc)
>  			continue;
>
> -		drm_for_each_connector(connector, dev) {
> +		drm_connector_list_iter_get(dev, &conn_iter);
> +		drm_for_each_connector_iter(connector, &conn_iter) {
>  			if (connector->encoder != encoder)
>  				continue;
>
> @@ -456,6 +466,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>  			/* we keep a reference while the encoder is bound */
>  			drm_connector_unreference(connector);
>  		}
> +		drm_connector_list_iter_put(&conn_iter);
>  	}
>
>  	__drm_helper_disable_unused_functions(dev);
> @@ -507,6 +518,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	bool mode_changed = false; /* if true do a full mode set */
>  	bool fb_changed = false; /* if true and !mode_changed just do a flip */
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int count = 0, ro, fail = 0;
>  	const struct drm_crtc_helper_funcs *crtc_funcs;
>  	struct drm_mode_set save_set;
> @@ -571,9 +583,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		save_connector_encoders[count++] = connector->encoder;
> -	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	save_set.crtc = set->crtc;
>  	save_set.mode = &set->crtc->mode;
> @@ -615,7 +628,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>
>  	/* a) traverse passed in connector list and get encoders for them */
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		const struct drm_connector_helper_funcs *connector_funcs =
>  			connector->helper_private;
>  		new_encoder = connector->encoder;
> @@ -648,6 +662,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  			connector->encoder = new_encoder;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	if (fail) {
>  		ret = -EINVAL;
> @@ -655,7 +670,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (!connector->encoder)
>  			continue;
>
> @@ -673,6 +689,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  		if (new_crtc &&
>  		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
>  			ret = -EINVAL;
> +			drm_connector_list_iter_put(&conn_iter);
>  			goto fail;
>  		}
>  		if (new_crtc != connector->encoder->crtc) {
> @@ -689,6 +706,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  				      connector->base.id, connector->name);
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* mode_set_base is not a required function */
>  	if (fb_changed && !crtc_funcs->mode_set_base)
> @@ -743,9 +761,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>  	}
>
>  	count = 0;
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		connector->encoder = save_connector_encoders[count++];
> -	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	/* after fail drop reference on all unbound connectors in set, let
>  	 * bound connectors keep their reference
> @@ -772,12 +791,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
>  {
>  	int dpms = DRM_MODE_DPMS_OFF;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = encoder->dev;
>
> -	drm_for_each_connector(connector, dev)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		if (connector->encoder == encoder)
>  			if (connector->dpms < dpms)
>  				dpms = connector->dpms;
> +	drm_connector_list_iter_put(&conn_iter);
> +
>  	return dpms;
>  }
>
> @@ -809,12 +832,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
>  {
>  	int dpms = DRM_MODE_DPMS_OFF;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	struct drm_device *dev = crtc->dev;
>
> -	drm_for_each_connector(connector, dev)
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter)
>  		if (connector->encoder && connector->encoder->crtc == crtc)
>  			if (connector->dpms < dpms)
>  				dpms = connector->dpms;
> +	drm_connector_list_iter_put(&conn_iter);
> +
>  	return dpms;
>  }
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index bee5e4149a1c..145d55fef69e 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>  {
>  	struct drm_device *dev = fb_helper->dev;
>  	struct drm_connector *connector;
> -	int i, ret;
> +	struct drm_connector_list_iter conn_iter;
> +	int i, ret = 0;
>
>  	if (!drm_fbdev_emulation)
>  		return 0;
>
>  	mutex_lock(&dev->mode_config.mutex);
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		ret = drm_fb_helper_add_one_connector(fb_helper, connector);
>
>  		if (ret)
>  			goto fail;
>  	}
> -	mutex_unlock(&dev->mode_config.mutex);
> -	return 0;
> +	goto out;
> +
>  fail:
>  	drm_fb_helper_for_each_connector(fb_helper, i) {
>  		struct drm_fb_helper_connector *fb_helper_connector =
> @@ -145,6 +147,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>  		fb_helper->connector_info[i] = NULL;
>  	}
>  	fb_helper->connector_count = 0;
> +out:
> +	drm_connector_list_iter_put(&conn_iter);
>  	mutex_unlock(&dev->mode_config.mutex);
>
>  	return ret;
> diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
> index 5b051859b8d3..5d8fa791fff5 100644
> --- a/drivers/gpu/drm/drm_modeset_helper.c
> +++ b/drivers/gpu/drm/drm_modeset_helper.c
> @@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>
>  	INIT_LIST_HEAD(&panel_list);
>
> +	spin_lock_irq(&dev->mode_config.connector_list_lock);
>  	list_for_each_entry_safe(connector, tmp,
>  				 &dev->mode_config.connector_list, head) {
>  		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
> @@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>  	}
>
>  	list_splice(&panel_list, &dev->mode_config.connector_list);
> +	spin_unlock_irq(&dev->mode_config.connector_list_lock);
>  }
>  EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
>
> diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
> index 7a7dddf604d7..bc9f97422cd1 100644
> --- a/drivers/gpu/drm/drm_plane_helper.c
> +++ b/drivers/gpu/drm/drm_plane_helper.c
> @@ -74,6 +74,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	int count = 0;
>
>  	/*
> @@ -83,7 +84,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  	 */
>  	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->encoder && connector->encoder->crtc == crtc) {
>  			if (connector_list != NULL && count < num_connectors)
>  				*(connector_list++) = connector;
> @@ -91,6 +93,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  			count++;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	return count;
>  }
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index ac953f037be7..7cff91e7497f 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>  {
>  	bool poll = false;
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
>
>  	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
> @@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>  	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
>  		return;
>
> -	drm_for_each_connector(connector, dev) {
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
>  					 DRM_CONNECTOR_POLL_DISCONNECT))
>  			poll = true;
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	if (dev->mode_config.delayed_event) {
>  		poll = true;
> @@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
>  	struct delayed_work *delayed_work = to_delayed_work(work);
>  	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	enum drm_connector_status old_status;
>  	bool repoll = false, changed;
>
> @@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
>  		goto out;
>  	}
>
> -	drm_for_each_connector(connector, dev) {
> -
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		/* Ignore forced connectors. */
>  		if (connector->force)
>  			continue;
> @@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
>  			changed = true;
>  		}
>  	}
> +	drm_connector_list_iter_put(&conn_iter);
>
>  	mutex_unlock(&dev->mode_config.mutex);
>
> @@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
>  bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  {
>  	struct drm_connector *connector;
> +	struct drm_connector_list_iter conn_iter;
>  	enum drm_connector_status old_status;
>  	bool changed = false;
>
> @@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  		return false;
>
>  	mutex_lock(&dev->mode_config.mutex);
> -	drm_for_each_connector(connector, dev) {
> -
> +	drm_connector_list_iter_get(dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
>  		/* Only handle HPD capable connectors. */
>  		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
>  			continue;
> @@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  		if (old_status != connector->status)
>  			changed = true;
>  	}
> -
> +	drm_connector_list_iter_put(&conn_iter);
>  	mutex_unlock(&dev->mode_config.mutex);
>
>  	if (changed)
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
  2016-12-15 16:32     ` Harry Wentland
@ 2016-12-15 22:47     ` kbuild test robot
  2016-12-15 22:59     ` kbuild test robot
  2016-12-16 15:03     ` Sean Paul
  3 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2016-12-15 22:47 UTC (permalink / raw)
  Cc: Daniel Vetter, Intel Graphics Development, Harry Wentland,
	kbuild-all, DRI Development

[-- Attachment #1: Type: text/plain, Size: 6834 bytes --]

Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20161215]
[cannot apply to v4.9]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-x005-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
   drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' isn't known
      struct drm_connector_list_iter conn_iter;
                                     ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' token
      drm_for_each_connector_iter(connector, &conn_iter) {
                                                         ^
   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 'conn_iter' [-Wunused-variable]
      struct drm_connector_list_iter conn_iter;
                                     ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 'save_connector_encoders'
      save_connector_encoders[count++] = connector->encoder;
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_put(&conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'
      connector->encoder = save_connector_encoders[count++];
      ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 'new_encoder' [-Wunused-variable]
     struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
                                                    ^~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 'new_crtc' [-Wunused-variable]
     struct drm_crtc **save_encoder_crtcs, *new_crtc;
                                            ^~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_encoder_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:800:3: error: expected ';' before 'if'
      if (connector->encoder == encoder)
      ^~
   drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_crtc_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:836:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:841:3: error: expected ';' before 'if'
      if (connector->encoder && connector->encoder->crtc == crtc)
      ^~
   drivers/gpu/drm/drm_crtc_helper.c:836:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors

vim +800 drivers/gpu/drm/drm_crtc_helper.c

c9fb15f60 Keith Packard 2009-05-30  794  	struct drm_connector *connector;
bb3781dd0 Daniel Vetter 2016-12-15  795  	struct drm_connector_list_iter conn_iter;
c9fb15f60 Keith Packard 2009-05-30  796  	struct drm_device *dev = encoder->dev;
c9fb15f60 Keith Packard 2009-05-30  797  
bb3781dd0 Daniel Vetter 2016-12-15  798  	drm_connector_list_iter_get(dev, &conn_iter);
bb3781dd0 Daniel Vetter 2016-12-15  799  	drm_for_each_connector_iter(connector, &conn_iter)
c9fb15f60 Keith Packard 2009-05-30 @800  		if (connector->encoder == encoder)
c9fb15f60 Keith Packard 2009-05-30  801  			if (connector->dpms < dpms)
c9fb15f60 Keith Packard 2009-05-30  802  				dpms = connector->dpms;
bb3781dd0 Daniel Vetter 2016-12-15  803  	drm_connector_list_iter_put(&conn_iter);

:::::: The code at line 800 was first introduced by commit
:::::: c9fb15f60eb517c958dec64dca9357bf62bf2201 drm: Hook up DPMS property handling in drm_crtc.c. Add drm_helper_connector_dpms.

:::::: TO: Keith Packard <keithp@keithp.com>
:::::: CC: Dave Airlie <airlied@redhat.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27883 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
  2016-12-15 16:32     ` Harry Wentland
  2016-12-15 22:47     ` kbuild test robot
@ 2016-12-15 22:59     ` kbuild test robot
  2016-12-16  7:29       ` Daniel Vetter
  2016-12-16 15:03     ` Sean Paul
  3 siblings, 1 reply; 41+ messages in thread
From: kbuild test robot @ 2016-12-15 22:59 UTC (permalink / raw)
  Cc: Daniel Vetter, Intel Graphics Development, Harry Wentland,
	kbuild-all, DRI Development

[-- Attachment #1: Type: text/plain, Size: 20487 bytes --]

Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20161215]
[cannot apply to v4.9]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-x003-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>> drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' isn't known
      struct drm_connector_list_iter conn_iter;
                                     ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' token
      drm_for_each_connector_iter(connector, &conn_iter) {
                                                         ^
   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 'conn_iter' [-Wunused-variable]
      struct drm_connector_list_iter conn_iter;
                                     ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 'save_connector_encoders'
      save_connector_encoders[count++] = connector->encoder;
      ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_put(&conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
>> drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'
      connector->encoder = save_connector_encoders[count++];
      ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 'new_encoder' [-Wunused-variable]
     struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
                                                    ^~~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 'new_crtc' [-Wunused-variable]
     struct drm_crtc **save_encoder_crtcs, *new_crtc;
                                            ^~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_encoder_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   In file included from include/linux/linkage.h:4:0,
                    from include/linux/kernel.h:6,
                    from drivers/gpu/drm/drm_crtc_helper.c:32:
>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
     ^
   include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
    #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
                          ^~~~~~~~~~
>> drivers/gpu/drm/drm_crtc_helper.c:800:3: note: in expansion of macro 'if'
      if (connector->encoder == encoder)
      ^~
   drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_crtc_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:836:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   In file included from include/linux/linkage.h:4:0,
                    from include/linux/kernel.h:6,
                    from drivers/gpu/drm/drm_crtc_helper.c:32:
>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
     ^
   include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
    #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
                          ^~~~~~~~~~
   drivers/gpu/drm/drm_crtc_helper.c:841:3: note: in expansion of macro 'if'
      if (connector->encoder && connector->encoder->crtc == crtc)
      ^~
   drivers/gpu/drm/drm_crtc_helper.c:836:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/drm_probe_helper.c: In function 'drm_kms_helper_poll_enable_locked':
>> drivers/gpu/drm/drm_probe_helper.c:132:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_probe_helper.c:140:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_probe_helper.c:141:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_probe_helper.c:141:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_probe_helper.c:132:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c: In function 'output_poll_execute':
   drivers/gpu/drm/drm_probe_helper.c:388:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c:405:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_probe_helper.c:389:28: warning: unused variable 'old_status' [-Wunused-variable]
     enum drm_connector_status old_status;
                               ^~~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c:388:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c: In function 'drm_helper_hpd_irq_event':
   drivers/gpu/drm/drm_probe_helper.c:570:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c:579:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_probe_helper.c:571:28: warning: unused variable 'old_status' [-Wunused-variable]
     enum drm_connector_status old_status;
                               ^~~~~~~~~~
   drivers/gpu/drm/drm_probe_helper.c:570:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/drm_plane_helper.c: In function 'get_connectors_for_crtc':
>> drivers/gpu/drm/drm_plane_helper.c:77:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_plane_helper.c:87:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_plane_helper.c:88:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_plane_helper.c:88:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_plane_helper.c:77:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/drm_atomic_helper.c: In function 'handle_conflicting_encoders':
>> drivers/gpu/drm/drm_atomic_helper.c:97:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_atomic_helper.c:148:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(state->dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_atomic_helper.c:149:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_atomic_helper.c:149:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
   drivers/gpu/drm/drm_atomic_helper.c:98:22: warning: unused variable 'encoder' [-Wunused-variable]
     struct drm_encoder *encoder;
                         ^~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c:97:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_disable_all':
   drivers/gpu/drm/drm_atomic_helper.c:2452:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c:2462:48: error: expected ';' before '{' token
     drm_for_each_connector_iter(conn, &conn_iter) {
                                                   ^
>> drivers/gpu/drm/drm_atomic_helper.c:2480:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_put(&conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c:2479:1: warning: label 'free' defined but not used [-Wunused-label]
    free:
    ^~~~
   drivers/gpu/drm/drm_atomic_helper.c:2452:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_connector_dpms':
   drivers/gpu/drm/drm_atomic_helper.c:2853:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c:2882:57: error: expected ';' before '{' token
     drm_for_each_connector_iter(tmp_connector, &conn_iter) {
                                                            ^
   drivers/gpu/drm/drm_atomic_helper.c:2853:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_duplicate_state':
   drivers/gpu/drm/drm_atomic_helper.c:3269:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   drivers/gpu/drm/drm_atomic_helper.c:3301:48: error: expected ';' before '{' token
     drm_for_each_connector_iter(conn, &conn_iter) {
                                                   ^
   drivers/gpu/drm/drm_atomic_helper.c:3269:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/drm_modeset_helper.c: In function 'drm_helper_move_panel_connectors_to_head':
>> drivers/gpu/drm/drm_modeset_helper.c:51:33: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
     spin_lock_irq(&dev->mode_config.connector_list_lock);
                                    ^
   drivers/gpu/drm/drm_modeset_helper.c:61:35: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
     spin_unlock_irq(&dev->mode_config.connector_list_lock);
                                      ^
--
   drivers/gpu/drm/drm_fb_helper.c: In function 'drm_fb_helper_single_add_all_connectors':
>> drivers/gpu/drm/drm_fb_helper.c:123:33: error: storage size of 'conn_iter' isn't known
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
>> drivers/gpu/drm/drm_fb_helper.c:130:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_get(dev, &conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_fb_helper.c:131:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
     drm_for_each_connector_iter(connector, &conn_iter) {
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/drm_fb_helper.c:131:53: error: expected ';' before '{' token
     drm_for_each_connector_iter(connector, &conn_iter) {
                                                        ^
>> drivers/gpu/drm/drm_fb_helper.c:151:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
     drm_connector_list_iter_put(&conn_iter);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/drm_fb_helper.c:150:1: warning: label 'out' defined but not used [-Wunused-label]
    out:
    ^~~
   drivers/gpu/drm/drm_fb_helper.c:139:1: warning: label 'fail' defined but not used [-Wunused-label]
    fail:
    ^~~~
   drivers/gpu/drm/drm_fb_helper.c:123:33: warning: unused variable 'conn_iter' [-Wunused-variable]
     struct drm_connector_list_iter conn_iter;
                                    ^~~~~~~~~
   cc1: some warnings being treated as errors

vim +91 drivers/gpu/drm/drm_crtc_helper.c

    26	 *      Keith Packard
    27	 *	Eric Anholt <eric@anholt.net>
    28	 *      Dave Airlie <airlied@linux.ie>
    29	 *      Jesse Barnes <jesse.barnes@intel.com>
    30	 */
    31	
  > 32	#include <linux/kernel.h>
    33	#include <linux/export.h>
    34	#include <linux/moduleparam.h>
    35	
    36	#include <drm/drmP.h>
    37	#include <drm/drm_atomic.h>
    38	#include <drm/drm_crtc.h>
    39	#include <drm/drm_fourcc.h>
    40	#include <drm/drm_crtc_helper.h>
    41	#include <drm/drm_fb_helper.h>
    42	#include <drm/drm_plane_helper.h>
    43	#include <drm/drm_atomic_helper.h>
    44	#include <drm/drm_edid.h>
    45	
    46	/**
    47	 * DOC: overview
    48	 *
    49	 * The CRTC modeset helper library provides a default set_config implementation
    50	 * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
    51	 * the same callbacks which drivers can use to e.g. restore the modeset
    52	 * configuration on resume with drm_helper_resume_force_mode().
    53	 *
    54	 * Note that this helper library doesn't track the current power state of CRTCs
    55	 * and encoders. It can call callbacks like ->dpms() even though the hardware is
    56	 * already in the desired state. This deficiency has been fixed in the atomic
    57	 * helpers.
    58	 *
    59	 * The driver callbacks are mostly compatible with the atomic modeset helpers,
    60	 * except for the handling of the primary plane: Atomic helpers require that the
    61	 * primary plane is implemented as a real standalone plane and not directly tied
    62	 * to the CRTC state. For easier transition this library provides functions to
    63	 * implement the old semantics required by the CRTC helpers using the new plane
    64	 * and atomic helper callbacks.
    65	 *
    66	 * Drivers are strongly urged to convert to the atomic helpers (by way of first
    67	 * converting to the plane helpers). New drivers must not use these functions
    68	 * but need to implement the atomic interface instead, potentially using the
    69	 * atomic helpers for that.
    70	 *
    71	 * These legacy modeset helpers use the same function table structures as
    72	 * all other modesetting helpers. See the documentation for struct
    73	 * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
    74	 * &drm_connector_helper_funcs.
    75	 */
    76	
    77	/**
    78	 * drm_helper_encoder_in_use - check if a given encoder is in use
    79	 * @encoder: encoder to check
    80	 *
    81	 * Checks whether @encoder is with the current mode setting output configuration
    82	 * in use by any connector. This doesn't mean that it is actually enabled since
    83	 * the DPMS state is tracked separately.
    84	 *
    85	 * Returns:
    86	 * True if @encoder is used, false otherwise.
    87	 */
    88	bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
    89	{
    90		struct drm_connector *connector;
  > 91		struct drm_connector_list_iter conn_iter;
    92		struct drm_device *dev = encoder->dev;
    93	
    94		/*
    95		 * We can expect this mutex to be locked if we are not panicking.
    96		 * Locking is currently fubar in the panic handler.
    97		 */
    98		if (!oops_in_progress) {
    99			WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
   100			WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
   101		}
   102	
   103	
 > 104		drm_connector_list_iter_get(dev, &conn_iter);
 > 105		drm_for_each_connector_iter(connector, &conn_iter) {
   106			if (connector->encoder == encoder) {
   107				drm_connector_list_iter_put(&conn_iter);
   108				return true;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26883 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-15 22:59     ` kbuild test robot
@ 2016-12-16  7:29       ` Daniel Vetter
  2016-12-16  7:41         ` [kbuild-all] " Fengguang Wu
  0 siblings, 1 reply; 41+ messages in thread
From: Daniel Vetter @ 2016-12-16  7:29 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Intel Graphics Development, Harry Wentland, kbuild-all, DRI Development

Hi Kbuild folks

So yeah this doesn't apply because it's just 1 patch resent out of a
big patch series, in-reply-to the patch it replaces. So applying this
alone and telling me (and all the mailing lists) that it doesn't apply
isn't all that useful.

And it shouldn't be too hard to detect this, since the fdo patchwork
instance does catch most of these partial resends successfully and
correctly, and will retest the entire patch series.
-Daniel


On Thu, Dec 15, 2016 at 11:59 PM, kbuild test robot <lkp@intel.com> wrote:
> Hi Daniel,
>
> [auto build test ERROR on drm/drm-next]
> [also build test ERROR on next-20161215]
> [cannot apply to v4.9]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
> base:   git://people.freedesktop.org/~airlied/linux.git drm-next
> config: i386-randconfig-x003-201650 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386
>
> All error/warnings (new ones prefixed by >>):
>
>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>>> drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_get(dev, &conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>      drm_for_each_connector_iter(connector, &conn_iter) {
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
>    drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' isn't known
>       struct drm_connector_list_iter conn_iter;
>                                      ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' token
>       drm_for_each_connector_iter(connector, &conn_iter) {
>                                                          ^
>    drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 'conn_iter' [-Wunused-variable]
>       struct drm_connector_list_iter conn_iter;
>                                      ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
>    drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 'save_connector_encoders'
>       save_connector_encoders[count++] = connector->encoder;
>       ^~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_put(&conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>>> drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'
>       connector->encoder = save_connector_encoders[count++];
>       ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 'new_encoder' [-Wunused-variable]
>      struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
>                                                     ^~~~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 'new_crtc' [-Wunused-variable]
>      struct drm_crtc **save_encoder_crtcs, *new_crtc;
>                                             ^~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_encoder_dpms':
>    drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    In file included from include/linux/linkage.h:4:0,
>                     from include/linux/kernel.h:6,
>                     from drivers/gpu/drm/drm_crtc_helper.c:32:
>>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
>      if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>      ^
>    include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>     #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>                           ^~~~~~~~~~
>>> drivers/gpu/drm/drm_crtc_helper.c:800:3: note: in expansion of macro 'if'
>       if (connector->encoder == encoder)
>       ^~
>    drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_crtc_dpms':
>    drivers/gpu/drm/drm_crtc_helper.c:836:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    In file included from include/linux/linkage.h:4:0,
>                     from include/linux/kernel.h:6,
>                     from drivers/gpu/drm/drm_crtc_helper.c:32:
>>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
>      if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>      ^
>    include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>     #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>                           ^~~~~~~~~~
>    drivers/gpu/drm/drm_crtc_helper.c:841:3: note: in expansion of macro 'if'
>       if (connector->encoder && connector->encoder->crtc == crtc)
>       ^~
>    drivers/gpu/drm/drm_crtc_helper.c:836:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    cc1: some warnings being treated as errors
> --
>    drivers/gpu/drm/drm_probe_helper.c: In function 'drm_kms_helper_poll_enable_locked':
>>> drivers/gpu/drm/drm_probe_helper.c:132:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_probe_helper.c:140:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_get(dev, &conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_probe_helper.c:141:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>      drm_for_each_connector_iter(connector, &conn_iter) {
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_probe_helper.c:141:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_probe_helper.c:132:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c: In function 'output_poll_execute':
>    drivers/gpu/drm/drm_probe_helper.c:388:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c:405:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_probe_helper.c:389:28: warning: unused variable 'old_status' [-Wunused-variable]
>      enum drm_connector_status old_status;
>                                ^~~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c:388:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c: In function 'drm_helper_hpd_irq_event':
>    drivers/gpu/drm/drm_probe_helper.c:570:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c:579:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_probe_helper.c:571:28: warning: unused variable 'old_status' [-Wunused-variable]
>      enum drm_connector_status old_status;
>                                ^~~~~~~~~~
>    drivers/gpu/drm/drm_probe_helper.c:570:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    cc1: some warnings being treated as errors
> --
>    drivers/gpu/drm/drm_plane_helper.c: In function 'get_connectors_for_crtc':
>>> drivers/gpu/drm/drm_plane_helper.c:77:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_plane_helper.c:87:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_get(dev, &conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_plane_helper.c:88:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>      drm_for_each_connector_iter(connector, &conn_iter) {
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_plane_helper.c:88:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_plane_helper.c:77:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    cc1: some warnings being treated as errors
> --
>    drivers/gpu/drm/drm_atomic_helper.c: In function 'handle_conflicting_encoders':
>>> drivers/gpu/drm/drm_atomic_helper.c:97:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_atomic_helper.c:148:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_get(state->dev, &conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_atomic_helper.c:149:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>      drm_for_each_connector_iter(connector, &conn_iter) {
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_atomic_helper.c:149:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>    drivers/gpu/drm/drm_atomic_helper.c:98:22: warning: unused variable 'encoder' [-Wunused-variable]
>      struct drm_encoder *encoder;
>                          ^~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c:97:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_disable_all':
>    drivers/gpu/drm/drm_atomic_helper.c:2452:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c:2462:48: error: expected ';' before '{' token
>      drm_for_each_connector_iter(conn, &conn_iter) {
>                                                    ^
>>> drivers/gpu/drm/drm_atomic_helper.c:2480:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_put(&conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c:2479:1: warning: label 'free' defined but not used [-Wunused-label]
>     free:
>     ^~~~
>    drivers/gpu/drm/drm_atomic_helper.c:2452:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_connector_dpms':
>    drivers/gpu/drm/drm_atomic_helper.c:2853:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c:2882:57: error: expected ';' before '{' token
>      drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>                                                             ^
>    drivers/gpu/drm/drm_atomic_helper.c:2853:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_duplicate_state':
>    drivers/gpu/drm/drm_atomic_helper.c:3269:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    drivers/gpu/drm/drm_atomic_helper.c:3301:48: error: expected ';' before '{' token
>      drm_for_each_connector_iter(conn, &conn_iter) {
>                                                    ^
>    drivers/gpu/drm/drm_atomic_helper.c:3269:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    cc1: some warnings being treated as errors
> --
>    drivers/gpu/drm/drm_modeset_helper.c: In function 'drm_helper_move_panel_connectors_to_head':
>>> drivers/gpu/drm/drm_modeset_helper.c:51:33: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>      spin_lock_irq(&dev->mode_config.connector_list_lock);
>                                     ^
>    drivers/gpu/drm/drm_modeset_helper.c:61:35: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>      spin_unlock_irq(&dev->mode_config.connector_list_lock);
>                                       ^
> --
>    drivers/gpu/drm/drm_fb_helper.c: In function 'drm_fb_helper_single_add_all_connectors':
>>> drivers/gpu/drm/drm_fb_helper.c:123:33: error: storage size of 'conn_iter' isn't known
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>>> drivers/gpu/drm/drm_fb_helper.c:130:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_get(dev, &conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_fb_helper.c:131:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>      drm_for_each_connector_iter(connector, &conn_iter) {
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/gpu/drm/drm_fb_helper.c:131:53: error: expected ';' before '{' token
>      drm_for_each_connector_iter(connector, &conn_iter) {
>                                                         ^
>>> drivers/gpu/drm/drm_fb_helper.c:151:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>      drm_connector_list_iter_put(&conn_iter);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>    drivers/gpu/drm/drm_fb_helper.c:150:1: warning: label 'out' defined but not used [-Wunused-label]
>     out:
>     ^~~
>    drivers/gpu/drm/drm_fb_helper.c:139:1: warning: label 'fail' defined but not used [-Wunused-label]
>     fail:
>     ^~~~
>    drivers/gpu/drm/drm_fb_helper.c:123:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>      struct drm_connector_list_iter conn_iter;
>                                     ^~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +91 drivers/gpu/drm/drm_crtc_helper.c
>
>     26   *      Keith Packard
>     27   *      Eric Anholt <eric@anholt.net>
>     28   *      Dave Airlie <airlied@linux.ie>
>     29   *      Jesse Barnes <jesse.barnes@intel.com>
>     30   */
>     31
>   > 32  #include <linux/kernel.h>
>     33  #include <linux/export.h>
>     34  #include <linux/moduleparam.h>
>     35
>     36  #include <drm/drmP.h>
>     37  #include <drm/drm_atomic.h>
>     38  #include <drm/drm_crtc.h>
>     39  #include <drm/drm_fourcc.h>
>     40  #include <drm/drm_crtc_helper.h>
>     41  #include <drm/drm_fb_helper.h>
>     42  #include <drm/drm_plane_helper.h>
>     43  #include <drm/drm_atomic_helper.h>
>     44  #include <drm/drm_edid.h>
>     45
>     46  /**
>     47   * DOC: overview
>     48   *
>     49   * The CRTC modeset helper library provides a default set_config implementation
>     50   * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
>     51   * the same callbacks which drivers can use to e.g. restore the modeset
>     52   * configuration on resume with drm_helper_resume_force_mode().
>     53   *
>     54   * Note that this helper library doesn't track the current power state of CRTCs
>     55   * and encoders. It can call callbacks like ->dpms() even though the hardware is
>     56   * already in the desired state. This deficiency has been fixed in the atomic
>     57   * helpers.
>     58   *
>     59   * The driver callbacks are mostly compatible with the atomic modeset helpers,
>     60   * except for the handling of the primary plane: Atomic helpers require that the
>     61   * primary plane is implemented as a real standalone plane and not directly tied
>     62   * to the CRTC state. For easier transition this library provides functions to
>     63   * implement the old semantics required by the CRTC helpers using the new plane
>     64   * and atomic helper callbacks.
>     65   *
>     66   * Drivers are strongly urged to convert to the atomic helpers (by way of first
>     67   * converting to the plane helpers). New drivers must not use these functions
>     68   * but need to implement the atomic interface instead, potentially using the
>     69   * atomic helpers for that.
>     70   *
>     71   * These legacy modeset helpers use the same function table structures as
>     72   * all other modesetting helpers. See the documentation for struct
>     73   * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
>     74   * &drm_connector_helper_funcs.
>     75   */
>     76
>     77  /**
>     78   * drm_helper_encoder_in_use - check if a given encoder is in use
>     79   * @encoder: encoder to check
>     80   *
>     81   * Checks whether @encoder is with the current mode setting output configuration
>     82   * in use by any connector. This doesn't mean that it is actually enabled since
>     83   * the DPMS state is tracked separately.
>     84   *
>     85   * Returns:
>     86   * True if @encoder is used, false otherwise.
>     87   */
>     88  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>     89  {
>     90          struct drm_connector *connector;
>   > 91          struct drm_connector_list_iter conn_iter;
>     92          struct drm_device *dev = encoder->dev;
>     93
>     94          /*
>     95           * We can expect this mutex to be locked if we are not panicking.
>     96           * Locking is currently fubar in the panic handler.
>     97           */
>     98          if (!oops_in_progress) {
>     99                  WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
>    100                  WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>    101          }
>    102
>    103
>  > 104          drm_connector_list_iter_get(dev, &conn_iter);
>  > 105          drm_for_each_connector_iter(connector, &conn_iter) {
>    106                  if (connector->encoder == encoder) {
>    107                          drm_connector_list_iter_put(&conn_iter);
>    108                          return true;
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [kbuild-all] [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-16  7:29       ` Daniel Vetter
@ 2016-12-16  7:41         ` Fengguang Wu
  2016-12-18 18:04           ` Ye Xiaolong
  0 siblings, 1 reply; 41+ messages in thread
From: Fengguang Wu @ 2016-12-16  7:41 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, Harry Wentland, kbuild-all,
	DRI Development, Ye Xiaolong

Hi Daniel,

On Fri, Dec 16, 2016 at 08:29:43AM +0100, Daniel Vetter wrote:
>Hi Kbuild folks
>
>So yeah this doesn't apply because it's just 1 patch resent out of a
>big patch series, in-reply-to the patch it replaces. So applying this
>alone and telling me (and all the mailing lists) that it doesn't apply
>isn't all that useful.
>
>And it shouldn't be too hard to detect this, since the fdo patchwork
>instance does catch most of these partial resends successfully and
>correctly, and will retest the entire patch series.

Good point! CC Xiaolong. This scenario seems happen frequent enough in
LKML to worth the efforts to add auto detect logic for.

Thanks,
Fengguang

>On Thu, Dec 15, 2016 at 11:59 PM, kbuild test robot <lkp@intel.com> wrote:
>> Hi Daniel,
>>
>> [auto build test ERROR on drm/drm-next]
>> [also build test ERROR on next-20161215]
>> [cannot apply to v4.9]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
>> base:   git://people.freedesktop.org/~airlied/linux.git drm-next
>> config: i386-randconfig-x003-201650 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=i386
>>
>> All error/warnings (new ones prefixed by >>):
>>
>>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>>>> drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_get(dev, &conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
>>    drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' isn't known
>>       struct drm_connector_list_iter conn_iter;
>>                                      ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' token
>>       drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                          ^
>>    drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 'conn_iter' [-Wunused-variable]
>>       struct drm_connector_list_iter conn_iter;
>>                                      ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
>>    drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 'save_connector_encoders'
>>       save_connector_encoders[count++] = connector->encoder;
>>       ^~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_put(&conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>>> drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'
>>       connector->encoder = save_connector_encoders[count++];
>>       ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 'new_encoder' [-Wunused-variable]
>>      struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
>>                                                     ^~~~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 'new_crtc' [-Wunused-variable]
>>      struct drm_crtc **save_encoder_crtcs, *new_crtc;
>>                                             ^~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_encoder_dpms':
>>    drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    In file included from include/linux/linkage.h:4:0,
>>                     from include/linux/kernel.h:6,
>>                     from drivers/gpu/drm/drm_crtc_helper.c:32:
>>>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
>>      if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>>      ^
>>    include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>>     #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>>                           ^~~~~~~~~~
>>>> drivers/gpu/drm/drm_crtc_helper.c:800:3: note: in expansion of macro 'if'
>>       if (connector->encoder == encoder)
>>       ^~
>>    drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_crtc_dpms':
>>    drivers/gpu/drm/drm_crtc_helper.c:836:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    In file included from include/linux/linkage.h:4:0,
>>                     from include/linux/kernel.h:6,
>>                     from drivers/gpu/drm/drm_crtc_helper.c:32:
>>>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
>>      if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>>      ^
>>    include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>>     #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>>                           ^~~~~~~~~~
>>    drivers/gpu/drm/drm_crtc_helper.c:841:3: note: in expansion of macro 'if'
>>       if (connector->encoder && connector->encoder->crtc == crtc)
>>       ^~
>>    drivers/gpu/drm/drm_crtc_helper.c:836:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    cc1: some warnings being treated as errors
>> --
>>    drivers/gpu/drm/drm_probe_helper.c: In function 'drm_kms_helper_poll_enable_locked':
>>>> drivers/gpu/drm/drm_probe_helper.c:132:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_probe_helper.c:140:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_get(dev, &conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_probe_helper.c:141:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_probe_helper.c:141:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_probe_helper.c:132:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c: In function 'output_poll_execute':
>>    drivers/gpu/drm/drm_probe_helper.c:388:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c:405:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_probe_helper.c:389:28: warning: unused variable 'old_status' [-Wunused-variable]
>>      enum drm_connector_status old_status;
>>                                ^~~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c:388:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c: In function 'drm_helper_hpd_irq_event':
>>    drivers/gpu/drm/drm_probe_helper.c:570:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c:579:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_probe_helper.c:571:28: warning: unused variable 'old_status' [-Wunused-variable]
>>      enum drm_connector_status old_status;
>>                                ^~~~~~~~~~
>>    drivers/gpu/drm/drm_probe_helper.c:570:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    cc1: some warnings being treated as errors
>> --
>>    drivers/gpu/drm/drm_plane_helper.c: In function 'get_connectors_for_crtc':
>>>> drivers/gpu/drm/drm_plane_helper.c:77:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_plane_helper.c:87:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_get(dev, &conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_plane_helper.c:88:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_plane_helper.c:88:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_plane_helper.c:77:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    cc1: some warnings being treated as errors
>> --
>>    drivers/gpu/drm/drm_atomic_helper.c: In function 'handle_conflicting_encoders':
>>>> drivers/gpu/drm/drm_atomic_helper.c:97:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_atomic_helper.c:148:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_get(state->dev, &conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_atomic_helper.c:149:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_atomic_helper.c:149:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>    drivers/gpu/drm/drm_atomic_helper.c:98:22: warning: unused variable 'encoder' [-Wunused-variable]
>>      struct drm_encoder *encoder;
>>                          ^~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:97:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_disable_all':
>>    drivers/gpu/drm/drm_atomic_helper.c:2452:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:2462:48: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(conn, &conn_iter) {
>>                                                    ^
>>>> drivers/gpu/drm/drm_atomic_helper.c:2480:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_put(&conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:2479:1: warning: label 'free' defined but not used [-Wunused-label]
>>     free:
>>     ^~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:2452:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_connector_dpms':
>>    drivers/gpu/drm/drm_atomic_helper.c:2853:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:2882:57: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>>                                                             ^
>>    drivers/gpu/drm/drm_atomic_helper.c:2853:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_duplicate_state':
>>    drivers/gpu/drm/drm_atomic_helper.c:3269:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    drivers/gpu/drm/drm_atomic_helper.c:3301:48: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(conn, &conn_iter) {
>>                                                    ^
>>    drivers/gpu/drm/drm_atomic_helper.c:3269:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    cc1: some warnings being treated as errors
>> --
>>    drivers/gpu/drm/drm_modeset_helper.c: In function 'drm_helper_move_panel_connectors_to_head':
>>>> drivers/gpu/drm/drm_modeset_helper.c:51:33: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>>      spin_lock_irq(&dev->mode_config.connector_list_lock);
>>                                     ^
>>    drivers/gpu/drm/drm_modeset_helper.c:61:35: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>>      spin_unlock_irq(&dev->mode_config.connector_list_lock);
>>                                       ^
>> --
>>    drivers/gpu/drm/drm_fb_helper.c: In function 'drm_fb_helper_single_add_all_connectors':
>>>> drivers/gpu/drm/drm_fb_helper.c:123:33: error: storage size of 'conn_iter' isn't known
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>>> drivers/gpu/drm/drm_fb_helper.c:130:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_get(dev, &conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_fb_helper.c:131:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> drivers/gpu/drm/drm_fb_helper.c:131:53: error: expected ';' before '{' token
>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>                                                         ^
>>>> drivers/gpu/drm/drm_fb_helper.c:151:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>      drm_connector_list_iter_put(&conn_iter);
>>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>    drivers/gpu/drm/drm_fb_helper.c:150:1: warning: label 'out' defined but not used [-Wunused-label]
>>     out:
>>     ^~~
>>    drivers/gpu/drm/drm_fb_helper.c:139:1: warning: label 'fail' defined but not used [-Wunused-label]
>>     fail:
>>     ^~~~
>>    drivers/gpu/drm/drm_fb_helper.c:123:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>      struct drm_connector_list_iter conn_iter;
>>                                     ^~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +91 drivers/gpu/drm/drm_crtc_helper.c
>>
>>     26   *      Keith Packard
>>     27   *      Eric Anholt <eric@anholt.net>
>>     28   *      Dave Airlie <airlied@linux.ie>
>>     29   *      Jesse Barnes <jesse.barnes@intel.com>
>>     30   */
>>     31
>>   > 32  #include <linux/kernel.h>
>>     33  #include <linux/export.h>
>>     34  #include <linux/moduleparam.h>
>>     35
>>     36  #include <drm/drmP.h>
>>     37  #include <drm/drm_atomic.h>
>>     38  #include <drm/drm_crtc.h>
>>     39  #include <drm/drm_fourcc.h>
>>     40  #include <drm/drm_crtc_helper.h>
>>     41  #include <drm/drm_fb_helper.h>
>>     42  #include <drm/drm_plane_helper.h>
>>     43  #include <drm/drm_atomic_helper.h>
>>     44  #include <drm/drm_edid.h>
>>     45
>>     46  /**
>>     47   * DOC: overview
>>     48   *
>>     49   * The CRTC modeset helper library provides a default set_config implementation
>>     50   * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
>>     51   * the same callbacks which drivers can use to e.g. restore the modeset
>>     52   * configuration on resume with drm_helper_resume_force_mode().
>>     53   *
>>     54   * Note that this helper library doesn't track the current power state of CRTCs
>>     55   * and encoders. It can call callbacks like ->dpms() even though the hardware is
>>     56   * already in the desired state. This deficiency has been fixed in the atomic
>>     57   * helpers.
>>     58   *
>>     59   * The driver callbacks are mostly compatible with the atomic modeset helpers,
>>     60   * except for the handling of the primary plane: Atomic helpers require that the
>>     61   * primary plane is implemented as a real standalone plane and not directly tied
>>     62   * to the CRTC state. For easier transition this library provides functions to
>>     63   * implement the old semantics required by the CRTC helpers using the new plane
>>     64   * and atomic helper callbacks.
>>     65   *
>>     66   * Drivers are strongly urged to convert to the atomic helpers (by way of first
>>     67   * converting to the plane helpers). New drivers must not use these functions
>>     68   * but need to implement the atomic interface instead, potentially using the
>>     69   * atomic helpers for that.
>>     70   *
>>     71   * These legacy modeset helpers use the same function table structures as
>>     72   * all other modesetting helpers. See the documentation for struct
>>     73   * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
>>     74   * &drm_connector_helper_funcs.
>>     75   */
>>     76
>>     77  /**
>>     78   * drm_helper_encoder_in_use - check if a given encoder is in use
>>     79   * @encoder: encoder to check
>>     80   *
>>     81   * Checks whether @encoder is with the current mode setting output configuration
>>     82   * in use by any connector. This doesn't mean that it is actually enabled since
>>     83   * the DPMS state is tracked separately.
>>     84   *
>>     85   * Returns:
>>     86   * True if @encoder is used, false otherwise.
>>     87   */
>>     88  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>>     89  {
>>     90          struct drm_connector *connector;
>>   > 91          struct drm_connector_list_iter conn_iter;
>>     92          struct drm_device *dev = encoder->dev;
>>     93
>>     94          /*
>>     95           * We can expect this mutex to be locked if we are not panicking.
>>     96           * Locking is currently fubar in the panic handler.
>>     97           */
>>     98          if (!oops_in_progress) {
>>     99                  WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
>>    100                  WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>>    101          }
>>    102
>>    103
>>  > 104          drm_connector_list_iter_get(dev, &conn_iter);
>>  > 105          drm_for_each_connector_iter(connector, &conn_iter) {
>>    106                  if (connector->encoder == encoder) {
>>    107                          drm_connector_list_iter_put(&conn_iter);
>>    108                          return true;
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>
>
>
>-- 
>Daniel Vetter
>Software Engineer, Intel Corporation
>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>_______________________________________________
>kbuild-all mailing list
>kbuild-all@lists.01.org
>https://lists.01.org/mailman/listinfo/kbuild-all
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls
  2016-12-13 23:08 ` [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls Daniel Vetter
@ 2016-12-16 15:02   ` Sean Paul
  0 siblings, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:02 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> Spotted while auditing our ioctl table. Also nuke the
> not-really-kerneldoc comments, we don't document internals and
> definitely don't want to mislead people with the old dragons.
>
> I think with this all the legacy ioctls now have proper drm_legacy_
> prefixes.
>


Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_internal.h |  8 ++++----
>  drivers/gpu/drm/drm_ioctl.c    |  4 ++--
>  drivers/gpu/drm/drm_irq.c      | 30 ++++--------------------------
>  3 files changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index db80ec860e33..a6213f814345 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -58,10 +58,10 @@ extern unsigned int drm_timestamp_monotonic;
>  /* IOCTLS */
>  int drm_wait_vblank(struct drm_device *dev, void *data,
>                     struct drm_file *filp);
> -int drm_control(struct drm_device *dev, void *data,
> -               struct drm_file *file_priv);
> -int drm_modeset_ctl(struct drm_device *dev, void *data,
> -                   struct drm_file *file_priv);
> +int drm_legacy_irq_control(struct drm_device *dev, void *data,
> +                          struct drm_file *file_priv);
> +int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
> +                          struct drm_file *file_priv);
>
>  /* drm_auth.c */
>  int drm_getmagic(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index e21a18ac968e..a16b6fbd1004 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -581,7 +581,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>         DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
>         DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
>
> -       DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +       DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
>
>  #if IS_ENABLED(CONFIG_AGP)
>         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> @@ -599,7 +599,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>
>         DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_MASTER|DRM_UNLOCKED),
>
> -       DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
> +       DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl, 0),
>
>         DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
>
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 273625a85036..feb091310ffe 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -579,19 +579,8 @@ int drm_irq_uninstall(struct drm_device *dev)
>  }
>  EXPORT_SYMBOL(drm_irq_uninstall);
>
> -/*
> - * IRQ control ioctl.
> - *
> - * \param inode device inode.
> - * \param file_priv DRM file private.
> - * \param cmd command.
> - * \param arg user argument, pointing to a drm_control structure.
> - * \return zero on success or a negative number on failure.
> - *
> - * Calls irq_install() or irq_uninstall() according to \p arg.
> - */
> -int drm_control(struct drm_device *dev, void *data,
> -               struct drm_file *file_priv)
> +int drm_legacy_irq_control(struct drm_device *dev, void *data,
> +                          struct drm_file *file_priv)
>  {
>         struct drm_control *ctl = data;
>         int ret = 0, irq;
> @@ -1442,19 +1431,8 @@ static void drm_legacy_vblank_post_modeset(struct drm_device *dev,
>         }
>  }
>
> -/*
> - * drm_modeset_ctl - handle vblank event counter changes across mode switch
> - * @DRM_IOCTL_ARGS: standard ioctl arguments
> - *
> - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
> - * ioctls around modesetting so that any lost vblank events are accounted for.
> - *
> - * Generally the counter will reset across mode sets.  If interrupts are
> - * enabled around this call, we don't have to do anything since the counter
> - * will have already been incremented.
> - */
> -int drm_modeset_ctl(struct drm_device *dev, void *data,
> -                   struct drm_file *file_priv)
> +int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
> +                          struct drm_file *file_priv)
>  {
>         struct drm_modeset_ctl *modeset = data;
>         unsigned int pipe;
> --
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h
  2016-12-13 23:08 ` [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h Daniel Vetter
@ 2016-12-16 15:02   ` Sean Paul
  0 siblings, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:02 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> This is not driver interface stuff.
>


Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Fixes: 6559c901cb48 ("drm/atomic: add debugfs file to dump out atomic state")
> Cc: Rob Clark <robdclark@gmail.com>
> Cc: Sean Paul <seanpaul@chromium.org>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_crtc_internal.h | 6 ++++++
>  drivers/gpu/drm/drm_debugfs.c       | 1 +
>  include/drm/drm_atomic.h            | 6 ------
>  3 files changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
> index cdf6860c9d22..0b8454c7dc00 100644
> --- a/drivers/gpu/drm/drm_crtc_internal.h
> +++ b/drivers/gpu/drm/drm_crtc_internal.h
> @@ -174,6 +174,12 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
>                            void *data, struct drm_file *file_priv);
>
>  /* drm_atomic.c */
> +#ifdef CONFIG_DEBUG_FS
> +struct drm_minor;
> +int drm_atomic_debugfs_init(struct drm_minor *minor);
> +int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
> +#endif
> +
>  int drm_atomic_get_property(struct drm_mode_object *obj,
>                             struct drm_property *property, uint64_t *val);
>  int drm_mode_atomic_ioctl(struct drm_device *dev,
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index 2e3e46a53805..37fd612d57a6 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -38,6 +38,7 @@
>  #include <drm/drm_edid.h>
>  #include <drm/drm_atomic.h>
>  #include "drm_internal.h"
> +#include "drm_crtc_internal.h"
>
>  #if defined(CONFIG_DEBUG_FS)
>
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 01d02e1935b1..c35b4aba36b6 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -379,12 +379,6 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
>
>  void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
>
> -#ifdef CONFIG_DEBUG_FS
> -struct drm_minor;
> -int drm_atomic_debugfs_init(struct drm_minor *minor);
> -int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
> -#endif
> -
>  #define for_each_connector_in_state(__state, connector, connector_state, __i) \
>         for ((__i) = 0;                                                 \
>              (__i) < (__state)->num_connector &&                                \
> --
> 2.11.0
>



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Intel-gfx] [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init
  2016-12-13 23:08 ` [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init Daniel Vetter
  2016-12-14  9:23   ` [Intel-gfx] " Daniel Stone
@ 2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> This is single-threaded setup code, no need for locks. And anyway,
> all properties need to be set up before the driver is registered
> anyway, they can't be hot-added.
>


Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_mode_config.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index b1e8bbceaf39..85a25fd9eff8 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -374,9 +374,7 @@ void drm_mode_config_init(struct drm_device *dev)
>         idr_init(&dev->mode_config.tile_idr);
>         ida_init(&dev->mode_config.connector_ida);
>
> -       drm_modeset_lock_all(dev);
>         drm_mode_create_standard_properties(dev);
> -       drm_modeset_unlock_all(dev);
>
>         /* Just to be sure */
>         dev->mode_config.num_fb = 0;
> --
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Intel-gfx] [PATCH 05/13] drm: locking&new iterators for connector_list
  2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
  2016-12-14  8:35   ` Chris Wilson
  2016-12-14 11:22   ` Jani Nikula
@ 2016-12-16 15:03   ` Sean Paul
  2 siblings, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> The requirements for connector_list locking are a bit tricky:
> - We need to be able to jump over zombie conectors (i.e. with refcount
>   == 0, but not yet removed from the list). If instead we require that
>   there's no zombies on the list then the final kref_put must happen
>   under the list protection lock, which means that locking context
>   leaks all over the place. Not pretty - better to deal with zombies
>   and wrap the locking just around the list_del in the destructor.
>
> - When we walk the list we must _not_ hold the connector list lock. We
>   walk the connector list at an absolutely massive amounts of places,
>   if all those places can't ever call drm_connector_unreference the
>   code would get unecessarily complicated.
>
> - connector_list needs it own lock, again too many places that walk it
>   that we could reuse e.g. mode_config.mutex without resulting in
>   inversions.
>
> - Lots of code uses these loops to look-up a connector, i.e. they want
>   to be able to call drm_connector_reference. But on the other hand we
>   want connectors to stay on that list until they're dead (i.e.
>   connector_list can't hold a full reference), which means despite the
>   "can't hold lock for the loop body" rule we need to make sure a
>   connector doesn't suddenly become a zombie.
>
> At first Dave&I discussed various horror-show approaches using srcu,
> but turns out it's fairly easy:
>
> - For the loop body we always hold an additional reference to the
>   current connector. That means it can't zombify, and it also means
>   it'll stay on the list, which means we can use it as our iterator to
>   find the next connector.
>
> - When we try to find the next connector we only have to jump over
>   zombies. To make sure we don't chase bad pointers that entire loop
>   is protected with the new connect_list_lock spinlock. And because we
>   know that we're starting out with a non-zombie (need to drop our
>   reference for the old connector only after we have our new one),
>   we're guranteed to still be on the connector_list and either find
>   the next non-zombie or complete the iteration.
>
> - Only downside is that we need to make sure that the temporary
>   reference for the loop body doesn't leak. iter_get/put() functions +
>   lockdep make sure that's the case.
>
> - To avoid a flag day the new iterator macro has an _iter postfix. We
>   can rename it back once all the users of the unsafe version are gone
>   (there's about 100 list walkers for the connector_list).
>
> For now this patch only converts all the list walking in the core,
> leaving helpers and drivers for later patches. The nice thing is that
> we can now finally remove 2 FIXME comments from the
> register/unregister functions.
>
> v2:
> - use irqsafe spinlocks, so that we can use this in drm_state_dump
>   too.
> - nuke drm_modeset_lock_all from drm_connector_init, now entirely
>   cargo-culted nonsense.
>
> v3:
> - do {} while (!kref_get_unless_zero), makes for a tidier loop (Dave).
> - pretty kerneldoc
> - add EXPORT_SYMBOL, helpers&drivers are supposed to use this.
>
> v4: Change lockdep annotations to only check whether we release the
> iter fake lock again (i.e. make sure that iter_put is called), but
> not check any locking dependecies itself. That seams to require a
> recursive read lock in trylock mode.
>
> Cc: Dave Airlie <airlied@gmail.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>



Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

<snip>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-15 15:58   ` [PATCH] " Daniel Vetter
                       ` (2 preceding siblings ...)
  2016-12-15 22:59     ` kbuild test robot
@ 2016-12-16 15:03     ` Sean Paul
  3 siblings, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development, Harry Wentland, DRI Development

On Thu, Dec 15, 2016 at 10:58 AM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> Mostly nothing special (except making sure that really all error paths
> and friends call iter_put).
>
> v2: Don't forget the raw connector_list walking in
> drm_helper_move_panel_connectors_to_head. That one unfortunately can't
> be converted to the iterator helpers, but since it's just some list
> splicing best to just wrap the entire thing up in one critical
> section.
>
> v3: Bail out after iter_put (Harry).
>
> Cc: Harry Wentland <harry.wentland@amd.com>


Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c  | 39 ++++++++++++++++++++--------
>  drivers/gpu/drm/drm_crtc_helper.c    | 49 ++++++++++++++++++++++++++++--------
>  drivers/gpu/drm/drm_fb_helper.c      | 12 ++++++---
>  drivers/gpu/drm/drm_modeset_helper.c |  2 ++
>  drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
>  drivers/gpu/drm/drm_probe_helper.c   | 18 ++++++++-----
>  6 files changed, 92 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 23767df72615..e2e15a9903a9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  {
>         struct drm_connector_state *conn_state;
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_encoder *encoder;
>         unsigned encoder_mask = 0;
> -       int i, ret;
> +       int i, ret = 0;
>
>         /*
>          * First loop, find all newly assigned encoders from the connectors
> @@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>          * and the crtc is disabled if no encoder is left. This preserves
>          * compatibility with the legacy set_config behavior.
>          */
> -       drm_for_each_connector(connector, state->dev) {
> +       drm_connector_list_iter_get(state->dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 struct drm_crtc_state *crtc_state;
>
>                 if (drm_atomic_get_existing_connector_state(state, connector))
> @@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>                                          connector->state->crtc->base.id,
>                                          connector->state->crtc->name,
>                                          connector->base.id, connector->name);
> -                       return -EINVAL;
> +                       ret = -EINVAL;
> +                       goto out;
>                 }
>
>                 conn_state = drm_atomic_get_connector_state(state, connector);
> -               if (IS_ERR(conn_state))
> -                       return PTR_ERR(conn_state);
> +               if (IS_ERR(conn_state)) {
> +                       ret = PTR_ERR(conn_state);
> +                       goto out;
> +               }
>
>                 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
>                                  encoder->base.id, encoder->name,
> @@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>
>                 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
>                 if (ret)
> -                       return ret;
> +                       goto out;
>
>                 if (!crtc_state->connector_mask) {
>                         ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
>                                                                 NULL);
>                         if (ret < 0)
> -                               return ret;
> +                               goto out;
>
>                         crtc_state->active = false;
>                 }
>         }
> +out:
> +       drm_connector_list_iter_put(&conn_iter);
>
> -       return 0;
> +       return ret;
>  }
>
>  static void
> @@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>  {
>         struct drm_atomic_state *state;
>         struct drm_connector *conn;
> +       struct drm_connector_list_iter conn_iter;
>         int err;
>
>         state = drm_atomic_state_alloc(dev);
> @@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>         state->acquire_ctx = ctx;
>
> -       drm_for_each_connector(conn, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(conn, &conn_iter) {
>                 struct drm_crtc *crtc = conn->state->crtc;
>                 struct drm_crtc_state *crtc_state;
>
> @@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
>
>         err = drm_atomic_commit(state);
>  free:
> +       drm_connector_list_iter_put(&conn_iter);
>         drm_atomic_state_put(state);
>         return err;
>  }
> @@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>         struct drm_crtc_state *crtc_state;
>         struct drm_crtc *crtc;
>         struct drm_connector *tmp_connector;
> +       struct drm_connector_list_iter conn_iter;
>         int ret;
>         bool active = false;
>         int old_mode = connector->dpms;
> @@ -2867,7 +2878,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>
>         WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
>
> -       drm_for_each_connector(tmp_connector, connector->dev) {
> +       drm_connector_list_iter_get(connector->dev, &conn_iter);
> +       drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>                 if (tmp_connector->state->crtc != crtc)
>                         continue;
>
> @@ -2876,6 +2888,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
>                         break;
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>         crtc_state->active = active;
>
>         ret = drm_atomic_commit(state);
> @@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>  {
>         struct drm_atomic_state *state;
>         struct drm_connector *conn;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_plane *plane;
>         struct drm_crtc *crtc;
>         int err = 0;
> @@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
>                 }
>         }
>
> -       drm_for_each_connector(conn, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(conn, &conn_iter) {
>                 struct drm_connector_state *conn_state;
>
>                 conn_state = drm_atomic_get_connector_state(state, conn);
>                 if (IS_ERR(conn_state)) {
>                         err = PTR_ERR(conn_state);
> +                       drm_connector_list_iter_put(&conn_iter);
>                         goto free;
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         /* clear the acquire context so that it isn't accidentally reused */
>         state->acquire_ctx = NULL;
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 9d007f5f9732..ad154325a0fd 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -88,6 +88,7 @@
>  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>  {
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_device *dev = encoder->dev;
>
>         /*
> @@ -99,9 +100,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>                 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>         }
>
> -       drm_for_each_connector(connector, dev)
> -               if (connector->encoder == encoder)
> +
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
> +               if (connector->encoder == encoder) {
> +                       drm_connector_list_iter_put(&conn_iter);
>                         return true;
> +               }
> +       }
> +       drm_connector_list_iter_put(&conn_iter);
>         return false;
>  }
>  EXPORT_SYMBOL(drm_helper_encoder_in_use);
> @@ -436,10 +443,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>
>         /* Decouple all encoders and their attached connectors from this crtc */
>         drm_for_each_encoder(encoder, dev) {
> +               struct drm_connector_list_iter conn_iter;
> +
>                 if (encoder->crtc != crtc)
>                         continue;
>
> -               drm_for_each_connector(connector, dev) {
> +               drm_connector_list_iter_get(dev, &conn_iter);
> +               drm_for_each_connector_iter(connector, &conn_iter) {
>                         if (connector->encoder != encoder)
>                                 continue;
>
> @@ -456,6 +466,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
>                         /* we keep a reference while the encoder is bound */
>                         drm_connector_unreference(connector);
>                 }
> +               drm_connector_list_iter_put(&conn_iter);
>         }
>
>         __drm_helper_disable_unused_functions(dev);
> @@ -507,6 +518,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>         bool mode_changed = false; /* if true do a full mode set */
>         bool fb_changed = false; /* if true and !mode_changed just do a flip */
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         int count = 0, ro, fail = 0;
>         const struct drm_crtc_helper_funcs *crtc_funcs;
>         struct drm_mode_set save_set;
> @@ -571,9 +583,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>         }
>
>         count = 0;
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter)
>                 save_connector_encoders[count++] = connector->encoder;
> -       }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         save_set.crtc = set->crtc;
>         save_set.mode = &set->crtc->mode;
> @@ -615,7 +628,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>
>         /* a) traverse passed in connector list and get encoders for them */
>         count = 0;
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 const struct drm_connector_helper_funcs *connector_funcs =
>                         connector->helper_private;
>                 new_encoder = connector->encoder;
> @@ -648,6 +662,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>                         connector->encoder = new_encoder;
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         if (fail) {
>                 ret = -EINVAL;
> @@ -655,7 +670,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>         }
>
>         count = 0;
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 if (!connector->encoder)
>                         continue;
>
> @@ -673,6 +689,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>                 if (new_crtc &&
>                     !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
>                         ret = -EINVAL;
> +                       drm_connector_list_iter_put(&conn_iter);
>                         goto fail;
>                 }
>                 if (new_crtc != connector->encoder->crtc) {
> @@ -689,6 +706,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>                                       connector->base.id, connector->name);
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         /* mode_set_base is not a required function */
>         if (fb_changed && !crtc_funcs->mode_set_base)
> @@ -743,9 +761,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
>         }
>
>         count = 0;
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter)
>                 connector->encoder = save_connector_encoders[count++];
> -       }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         /* after fail drop reference on all unbound connectors in set, let
>          * bound connectors keep their reference
> @@ -772,12 +791,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
>  {
>         int dpms = DRM_MODE_DPMS_OFF;
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_device *dev = encoder->dev;
>
> -       drm_for_each_connector(connector, dev)
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter)
>                 if (connector->encoder == encoder)
>                         if (connector->dpms < dpms)
>                                 dpms = connector->dpms;
> +       drm_connector_list_iter_put(&conn_iter);
> +
>         return dpms;
>  }
>
> @@ -809,12 +832,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
>  {
>         int dpms = DRM_MODE_DPMS_OFF;
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_device *dev = crtc->dev;
>
> -       drm_for_each_connector(connector, dev)
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter)
>                 if (connector->encoder && connector->encoder->crtc == crtc)
>                         if (connector->dpms < dpms)
>                                 dpms = connector->dpms;
> +       drm_connector_list_iter_put(&conn_iter);
> +
>         return dpms;
>  }
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index bee5e4149a1c..145d55fef69e 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>  {
>         struct drm_device *dev = fb_helper->dev;
>         struct drm_connector *connector;
> -       int i, ret;
> +       struct drm_connector_list_iter conn_iter;
> +       int i, ret = 0;
>
>         if (!drm_fbdev_emulation)
>                 return 0;
>
>         mutex_lock(&dev->mode_config.mutex);
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 ret = drm_fb_helper_add_one_connector(fb_helper, connector);
>
>                 if (ret)
>                         goto fail;
>         }
> -       mutex_unlock(&dev->mode_config.mutex);
> -       return 0;
> +       goto out;
> +
>  fail:
>         drm_fb_helper_for_each_connector(fb_helper, i) {
>                 struct drm_fb_helper_connector *fb_helper_connector =
> @@ -145,6 +147,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
>                 fb_helper->connector_info[i] = NULL;
>         }
>         fb_helper->connector_count = 0;
> +out:
> +       drm_connector_list_iter_put(&conn_iter);
>         mutex_unlock(&dev->mode_config.mutex);
>
>         return ret;
> diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
> index 5b051859b8d3..5d8fa791fff5 100644
> --- a/drivers/gpu/drm/drm_modeset_helper.c
> +++ b/drivers/gpu/drm/drm_modeset_helper.c
> @@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>
>         INIT_LIST_HEAD(&panel_list);
>
> +       spin_lock_irq(&dev->mode_config.connector_list_lock);
>         list_for_each_entry_safe(connector, tmp,
>                                  &dev->mode_config.connector_list, head) {
>                 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
> @@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
>         }
>
>         list_splice(&panel_list, &dev->mode_config.connector_list);
> +       spin_unlock_irq(&dev->mode_config.connector_list_lock);
>  }
>  EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
>
> diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
> index 7a7dddf604d7..bc9f97422cd1 100644
> --- a/drivers/gpu/drm/drm_plane_helper.c
> +++ b/drivers/gpu/drm/drm_plane_helper.c
> @@ -74,6 +74,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         int count = 0;
>
>         /*
> @@ -83,7 +84,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>          */
>         WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 if (connector->encoder && connector->encoder->crtc == crtc) {
>                         if (connector_list != NULL && count < num_connectors)
>                                 *(connector_list++) = connector;
> @@ -91,6 +93,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>                         count++;
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         return count;
>  }
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index ac953f037be7..7cff91e7497f 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>  {
>         bool poll = false;
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
>
>         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
> @@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
>         if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
>                 return;
>
> -       drm_for_each_connector(connector, dev) {
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
>                                          DRM_CONNECTOR_POLL_DISCONNECT))
>                         poll = true;
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         if (dev->mode_config.delayed_event) {
>                 poll = true;
> @@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
>         struct delayed_work *delayed_work = to_delayed_work(work);
>         struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         enum drm_connector_status old_status;
>         bool repoll = false, changed;
>
> @@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
>                 goto out;
>         }
>
> -       drm_for_each_connector(connector, dev) {
> -
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 /* Ignore forced connectors. */
>                 if (connector->force)
>                         continue;
> @@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
>                         changed = true;
>                 }
>         }
> +       drm_connector_list_iter_put(&conn_iter);
>
>         mutex_unlock(&dev->mode_config.mutex);
>
> @@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
>  bool drm_helper_hpd_irq_event(struct drm_device *dev)
>  {
>         struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         enum drm_connector_status old_status;
>         bool changed = false;
>
> @@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>                 return false;
>
>         mutex_lock(&dev->mode_config.mutex);
> -       drm_for_each_connector(connector, dev) {
> -
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
>                 /* Only handle HPD capable connectors. */
>                 if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
>                         continue;
> @@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
>                 if (old_status != connector->status)
>                         changed = true;
>         }
> -
> +       drm_connector_list_iter_put(&conn_iter);
>         mutex_unlock(&dev->mode_config.mutex);
>
>         if (changed)
> --
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 07/13] drm: Clean up connectors by unreferencing them
  2016-12-13 23:08 ` [PATCH 07/13] drm: Clean up connectors by unreferencing them Daniel Vetter
  2016-12-15 15:45   ` Harry Wentland
@ 2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> Only static connectors should be left at this point, and we should be
> able to clean them out by simply dropping that last reference still
> around from drm_connector_init.
>
> If that leaves anything behind then we have a driver bug.
>
> Doing the final cleanup this way also allows us to use
> drm_connector_iter, removing the very last place where we walk
> connector_list explicitly in drm core&helpers.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_mode_config.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 747a26df0e90..a942536abd60 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -397,7 +397,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
>   */
>  void drm_mode_config_cleanup(struct drm_device *dev)
>  {
> -       struct drm_connector *connector, *ot;
> +       struct drm_connector *connector;
> +       struct drm_connector_list_iter conn_iter;
>         struct drm_crtc *crtc, *ct;
>         struct drm_encoder *encoder, *enct;
>         struct drm_framebuffer *fb, *fbt;
> @@ -410,10 +411,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>                 encoder->funcs->destroy(encoder);
>         }
>
> -       list_for_each_entry_safe(connector, ot,
> -                                &dev->mode_config.connector_list, head) {
> -               connector->funcs->destroy(connector);
> +       drm_connector_list_iter_get(dev, &conn_iter);
> +       drm_for_each_connector_iter(connector, &conn_iter) {
> +               /* drm_connector_list_iter holds an full reference to the
> +                * current connector itself, which means it is inherently safe
> +                * against unreferencing the current connector - but not against
> +                * deleting it right away. */

pedantic nit: doesn't conform to CodingStyle

Reviewed-by: Sean Paul <seanpaul@chromium.org>

> +               drm_connector_unreference(connector);
>         }
> +       drm_connector_list_iter_put(&conn_iter);
> +       WARN_ON(!list_empty(&dev->mode_config.connector_list));
>
>         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
>                                  head) {
> --
> 2.11.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 08/13] drm: prevent double-(un)registration for connectors
  2016-12-13 23:08 ` [PATCH 08/13] drm: prevent double-(un)registration for connectors Daniel Vetter
  2016-12-13 23:52   ` Chris Wilson
@ 2016-12-16 15:03   ` Sean Paul
  1 sibling, 0 replies; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> If we're unlucky then the registration from a hotplugged connector
> might race with the final registration step on driver load. And since
> MST topology discover is asynchronous that's even somewhat likely.
>
> v2: Also update the kerneldoc for @registered!
>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Reported-by: Chris Wilson <chris@chris-wilson.co.uk>


With Chris' suggested improvements

Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c | 18 +++++++++++++-----
>  include/drm/drm_connector.h     | 12 +++++++++++-
>  2 files changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index b33334e09b00..0d4728704099 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -223,6 +223,7 @@ int drm_connector_init(struct drm_device *dev,
>
>         INIT_LIST_HEAD(&connector->probed_modes);
>         INIT_LIST_HEAD(&connector->modes);
> +       mutex_init(&connector->mutex);
>         connector->edid_blob_ptr = NULL;
>         connector->status = connector_status_unknown;
>
> @@ -373,14 +374,15 @@ EXPORT_SYMBOL(drm_connector_cleanup);
>   */
>  int drm_connector_register(struct drm_connector *connector)
>  {
> -       int ret;
> +       int ret = 0;
>
> +       mutex_lock(&connector->mutex);
>         if (connector->registered)
> -               return 0;
> +               goto unlock;
>
>         ret = drm_sysfs_connector_add(connector);
>         if (ret)
> -               return ret;
> +               goto unlock;
>
>         ret = drm_debugfs_connector_add(connector);
>         if (ret) {
> @@ -396,12 +398,14 @@ int drm_connector_register(struct drm_connector *connector)
>         drm_mode_object_register(connector->dev, &connector->base);
>
>         connector->registered = true;
> -       return 0;
> +       goto unlock;
>
>  err_debugfs:
>         drm_debugfs_connector_remove(connector);
>  err_sysfs:
>         drm_sysfs_connector_remove(connector);
> +unlock:
> +       mutex_unlock(&connector->mutex);
>         return ret;
>  }
>  EXPORT_SYMBOL(drm_connector_register);
> @@ -414,8 +418,11 @@ EXPORT_SYMBOL(drm_connector_register);
>   */
>  void drm_connector_unregister(struct drm_connector *connector)
>  {
> -       if (!connector->registered)
> +       mutex_lock(&connector->mutex);
> +       if (!connector->registered) {
> +               mutex_unlock(&connector->mutex);
>                 return;
> +       }
>
>         if (connector->funcs->early_unregister)
>                 connector->funcs->early_unregister(connector);
> @@ -424,6 +431,7 @@ void drm_connector_unregister(struct drm_connector *connector)
>         drm_debugfs_connector_remove(connector);
>
>         connector->registered = false;
> +       mutex_unlock(&connector->mutex);
>  }
>  EXPORT_SYMBOL(drm_connector_unregister);
>
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 0e41a2e184a9..a24559ef8bb7 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -559,7 +559,6 @@ struct drm_cmdline_mode {
>   * @interlace_allowed: can this connector handle interlaced modes?
>   * @doublescan_allowed: can this connector handle doublescan?
>   * @stereo_allowed: can this connector handle stereo modes?
> - * @registered: is this connector exposed (registered) with userspace?
>   * @modes: modes available on this connector (from fill_modes() + user)
>   * @status: one of the drm_connector_status enums (connected, not, or unknown)
>   * @probed_modes: list of modes derived directly from the display
> @@ -608,6 +607,13 @@ struct drm_connector {
>         char *name;
>
>         /**
> +        * @mutex: Lock for general connector state, but currently only protects
> +        * @registered. Most of the connector state is still protected by the
> +        * mutex in &drm_mode_config.
> +        */
> +       struct mutex mutex;
> +
> +       /**
>          * @index: Compacted connector index, which matches the position inside
>          * the mode_config.list for drivers not supporting hot-add/removing. Can
>          * be used as an array index. It is invariant over the lifetime of the
> @@ -620,6 +626,10 @@ struct drm_connector {
>         bool interlace_allowed;
>         bool doublescan_allowed;
>         bool stereo_allowed;
> +       /**
> +        * @registered: Is this connector exposed (registered) with userspace?
> +        * Protected by @mutex.
> +        */
>         bool registered;
>         struct list_head modes; /* list of modes on this connector */
>
> --
> 2.11.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector
  2016-12-13 23:08 ` [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector Daniel Vetter
@ 2016-12-16 15:03   ` Sean Paul
  2016-12-18 13:40     ` Daniel Vetter
  0 siblings, 1 reply; 41+ messages in thread
From: Sean Paul @ 2016-12-16 15:03 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> - Modeset state needs mode_config->connection mutex, that covers
>   figuring out the encoder, and reading properties (since in the
>   atomic case those need to look at connector->state).
>
> - Don't hold any locks for stuff that's invariant (i.e. possible
>   connectors).
>
> - Same for connector lookup and unref, those don't need any locks.
>
> - And finally the probe stuff is only protected by mode_config->mutex.
>
> While at it updated the kerneldoc for these fields in drm_connector
> and add docs explaining what's protected by which locks.
>


Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c | 92 ++++++++++++++++++++---------------------
>  include/drm/drm_connector.h     | 23 +++++++++--
>  2 files changed, 63 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 0d4728704099..44b556d5d40c 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1160,43 +1160,65 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
>
>         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
>
> -       mutex_lock(&dev->mode_config.mutex);
> -
>         connector = drm_connector_lookup(dev, out_resp->connector_id);
> -       if (!connector) {
> -               ret = -ENOENT;
> -               goto out_unlock;
> -       }
> +       if (!connector)
> +               return -ENOENT;
> +
> +       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> +       encoder = drm_connector_get_encoder(connector);
> +       if (encoder)
> +               out_resp->encoder_id = encoder->base.id;
> +       else
> +               out_resp->encoder_id = 0;
> +
> +       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
> +                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
> +                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
> +                       &out_resp->count_props);
> +       drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +       if (ret)
> +               goto out_unref;
>
>         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
>                 if (connector->encoder_ids[i] != 0)
>                         encoders_count++;
>
> +       if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
> +               copied = 0;
> +               encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
> +               for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> +                       if (connector->encoder_ids[i] != 0) {
> +                               if (put_user(connector->encoder_ids[i],
> +                                            encoder_ptr + copied)) {
> +                                       ret = -EFAULT;
> +                                       goto out_unref;
> +                               }
> +                               copied++;
> +                       }
> +               }
> +       }
> +       out_resp->count_encoders = encoders_count;
> +
> +       out_resp->connector_id = connector->base.id;
> +       out_resp->connector_type = connector->connector_type;
> +       out_resp->connector_type_id = connector->connector_type_id;
> +
> +       mutex_lock(&dev->mode_config.mutex);
>         if (out_resp->count_modes == 0) {
>                 connector->funcs->fill_modes(connector,
>                                              dev->mode_config.max_width,
>                                              dev->mode_config.max_height);
>         }
>
> -       /* delayed so we get modes regardless of pre-fill_modes state */
> -       list_for_each_entry(mode, &connector->modes, head)
> -               if (drm_mode_expose_to_userspace(mode, file_priv))
> -                       mode_count++;
> -
> -       out_resp->connector_id = connector->base.id;
> -       out_resp->connector_type = connector->connector_type;
> -       out_resp->connector_type_id = connector->connector_type_id;
>         out_resp->mm_width = connector->display_info.width_mm;
>         out_resp->mm_height = connector->display_info.height_mm;
>         out_resp->subpixel = connector->display_info.subpixel_order;
>         out_resp->connection = connector->status;
>
> -       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> -       encoder = drm_connector_get_encoder(connector);
> -       if (encoder)
> -               out_resp->encoder_id = encoder->base.id;
> -       else
> -               out_resp->encoder_id = 0;
> +       /* delayed so we get modes regardless of pre-fill_modes state */
> +       list_for_each_entry(mode, &connector->modes, head)
> +               if (drm_mode_expose_to_userspace(mode, file_priv))
> +                       mode_count++;
>
>         /*
>          * This ioctl is called twice, once to determine how much space is
> @@ -1219,36 +1241,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
>                 }
>         }
>         out_resp->count_modes = mode_count;
> -
> -       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
> -                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
> -                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
> -                       &out_resp->count_props);
> -       if (ret)
> -               goto out;
> -
> -       if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
> -               copied = 0;
> -               encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
> -               for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> -                       if (connector->encoder_ids[i] != 0) {
> -                               if (put_user(connector->encoder_ids[i],
> -                                            encoder_ptr + copied)) {
> -                                       ret = -EFAULT;
> -                                       goto out;
> -                               }
> -                               copied++;
> -                       }
> -               }
> -       }
> -       out_resp->count_encoders = encoders_count;
> -
>  out:
> -       drm_modeset_unlock(&dev->mode_config.connection_mutex);
> -
> -       drm_connector_unreference(connector);
> -out_unlock:
>         mutex_unlock(&dev->mode_config.mutex);
> +out_unref:
> +       drm_connector_unreference(connector);
>
>         return ret;
>  }
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a24559ef8bb7..9af4141165d3 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -559,9 +559,6 @@ struct drm_cmdline_mode {
>   * @interlace_allowed: can this connector handle interlaced modes?
>   * @doublescan_allowed: can this connector handle doublescan?
>   * @stereo_allowed: can this connector handle stereo modes?
> - * @modes: modes available on this connector (from fill_modes() + user)
> - * @status: one of the drm_connector_status enums (connected, not, or unknown)
> - * @probed_modes: list of modes derived directly from the display
>   * @funcs: connector control functions
>   * @edid_blob_ptr: DRM property containing EDID if present
>   * @properties: property tracking for this connector
> @@ -631,11 +628,27 @@ struct drm_connector {
>          * Protected by @mutex.
>          */
>         bool registered;
> +
> +       /**
> +        * @modes:
> +        * Modes available on this connector (from fill_modes() + user).
> +        * Protected by dev->mode_config.mutex.
> +        */
>         struct list_head modes; /* list of modes on this connector */
>
> +       /**
> +        * @status:
> +        * One of the drm_connector_status enums (connected, not, or unknown).
> +        * Protected by dev->mode_config.mutex.
> +        */
>         enum drm_connector_status status;
>
> -       /* these are modes added by probing with DDC or the BIOS */
> +       /**
> +        * @probed_modes:
> +        * These are modes added by probing with DDC or the BIOS, before
> +        * filtering is applied. Used by the probe helpers.Protected by
> +        * dev->mode_config.mutex.
> +        */
>         struct list_head probed_modes;
>
>         /**
> @@ -644,6 +657,8 @@ struct drm_connector {
>          * flat panels in embedded systems, the driver should initialize the
>          * display_info.width_mm and display_info.height_mm fields with the
>          * physical size of the display.
> +        *
> +        * Protected by dev->mode_config.mutex.
>          */
>         struct drm_display_info display_info;
>         const struct drm_connector_funcs *funcs;
> --
> 2.11.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector
  2016-12-16 15:03   ` Sean Paul
@ 2016-12-18 13:40     ` Daniel Vetter
  0 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2016-12-18 13:40 UTC (permalink / raw)
  To: Sean Paul
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Fri, Dec 16, 2016 at 10:03:32AM -0500, Sean Paul wrote:
> On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > - Modeset state needs mode_config->connection mutex, that covers
> >   figuring out the encoder, and reading properties (since in the
> >   atomic case those need to look at connector->state).
> >
> > - Don't hold any locks for stuff that's invariant (i.e. possible
> >   connectors).
> >
> > - Same for connector lookup and unref, those don't need any locks.
> >
> > - And finally the probe stuff is only protected by mode_config->mutex.
> >
> > While at it updated the kerneldoc for these fields in drm_connector
> > and add docs explaining what's protected by which locks.
> >
> 
> 
> Reviewed-by: Sean Paul <seanpaul@chromium.org>

Merged up to this patch to drm-misc, thanks for the reviews to everyone.
-Daniel

> 
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_connector.c | 92 ++++++++++++++++++++---------------------
> >  include/drm/drm_connector.h     | 23 +++++++++--
> >  2 files changed, 63 insertions(+), 52 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 0d4728704099..44b556d5d40c 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1160,43 +1160,65 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
> >
> >         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
> >
> > -       mutex_lock(&dev->mode_config.mutex);
> > -
> >         connector = drm_connector_lookup(dev, out_resp->connector_id);
> > -       if (!connector) {
> > -               ret = -ENOENT;
> > -               goto out_unlock;
> > -       }
> > +       if (!connector)
> > +               return -ENOENT;
> > +
> > +       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> > +       encoder = drm_connector_get_encoder(connector);
> > +       if (encoder)
> > +               out_resp->encoder_id = encoder->base.id;
> > +       else
> > +               out_resp->encoder_id = 0;
> > +
> > +       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
> > +                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
> > +                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
> > +                       &out_resp->count_props);
> > +       drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > +       if (ret)
> > +               goto out_unref;
> >
> >         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
> >                 if (connector->encoder_ids[i] != 0)
> >                         encoders_count++;
> >
> > +       if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
> > +               copied = 0;
> > +               encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
> > +               for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> > +                       if (connector->encoder_ids[i] != 0) {
> > +                               if (put_user(connector->encoder_ids[i],
> > +                                            encoder_ptr + copied)) {
> > +                                       ret = -EFAULT;
> > +                                       goto out_unref;
> > +                               }
> > +                               copied++;
> > +                       }
> > +               }
> > +       }
> > +       out_resp->count_encoders = encoders_count;
> > +
> > +       out_resp->connector_id = connector->base.id;
> > +       out_resp->connector_type = connector->connector_type;
> > +       out_resp->connector_type_id = connector->connector_type_id;
> > +
> > +       mutex_lock(&dev->mode_config.mutex);
> >         if (out_resp->count_modes == 0) {
> >                 connector->funcs->fill_modes(connector,
> >                                              dev->mode_config.max_width,
> >                                              dev->mode_config.max_height);
> >         }
> >
> > -       /* delayed so we get modes regardless of pre-fill_modes state */
> > -       list_for_each_entry(mode, &connector->modes, head)
> > -               if (drm_mode_expose_to_userspace(mode, file_priv))
> > -                       mode_count++;
> > -
> > -       out_resp->connector_id = connector->base.id;
> > -       out_resp->connector_type = connector->connector_type;
> > -       out_resp->connector_type_id = connector->connector_type_id;
> >         out_resp->mm_width = connector->display_info.width_mm;
> >         out_resp->mm_height = connector->display_info.height_mm;
> >         out_resp->subpixel = connector->display_info.subpixel_order;
> >         out_resp->connection = connector->status;
> >
> > -       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> > -       encoder = drm_connector_get_encoder(connector);
> > -       if (encoder)
> > -               out_resp->encoder_id = encoder->base.id;
> > -       else
> > -               out_resp->encoder_id = 0;
> > +       /* delayed so we get modes regardless of pre-fill_modes state */
> > +       list_for_each_entry(mode, &connector->modes, head)
> > +               if (drm_mode_expose_to_userspace(mode, file_priv))
> > +                       mode_count++;
> >
> >         /*
> >          * This ioctl is called twice, once to determine how much space is
> > @@ -1219,36 +1241,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
> >                 }
> >         }
> >         out_resp->count_modes = mode_count;
> > -
> > -       ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
> > -                       (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
> > -                       (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
> > -                       &out_resp->count_props);
> > -       if (ret)
> > -               goto out;
> > -
> > -       if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
> > -               copied = 0;
> > -               encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
> > -               for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> > -                       if (connector->encoder_ids[i] != 0) {
> > -                               if (put_user(connector->encoder_ids[i],
> > -                                            encoder_ptr + copied)) {
> > -                                       ret = -EFAULT;
> > -                                       goto out;
> > -                               }
> > -                               copied++;
> > -                       }
> > -               }
> > -       }
> > -       out_resp->count_encoders = encoders_count;
> > -
> >  out:
> > -       drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > -
> > -       drm_connector_unreference(connector);
> > -out_unlock:
> >         mutex_unlock(&dev->mode_config.mutex);
> > +out_unref:
> > +       drm_connector_unreference(connector);
> >
> >         return ret;
> >  }
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index a24559ef8bb7..9af4141165d3 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -559,9 +559,6 @@ struct drm_cmdline_mode {
> >   * @interlace_allowed: can this connector handle interlaced modes?
> >   * @doublescan_allowed: can this connector handle doublescan?
> >   * @stereo_allowed: can this connector handle stereo modes?
> > - * @modes: modes available on this connector (from fill_modes() + user)
> > - * @status: one of the drm_connector_status enums (connected, not, or unknown)
> > - * @probed_modes: list of modes derived directly from the display
> >   * @funcs: connector control functions
> >   * @edid_blob_ptr: DRM property containing EDID if present
> >   * @properties: property tracking for this connector
> > @@ -631,11 +628,27 @@ struct drm_connector {
> >          * Protected by @mutex.
> >          */
> >         bool registered;
> > +
> > +       /**
> > +        * @modes:
> > +        * Modes available on this connector (from fill_modes() + user).
> > +        * Protected by dev->mode_config.mutex.
> > +        */
> >         struct list_head modes; /* list of modes on this connector */
> >
> > +       /**
> > +        * @status:
> > +        * One of the drm_connector_status enums (connected, not, or unknown).
> > +        * Protected by dev->mode_config.mutex.
> > +        */
> >         enum drm_connector_status status;
> >
> > -       /* these are modes added by probing with DDC or the BIOS */
> > +       /**
> > +        * @probed_modes:
> > +        * These are modes added by probing with DDC or the BIOS, before
> > +        * filtering is applied. Used by the probe helpers.Protected by
> > +        * dev->mode_config.mutex.
> > +        */
> >         struct list_head probed_modes;
> >
> >         /**
> > @@ -644,6 +657,8 @@ struct drm_connector {
> >          * flat panels in embedded systems, the driver should initialize the
> >          * display_info.width_mm and display_info.height_mm fields with the
> >          * physical size of the display.
> > +        *
> > +        * Protected by dev->mode_config.mutex.
> >          */
> >         struct drm_display_info display_info;
> >         const struct drm_connector_funcs *funcs;
> > --
> > 2.11.0
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
> 
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [kbuild-all] [PATCH] drm: Convert all helpers to drm_connector_list_iter
  2016-12-16  7:41         ` [kbuild-all] " Fengguang Wu
@ 2016-12-18 18:04           ` Ye Xiaolong
  0 siblings, 0 replies; 41+ messages in thread
From: Ye Xiaolong @ 2016-12-18 18:04 UTC (permalink / raw)
  To: Fengguang Wu
  Cc: Daniel Vetter, Intel Graphics Development, Harry Wentland,
	kbuild-all, DRI Development

On 12/16, Fengguang Wu wrote:
>Hi Daniel,
>
>On Fri, Dec 16, 2016 at 08:29:43AM +0100, Daniel Vetter wrote:
>>Hi Kbuild folks
>>
>>So yeah this doesn't apply because it's just 1 patch resent out of a
>>big patch series, in-reply-to the patch it replaces. So applying this
>>alone and telling me (and all the mailing lists) that it doesn't apply
>>isn't all that useful.
>>
>>And it shouldn't be too hard to detect this, since the fdo patchwork
>>instance does catch most of these partial resends successfully and
>>correctly, and will retest the entire patch series.
>
>Good point! CC Xiaolong. This scenario seems happen frequent enough in
>LKML to worth the efforts to add auto detect logic for.

Got it, I'll add auto detect logic to handle it.

Thanks,
Xiaolong

>
>Thanks,
>Fengguang
>
>>On Thu, Dec 15, 2016 at 11:59 PM, kbuild test robot <lkp@intel.com> wrote:
>>>Hi Daniel,
>>>
>>>[auto build test ERROR on drm/drm-next]
>>>[also build test ERROR on next-20161215]
>>>[cannot apply to v4.9]
>>>[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>>
>>>url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
>>>base:   git://people.freedesktop.org/~airlied/linux.git drm-next
>>>config: i386-randconfig-x003-201650 (attached as .config)
>>>compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>>>reproduce:
>>>        # save the attached .config to linux build tree
>>>        make ARCH=i386
>>>
>>>All error/warnings (new ones prefixed by >>):
>>>
>>>   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>>>>>drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_get(dev, &conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
>>>   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' isn't known
>>>      struct drm_connector_list_iter conn_iter;
>>>                                     ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' token
>>>      drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                         ^
>>>   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>      struct drm_connector_list_iter conn_iter;
>>>                                     ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
>>>   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 'save_connector_encoders'
>>>      save_connector_encoders[count++] = connector->encoder;
>>>      ^~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_put(&conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>>>drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'
>>>      connector->encoder = save_connector_encoders[count++];
>>>      ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 'new_encoder' [-Wunused-variable]
>>>     struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
>>>                                                    ^~~~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 'new_crtc' [-Wunused-variable]
>>>     struct drm_crtc **save_encoder_crtcs, *new_crtc;
>>>                                            ^~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_encoder_dpms':
>>>   drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   In file included from include/linux/linkage.h:4:0,
>>>                    from include/linux/kernel.h:6,
>>>                    from drivers/gpu/drm/drm_crtc_helper.c:32:
>>>>>include/linux/compiler.h:149:2: error: expected ';' before 'if'
>>>     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>>>     ^
>>>   include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>>>    #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>>>                          ^~~~~~~~~~
>>>>>drivers/gpu/drm/drm_crtc_helper.c:800:3: note: in expansion of macro 'if'
>>>      if (connector->encoder == encoder)
>>>      ^~
>>>   drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_choose_crtc_dpms':
>>>   drivers/gpu/drm/drm_crtc_helper.c:836:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   In file included from include/linux/linkage.h:4:0,
>>>                    from include/linux/kernel.h:6,
>>>                    from drivers/gpu/drm/drm_crtc_helper.c:32:
>>>>>include/linux/compiler.h:149:2: error: expected ';' before 'if'
>>>     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
>>>     ^
>>>   include/linux/compiler.h:147:23: note: in expansion of macro '__trace_if'
>>>    #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
>>>                          ^~~~~~~~~~
>>>   drivers/gpu/drm/drm_crtc_helper.c:841:3: note: in expansion of macro 'if'
>>>      if (connector->encoder && connector->encoder->crtc == crtc)
>>>      ^~
>>>   drivers/gpu/drm/drm_crtc_helper.c:836:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   cc1: some warnings being treated as errors
>>>--
>>>   drivers/gpu/drm/drm_probe_helper.c: In function 'drm_kms_helper_poll_enable_locked':
>>>>>drivers/gpu/drm/drm_probe_helper.c:132:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_probe_helper.c:140:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_get(dev, &conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_probe_helper.c:141:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_probe_helper.c:141:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_probe_helper.c:132:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c: In function 'output_poll_execute':
>>>   drivers/gpu/drm/drm_probe_helper.c:388:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c:405:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_probe_helper.c:389:28: warning: unused variable 'old_status' [-Wunused-variable]
>>>     enum drm_connector_status old_status;
>>>                               ^~~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c:388:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c: In function 'drm_helper_hpd_irq_event':
>>>   drivers/gpu/drm/drm_probe_helper.c:570:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c:579:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_probe_helper.c:571:28: warning: unused variable 'old_status' [-Wunused-variable]
>>>     enum drm_connector_status old_status;
>>>                               ^~~~~~~~~~
>>>   drivers/gpu/drm/drm_probe_helper.c:570:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   cc1: some warnings being treated as errors
>>>--
>>>   drivers/gpu/drm/drm_plane_helper.c: In function 'get_connectors_for_crtc':
>>>>>drivers/gpu/drm/drm_plane_helper.c:77:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_plane_helper.c:87:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_get(dev, &conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_plane_helper.c:88:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_plane_helper.c:88:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_plane_helper.c:77:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   cc1: some warnings being treated as errors
>>>--
>>>   drivers/gpu/drm/drm_atomic_helper.c: In function 'handle_conflicting_encoders':
>>>>>drivers/gpu/drm/drm_atomic_helper.c:97:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_atomic_helper.c:148:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_get(state->dev, &conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_atomic_helper.c:149:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_atomic_helper.c:149:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>   drivers/gpu/drm/drm_atomic_helper.c:98:22: warning: unused variable 'encoder' [-Wunused-variable]
>>>     struct drm_encoder *encoder;
>>>                         ^~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:97:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_disable_all':
>>>   drivers/gpu/drm/drm_atomic_helper.c:2452:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:2462:48: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(conn, &conn_iter) {
>>>                                                   ^
>>>>>drivers/gpu/drm/drm_atomic_helper.c:2480:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_put(&conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:2479:1: warning: label 'free' defined but not used [-Wunused-label]
>>>    free:
>>>    ^~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:2452:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_connector_dpms':
>>>   drivers/gpu/drm/drm_atomic_helper.c:2853:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:2882:57: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(tmp_connector, &conn_iter) {
>>>                                                            ^
>>>   drivers/gpu/drm/drm_atomic_helper.c:2853:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c: In function 'drm_atomic_helper_duplicate_state':
>>>   drivers/gpu/drm/drm_atomic_helper.c:3269:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   drivers/gpu/drm/drm_atomic_helper.c:3301:48: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(conn, &conn_iter) {
>>>                                                   ^
>>>   drivers/gpu/drm/drm_atomic_helper.c:3269:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   cc1: some warnings being treated as errors
>>>--
>>>   drivers/gpu/drm/drm_modeset_helper.c: In function 'drm_helper_move_panel_connectors_to_head':
>>>>>drivers/gpu/drm/drm_modeset_helper.c:51:33: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>>>     spin_lock_irq(&dev->mode_config.connector_list_lock);
>>>                                    ^
>>>   drivers/gpu/drm/drm_modeset_helper.c:61:35: error: 'struct drm_mode_config' has no member named 'connector_list_lock'; did you mean 'connector_list'?
>>>     spin_unlock_irq(&dev->mode_config.connector_list_lock);
>>>                                      ^
>>>--
>>>   drivers/gpu/drm/drm_fb_helper.c: In function 'drm_fb_helper_single_add_all_connectors':
>>>>>drivers/gpu/drm/drm_fb_helper.c:123:33: error: storage size of 'conn_iter' isn't known
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>>>drivers/gpu/drm/drm_fb_helper.c:130:2: error: implicit declaration of function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_get(dev, &conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_fb_helper.c:131:2: error: implicit declaration of function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>drivers/gpu/drm/drm_fb_helper.c:131:53: error: expected ';' before '{' token
>>>     drm_for_each_connector_iter(connector, &conn_iter) {
>>>                                                        ^
>>>>>drivers/gpu/drm/drm_fb_helper.c:151:2: error: implicit declaration of function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
>>>     drm_connector_list_iter_put(&conn_iter);
>>>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>   drivers/gpu/drm/drm_fb_helper.c:150:1: warning: label 'out' defined but not used [-Wunused-label]
>>>    out:
>>>    ^~~
>>>   drivers/gpu/drm/drm_fb_helper.c:139:1: warning: label 'fail' defined but not used [-Wunused-label]
>>>    fail:
>>>    ^~~~
>>>   drivers/gpu/drm/drm_fb_helper.c:123:33: warning: unused variable 'conn_iter' [-Wunused-variable]
>>>     struct drm_connector_list_iter conn_iter;
>>>                                    ^~~~~~~~~
>>>   cc1: some warnings being treated as errors
>>>
>>>vim +91 drivers/gpu/drm/drm_crtc_helper.c
>>>
>>>    26   *      Keith Packard
>>>    27   *      Eric Anholt <eric@anholt.net>
>>>    28   *      Dave Airlie <airlied@linux.ie>
>>>    29   *      Jesse Barnes <jesse.barnes@intel.com>
>>>    30   */
>>>    31
>>>  > 32  #include <linux/kernel.h>
>>>    33  #include <linux/export.h>
>>>    34  #include <linux/moduleparam.h>
>>>    35
>>>    36  #include <drm/drmP.h>
>>>    37  #include <drm/drm_atomic.h>
>>>    38  #include <drm/drm_crtc.h>
>>>    39  #include <drm/drm_fourcc.h>
>>>    40  #include <drm/drm_crtc_helper.h>
>>>    41  #include <drm/drm_fb_helper.h>
>>>    42  #include <drm/drm_plane_helper.h>
>>>    43  #include <drm/drm_atomic_helper.h>
>>>    44  #include <drm/drm_edid.h>
>>>    45
>>>    46  /**
>>>    47   * DOC: overview
>>>    48   *
>>>    49   * The CRTC modeset helper library provides a default set_config implementation
>>>    50   * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
>>>    51   * the same callbacks which drivers can use to e.g. restore the modeset
>>>    52   * configuration on resume with drm_helper_resume_force_mode().
>>>    53   *
>>>    54   * Note that this helper library doesn't track the current power state of CRTCs
>>>    55   * and encoders. It can call callbacks like ->dpms() even though the hardware is
>>>    56   * already in the desired state. This deficiency has been fixed in the atomic
>>>    57   * helpers.
>>>    58   *
>>>    59   * The driver callbacks are mostly compatible with the atomic modeset helpers,
>>>    60   * except for the handling of the primary plane: Atomic helpers require that the
>>>    61   * primary plane is implemented as a real standalone plane and not directly tied
>>>    62   * to the CRTC state. For easier transition this library provides functions to
>>>    63   * implement the old semantics required by the CRTC helpers using the new plane
>>>    64   * and atomic helper callbacks.
>>>    65   *
>>>    66   * Drivers are strongly urged to convert to the atomic helpers (by way of first
>>>    67   * converting to the plane helpers). New drivers must not use these functions
>>>    68   * but need to implement the atomic interface instead, potentially using the
>>>    69   * atomic helpers for that.
>>>    70   *
>>>    71   * These legacy modeset helpers use the same function table structures as
>>>    72   * all other modesetting helpers. See the documentation for struct
>>>    73   * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
>>>    74   * &drm_connector_helper_funcs.
>>>    75   */
>>>    76
>>>    77  /**
>>>    78   * drm_helper_encoder_in_use - check if a given encoder is in use
>>>    79   * @encoder: encoder to check
>>>    80   *
>>>    81   * Checks whether @encoder is with the current mode setting output configuration
>>>    82   * in use by any connector. This doesn't mean that it is actually enabled since
>>>    83   * the DPMS state is tracked separately.
>>>    84   *
>>>    85   * Returns:
>>>    86   * True if @encoder is used, false otherwise.
>>>    87   */
>>>    88  bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
>>>    89  {
>>>    90          struct drm_connector *connector;
>>>  > 91          struct drm_connector_list_iter conn_iter;
>>>    92          struct drm_device *dev = encoder->dev;
>>>    93
>>>    94          /*
>>>    95           * We can expect this mutex to be locked if we are not panicking.
>>>    96           * Locking is currently fubar in the panic handler.
>>>    97           */
>>>    98          if (!oops_in_progress) {
>>>    99                  WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
>>>   100                  WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
>>>   101          }
>>>   102
>>>   103
>>> > 104          drm_connector_list_iter_get(dev, &conn_iter);
>>> > 105          drm_for_each_connector_iter(connector, &conn_iter) {
>>>   106                  if (connector->encoder == encoder) {
>>>   107                          drm_connector_list_iter_put(&conn_iter);
>>>   108                          return true;
>>>
>>>---
>>>0-DAY kernel test infrastructure                Open Source Technology Center
>>>https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>>
>>
>>
>>-- 
>>Daniel Vetter
>>Software Engineer, Intel Corporation
>>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>>_______________________________________________
>>kbuild-all mailing list
>>kbuild-all@lists.01.org
>>https://lists.01.org/mailman/listinfo/kbuild-all
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2016-12-18 18:04 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-13 23:08 [PATCH 00/13] some stuff, and then connector_list locking Daniel Vetter
2016-12-13 23:08 ` [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls Daniel Vetter
2016-12-16 15:02   ` Sean Paul
2016-12-13 23:08 ` [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h Daniel Vetter
2016-12-16 15:02   ` Sean Paul
2016-12-13 23:08 ` [PATCH 03/13] drm/radeon|amdgpu: Remove redundant num_connectors check Daniel Vetter
2016-12-14 16:59   ` Alex Deucher
2016-12-13 23:08 ` [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init Daniel Vetter
2016-12-14  9:23   ` [Intel-gfx] " Daniel Stone
2016-12-16 15:03   ` Sean Paul
2016-12-13 23:08 ` [PATCH 05/13] drm: locking&new iterators for connector_list Daniel Vetter
2016-12-14  8:35   ` Chris Wilson
2016-12-14 11:22   ` Jani Nikula
2016-12-14 12:26     ` Daniel Vetter
2016-12-14 15:04       ` [Intel-gfx] " Jani Nikula
2016-12-16 15:03   ` Sean Paul
2016-12-13 23:08 ` [PATCH 06/13] drm: Convert all helpers to drm_connector_list_iter Daniel Vetter
2016-12-15 14:34   ` Harry Wentland
2016-12-15 15:58   ` [PATCH] " Daniel Vetter
2016-12-15 16:32     ` Harry Wentland
2016-12-15 22:47     ` kbuild test robot
2016-12-15 22:59     ` kbuild test robot
2016-12-16  7:29       ` Daniel Vetter
2016-12-16  7:41         ` [kbuild-all] " Fengguang Wu
2016-12-18 18:04           ` Ye Xiaolong
2016-12-16 15:03     ` Sean Paul
2016-12-13 23:08 ` [PATCH 07/13] drm: Clean up connectors by unreferencing them Daniel Vetter
2016-12-15 15:45   ` Harry Wentland
2016-12-16 15:03   ` Sean Paul
2016-12-13 23:08 ` [PATCH 08/13] drm: prevent double-(un)registration for connectors Daniel Vetter
2016-12-13 23:52   ` Chris Wilson
2016-12-16 15:03   ` Sean Paul
2016-12-13 23:08 ` [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector Daniel Vetter
2016-12-16 15:03   ` Sean Paul
2016-12-18 13:40     ` Daniel Vetter
2016-12-13 23:08 ` [PATCH 10/13] drm/i915: Use drm_connector_list_iter in debugfs Daniel Vetter
2016-12-14 14:44   ` Jani Nikula
2016-12-14 14:51     ` [Intel-gfx] " Daniel Vetter
2016-12-13 23:08 ` [PATCH 11/13] drm/i915: use drm_connector_list_iter in intel_hotplug.c Daniel Vetter
2016-12-13 23:08 ` [PATCH 12/13] drm/i915: use drm_connector_list_iter in intel_opregion.c Daniel Vetter
2016-12-13 23:08 ` [PATCH 13/13] drm/i915: Make intel_get_pipe_from_connector atomic Daniel Vetter

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.