Hitting the failure path through check_digital_port_conflicts triggers:
================================================
WARNING: lock held when returning to user space!
4.16.0-rc1-CI-kasan_1+ #1 Tainted: G W
------------------------------------------------
kms_3d/1439 is leaving the kernel with locks still held!
1 lock held by kms_3d/1439:
#0: (drm_connector_list_iter){.+.+}, at: [<000000003745d183>]
intel_atomic_check+0x1d9d/0x3ff0 [i915]
Rearrange the code to have a single exit path through the unlock.
Signed-off-by: Chris Wilson <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c
b/drivers/gpu/drm/i915/intel_display.c
index 95d0e7a64773..2c240adeecf6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10703,8 +10703,9 @@ static bool check_digital_port_conflicts(struct
drm_atomic_state *state)
struct drm_device *dev = state->dev;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
- unsigned int used_ports = 0;
- unsigned int used_mst_ports = 0;
+ unsigned long used_ports = 0;
+ unsigned long used_mst_ports = 0;
+ bool ok = false;
/*
* Walk the connector list instead of the encoder
@@ -10715,6 +10716,7 @@ static bool check_digital_port_conflicts(struct
drm_atomic_state *state)
drm_for_each_connector_iter(connector, &conn_iter) {
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
+ unsigned int port_mask;
connector_state =
drm_atomic_get_existing_connector_state(state, connector);
if (!connector_state)
@@ -10724,40 +10726,41 @@ static bool check_digital_port_conflicts(struct
drm_atomic_state *state)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
+ port_mask = BIT(encoder->port);
WARN_ON(!connector_state->crtc);
switch (encoder->type) {
- unsigned int port_mask;
case INTEL_OUTPUT_DDI:
if (WARN_ON(!HAS_DDI(to_i915(dev))))
- break;
+ goto error;
case INTEL_OUTPUT_DP:
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
- port_mask = 1 << encoder->port;
-
- /* the same port mustn't appear more than once */
- if (used_ports & port_mask)
- return false;
+ /* the same port must not appear more than once */
+ if ((used_ports | used_mst_ports) & port_mask)
+ goto error;
used_ports |= port_mask;
break;
+
case INTEL_OUTPUT_DP_MST:
- used_mst_ports |=
- 1 << encoder->port;
+ /* can not mix MST and SST/HDMI on the same port */
+ if (used_ports & port_mask)
+ goto error;
+
+ used_mst_ports |= port_mask;
break;
+
default:
break;
}
}
+ ok = true;
+error:
drm_connector_list_iter_end(&conn_iter);
- /* can't mix MST and SST/HDMI on the same port */
- if (used_ports & used_mst_ports)
- return false;
-
- return true;
+ return ok;
}
static void
--
2.16.1
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx