All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 00/11] HDCP2.2 Phase II
@ 2019-05-07 16:27 Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 01/11] drm: move content protection property to mode_config Ramalingam C
                   ` (14 more replies)
  0 siblings, 15 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter

This series adds the content type capability for HDCP through a
drm connetor proeprty "HDCP Content Type". By default this property will
be "Type 0". And this property is exposed by the drivers which has the
HDCP2.2 capability to enable the userspace to configure for "Type 1".

HDCP Content Type:
	This property is used to indicate the content type
classification of a stream. Which indicate the HDCP version required
for the rendering of that streams. This conten type is one of the
parameter in the HDCP2.2 authentication flow, as even downstream
repeaters will mandate the HDCP version requirement.

Two values possible for content type of a stream:
	Type 0: Stream can be rendered only on HDCP encrypted link no
		restriction on HDCP versions.
	Type 1: Stream can be rendered only on HDCP2.2 encrypted link.

And also this series adds a uevent for a change in the property state
change of a connector. This helps the userspace to monitor the uevent
for a property state change than the trivial polling.

Userspace consumer for above "HDCP Content Type" property and uevent is
almost at the last phase of review at #wayland community. So Patches 
7, 8, 9, 10 and 11 can be merged only when patches in #wayland community
receives the ACK.

HDCP SRM is implemented through request_firmware() interface. Hence
userspace is expected to write the signature validated latest available
SRM table into /lib/firmware/ as "display_hdcp_srm.bin". On every HDCP
authentication kernel will read the SRM from above mentioned file and
do the revocation check.

And also this series gathers all HDCP related DRM code into drm_hdcp.c

Thanks Daniel Vetter for all the reviews.

v7:
  few suggestions in SRM handling at drm is addressed [Daniel]
  A prep patch is added.
  fix at content_type attachment is added.

Series can be cloned from github
https://github.com/ramalingampc2008/drm-tip.git hdcp2_2_p2_v7

Test-with: <20190502131625.27551-2-ramalingam.c@intel.com>

Ramalingam C (11):
  drm: move content protection property to mode_config
  drm/i915: debugfs: HDCP2.2 capability read
  drm: generic fn converting be24 to cpu and vice versa
  drm: revocation check at drm subsystem
  drm/i915: SRM revocation check for HDCP1.4 and 2.2
  drm/hdcp: gathering hdcp related code into drm_hdcp.c
  drm: Add Content protection type property
  drm/i915: Attach content type property
  drm: uevent for connector status change
  drm/hdcp: update content protection property with uevent
  drm/i915: update the hdcp state with uevent

 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile              |   2 +-
 drivers/gpu/drm/drm_atomic_uapi.c     |   8 +-
 drivers/gpu/drm/drm_connector.c       |  61 ++--
 drivers/gpu/drm/drm_hdcp.c            | 446 ++++++++++++++++++++++++++
 drivers/gpu/drm/drm_internal.h        |   4 +
 drivers/gpu/drm/drm_sysfs.c           |  37 +++
 drivers/gpu/drm/i915/i915_debugfs.c   |  13 +-
 drivers/gpu/drm/i915/intel_ddi.c      |  39 ++-
 drivers/gpu/drm/i915/intel_hdcp.c     | 105 ++++--
 drivers/gpu/drm/i915/intel_hdcp.h     |   3 +-
 drivers/misc/mei/hdcp/mei_hdcp.c      |   2 +-
 include/drm/drm_connector.h           |  15 +-
 include/drm/drm_hdcp.h                |  33 +-
 include/drm/drm_mode_config.h         |  12 +
 include/drm/drm_sysfs.h               |   5 +-
 include/uapi/drm/drm_mode.h           |   4 +
 17 files changed, 698 insertions(+), 97 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

-- 
2.19.1

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

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

* [PATCH v7 01/11] drm: move content protection property to mode_config
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 02/11] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

Content protection property is created once and stored in
drm_mode_config. And attached to all HDCP capable connectors.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++--
 drivers/gpu/drm/drm_connector.c   | 13 +++++++------
 include/drm/drm_connector.h       |  6 ------
 include/drm/drm_mode_config.h     |  6 ++++++
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 428d82662dc4..4131e669785a 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -732,7 +732,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->content_type = val;
 	} else if (property == connector->scaling_mode_property) {
 		state->scaling_mode = val;
-	} else if (property == connector->content_protection_property) {
+	} else if (property == config->content_protection_property) {
 		if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
 			DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
 			return -EINVAL;
@@ -814,7 +814,7 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->colorspace;
 	} else if (property == connector->scaling_mode_property) {
 		*val = state->scaling_mode;
-	} else if (property == connector->content_protection_property) {
+	} else if (property == config->content_protection_property) {
 		*val = state->content_protection;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 2355124849db..7c0eda9cca60 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1534,18 +1534,19 @@ int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct drm_property *prop;
+	struct drm_property *prop =
+			dev->mode_config.content_protection_property;
 
-	prop = drm_property_create_enum(dev, 0, "Content Protection",
-					drm_cp_enum_list,
-					ARRAY_SIZE(drm_cp_enum_list));
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "Content Protection",
+						drm_cp_enum_list,
+						ARRAY_SIZE(drm_cp_enum_list));
 	if (!prop)
 		return -ENOMEM;
 
 	drm_object_attach_property(&connector->base, prop,
 				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-
-	connector->content_protection_property = prop;
+	dev->mode_config.content_protection_property = prop;
 
 	return 0;
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f43f40d5888a..2186eec0408b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1065,12 +1065,6 @@ struct drm_connector {
 	 */
 	struct drm_property *vrr_capable_property;
 
-	/**
-	 * @content_protection_property: DRM ENUM property for content
-	 * protection. See drm_connector_attach_content_protection_property().
-	 */
-	struct drm_property *content_protection_property;
-
 	/**
 	 * @colorspace_property: Connector property to set the suitable
 	 * colorspace supported by the sink.
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7f60e8eb269a..5764ee3c7453 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -836,6 +836,12 @@ struct drm_mode_config {
 	 */
 	struct drm_property *writeback_out_fence_ptr_property;
 
+	/**
+	 * @content_protection_property: DRM ENUM property for content
+	 * protection. See drm_connector_attach_content_protection_property().
+	 */
+	struct drm_property *content_protection_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.19.1

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

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

* [PATCH v7 02/11] drm/i915: debugfs: HDCP2.2 capability read
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 01/11] drm: move content protection property to mode_config Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 03/11] drm: generic fn converting be24 to cpu and vice versa Ramalingam C
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

Adding the HDCP2.2 capability of HDCP src and sink info into debugfs
entry "i915_hdcp_sink_capability"

This helps the userspace tests to skip the HDCP2.2 test on non HDCP2.2
sinks.

v2:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 13 +++++++++++--
 drivers/gpu/drm/i915/intel_hdcp.c   |  2 +-
 drivers/gpu/drm/i915/intel_hdcp.h   |  1 +
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 14cd83e9ea8b..c15d3f3bb8e0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4753,6 +4753,7 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 {
 	struct drm_connector *connector = m->private;
 	struct intel_connector *intel_connector = to_intel_connector(connector);
+	bool hdcp_cap, hdcp2_cap;
 
 	if (connector->status != connector_status_connected)
 		return -ENODEV;
@@ -4763,8 +4764,16 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 
 	seq_printf(m, "%s:%d HDCP version: ", connector->name,
 		   connector->base.id);
-	seq_printf(m, "%s ", !intel_hdcp_capable(intel_connector) ?
-		   "None" : "HDCP1.4");
+	hdcp_cap = intel_hdcp_capable(intel_connector);
+	hdcp2_cap = intel_hdcp2_capable(intel_connector);
+
+	if (hdcp_cap)
+		seq_puts(m, "HDCP1.4 ");
+	if (hdcp2_cap)
+		seq_puts(m, "HDCP2.2 ");
+
+	if (!hdcp_cap && !hdcp2_cap)
+		seq_puts(m, "None");
 	seq_puts(m, "\n");
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index ca5982e45e3e..b8c8d6d1a33d 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -79,7 +79,7 @@ bool intel_hdcp_capable(struct intel_connector *connector)
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-static bool intel_hdcp2_capable(struct intel_connector *connector)
+bool intel_hdcp2_capable(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
index a75f25f09d39..be8da85c866a 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/intel_hdcp.h
@@ -25,6 +25,7 @@ int intel_hdcp_enable(struct intel_connector *connector);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
+bool intel_hdcp2_capable(struct intel_connector *connector);
 void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
 void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
 void intel_hdcp_cleanup(struct intel_connector *connector);
-- 
2.19.1

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

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

* [PATCH v7 03/11] drm: generic fn converting be24 to cpu and vice versa
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 01/11] drm: move content protection property to mode_config Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 02/11] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 04/11] drm: revocation check at drm subsystem Ramalingam C
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: Tomas Winkler

Existing functions for converting a 3bytes(be24) of big endian value
into u32 of little endian and vice versa are renamed as

s/drm_hdcp2_seq_num_to_u32/drm_hdcp_be24_to_cpu
s/drm_hdcp2_u32_to_seq_num/drm_hdcp_cpu_to_be24

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
cc: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 5 +++--
 drivers/misc/mei/hdcp/mei_hdcp.c  | 2 +-
 include/drm/drm_hdcp.h            | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index b8c8d6d1a33d..c308dfee9ca4 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1305,7 +1305,7 @@ int hdcp2_propagate_stream_management_info(struct intel_connector *connector)
 
 	/* Prepare RepeaterAuth_Stream_Manage msg */
 	msgs.stream_manage.msg_id = HDCP_2_2_REP_STREAM_MANAGE;
-	drm_hdcp2_u32_to_seq_num(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
+	drm_hdcp_cpu_to_be24(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
 
 	/* K no of streams is fixed as 1. Stored as big-endian. */
 	msgs.stream_manage.k = cpu_to_be16(1);
@@ -1370,7 +1370,8 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 	}
 
 	/* Converting and Storing the seq_num_v to local variable as DWORD */
-	seq_num_v = drm_hdcp2_seq_num_to_u32(msgs.recvid_list.seq_num_v);
+	seq_num_v =
+		drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v);
 
 	if (seq_num_v < hdcp->seq_num_v) {
 		/* Roll over of the seq_num_v from repeater. Reauthenticate. */
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 90b6ae8e9dae..2f192d6d8b54 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -576,7 +576,7 @@ static int mei_hdcp_verify_mprime(struct device *dev,
 
 	memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
 	       HDCP_2_2_MPRIME_LEN);
-	drm_hdcp2_u32_to_seq_num(verify_mprime_in.seq_num_m, data->seq_num_m);
+	drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
 	memcpy(verify_mprime_in.streams, data->streams,
 	       (data->k * sizeof(struct hdcp2_streamid_type)));
 
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..1cc66df05a43 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -252,13 +252,13 @@ struct hdcp2_rep_stream_ready {
  * host format and back
  */
 static inline
-u32 drm_hdcp2_seq_num_to_u32(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
+u32 drm_hdcp_be24_to_cpu(const u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
 {
 	return (u32)(seq_num[2] | seq_num[1] << 8 | seq_num[0] << 16);
 }
 
 static inline
-void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
+void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 {
 	seq_num[0] = val >> 16;
 	seq_num[1] = val >> 8;
-- 
2.19.1

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

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

* [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (2 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 03/11] drm: generic fn converting be24 to cpu and vice versa Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-07-04 10:53   ` Pekka Paalanen
  2019-09-12  0:15   ` Harry Wentland
  2019-05-07 16:27 ` [PATCH v7 05/11] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
                   ` (10 subsequent siblings)
  14 siblings, 2 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter

On every hdcp revocation check request SRM is read from fw file
/lib/firmware/display_hdcp_srm.bin

SRM table is parsed and stored at drm_hdcp.c, with functions exported
for the services for revocation check from drivers (which
implements the HDCP authentication)

This patch handles the HDCP1.4 and 2.2 versions of SRM table.

v2:
  moved the uAPI to request_firmware_direct() [Daniel]
v3:
  kdoc added. [Daniel]
  srm_header unified and bit field definitions are removed. [Daniel]
  locking improved. [Daniel]
  vrl length violation is fixed. [Daniel]
v4:
  s/__swab16/be16_to_cpu [Daniel]
  be24_to_cpu is done through a global func [Daniel]
  Unused variables are removed. [Daniel]
  unchecked return values are dropped from static funcs [Daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
---
 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile              |   2 +-
 drivers/gpu/drm/drm_hdcp.c            | 333 ++++++++++++++++++++++++++
 drivers/gpu/drm/drm_internal.h        |   4 +
 drivers/gpu/drm/drm_sysfs.c           |   2 +
 include/drm/drm_hdcp.h                |  24 ++
 6 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 14102ae035dc..0fe726a6ee67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -181,6 +181,12 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
    :export:
 
+HDCP Helper Functions Reference
+===============================
+
+.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
+   :export:
+
 Display Port Helper Functions Reference
 =======================================
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 72f5036d9bfa..dd02e9dec810 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y       :=	drm_auth.o drm_cache.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
 		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-		drm_atomic_uapi.o
+		drm_atomic_uapi.o drm_hdcp.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
new file mode 100644
index 000000000000..5e5409505c31
--- /dev/null
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation.
+ *
+ * Authors:
+ * Ramalingam C <ramalingam.c@intel.com>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+
+#include <drm/drm_hdcp.h>
+#include <drm/drm_sysfs.h>
+#include <drm/drm_print.h>
+#include <drm/drm_device.h>
+
+struct hdcp_srm {
+	u32 revoked_ksv_cnt;
+	u8 *revoked_ksv_list;
+
+	/* Mutex to protect above struct member */
+	struct mutex mutex;
+} *srm_data;
+
+static inline void drm_hdcp_print_ksv(const u8 *ksv)
+{
+	DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
+		  ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
+}
+
+static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
+
+	while (parsed_bytes < vrls_length) {
+		vrl_ksv_cnt = *buf;
+		ksv_count += vrl_ksv_cnt;
+
+		vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
+		buf += vrl_sz;
+		parsed_bytes += vrl_sz;
+	}
+
+	/*
+	 * When vrls are not valid, ksvs are not considered.
+	 * Hence SRM will be discarded.
+	 */
+	if (parsed_bytes != vrls_length)
+		ksv_count = 0;
+
+	return ksv_count;
+}
+
+static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
+				     u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0;
+	u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
+
+	do {
+		vrl_ksv_cnt = *buf;
+		vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
+
+		buf++;
+
+		DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+			  vrl_ksv_cnt);
+		memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
+
+		ksv_count += vrl_ksv_cnt;
+		revoked_ksv_list += vrl_ksv_sz;
+		buf += vrl_ksv_sz;
+
+		parsed_bytes += (vrl_ksv_sz + 1);
+	} while (parsed_bytes < vrls_length);
+
+	return ksv_count;
+}
+
+static inline u32 get_vrl_length(const u8 *buf)
+{
+	return drm_hdcp_be24_to_cpu(buf);
+}
+
+static int drm_hdcp_parse_hdcp1_srm(const u8 *buf, size_t count)
+{
+	struct hdcp_srm_header *header;
+	u32 vrl_length, ksv_count;
+
+	if (count < (sizeof(struct hdcp_srm_header) +
+	    DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		return -EINVAL;
+	}
+
+	header = (struct hdcp_srm_header *)buf;
+	DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
+		  header->srm_id,
+		  be16_to_cpu(header->srm_version), header->srm_gen_no);
+
+	WARN_ON(header->reserved);
+
+	buf = buf + sizeof(*header);
+	vrl_length = get_vrl_length(buf);
+	if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
+	    vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+			  DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length or vrl length\n");
+		return -EINVAL;
+	}
+
+	/* Length of the all vrls combined */
+	vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+		       DRM_HDCP_1_4_DCP_SIG_SIZE);
+
+	if (!vrl_length) {
+		DRM_ERROR("No vrl found\n");
+		return -EINVAL;
+	}
+
+	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
+	ksv_count = drm_hdcp_get_revoked_ksv_count(buf, vrl_length);
+	if (!ksv_count) {
+		DRM_DEBUG("Revoked KSV count is 0\n");
+		return count;
+	}
+
+	kfree(srm_data->revoked_ksv_list);
+	srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
+					     GFP_KERNEL);
+	if (!srm_data->revoked_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	if (drm_hdcp_get_revoked_ksvs(buf, srm_data->revoked_ksv_list,
+				      vrl_length) != ksv_count) {
+		srm_data->revoked_ksv_cnt = 0;
+		kfree(srm_data->revoked_ksv_list);
+		return -EINVAL;
+	}
+
+	srm_data->revoked_ksv_cnt = ksv_count;
+	return count;
+}
+
+static int drm_hdcp_parse_hdcp2_srm(const u8 *buf, size_t count)
+{
+	struct hdcp_srm_header *header;
+	u32 vrl_length, ksv_count, ksv_sz;
+
+	if (count < (sizeof(struct hdcp_srm_header) +
+	    DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		return -EINVAL;
+	}
+
+	header = (struct hdcp_srm_header *)buf;
+	DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
+		  header->srm_id & DRM_HDCP_SRM_ID_MASK,
+		  be16_to_cpu(header->srm_version), header->srm_gen_no);
+
+	if (header->reserved)
+		return -EINVAL;
+
+	buf = buf + sizeof(*header);
+	vrl_length = get_vrl_length(buf);
+
+	if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
+	    vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
+	    DRM_HDCP_2_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length or vrl length\n");
+		return -EINVAL;
+	}
+
+	/* Length of the all vrls combined */
+	vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE +
+		       DRM_HDCP_2_DCP_SIG_SIZE);
+
+	if (!vrl_length) {
+		DRM_ERROR("No vrl found\n");
+		return -EINVAL;
+	}
+
+	buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
+	ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
+	if (!ksv_count) {
+		DRM_DEBUG("Revoked KSV count is 0\n");
+		return count;
+	}
+
+	kfree(srm_data->revoked_ksv_list);
+	srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
+					     GFP_KERNEL);
+	if (!srm_data->revoked_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
+	buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
+
+	DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
+	memcpy(srm_data->revoked_ksv_list, buf, ksv_sz);
+
+	srm_data->revoked_ksv_cnt = ksv_count;
+	return count;
+}
+
+static inline bool is_srm_version_hdcp1(const u8 *buf)
+{
+	return *buf == (u8)(DRM_HDCP_1_4_SRM_ID << 4);
+}
+
+static inline bool is_srm_version_hdcp2(const u8 *buf)
+{
+	return *buf == (u8)(DRM_HDCP_2_SRM_ID << 4 | DRM_HDCP_2_INDICATOR);
+}
+
+static void drm_hdcp_srm_update(const u8 *buf, size_t count)
+{
+	if (count < sizeof(struct hdcp_srm_header))
+		return;
+
+	if (is_srm_version_hdcp1(buf))
+		drm_hdcp_parse_hdcp1_srm(buf, count);
+	else if (is_srm_version_hdcp2(buf))
+		drm_hdcp_parse_hdcp2_srm(buf, count);
+}
+
+void drm_hdcp_request_srm(struct drm_device *drm_dev)
+{
+	char fw_name[36] = "display_hdcp_srm.bin";
+	const struct firmware *fw;
+
+	int ret;
+
+	ret = request_firmware_direct(&fw, (const char *)fw_name,
+				      drm_dev->dev);
+	if (ret < 0)
+		goto exit;
+
+	if (fw->size && fw->data)
+		drm_hdcp_srm_update(fw->data, fw->size);
+
+exit:
+	release_firmware(fw);
+}
+
+/**
+ * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
+ *
+ * @drm_dev: drm_device for which HDCP revocation check is requested
+ * @ksvs: List of KSVs (HDCP receiver IDs)
+ * @ksv_count: KSV count passed in through @ksvs
+ *
+ * This function reads the HDCP System renewability Message(SRM Table)
+ * from userspace as a firmware and parses it for the revoked HDCP
+ * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known,
+ * revoked state of the KSVs in the list passed in by display drivers are
+ * decided and response is sent.
+ *
+ * SRM should be presented in the name of "display_hdcp_srm.bin".
+ *
+ * Returns:
+ * TRUE on any of the KSV is revoked, else FALSE.
+ */
+bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
+				 u32 ksv_count)
+{
+	u32 rev_ksv_cnt, cnt, i, j;
+	u8 *rev_ksv_list;
+
+	if (!srm_data)
+		return false;
+
+	mutex_lock(&srm_data->mutex);
+	drm_hdcp_request_srm(drm_dev);
+
+	rev_ksv_cnt = srm_data->revoked_ksv_cnt;
+	rev_ksv_list = srm_data->revoked_ksv_list;
+
+	/* If the Revoked ksv list is empty */
+	if (!rev_ksv_cnt || !rev_ksv_list) {
+		mutex_unlock(&srm_data->mutex);
+		return false;
+	}
+
+	for  (cnt = 0; cnt < ksv_count; cnt++) {
+		rev_ksv_list = srm_data->revoked_ksv_list;
+		for (i = 0; i < rev_ksv_cnt; i++) {
+			for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
+				if (ksvs[j] != rev_ksv_list[j]) {
+					break;
+				} else if (j == (DRM_HDCP_KSV_LEN - 1)) {
+					DRM_DEBUG("Revoked KSV is ");
+					drm_hdcp_print_ksv(ksvs);
+					mutex_unlock(&srm_data->mutex);
+					return true;
+				}
+			/* Move the offset to next KSV in the revoked list */
+			rev_ksv_list += DRM_HDCP_KSV_LEN;
+		}
+
+		/* Iterate to next ksv_offset */
+		ksvs += DRM_HDCP_KSV_LEN;
+	}
+	mutex_unlock(&srm_data->mutex);
+	return false;
+}
+EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
+
+int drm_setup_hdcp_srm(struct class *drm_class)
+{
+	srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
+	if (!srm_data)
+		return -ENOMEM;
+	mutex_init(&srm_data->mutex);
+
+	return 0;
+}
+
+void drm_teardown_hdcp_srm(struct class *drm_class)
+{
+	if (srm_data) {
+		kfree(srm_data->revoked_ksv_list);
+		kfree(srm_data);
+	}
+}
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index e19ac7ca602d..476a422414f6 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 				const struct drm_framebuffer *fb);
 int drm_framebuffer_debugfs_init(struct drm_minor *minor);
+
+/* drm_hdcp.c */
+int drm_setup_hdcp_srm(struct class *drm_class);
+void drm_teardown_hdcp_srm(struct class *drm_class);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index ecb7b33002bb..18b1ac442997 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -78,6 +78,7 @@ int drm_sysfs_init(void)
 	}
 
 	drm_class->devnode = drm_devnode;
+	drm_setup_hdcp_srm(drm_class);
 	return 0;
 }
 
@@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
 {
 	if (IS_ERR_OR_NULL(drm_class))
 		return;
+	drm_teardown_hdcp_srm(drm_class);
 	class_remove_file(drm_class, &class_attr_version.attr);
 	class_destroy(drm_class);
 	drm_class = NULL;
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 1cc66df05a43..2f0335d0a50f 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 	seq_num[2] = val;
 }
 
+#define DRM_HDCP_SRM_GEN1_MAX_BYTES		(5 * 1024)
+#define DRM_HDCP_1_4_SRM_ID			0x8
+#define DRM_HDCP_SRM_ID_MASK			(0xF << 4)
+#define DRM_HDCP_1_4_VRL_LENGTH_SIZE		3
+#define DRM_HDCP_1_4_DCP_SIG_SIZE		40
+#define DRM_HDCP_2_SRM_ID			0x9
+#define DRM_HDCP_2_INDICATOR			0x1
+#define DRM_HDCP_2_INDICATOR_MASK		0xF
+#define DRM_HDCP_2_VRL_LENGTH_SIZE		3
+#define DRM_HDCP_2_DCP_SIG_SIZE			384
+#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ	4
+#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)	(((byte) & 0xC) >> 6)
+
+struct hdcp_srm_header {
+	u8 srm_id;
+	u8 reserved;
+	__be16 srm_version;
+	u8 srm_gen_no;
+} __packed;
+
+struct drm_device;
+
+bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
+				 u8 *ksvs, u32 ksv_count);
 #endif
-- 
2.19.1

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

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

* [PATCH v7 05/11] drm/i915: SRM revocation check for HDCP1.4 and 2.2
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (3 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 04/11] drm: revocation check at drm subsystem Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 06/11] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter

DRM HDCP SRM revocation check services are used from I915 for HDCP1.4
and 2.2 revocation check during the respective authentication flow.

v2:
  Rebased.
v3:
  %s/*_ksvs_revocated/*_check_ksvs_revoked [Daniel]
  unwanted noise is removed.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 45 ++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index c308dfee9ca4..53df2f2376e8 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -491,9 +491,11 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
 
 /* Implements Part 2 of the HDCP authorization procedure */
 static
-int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
-			       const struct intel_hdcp_shim *shim)
+int intel_hdcp_auth_downstream(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
+	struct drm_device *dev = connector->base.dev;
 	u8 bstatus[2], num_downstream, *ksv_fifo;
 	int ret, i, tries = 3;
 
@@ -532,6 +534,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 	if (ret)
 		goto err;
 
+	if (drm_hdcp_check_ksvs_revoked(dev, ksv_fifo, num_downstream)) {
+		DRM_ERROR("Revoked Ksv(s) in ksv_fifo\n");
+		return -EPERM;
+	}
+
 	/*
 	 * When V prime mismatches, DP Spec mandates re-read of
 	 * V prime atleast twice.
@@ -558,9 +565,12 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 }
 
 /* Implements Part 1 of the HDCP authorization procedure */
-static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
-			   const struct intel_hdcp_shim *shim)
+static int intel_hdcp_auth(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct drm_device *dev = connector->base.dev;
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	struct drm_i915_private *dev_priv;
 	enum port port;
 	unsigned long r0_prime_gen_start;
@@ -626,6 +636,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	if (ret < 0)
 		return ret;
 
+	if (drm_hdcp_check_ksvs_revoked(dev, bksv.shim, 1)) {
+		DRM_ERROR("BKSV is revoked\n");
+		return -EPERM;
+	}
+
 	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
 	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);
 
@@ -699,7 +714,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	 */
 
 	if (repeater_present)
-		return intel_hdcp_auth_downstream(intel_dig_port, shim);
+		return intel_hdcp_auth_downstream(connector);
 
 	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
 	return 0;
@@ -762,7 +777,7 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
 
 	/* Incase of authentication failures, HDCP spec expects reauth. */
 	for (i = 0; i < tries; i++) {
-		ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
+		ret = intel_hdcp_auth(connector);
 		if (!ret) {
 			hdcp->hdcp_encrypted = true;
 			return 0;
@@ -1161,6 +1176,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct drm_device *dev = connector->base.dev;
 	union {
 		struct hdcp2_ake_init ake_init;
 		struct hdcp2_ake_send_cert send_cert;
@@ -1195,6 +1211,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 
 	hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);
 
+	if (drm_hdcp_check_ksvs_revoked(dev, msgs.send_cert.cert_rx.receiver_id,
+					1)) {
+		DRM_ERROR("Receiver ID is revoked\n");
+		return -EPERM;
+	}
+
 	/*
 	 * Here msgs.no_stored_km will hold msgs corresponding to the km
 	 * stored also.
@@ -1347,13 +1369,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct drm_device *dev = connector->base.dev;
 	union {
 		struct hdcp2_rep_send_receiverid_list recvid_list;
 		struct hdcp2_rep_send_ack rep_ack;
 	} msgs;
 	const struct intel_hdcp_shim *shim = hdcp->shim;
+	u32 seq_num_v, device_cnt;
 	u8 *rx_info;
-	u32 seq_num_v;
 	int ret;
 
 	ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
@@ -1379,6 +1402,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 		return -EINVAL;
 	}
 
+	device_cnt = HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 ||
+			HDCP_2_2_DEV_COUNT_LO(rx_info[1]);
+	if (drm_hdcp_check_ksvs_revoked(dev, msgs.recvid_list.receiver_ids,
+					device_cnt)) {
+		DRM_ERROR("Revoked receiver ID(s) is in list\n");
+		return -EPERM;
+	}
+
 	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
 						    &msgs.recvid_list,
 						    &msgs.rep_ack);
-- 
2.19.1

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

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

* [PATCH v7 06/11] drm/hdcp: gathering hdcp related code into drm_hdcp.c
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (4 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 05/11] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 07/11] drm: Add Content protection type property Ramalingam C
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

Considering the significant size of hdcp related code in drm, all
hdcp related codes are moved into separate file called drm_hdcp.c.

v2:
  Rebased.
v2:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_connector.c | 44 ------------------------------
 drivers/gpu/drm/drm_hdcp.c      | 47 +++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  2 --
 include/drm/drm_hdcp.h          |  3 +++
 4 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 7c0eda9cca60..764c7903edf6 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -823,13 +823,6 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 		 drm_tv_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_cp_enum_list[] = {
-	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
-	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
-	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
-};
-DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
-
 static const struct drm_prop_enum_list hdmi_colorspaces[] = {
 	/* For Default case, driver will set the colorspace */
 	{ DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
@@ -1515,43 +1508,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
 
-/**
- * drm_connector_attach_content_protection_property - attach content protection
- * property
- *
- * @connector: connector to attach CP property on.
- *
- * This is used to add support for content protection on select connectors.
- * Content Protection is intentionally vague to allow for different underlying
- * technologies, however it is most implemented by HDCP.
- *
- * The content protection will be set to &drm_connector_state.content_protection
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
-int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_property *prop =
-			dev->mode_config.content_protection_property;
-
-	if (!prop)
-		prop = drm_property_create_enum(dev, 0, "Content Protection",
-						drm_cp_enum_list,
-						ARRAY_SIZE(drm_cp_enum_list));
-	if (!prop)
-		return -ENOMEM;
-
-	drm_object_attach_property(&connector->base, prop,
-				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-	dev->mode_config.content_protection_property = prop;
-
-	return 0;
-}
-EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
-
 /**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 5e5409505c31..0da7b3718bad 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -17,6 +17,9 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_print.h>
 #include <drm/drm_device.h>
+#include <drm/drm_property.h>
+#include <drm/drm_mode_object.h>
+#include <drm/drm_connector.h>
 
 struct hdcp_srm {
 	u32 revoked_ksv_cnt;
@@ -331,3 +334,47 @@ void drm_teardown_hdcp_srm(struct class *drm_class)
 		kfree(srm_data);
 	}
 }
+
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
+/**
+ * drm_connector_attach_content_protection_property - attach content protection
+ * property
+ *
+ * @connector: connector to attach CP property on.
+ *
+ * This is used to add support for content protection on select connectors.
+ * Content Protection is intentionally vague to allow for different underlying
+ * technologies, however it is most implemented by HDCP.
+ *
+ * The content protection will be set to &drm_connector_state.content_protection
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_content_protection_property(
+		struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop =
+			dev->mode_config.content_protection_property;
+
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "Content Protection",
+						drm_cp_enum_list,
+						ARRAY_SIZE(drm_cp_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+	dev->mode_config.content_protection_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 2186eec0408b..e257b879b72c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1343,8 +1343,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 					       u32 scaling_mode_mask);
 int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
-int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_colorspace_property(struct drm_connector *connector);
 int drm_mode_create_content_type_property(struct drm_device *dev);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 2f0335d0a50f..13771a496e2b 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -286,7 +286,10 @@ struct hdcp_srm_header {
 } __packed;
 
 struct drm_device;
+struct drm_connector;
 
 bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
 				 u8 *ksvs, u32 ksv_count);
+int drm_connector_attach_content_protection_property(
+		struct drm_connector *connector);
 #endif
-- 
2.19.1

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

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

* [PATCH v7 07/11] drm: Add Content protection type property
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (5 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 06/11] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-07-04 11:11   ` Pekka Paalanen
  2019-05-07 16:27 ` [PATCH v7 08/11] drm/i915: Attach content " Ramalingam C
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter

This patch adds a DRM ENUM property to the selected connectors.
This property is used for mentioning the protected content's type
from userspace to kernel HDCP authentication.

Type of the stream is decided by the protected content providers.
Type 0 content can be rendered on any HDCP protected display wires.
But Type 1 content can be rendered only on HDCP2.2 protected paths.

So when a userspace sets this property to Type 1 and starts the HDCP
enable, kernel will honour it only if HDCP2.2 authentication is through
for type 1. Else HDCP enable will be failed.

Need ACK for this new conenctor property from userspace consumer.

v2:
  cp_content_type is replaced with content_protection_type [daniel]
  check at atomic_set_property is removed [Maarten]
v3:
  %s/content_protection_type/hdcp_content_type [Pekka]
v4:
  property is created for the first requested connector and then reused.
	[Danvet]
v5:
  kernel doc nits addressed [Daniel]
  Rebased as part of patch reordering.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
 drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
 drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
 include/drm/drm_connector.h       |  7 ++++++
 include/drm/drm_hdcp.h            |  2 +-
 include/drm/drm_mode_config.h     |  6 ++++++
 include/uapi/drm/drm_mode.h       |  4 ++++
 8 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 4131e669785a..a85f3ccfe699 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 			return -EINVAL;
 		}
 		state->content_protection = val;
+	} else if (property == config->hdcp_content_type_property) {
+		state->hdcp_content_type = val;
 	} else if (property == connector->colorspace_property) {
 		state->colorspace = val;
 	} else if (property == config->writeback_fb_id_property) {
@@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->scaling_mode;
 	} else if (property == config->content_protection_property) {
 		*val = state->content_protection;
+	} else if (property == config->hdcp_content_type_property) {
+		*val = state->hdcp_content_type;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
 		*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 764c7903edf6..de9e06583e8c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
  *	  the value transitions from ENABLED to DESIRED. This signifies the link
  *	  is no longer protected and userspace should take appropriate action
  *	  (whatever that might be).
+ * HDCP Content Type:
+ *	This property is used by the userspace to configure the kernel with
+ *	to be displayed stream's content type. Content Type of a stream is
+ *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
+ *
+ *	The value of the property can be one the below:
+ *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ *		HDCP Type0 streams can be transmitted on a link which is
+ *		encrypted with HDCP 1.4 or HDCP 2.2.
+ *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *		HDCP Type1 streams can be transmitted on a link which is
+ *		encrypted only with HDCP 2.2.
+ *
+ *	Note that the HDCP Content Type property is specific to HDCP 2.2, and
+ *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.2
+ *	If content type is changed when content_protection is not UNDESIRED,
+ *	then kernel will disable the HDCP and re-enable with new type in the
+ *	same atomic commit
  *
  * max bpc:
  *	This range property is used by userspace to limit the bit depth. When
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 0da7b3718bad..75402463466b 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -342,23 +342,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
 };
 DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
 
+static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
+	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
+	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
+		 drm_hdcp_content_type_enum_list)
+
 /**
  * drm_connector_attach_content_protection_property - attach content protection
  * property
  *
  * @connector: connector to attach CP property on.
+ * @hdcp_content_type: is HDCP Content Type property needed for connector
  *
  * This is used to add support for content protection on select connectors.
  * Content Protection is intentionally vague to allow for different underlying
  * technologies, however it is most implemented by HDCP.
  *
+ * When hdcp_content_type is true enum property called HDCP Content Type is
+ * created (if it is not already) and attached to the connector.
+ *
+ * This property is used for sending the protected content's stream type
+ * from userspace to kernel on selected connectors. Protected content provider
+ * will decide their type of their content and declare the same to kernel.
+ *
+ * Content type will be used during the HDCP 2.2 authentication.
+ * Content type will be set to &drm_connector_state.hdcp_content_type.
+ *
  * The content protection will be set to &drm_connector_state.content_protection
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
 int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector)
+		struct drm_connector *connector, bool hdcp_content_type)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_property *prop =
@@ -375,6 +393,22 @@ int drm_connector_attach_content_protection_property(
 				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
 	dev->mode_config.content_protection_property = prop;
 
+	if (!hdcp_content_type)
+		return 0;
+
+	prop = dev->mode_config.hdcp_content_type_property;
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,
+					ARRAY_SIZE(
+					drm_hdcp_content_type_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_HDCP_CONTENT_TYPE0);
+	dev->mode_config.hdcp_content_type_property = prop;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 53df2f2376e8..be6c81addca0 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1829,7 +1829,9 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
-	ret = drm_connector_attach_content_protection_property(&connector->base);
+	ret =
+	drm_connector_attach_content_protection_property(&connector->base,
+							 false);
 	if (ret)
 		return ret;
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index e257b879b72c..65005240c561 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -560,6 +560,12 @@ struct drm_connector_state {
 	 */
 	unsigned int content_type;
 
+	/**
+	 * @hdcp_content_type: Connector property to pass the type of
+	 * protected content. This is most commonly used for HDCP.
+	 */
+	unsigned int hdcp_content_type;
+
 	/**
 	 * @scaling_mode: Connector property to control the
 	 * upscaling, mostly used for built-in panels.
@@ -1330,6 +1336,7 @@ const char *drm_get_dvi_i_select_name(int val);
 const char *drm_get_tv_subconnector_name(int val);
 const char *drm_get_tv_select_name(int val);
 const char *drm_get_content_protection_name(int val);
+const char *drm_get_hdcp_content_type_name(int val);
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_margin_properties(struct drm_device *dev);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 13771a496e2b..2970abdfaf12 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -291,5 +291,5 @@ struct drm_connector;
 bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
 				 u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector);
+		struct drm_connector *connector, bool hdcp_content_type);
 #endif
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 5764ee3c7453..b359b5b71eb9 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -842,6 +842,12 @@ struct drm_mode_config {
 	 */
 	struct drm_property *content_protection_property;
 
+	/**
+	 * @hdcp_content_type_property: DRM ENUM property for type of
+	 * Protected Content.
+	 */
+	struct drm_property *hdcp_content_type_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 83cd1636b9be..8ac03351fdee 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -209,6 +209,10 @@ extern "C" {
 #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
 #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
 
+/* Content Type classification for HDCP2.2 vs others */
+#define DRM_MODE_HDCP_CONTENT_TYPE0		0
+#define DRM_MODE_HDCP_CONTENT_TYPE1		1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
2.19.1

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

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

* [PATCH v7 08/11] drm/i915: Attach content type property
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (6 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 07/11] drm: Add Content protection type property Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:27 ` [PATCH v7 09/11] drm: uevent for connector status change Ramalingam C
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

Attaches the content type property for HDCP2.2 capable connectors.

Implements the update of content type from property and apply the
restriction on HDCP version selection.

Need ACK for content type property from userspace consumer.

v2:
  s/cp_content_type/content_protection_type [daniel]
  disable at hdcp_atomic_check to avoid check at atomic_set_property
	[Maarten]
v3:
  s/content_protection_type/hdcp_content_type [Pekka]
v4:
  hdcp disable incase of type change is moved into commit [daniel].
v5:
  Simplified the Type change procedure. [Daniel]
v6:
  Type change with UNDESIRED state is ignored.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 39 +++++++++++++++++++++++-----
 drivers/gpu/drm/i915/intel_hdcp.c | 43 ++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_hdcp.h |  2 +-
 3 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cd5277d98b03..0ffba18613b2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3490,7 +3490,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 	/* Enable hdcp if it's desired */
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
-		intel_hdcp_enable(to_intel_connector(conn_state->connector));
+		intel_hdcp_enable(to_intel_connector(conn_state->connector),
+				  (u8)conn_state->hdcp_content_type);
 }
 
 static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@ -3559,15 +3560,41 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
+	struct intel_connector *connector =
+				to_intel_connector(conn_state->connector);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	bool content_protection_type_changed =
+			(conn_state->hdcp_content_type != hdcp->content_type &&
+			 conn_state->content_protection !=
+			 DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+
 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
 
+	/*
+	 * During the HDCP encryption session if Type change is requested,
+	 * disable the HDCP and reenable it with new TYPE value.
+	 */
 	if (conn_state->content_protection ==
-	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
-		intel_hdcp_enable(to_intel_connector(conn_state->connector));
-	else if (conn_state->content_protection ==
-		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
-		intel_hdcp_disable(to_intel_connector(conn_state->connector));
+	    DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
+	    content_protection_type_changed)
+		intel_hdcp_disable(connector);
+
+	/*
+	 * Mark the hdcp state as DESIRED after the hdcp disable of type
+	 * change procedure.
+	 */
+	if (content_protection_type_changed) {
+		mutex_lock(&hdcp->mutex);
+		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+		schedule_work(&hdcp->prop_work);
+		mutex_unlock(&hdcp->mutex);
+	}
+
+	if (conn_state->content_protection ==
+	    DRM_MODE_CONTENT_PROTECTION_DESIRED ||
+	    content_protection_type_changed)
+		intel_hdcp_enable(connector, (u8)conn_state->hdcp_content_type);
 }
 
 static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index be6c81addca0..69522687b2cb 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1748,14 +1748,15 @@ static const struct component_ops i915_hdcp_component_ops = {
 	.unbind = i915_hdcp_component_unbind,
 };
 
-static inline int initialize_hdcp_port_data(struct intel_connector *connector)
+static inline int initialize_hdcp_port_data(struct intel_connector *connector,
+					    const struct intel_hdcp_shim *shim)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	struct hdcp_port_data *data = &hdcp->port_data;
 
 	data->port = connector->encoder->port;
 	data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
-	data->protocol = (u8)hdcp->shim->protocol;
+	data->protocol = (u8)shim->protocol;
 
 	data->k = 1;
 	if (!data->streams)
@@ -1805,12 +1806,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void intel_hdcp2_init(struct intel_connector *connector)
+static void intel_hdcp2_init(struct intel_connector *connector,
+			     const struct intel_hdcp_shim *shim)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
-	ret = initialize_hdcp_port_data(connector);
+	ret = initialize_hdcp_port_data(connector, shim);
 	if (ret) {
 		DRM_DEBUG_KMS("Mei hdcp data init failed\n");
 		return;
@@ -1829,25 +1831,28 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
+	if (is_hdcp2_supported(dev_priv))
+		intel_hdcp2_init(connector, shim);
+
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
-							 false);
-	if (ret)
+							 hdcp->hdcp2_supported);
+	if (ret) {
+		hdcp->hdcp2_supported = false;
+		kfree(hdcp->port_data.streams);
 		return ret;
+	}
 
 	hdcp->shim = shim;
 	mutex_init(&hdcp->mutex);
 	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
 	INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work);
-
-	if (is_hdcp2_supported(dev_priv))
-		intel_hdcp2_init(connector);
 	init_waitqueue_head(&hdcp->cp_irq_queue);
 
 	return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector)
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
@@ -1858,6 +1863,7 @@ int intel_hdcp_enable(struct intel_connector *connector)
 
 	mutex_lock(&hdcp->mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
+	hdcp->content_type = content_type;
 
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -1869,8 +1875,12 @@ int intel_hdcp_enable(struct intel_connector *connector)
 			check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS;
 	}
 
-	/* When HDCP2.2 fails, HDCP1.4 will be attempted */
-	if (ret && intel_hdcp_capable(connector)) {
+	/*
+	 * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will
+	 * be attempted.
+	 */
+	if (ret && intel_hdcp_capable(connector) &&
+	    hdcp->content_type != DRM_MODE_HDCP_CONTENT_TYPE1) {
 		ret = _intel_hdcp_enable(connector);
 	}
 
@@ -1952,12 +1962,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 
 	/*
 	 * Nothing to do if the state didn't change, or HDCP was activated since
-	 * the last commit
+	 * the last commit. And also no change in hdcp content type.
 	 */
 	if (old_cp == new_cp ||
 	    (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
-	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
-		return;
+	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) {
+		if (old_state->hdcp_content_type ==
+				new_state->hdcp_content_type)
+			return;
+	}
 
 	crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
 						   new_state->crtc);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
index be8da85c866a..13555b054930 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/intel_hdcp.h
@@ -21,7 +21,7 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *new_state);
 int intel_hdcp_init(struct intel_connector *connector,
 		    const struct intel_hdcp_shim *hdcp_shim);
-int intel_hdcp_enable(struct intel_connector *connector);
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
-- 
2.19.1

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

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

* [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (7 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 08/11] drm/i915: Attach content " Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-10 12:12   ` Paul Kocialkowski
  2019-07-04 11:12   ` Pekka Paalanen
  2019-05-07 16:27 ` [PATCH v7 10/11] drm/hdcp: update content protection property with uevent Ramalingam C
                   ` (5 subsequent siblings)
  14 siblings, 2 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

DRM API for generating uevent for a status changes of connector's
property.

This uevent will have following details related to the status change:

  HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>

Need ACK from this uevent from userspace consumer.

v2:
  Minor fixes at KDoc comments [Daniel]
v3:
  Check the property is really attached with connector [Daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
 include/drm/drm_sysfs.h     |  5 ++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 18b1ac442997..63fa951a20db 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -21,6 +21,7 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drmP.h>
 #include "drm_internal.h"
+#include "drm_crtc_internal.h"
 
 #define to_drm_minor(d) dev_get_drvdata(d)
 #define to_drm_connector(d) dev_get_drvdata(d)
@@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
  * Send a uevent for the DRM device specified by @dev.  Currently we only
  * set HOTPLUG=1 in the uevent environment, but this could be expanded to
  * deal with other types of events.
+ *
+ * Any new uapi should be using the drm_sysfs_connector_status_event()
+ * for uevents on connector status change.
  */
 void drm_sysfs_hotplug_event(struct drm_device *dev)
 {
@@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+/**
+ * drm_sysfs_connector_status_event - generate a DRM uevent for connector
+ * property status change
+ * @connector: connector on which property status changed
+ * @property: connector property whoes status changed.
+ *
+ * Send a uevent for the DRM device specified by @dev.  Currently we
+ * set HOTPLUG=1 and connector id along with the attached property id
+ * related to the status change.
+ */
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+				      struct drm_property *property)
+{
+	struct drm_device *dev = connector->dev;
+	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
+	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
+
+	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
+					   property->base.id));
+
+	snprintf(conn_id, ARRAY_SIZE(conn_id),
+		 "CONNECTOR=%u", connector->base.id);
+	snprintf(prop_id, ARRAY_SIZE(prop_id),
+		 "PROPERTY=%u", property->base.id);
+
+	DRM_DEBUG("generating connector status event\n");
+
+	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(drm_sysfs_connector_status_event);
+
 static void drm_sysfs_release(struct device *dev)
 {
 	kfree(dev);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 4f311e836cdc..d454ef617b2c 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -4,10 +4,13 @@
 
 struct drm_device;
 struct device;
+struct drm_connector;
+struct drm_property;
 
 int drm_class_device_register(struct device *dev);
 void drm_class_device_unregister(struct device *dev);
 
 void drm_sysfs_hotplug_event(struct drm_device *dev);
-
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+				      struct drm_property *property);
 #endif
-- 
2.19.1

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

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

* [PATCH v7 10/11] drm/hdcp: update content protection property with uevent
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (8 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 09/11] drm: uevent for connector status change Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-07-04 11:14   ` Pekka Paalanen
  2019-05-07 16:27 ` [PATCH v7 11/11] drm/i915: update the hdcp state " Ramalingam C
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter

drm function is defined and exported to update a connector's
content protection property state and to generate a uevent along
with it.

Need ACK for the uevent from userspace consumer.

v2:
  Update only when state is different from old one.
v3:
  KDoc is added [Daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_hdcp.c | 32 ++++++++++++++++++++++++++++++++
 include/drm/drm_hdcp.h     |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 75402463466b..f29b7abda51f 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
  *
  * The content protection will be set to &drm_connector_state.content_protection
  *
+ * When kernel triggered content protection state change like DESIRED->ENABLED
+ * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update
+ * the content protection state of a connector.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -412,3 +416,31 @@ int drm_connector_attach_content_protection_property(
 	return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+
+/**
+ * drm_hdcp_update_content_protection - Updates the content protection state
+ * of a connector
+ *
+ * @connector: drm_connector on which content protection state needs an update
+ * @val: New state of the content protection property
+ *
+ * This function can be used by display drivers, to update the kernel triggered
+ * content protection state change of a drm_connector. This function update the
+ * new state of the property into the connector's state and generate an uevent
+ * to notify the userspace.
+ */
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+					u64 val)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_connector_state *state = connector->state;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+	if (state->content_protection == val)
+		return;
+
+	state->content_protection = val;
+	drm_sysfs_connector_status_event(connector,
+				 dev->mode_config.content_protection_property);
+}
+EXPORT_SYMBOL(drm_hdcp_update_content_protection);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 2970abdfaf12..dd864ac9ce85 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -292,4 +292,6 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
 				 u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector, bool hdcp_content_type);
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+					u64 val);
 #endif
-- 
2.19.1

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

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

* [PATCH v7 11/11] drm/i915: update the hdcp state with uevent
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (9 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 10/11] drm/hdcp: update content protection property with uevent Ramalingam C
@ 2019-05-07 16:27 ` Ramalingam C
  2019-05-07 16:45 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev9) Patchwork
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-05-07 16:27 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter; +Cc: gwan-gyeong.mun

drm function to update the content protection property state and to
generate a uevent is invoked from the intel hdcp property work.

Hence whenever kernel changes the property state, userspace will be
updated with a uevent.

Need a ACK for uevent generating uAPI from userspace.

v2:
  state update is moved into drm function [daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 69522687b2cb..8abd69551ead 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -865,7 +865,6 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 					       prop_work);
 	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
 	struct drm_device *dev = connector->base.dev;
-	struct drm_connector_state *state;
 
 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
 	mutex_lock(&hdcp->mutex);
@@ -875,10 +874,9 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 	 * those to UNDESIRED is handled by core. If value == UNDESIRED,
 	 * we're running just after hdcp has been disabled, so just exit
 	 */
-	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		state = connector->base.state;
-		state->content_protection = hdcp->value;
-	}
+	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+		drm_hdcp_update_content_protection(&connector->base,
+						   hdcp->value);
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
-- 
2.19.1

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

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

* ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev9)
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (10 preceding siblings ...)
  2019-05-07 16:27 ` [PATCH v7 11/11] drm/i915: update the hdcp state " Ramalingam C
@ 2019-05-07 16:45 ` Patchwork
  2019-05-07 16:52 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 70+ messages in thread
From: Patchwork @ 2019-05-07 16:45 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev9)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
2c27a886355d drm: move content protection property to mode_config
95b249c75379 drm/i915: debugfs: HDCP2.2 capability read
8969d4d4cfd3 drm: generic fn converting be24 to cpu and vice versa
242f3762b645 drm: revocation check at drm subsystem
-:63: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#63: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 402 lines checked
71dfff191a9f drm/i915: SRM revocation check for HDCP1.4 and 2.2
b886f4c85175 drm/hdcp: gathering hdcp related code into drm_hdcp.c
-:104: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#104: FILE: drivers/gpu/drm/drm_hdcp.c:343:
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)

-:121: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#121: FILE: drivers/gpu/drm/drm_hdcp.c:360:
+int drm_connector_attach_content_protection_property(

-:167: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#167: FILE: include/drm/drm_hdcp.h:293:
+int drm_connector_attach_content_protection_property(

total: 0 errors, 0 warnings, 3 checks, 130 lines checked
bfdf6e8c73aa drm: Add Content protection type property
-:98: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#98: FILE: drivers/gpu/drm/drm_hdcp.c:349:
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,

-:143: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#143: FILE: drivers/gpu/drm/drm_hdcp.c:402:
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,

-:144: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#144: FILE: drivers/gpu/drm/drm_hdcp.c:403:
+					ARRAY_SIZE(

total: 0 errors, 0 warnings, 3 checks, 161 lines checked
99bfb7556dc5 drm/i915: Attach content type property
85c5a1d2fe9e drm: uevent for connector status change
5472c22a1374 drm/hdcp: update content protection property with uevent
-:64: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#64: FILE: drivers/gpu/drm/drm_hdcp.c:444:
+	drm_sysfs_connector_status_event(connector,
+				 dev->mode_config.content_protection_property);

total: 0 errors, 0 warnings, 1 checks, 47 lines checked
15115903dfac drm/i915: update the hdcp state with uevent

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

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

* ✗ Fi.CI.SPARSE: warning for HDCP2.2 Phase II (rev9)
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (11 preceding siblings ...)
  2019-05-07 16:45 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev9) Patchwork
@ 2019-05-07 16:52 ` Patchwork
  2019-05-07 17:37 ` ✓ Fi.CI.BAT: success " Patchwork
  2019-05-08  0:41 ` ✓ Fi.CI.IGT: " Patchwork
  14 siblings, 0 replies; 70+ messages in thread
From: Patchwork @ 2019-05-07 16:52 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev9)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm: move content protection property to mode_config
Okay!

Commit: drm/i915: debugfs: HDCP2.2 capability read
Okay!

Commit: drm: generic fn converting be24 to cpu and vice versa
Okay!

Commit: drm: revocation check at drm subsystem
+drivers/gpu/drm/drm_hdcp.c:235:6: warning: symbol 'drm_hdcp_request_srm' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:27:3: warning: symbol 'srm_data' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:317:5: warning: symbol 'drm_setup_hdcp_srm' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:327:6: warning: symbol 'drm_teardown_hdcp_srm' was not declared. Should it be static?
+./include/linux/slab.h:666:13: error: not a function <noident>
+./include/linux/slab.h:666:13: error: undefined identifier '__builtin_mul_overflow'
+./include/linux/slab.h:666:13: warning: call with no type!

Commit: drm/i915: SRM revocation check for HDCP1.4 and 2.2
Okay!

Commit: drm/hdcp: gathering hdcp related code into drm_hdcp.c
Okay!

Commit: drm: Add Content protection type property
Okay!

Commit: drm/i915: Attach content type property
Okay!

Commit: drm: uevent for connector status change
Okay!

Commit: drm/hdcp: update content protection property with uevent
Okay!

Commit: drm/i915: update the hdcp state with uevent
Okay!

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

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

* ✓ Fi.CI.BAT: success for HDCP2.2 Phase II (rev9)
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (12 preceding siblings ...)
  2019-05-07 16:52 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-05-07 17:37 ` Patchwork
  2019-05-08  0:41 ` ✓ Fi.CI.IGT: " Patchwork
  14 siblings, 0 replies; 70+ messages in thread
From: Patchwork @ 2019-05-07 17:37 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev9)
URL   : https://patchwork.freedesktop.org/series/57232/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6060 -> Patchwork_12980
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_12980:

### IGT changes ###

#### Possible regressions ####

  * {igt@kms_content_protection@srm} (NEW):
    - {fi-cml-u}:         NOTRUN -> [SKIP][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-cml-u/igt@kms_content_protection@srm.html
    - fi-cfl-8109u:       NOTRUN -> [FAIL][2]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-cfl-8109u/igt@kms_content_protection@srm.html
    - {fi-icl-y}:         NOTRUN -> [SKIP][3]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-icl-y/igt@kms_content_protection@srm.html
    - fi-skl-lmem:        NOTRUN -> [FAIL][4]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-skl-lmem/igt@kms_content_protection@srm.html
    - fi-apl-guc:         NOTRUN -> [FAIL][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-apl-guc/igt@kms_content_protection@srm.html
    - fi-skl-gvtdvm:      NOTRUN -> [FAIL][6]
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-skl-gvtdvm/igt@kms_content_protection@srm.html

  
New tests
---------

  New tests have been introduced between CI_DRM_6060 and Patchwork_12980:

### New IGT tests (1) ###

  * igt@kms_content_protection@srm:
    - Statuses : 4 fail(s) 7 pass(s) 32 skip(s)
    - Exec time: [0.0, 131.58] s

  

Known issues
------------

  Here are the changes found in Patchwork_12980 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_module_load@reload-with-fault-injection:
    - fi-skl-6770hq:      [PASS][7] -> [DMESG-WARN][8] ([fdo#108529]) +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/fi-skl-6770hq/igt@i915_module_load@reload-with-fault-injection.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-skl-6770hq/igt@i915_module_load@reload-with-fault-injection.html

  * igt@i915_selftest@live_hangcheck:
    - fi-skl-iommu:       [PASS][9] -> [INCOMPLETE][10] ([fdo#108602] / [fdo#108744])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/fi-skl-iommu/igt@i915_selftest@live_hangcheck.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-skl-iommu/igt@i915_selftest@live_hangcheck.html

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-skl-6770hq:      [PASS][11] -> [SKIP][12] ([fdo#109271]) +23 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html

  
#### Possible fixes ####

  * igt@i915_selftest@live_contexts:
    - fi-kbl-8809g:       [DMESG-FAIL][13] -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/fi-kbl-8809g/igt@i915_selftest@live_contexts.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-kbl-8809g/igt@i915_selftest@live_contexts.html

  * igt@i915_selftest@live_hangcheck:
    - {fi-icl-y}:         [INCOMPLETE][15] ([fdo#107713] / [fdo#108569]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/fi-icl-y/igt@i915_selftest@live_hangcheck.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/fi-icl-y/igt@i915_selftest@live_hangcheck.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#108529]: https://bugs.freedesktop.org/show_bug.cgi?id=108529
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
  [fdo#108602]: https://bugs.freedesktop.org/show_bug.cgi?id=108602
  [fdo#108744]: https://bugs.freedesktop.org/show_bug.cgi?id=108744
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271


Participating hosts (52 -> 44)
------------------------------

  Missing    (8): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-pnv-d510 fi-byt-clapper 


Build changes
-------------

  * IGT: IGT_4972 -> IGTPW_2939
  * Linux: CI_DRM_6060 -> Patchwork_12980

  CI_DRM_6060: d60cc5ba9072d0e606129ec5b8d1c5bcabf7867c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2939: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2939/
  IGT_4972: f052e49a43cc9704ea5f240df15dd9d3dfed68ab @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_12980: 15115903dfacdbe9ab4eebbc2390f089f9860d26 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

15115903dfac drm/i915: update the hdcp state with uevent
5472c22a1374 drm/hdcp: update content protection property with uevent
85c5a1d2fe9e drm: uevent for connector status change
99bfb7556dc5 drm/i915: Attach content type property
bfdf6e8c73aa drm: Add Content protection type property
b886f4c85175 drm/hdcp: gathering hdcp related code into drm_hdcp.c
71dfff191a9f drm/i915: SRM revocation check for HDCP1.4 and 2.2
242f3762b645 drm: revocation check at drm subsystem
8969d4d4cfd3 drm: generic fn converting be24 to cpu and vice versa
95b249c75379 drm/i915: debugfs: HDCP2.2 capability read
2c27a886355d drm: move content protection property to mode_config

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for HDCP2.2 Phase II (rev9)
  2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
                   ` (13 preceding siblings ...)
  2019-05-07 17:37 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-05-08  0:41 ` Patchwork
  14 siblings, 0 replies; 70+ messages in thread
From: Patchwork @ 2019-05-08  0:41 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev9)
URL   : https://patchwork.freedesktop.org/series/57232/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6060_full -> Patchwork_12980_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_12980_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@kms_content_protection@lic} (NEW):
    - shard-apl:          NOTRUN -> [FAIL][1] +2 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl5/igt@kms_content_protection@lic.html

  * {igt@kms_content_protection@srm} (NEW):
    - shard-kbl:          NOTRUN -> [FAIL][2] +1 similar issue
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl4/igt@kms_content_protection@srm.html

  * {igt@kms_content_protection@uevent} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][3] +5 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb2/igt@kms_content_protection@uevent.html

  
New tests
---------

  New tests have been introduced between CI_DRM_6060_full and Patchwork_12980_full:

### New IGT tests (6) ###

  * igt@kms_content_protection@content_type_change:
    - Statuses : 7 skip(s)
    - Exec time: [0.0, 0.01] s

  * igt@kms_content_protection@lic:
    - Statuses : 2 fail(s) 5 skip(s)
    - Exec time: [0.0, 123.79] s

  * igt@kms_content_protection@mei_interface:
    - Statuses : 6 skip(s)
    - Exec time: [0.00, 0.01] s

  * igt@kms_content_protection@srm:
    - Statuses : 2 fail(s) 5 skip(s)
    - Exec time: [0.00, 125.62] s

  * igt@kms_content_protection@type1:
    - Statuses : 7 skip(s)
    - Exec time: [0.0, 0.01] s

  * igt@kms_content_protection@uevent:
    - Statuses : 1 fail(s) 4 skip(s)
    - Exec time: [0.0, 107.77] s

  

Known issues
------------

  Here are the changes found in Patchwork_12980_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_persistent_relocs@forked-faulting-reloc:
    - shard-hsw:          [PASS][4] -> [INCOMPLETE][5] ([fdo#103540])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-hsw2/igt@gem_persistent_relocs@forked-faulting-reloc.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-hsw2/igt@gem_persistent_relocs@forked-faulting-reloc.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [PASS][6] -> [DMESG-WARN][7] ([fdo#108566]) +5 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-apl7/igt@i915_suspend@fence-restore-tiled2untiled.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl5/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-c:
    - shard-kbl:          [PASS][8] -> [DMESG-WARN][9] ([fdo#103558] / [fdo#105602] / [fdo#110222])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl4/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-c.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-c.html

  * igt@kms_color@pipe-c-degamma:
    - shard-glk:          [PASS][10] -> [FAIL][11] ([fdo#104782])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-glk7/igt@kms_color@pipe-c-degamma.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-glk4/igt@kms_color@pipe-c-degamma.html
    - shard-kbl:          [PASS][12] -> [FAIL][13] ([fdo#104782])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl6/igt@kms_color@pipe-c-degamma.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl6/igt@kms_color@pipe-c-degamma.html
    - shard-skl:          [PASS][14] -> [FAIL][15] ([fdo#104782])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl2/igt@kms_color@pipe-c-degamma.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl3/igt@kms_color@pipe-c-degamma.html
    - shard-apl:          [PASS][16] -> [FAIL][17] ([fdo#104782])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-apl3/igt@kms_color@pipe-c-degamma.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl2/igt@kms_color@pipe-c-degamma.html

  * igt@kms_cursor_crc@cursor-128x128-suspend:
    - shard-kbl:          [PASS][18] -> [DMESG-FAIL][19] ([fdo#103232] / [fdo#103558] / [fdo#105602])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl2/igt@kms_cursor_crc@cursor-128x128-suspend.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_cursor_crc@cursor-128x128-suspend.html

  * igt@kms_cursor_edge_walk@pipe-c-64x64-top-edge:
    - shard-kbl:          [PASS][20] -> [DMESG-WARN][21] ([fdo#103558] / [fdo#105602]) +51 similar issues
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl4/igt@kms_cursor_edge_walk@pipe-c-64x64-top-edge.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_cursor_edge_walk@pipe-c-64x64-top-edge.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible:
    - shard-skl:          [PASS][22] -> [FAIL][23] ([fdo#105363])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl3/igt@kms_flip@flip-vs-expired-vblank-interruptible.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl2/igt@kms_flip@flip-vs-expired-vblank-interruptible.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render:
    - shard-iclb:         [PASS][24] -> [FAIL][25] ([fdo#103167]) +2 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render.html

  * igt@kms_plane@pixel-format-pipe-b-planes-source-clamping:
    - shard-glk:          [PASS][26] -> [SKIP][27] ([fdo#109271])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-glk9/igt@kms_plane@pixel-format-pipe-b-planes-source-clamping.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-glk2/igt@kms_plane@pixel-format-pipe-b-planes-source-clamping.html

  * igt@kms_plane_scaling@pipe-a-scaler-with-clipping-clamping:
    - shard-glk:          [PASS][28] -> [SKIP][29] ([fdo#109271] / [fdo#109278])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-glk9/igt@kms_plane_scaling@pipe-a-scaler-with-clipping-clamping.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-glk5/igt@kms_plane_scaling@pipe-a-scaler-with-clipping-clamping.html

  * igt@kms_psr@psr2_sprite_blt:
    - shard-iclb:         [PASS][30] -> [SKIP][31] ([fdo#109441]) +2 similar issues
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb2/igt@kms_psr@psr2_sprite_blt.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb5/igt@kms_psr@psr2_sprite_blt.html

  * igt@kms_setmode@basic:
    - shard-apl:          [PASS][32] -> [FAIL][33] ([fdo#99912])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-apl7/igt@kms_setmode@basic.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl8/igt@kms_setmode@basic.html

  
#### Possible fixes ####

  * igt@gem_softpin@noreloc-s3:
    - shard-apl:          [DMESG-WARN][34] ([fdo#108566]) -> [PASS][35] +1 similar issue
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-apl6/igt@gem_softpin@noreloc-s3.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl7/igt@gem_softpin@noreloc-s3.html

  * igt@i915_pm_rpm@sysfs-read:
    - shard-skl:          [INCOMPLETE][36] ([fdo#107807]) -> [PASS][37] +2 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl9/igt@i915_pm_rpm@sysfs-read.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl3/igt@i915_pm_rpm@sysfs-read.html

  * igt@kms_ccs@pipe-b-missing-ccs-buffer:
    - shard-kbl:          [DMESG-WARN][38] ([fdo#103558] / [fdo#105602]) -> [PASS][39] +27 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl5/igt@kms_ccs@pipe-b-missing-ccs-buffer.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl7/igt@kms_ccs@pipe-b-missing-ccs-buffer.html

  * igt@kms_flip@dpms-vs-vblank-race-interruptible:
    - shard-apl:          [FAIL][40] ([fdo#103060]) -> [PASS][41]
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-apl6/igt@kms_flip@dpms-vs-vblank-race-interruptible.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-apl2/igt@kms_flip@dpms-vs-vblank-race-interruptible.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-skl:          [INCOMPLETE][42] ([fdo#109507]) -> [PASS][43]
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl6/igt@kms_flip@flip-vs-suspend.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl5/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move:
    - shard-glk:          [FAIL][44] ([fdo#103167]) -> [PASS][45]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-glk1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-glk6/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-cpu:
    - shard-skl:          [FAIL][46] ([fdo#103167] / [fdo#110379]) -> [PASS][47]
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl3/igt@kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-cpu.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl8/igt@kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-cpu.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render:
    - shard-iclb:         [FAIL][48] ([fdo#103167]) -> [PASS][49] +7 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb3/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb2/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-gtt:
    - shard-skl:          [FAIL][50] ([fdo#108040]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl3/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-gtt.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl3/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-gtt.html

  * igt@kms_plane_lowres@pipe-a-tiling-x:
    - shard-iclb:         [FAIL][52] ([fdo#103166]) -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb5/igt@kms_plane_lowres@pipe-a-tiling-x.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb5/igt@kms_plane_lowres@pipe-a-tiling-x.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [SKIP][54] ([fdo#109642]) -> [PASS][55]
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb4/igt@kms_psr2_su@page_flip.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb2/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@psr2_sprite_render:
    - shard-iclb:         [SKIP][56] ([fdo#109441]) -> [PASS][57]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-iclb7/igt@kms_psr@psr2_sprite_render.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-iclb2/igt@kms_psr@psr2_sprite_render.html

  
#### Warnings ####

  * igt@i915_pm_rpm@dpms-non-lpsp:
    - shard-skl:          [SKIP][58] ([fdo#109271]) -> [INCOMPLETE][59] ([fdo#107807])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-skl8/igt@i915_pm_rpm@dpms-non-lpsp.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-skl6/igt@i915_pm_rpm@dpms-non-lpsp.html

  * igt@kms_atomic_transition@3x-modeset-transitions-nonblocking:
    - shard-kbl:          [SKIP][60] ([fdo#109271] / [fdo#109278]) -> [SKIP][61] ([fdo#105602] / [fdo#109271] / [fdo#109278]) +2 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl3/igt@kms_atomic_transition@3x-modeset-transitions-nonblocking.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_atomic_transition@3x-modeset-transitions-nonblocking.html

  * igt@kms_busy@basic-modeset-d:
    - shard-kbl:          [SKIP][62] ([fdo#105602] / [fdo#109271] / [fdo#109278]) -> [SKIP][63] ([fdo#109271] / [fdo#109278]) +4 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl5/igt@kms_busy@basic-modeset-d.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl6/igt@kms_busy@basic-modeset-d.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-render:
    - shard-kbl:          [SKIP][64] ([fdo#105602] / [fdo#109271]) -> [SKIP][65] ([fdo#109271]) +19 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl5/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-render.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl3/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
    - shard-kbl:          [SKIP][66] ([fdo#109271]) -> [SKIP][67] ([fdo#105602] / [fdo#109271]) +37 similar issues
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl7/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max:
    - shard-kbl:          [FAIL][68] ([fdo#108145]) -> [DMESG-FAIL][69] ([fdo#103558] / [fdo#105602] / [fdo#108145])
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6060/shard-kbl5/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/shard-kbl5/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#103060]: https://bugs.freedesktop.org/show_bug.cgi?id=103060
  [fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103232]: https://bugs.freedesktop.org/show_bug.cgi?id=103232
  [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
  [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
  [fdo#104782]: https://bugs.freedesktop.org/show_bug.cgi?id=104782
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#107807]: https://bugs.freedesktop.org/show_bug.cgi?id=107807
  [fdo#108040]: https://bugs.freedesktop.org/show_bug.cgi?id=108040
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109507]: https://bugs.freedesktop.org/show_bug.cgi?id=109507
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110222]: https://bugs.freedesktop.org/show_bug.cgi?id=110222
  [fdo#110379]: https://bugs.freedesktop.org/show_bug.cgi?id=110379
  [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * IGT: IGT_4972 -> IGTPW_2939
  * Linux: CI_DRM_6060 -> Patchwork_12980

  CI_DRM_6060: d60cc5ba9072d0e606129ec5b8d1c5bcabf7867c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2939: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2939/
  IGT_4972: f052e49a43cc9704ea5f240df15dd9d3dfed68ab @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_12980: 15115903dfacdbe9ab4eebbc2390f089f9860d26 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12980/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-07 16:27 ` [PATCH v7 09/11] drm: uevent for connector status change Ramalingam C
@ 2019-05-10 12:12   ` Paul Kocialkowski
  2019-05-10 14:54     ` Daniel Vetter
  2019-05-13 21:20     ` Lyude Paul
  2019-07-04 11:12   ` Pekka Paalanen
  1 sibling, 2 replies; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-10 12:12 UTC (permalink / raw)
  To: Ramalingam C, intel-gfx, dri-devel, daniel.vetter
  Cc: David Airlie, Maxime Ripard, Daniel Vetter, gwan-gyeong.mun, Ser,
	Simon, Thomas Petazzoni, Sean Paul

Hi,

On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> DRM API for generating uevent for a status changes of connector's
> property.
> 
> This uevent will have following details related to the status change:
> 
>   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> 
> Need ACK from this uevent from userspace consumer.

So we just had some discussions over on IRC and at about the hotplug
issue and came up with similar ideas:
https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html

The conclusions of these discussions so far would be to have a more or
less fine grain of uevent reporting depending on what happened. The
point is that we need to cover different cases:
- one or more properties changed;
- the connector status changed;
- something else about the connector changed (e.g. EDID/modes)

For the first case, we can send out:
HOTPLUG=1
CONNECTOR=<id>
PROPERTY=<id>

and no reprobe is required.

For the second one, something like:
HOTPLUG=1
CONNECTOR=<id>
STATUS=Connected/Disconnected

and a connector probe is needed for connected, but not for
disconnected;

For the third one, we can only indicate the connector:
HOTPLUG=1
CONNECTOR=<id>

and a reprobe of the connector is always needed

Then we still have the legacy case:
HOTPLUG=1

where userspace is expected to reprobe all the connectors.

I think this would deserve to be a separate series on its own. So I am
proposing to take this one off your plate and come up with another
seres implementing this proposal. What do you think?

Cheers,

Paul

> v2:
>   Minor fixes at KDoc comments [Daniel]
> v3:
>   Check the property is really attached with connector [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
>  include/drm/drm_sysfs.h     |  5 ++++-
>  2 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index 18b1ac442997..63fa951a20db 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -21,6 +21,7 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drmP.h>
>  #include "drm_internal.h"
> +#include "drm_crtc_internal.h"
>  
>  #define to_drm_minor(d) dev_get_drvdata(d)
>  #define to_drm_connector(d) dev_get_drvdata(d)
> @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
>   * Send a uevent for the DRM device specified by @dev.  Currently we only
>   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
>   * deal with other types of events.
> + *
> + * Any new uapi should be using the drm_sysfs_connector_status_event()
> + * for uevents on connector status change.
>   */
>  void drm_sysfs_hotplug_event(struct drm_device *dev)
>  {
> @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
>  }
>  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
>  
> +/**
> + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> + * property status change
> + * @connector: connector on which property status changed
> + * @property: connector property whoes status changed.
> + *
> + * Send a uevent for the DRM device specified by @dev.  Currently we
> + * set HOTPLUG=1 and connector id along with the attached property id
> + * related to the status change.
> + */
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property)
> +{
> +	struct drm_device *dev = connector->dev;
> +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> +
> +	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> +					   property->base.id));
> +
> +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> +		 "CONNECTOR=%u", connector->base.id);
> +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> +		 "PROPERTY=%u", property->base.id);
> +
> +	DRM_DEBUG("generating connector status event\n");
> +
> +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> +}
> +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> +
>  static void drm_sysfs_release(struct device *dev)
>  {
>  	kfree(dev);
> diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> index 4f311e836cdc..d454ef617b2c 100644
> --- a/include/drm/drm_sysfs.h
> +++ b/include/drm/drm_sysfs.h
> @@ -4,10 +4,13 @@
>  
>  struct drm_device;
>  struct device;
> +struct drm_connector;
> +struct drm_property;
>  
>  int drm_class_device_register(struct device *dev);
>  void drm_class_device_unregister(struct device *dev);
>  
>  void drm_sysfs_hotplug_event(struct drm_device *dev);
> -
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property);
>  #endif
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-10 12:12   ` Paul Kocialkowski
@ 2019-05-10 14:54     ` Daniel Vetter
  2019-05-13  9:02       ` Paul Kocialkowski
  2019-05-13 21:20     ` Lyude Paul
  1 sibling, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-10 14:54 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
<paul.kocialkowski@bootlin.com> wrote:
>
> Hi,
>
> On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > DRM API for generating uevent for a status changes of connector's
> > property.
> >
> > This uevent will have following details related to the status change:
> >
> >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> >
> > Need ACK from this uevent from userspace consumer.
>
> So we just had some discussions over on IRC and at about the hotplug
> issue and came up with similar ideas:
> https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
>
> The conclusions of these discussions so far would be to have a more or
> less fine grain of uevent reporting depending on what happened. The
> point is that we need to cover different cases:
> - one or more properties changed;
> - the connector status changed;
> - something else about the connector changed (e.g. EDID/modes)
>
> For the first case, we can send out:
> HOTPLUG=1
> CONNECTOR=<id>
> PROPERTY=<id>
>
> and no reprobe is required.
>
> For the second one, something like:
> HOTPLUG=1
> CONNECTOR=<id>
> STATUS=Connected/Disconnected
>
> and a connector probe is needed for connected, but not for
> disconnected;
>
> For the third one, we can only indicate the connector:
> HOTPLUG=1
> CONNECTOR=<id>
>
> and a reprobe of the connector is always needed

There's no material difference between this one and the previous one.
Plus there's no beenfit in supplying the actual value of the property,
i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
Here's why:
- A side effect of forcing a probe on a connector is that you get to
read all the properties, so supplying them is kinda pointless.
- You can read STATUS without forcing a reprobe, if you want to avoid
the reprobe for disconnected. I'd kinda not recommend that though,
feels a bit like overoptimizing. And for reasonable connectors (i.e.
dp) reprobing a disconnected output is fast. HDMI is ... less
reasonable unfortunately, but oh well.
- There's no way to only reprobe status, you can only ever reprobe
everything with the current ioctl and implementations. Having an
option to reprobe only parts of it doesn't seem useful to me (we need
to read the EDID anyway, and that's the expensive part of reprobing in
almost all cases).

In a way PROPERTY=<status-prop-id> simply tells userspace that it
needs to reprobe this connector.

At that point we need to figure out whether this is a good uapi or
not, and that's where the epoch comes in. There's two reasons for an
epoch:
- We need it internally because I'm not goinig to wire a new return
value through hundreds of connector probe functions. It's much easier
to have an epoch counter which we set from e.g. drm_set_edid and
similar functions that update probe state.
- If userspace misses an event and there's no epoch, we're forcing
userspace to reprobe everything. Use case would be if a compositor is
switched away we probably don't want to piss of the current compositor
by blocking it's own probe kernel calls by doing our own (probe is
single-threaded in the kernel through the dev->mode_config.mutex). If
it can read the epoch property (which it can do without forcing a
reprobe) userspace would know which connectors it needs to check and
reprobe.

Hence why epoch, it's a bit more robust userspace api. Ofc you could
also require that userspace needs to keep parsing all uevents and make
a list of all connectors it needs to reprobe when it's back to being
the active compositor. But just comparing a current epoch with the one
you cached from the last full probe is much easier.

Another thing: None of this we can for connectors with unreliable hdp.
Or at least you'll piss of users if you cache always. The sad thing is
that HDMI is unreliable, at least on some machines/screen combos (you
never get a hpd irq if you plug in/unplug). So real compositors still
need to reprobe when the user asks for it. igt can probably get away
without reprobing.
-Daniel

> Then we still have the legacy case:
> HOTPLUG=1
>
> where userspace is expected to reprobe all the connectors.
>
> I think this would deserve to be a separate series on its own. So I am
> proposing to take this one off your plate and come up with another
> seres implementing this proposal. What do you think?
>
> Cheers,
>
> Paul
>
> > v2:
> >   Minor fixes at KDoc comments [Daniel]
> > v3:
> >   Check the property is really attached with connector [Daniel]
> >
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> >  include/drm/drm_sysfs.h     |  5 ++++-
> >  2 files changed, 39 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index 18b1ac442997..63fa951a20db 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -21,6 +21,7 @@
> >  #include <drm/drm_sysfs.h>
> >  #include <drm/drmP.h>
> >  #include "drm_internal.h"
> > +#include "drm_crtc_internal.h"
> >
> >  #define to_drm_minor(d) dev_get_drvdata(d)
> >  #define to_drm_connector(d) dev_get_drvdata(d)
> > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> >   * deal with other types of events.
> > + *
> > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > + * for uevents on connector status change.
> >   */
> >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  {
> > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  }
> >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> >
> > +/**
> > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > + * property status change
> > + * @connector: connector on which property status changed
> > + * @property: connector property whoes status changed.
> > + *
> > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > + * set HOTPLUG=1 and connector id along with the attached property id
> > + * related to the status change.
> > + */
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +                                   struct drm_property *property)
> > +{
> > +     struct drm_device *dev = connector->dev;
> > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > +
> > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > +                                        property->base.id));
> > +
> > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > +              "CONNECTOR=%u", connector->base.id);
> > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > +              "PROPERTY=%u", property->base.id);
> > +
> > +     DRM_DEBUG("generating connector status event\n");
> > +
> > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > +}
> > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > +
> >  static void drm_sysfs_release(struct device *dev)
> >  {
> >       kfree(dev);
> > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > index 4f311e836cdc..d454ef617b2c 100644
> > --- a/include/drm/drm_sysfs.h
> > +++ b/include/drm/drm_sysfs.h
> > @@ -4,10 +4,13 @@
> >
> >  struct drm_device;
> >  struct device;
> > +struct drm_connector;
> > +struct drm_property;
> >
> >  int drm_class_device_register(struct device *dev);
> >  void drm_class_device_unregister(struct device *dev);
> >
> >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > -
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +                                   struct drm_property *property);
> >  #endif
> --
> Paul Kocialkowski, Bootlin
> Embedded Linux and kernel engineering
> https://bootlin.com
>


-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-10 14:54     ` Daniel Vetter
@ 2019-05-13  9:02       ` Paul Kocialkowski
  2019-05-13  9:34         ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-13  9:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

Hi,

On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> > Hi,
> > 
> > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > DRM API for generating uevent for a status changes of connector's
> > > property.
> > > 
> > > This uevent will have following details related to the status change:
> > > 
> > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > 
> > > Need ACK from this uevent from userspace consumer.
> > 
> > So we just had some discussions over on IRC and at about the hotplug
> > issue and came up with similar ideas:
> > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > 
> > The conclusions of these discussions so far would be to have a more or
> > less fine grain of uevent reporting depending on what happened. The
> > point is that we need to cover different cases:
> > - one or more properties changed;
> > - the connector status changed;
> > - something else about the connector changed (e.g. EDID/modes)
> > 
> > For the first case, we can send out:
> > HOTPLUG=1
> > CONNECTOR=<id>
> > PROPERTY=<id>
> > 
> > and no reprobe is required.
> > 
> > For the second one, something like:
> > HOTPLUG=1
> > CONNECTOR=<id>
> > STATUS=Connected/Disconnected
> > 
> > and a connector probe is needed for connected, but not for
> > disconnected;
> > 
> > For the third one, we can only indicate the connector:
> > HOTPLUG=1
> > CONNECTOR=<id>
> > 
> > and a reprobe of the connector is always needed
> 
> There's no material difference between this one and the previous one.
> Plus there's no beenfit in supplying the actual value of the property,
> i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.

That's the idea, but we need to handle status changes differently than
properties, since as far as I know, connected/unconnected status is not
exposed as a prop for the connector.

> Here's why:
> - A side effect of forcing a probe on a connector is that you get to
> read all the properties, so supplying them is kinda pointless.

Agreed, except for the status case where it's useful to know it's a
disconnect, because we don't need any probe step in that case.

> - You can read STATUS without forcing a reprobe, if you want to avoid
> the reprobe for disconnected. I'd kinda not recommend that though,
> feels a bit like overoptimizing. And for reasonable connectors (i.e.
> dp) reprobing a disconnected output is fast. HDMI is ... less
> reasonable unfortunately, but oh well.

How would that be retreived then? From the looks of it, that's a
MODE_GETCONNECTOR ioctl and I was under the impression this is what
does the full reprobe.

Not sure what issues could arise in case of disconnect without reprobe
-- at least I don't see why userspace should have to do anything in
particular except no longer using the connector, even in complex DP MST
cases.

> - There's no way to only reprobe status, you can only ever reprobe
> everything with the current ioctl and implementations. Having an
> option to reprobe only parts of it doesn't seem useful to me (we need
> to read the EDID anyway, and that's the expensive part of reprobing in
> almost all cases).

Agreed.

> In a way PROPERTY=<status-prop-id> simply tells userspace that it
> needs to reprobe this connector.

I thought we could access the props alone, which avoids doing a reprobe
when the kernel knows that only a prop or a set of props changed and do
not require a full reprobe. That's the first case I was mentionning.

> At that point we need to figure out whether this is a good uapi or
> not, and that's where the epoch comes in. There's two reasons for an
> epoch:
> - We need it internally because I'm not goinig to wire a new return
> value through hundreds of connector probe functions. It's much easier
> to have an epoch counter which we set from e.g. drm_set_edid and
> similar functions that update probe state.

I don't think I'm following what issue this is trying to solve
internally.

> - If userspace misses an event and there's no epoch, we're forcing
> userspace to reprobe everything. Use case would be if a compositor is
> switched away we probably don't want to piss of the current compositor
> by blocking it's own probe kernel calls by doing our own (probe is
> single-threaded in the kernel through the dev->mode_config.mutex). If
> it can read the epoch property (which it can do without forcing a
> reprobe) userspace would know which connectors it needs to check and
> reprobe.
>
> Hence why epoch, it's a bit more robust userspace api. Ofc you could
> also require that userspace needs to keep parsing all uevents and make
> a list of all connectors it needs to reprobe when it's back to being
> the active compositor. But just comparing a current epoch with the one
> you cached from the last full probe is much easier.

Fair enough, I think it's a fine idea for robustness yes, but I think
we could also provide extra info in the uevent when relevant and not
rely on that entirely.

> Another thing: None of this we can for connectors with unreliable hdp.
> Or at least you'll piss of users if you cache always. The sad thing is
> that HDMI is unreliable, at least on some machines/screen combos (you
> never get a hpd irq if you plug in/unplug). So real compositors still
> need to reprobe when the user asks for it. igt can probably get away
> without reprobing.

I wonder how that is handled currently and how a user action can solve
the issue without any notification from the kernel. Maybe a need a
better understanding of that case to have a clearer idea.

Cheers,

Paul

> -Daniel
> 
> > Then we still have the legacy case:
> > HOTPLUG=1
> > 
> > where userspace is expected to reprobe all the connectors.
> > 
> > I think this would deserve to be a separate series on its own. So I am
> > proposing to take this one off your plate and come up with another
> > seres implementing this proposal. What do you think?
> > 
> > Cheers,
> > 
> > Paul
> > 
> > > v2:
> > >   Minor fixes at KDoc comments [Daniel]
> > > v3:
> > >   Check the property is really attached with connector [Daniel]
> > > 
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > >  include/drm/drm_sysfs.h     |  5 ++++-
> > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > index 18b1ac442997..63fa951a20db 100644
> > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > @@ -21,6 +21,7 @@
> > >  #include <drm/drm_sysfs.h>
> > >  #include <drm/drmP.h>
> > >  #include "drm_internal.h"
> > > +#include "drm_crtc_internal.h"
> > > 
> > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > >   * deal with other types of events.
> > > + *
> > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > + * for uevents on connector status change.
> > >   */
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  {
> > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  }
> > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > 
> > > +/**
> > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > + * property status change
> > > + * @connector: connector on which property status changed
> > > + * @property: connector property whoes status changed.
> > > + *
> > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > + * related to the status change.
> > > + */
> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +                                   struct drm_property *property)
> > > +{
> > > +     struct drm_device *dev = connector->dev;
> > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > +
> > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > +                                        property->base.id));
> > > +
> > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > +              "CONNECTOR=%u", connector->base.id);
> > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > +              "PROPERTY=%u", property->base.id);
> > > +
> > > +     DRM_DEBUG("generating connector status event\n");
> > > +
> > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > +}
> > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > +
> > >  static void drm_sysfs_release(struct device *dev)
> > >  {
> > >       kfree(dev);
> > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > index 4f311e836cdc..d454ef617b2c 100644
> > > --- a/include/drm/drm_sysfs.h
> > > +++ b/include/drm/drm_sysfs.h
> > > @@ -4,10 +4,13 @@
> > > 
> > >  struct drm_device;
> > >  struct device;
> > > +struct drm_connector;
> > > +struct drm_property;
> > > 
> > >  int drm_class_device_register(struct device *dev);
> > >  void drm_class_device_unregister(struct device *dev);
> > > 
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > -
> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +                                   struct drm_property *property);
> > >  #endif
> > --
> > Paul Kocialkowski, Bootlin
> > Embedded Linux and kernel engineering
> > https://bootlin.com
> > 
> 
> 
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13  9:02       ` Paul Kocialkowski
@ 2019-05-13  9:34         ` Daniel Vetter
  2019-05-13 10:11           ` Ser, Simon
                             ` (2 more replies)
  0 siblings, 3 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-13  9:34 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel, Ser, Simon,
	Pekka Paalanen, Thomas Petazzoni, Daniel Vetter

On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
<paul.kocialkowski@bootlin.com> wrote:
>
> Hi,
>
> On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hi,
> > >
> > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > DRM API for generating uevent for a status changes of connector's
> > > > property.
> > > >
> > > > This uevent will have following details related to the status change:
> > > >
> > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > >
> > > > Need ACK from this uevent from userspace consumer.
> > >
> > > So we just had some discussions over on IRC and at about the hotplug
> > > issue and came up with similar ideas:
> > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > >
> > > The conclusions of these discussions so far would be to have a more or
> > > less fine grain of uevent reporting depending on what happened. The
> > > point is that we need to cover different cases:
> > > - one or more properties changed;
> > > - the connector status changed;
> > > - something else about the connector changed (e.g. EDID/modes)
> > >
> > > For the first case, we can send out:
> > > HOTPLUG=1
> > > CONNECTOR=<id>
> > > PROPERTY=<id>
> > >
> > > and no reprobe is required.
> > >
> > > For the second one, something like:
> > > HOTPLUG=1
> > > CONNECTOR=<id>
> > > STATUS=Connected/Disconnected
> > >
> > > and a connector probe is needed for connected, but not for
> > > disconnected;
> > >
> > > For the third one, we can only indicate the connector:
> > > HOTPLUG=1
> > > CONNECTOR=<id>
> > >
> > > and a reprobe of the connector is always needed
> >
> > There's no material difference between this one and the previous one.
> > Plus there's no beenfit in supplying the actual value of the property,
> > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
>
> That's the idea, but we need to handle status changes differently than
> properties, since as far as I know, connected/unconnected status is not
> exposed as a prop for the connector.

Oops, totally missed that. "Everything is a property" is kinda
new-ish, at least compared to kms. Kinda tempted to just make status
into a property. Or another excuse why we should expose the epoch
property :-)

> > Here's why:
> > - A side effect of forcing a probe on a connector is that you get to
> > read all the properties, so supplying them is kinda pointless.
>
> Agreed, except for the status case where it's useful to know it's a
> disconnect, because we don't need any probe step in that case.
>
> > - You can read STATUS without forcing a reprobe, if you want to avoid
> > the reprobe for disconnected. I'd kinda not recommend that though,
> > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > dp) reprobing a disconnected output is fast. HDMI is ... less
> > reasonable unfortunately, but oh well.
>
> How would that be retreived then? From the looks of it, that's a
> MODE_GETCONNECTOR ioctl and I was under the impression this is what
> does the full reprobe.

drmGetConnector vs drmGetConnectorCurrent.

> Not sure what issues could arise in case of disconnect without reprobe
> -- at least I don't see why userspace should have to do anything in
> particular except no longer using the connector, even in complex DP MST
> cases.

connector->status might be a lie without a full reprobe, and wrongly
indicate that the connector is disconnected while there's still
something plugged in. I'm not sure we've fixed those bugs by now
(usually it's around "hpd indicates disconnected" vs. "i2c indicates
connected, and we can't break this because every intel platform ever
shipped has a few devices where this is somehow broken, irrespective
of the sink).

> > - There's no way to only reprobe status, you can only ever reprobe
> > everything with the current ioctl and implementations. Having an
> > option to reprobe only parts of it doesn't seem useful to me (we need
> > to read the EDID anyway, and that's the expensive part of reprobing in
> > almost all cases).
>
> Agreed.
>
> > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > needs to reprobe this connector.
>
> I thought we could access the props alone, which avoids doing a reprobe
> when the kernel knows that only a prop or a set of props changed and do
> not require a full reprobe. That's the first case I was mentionning.
>
> > At that point we need to figure out whether this is a good uapi or
> > not, and that's where the epoch comes in. There's two reasons for an
> > epoch:
> > - We need it internally because I'm not goinig to wire a new return
> > value through hundreds of connector probe functions. It's much easier
> > to have an epoch counter which we set from e.g. drm_set_edid and
> > similar functions that update probe state.
>
> I don't think I'm following what issue this is trying to solve
> internally.

So I'm assuming that if we handle a hotplug, we only want to generate
one uevent for that, not one for every little thing that changed.
There's two ways to implement this logic:
- With some epoch counter and a helper function you can call everytime
something changed (e.g. status, or edid, or anything else we care
about e.g. from dp aux). This won't need much (if any) driver changes,
because we can just put these into the relevant helper/core functions
(like edid update, or dp aux reading or whatever).
- Wiring a new return value through the entire stack (and _all_ the
kms drivers) so that the probe helpers could aggregate this like they
currently do.

One of these is a lot less typing.

> > - If userspace misses an event and there's no epoch, we're forcing
> > userspace to reprobe everything. Use case would be if a compositor is
> > switched away we probably don't want to piss of the current compositor
> > by blocking it's own probe kernel calls by doing our own (probe is
> > single-threaded in the kernel through the dev->mode_config.mutex). If
> > it can read the epoch property (which it can do without forcing a
> > reprobe) userspace would know which connectors it needs to check and
> > reprobe.
> >
> > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > also require that userspace needs to keep parsing all uevents and make
> > a list of all connectors it needs to reprobe when it's back to being
> > the active compositor. But just comparing a current epoch with the one
> > you cached from the last full probe is much easier.
>
> Fair enough, I think it's a fine idea for robustness yes, but I think
> we could also provide extra info in the uevent when relevant and not
> rely on that entirely.

See above, with drmGetConnectorCurrent there's no need to provide more
than what's needed in the uevent, since userspace can get everything
else at the cost of one ioctl, without reprobing. With a bit of
engineering work we could even avoid taking the expensive
dev->mode_config.mutex lock for this fastpath.

> > Another thing: None of this we can for connectors with unreliable hdp.
> > Or at least you'll piss of users if you cache always. The sad thing is
> > that HDMI is unreliable, at least on some machines/screen combos (you
> > never get a hpd irq if you plug in/unplug). So real compositors still
> > need to reprobe when the user asks for it. igt can probably get away
> > without reprobing.
>
> I wonder how that is handled currently and how a user action can solve
> the issue without any notification from the kernel. Maybe a need a
> better understanding of that case to have a clearer idea.

User opens the screen configuration tool -> usually at that point the
tool/compositor force a full reprobe, which then often triggers the
automatic reconfiguring. E.g. on one laptop I have here when I plug in
random shit projectors at conferences nothing happens, until I run
xrandr, which triggers the full reprobe, which then makes the kernel
realize something change, sending and uevent, which starts the
automatic reconfigure machinery.

There's also the issue that there's machines with hpd storms (even on
DP, where you really need hpd to work to be compliant), and we have to
turn of the hpd irq to keep the machine useable.

Cheers, Daniel

>
> Cheers,
>
> Paul
>
> > -Daniel
> >
> > > Then we still have the legacy case:
> > > HOTPLUG=1
> > >
> > > where userspace is expected to reprobe all the connectors.
> > >
> > > I think this would deserve to be a separate series on its own. So I am
> > > proposing to take this one off your plate and come up with another
> > > seres implementing this proposal. What do you think?
> > >
> > > Cheers,
> > >
> > > Paul
> > >
> > > > v2:
> > > >   Minor fixes at KDoc comments [Daniel]
> > > > v3:
> > > >   Check the property is really attached with connector [Daniel]
> > > >
> > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > ---
> > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > index 18b1ac442997..63fa951a20db 100644
> > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > @@ -21,6 +21,7 @@
> > > >  #include <drm/drm_sysfs.h>
> > > >  #include <drm/drmP.h>
> > > >  #include "drm_internal.h"
> > > > +#include "drm_crtc_internal.h"
> > > >
> > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > >   * deal with other types of events.
> > > > + *
> > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > + * for uevents on connector status change.
> > > >   */
> > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > >  {
> > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > >  }
> > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > >
> > > > +/**
> > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > + * property status change
> > > > + * @connector: connector on which property status changed
> > > > + * @property: connector property whoes status changed.
> > > > + *
> > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > + * related to the status change.
> > > > + */
> > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > +                                   struct drm_property *property)
> > > > +{
> > > > +     struct drm_device *dev = connector->dev;
> > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > +
> > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > +                                        property->base.id));
> > > > +
> > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > +              "CONNECTOR=%u", connector->base.id);
> > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > +              "PROPERTY=%u", property->base.id);
> > > > +
> > > > +     DRM_DEBUG("generating connector status event\n");
> > > > +
> > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > +}
> > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > +
> > > >  static void drm_sysfs_release(struct device *dev)
> > > >  {
> > > >       kfree(dev);
> > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > --- a/include/drm/drm_sysfs.h
> > > > +++ b/include/drm/drm_sysfs.h
> > > > @@ -4,10 +4,13 @@
> > > >
> > > >  struct drm_device;
> > > >  struct device;
> > > > +struct drm_connector;
> > > > +struct drm_property;
> > > >
> > > >  int drm_class_device_register(struct device *dev);
> > > >  void drm_class_device_unregister(struct device *dev);
> > > >
> > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > -
> > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > +                                   struct drm_property *property);
> > > >  #endif
> > > --
> > > Paul Kocialkowski, Bootlin
> > > Embedded Linux and kernel engineering
> > > https://bootlin.com
> > >
> >
> >
> --
> Paul Kocialkowski, Bootlin
> Embedded Linux and kernel engineering
> https://bootlin.com
>


-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13  9:34         ` Daniel Vetter
@ 2019-05-13 10:11           ` Ser, Simon
  2019-05-13 15:04             ` Daniel Vetter
  2019-05-13 17:14           ` Paul Kocialkowski
  2019-05-14  8:02           ` Pekka Paalanen
  2 siblings, 1 reply; 70+ messages in thread
From: Ser, Simon @ 2019-05-13 10:11 UTC (permalink / raw)
  To: daniel.vetter, paul.kocialkowski
  Cc: airlied, maxime.ripard, intel-gfx, dri-devel, Mun, Gwan-gyeong,
	thomas.petazzoni, Vetter, Daniel, sean

On Mon, 2019-05-13 at 11:34 +0200, Daniel Vetter wrote:
> On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> > Hi,
> > 
> > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hi,
> > > > 
> > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > DRM API for generating uevent for a status changes of connector's
> > > > > property.
> > > > > 
> > > > > This uevent will have following details related to the status change:
> > > > > 
> > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > 
> > > > > Need ACK from this uevent from userspace consumer.
> > > > 
> > > > So we just had some discussions over on IRC and at about the hotplug
> > > > issue and came up with similar ideas:
> > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > 
> > > > The conclusions of these discussions so far would be to have a more or
> > > > less fine grain of uevent reporting depending on what happened. The
> > > > point is that we need to cover different cases:
> > > > - one or more properties changed;
> > > > - the connector status changed;
> > > > - something else about the connector changed (e.g. EDID/modes)
> > > > 
> > > > For the first case, we can send out:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > PROPERTY=<id>
> > > > 
> > > > and no reprobe is required.
> > > > 
> > > > For the second one, something like:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > STATUS=Connected/Disconnected
> > > > 
> > > > and a connector probe is needed for connected, but not for
> > > > disconnected;
> > > > 
> > > > For the third one, we can only indicate the connector:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > 
> > > > and a reprobe of the connector is always needed
> > > 
> > > There's no material difference between this one and the previous one.
> > > Plus there's no beenfit in supplying the actual value of the property,
> > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > 
> > That's the idea, but we need to handle status changes differently than
> > properties, since as far as I know, connected/unconnected status is not
> > exposed as a prop for the connector.
> 
> Oops, totally missed that. "Everything is a property" is kinda
> new-ish, at least compared to kms. Kinda tempted to just make status
> into a property. Or another excuse why we should expose the epoch
> property :-)
> 
> > > Here's why:
> > > - A side effect of forcing a probe on a connector is that you get to
> > > read all the properties, so supplying them is kinda pointless.
> > 
> > Agreed, except for the status case where it's useful to know it's a
> > disconnect, because we don't need any probe step in that case.
> > 
> > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > reasonable unfortunately, but oh well.
> > 
> > How would that be retreived then? From the looks of it, that's a
> > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > does the full reprobe.
> 
> drmGetConnector vs drmGetConnectorCurrent.
> 
> > Not sure what issues could arise in case of disconnect without reprobe
> > -- at least I don't see why userspace should have to do anything in
> > particular except no longer using the connector, even in complex DP MST
> > cases.
> 
> connector->status might be a lie without a full reprobe, and wrongly
> indicate that the connector is disconnected while there's still
> something plugged in. I'm not sure we've fixed those bugs by now
> (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> connected, and we can't break this because every intel platform ever
> shipped has a few devices where this is somehow broken, irrespective
> of the sink).
> 
> > > - There's no way to only reprobe status, you can only ever reprobe
> > > everything with the current ioctl and implementations. Having an
> > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > almost all cases).
> > 
> > Agreed.
> > 
> > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > needs to reprobe this connector.
> > 
> > I thought we could access the props alone, which avoids doing a reprobe
> > when the kernel knows that only a prop or a set of props changed and do
> > not require a full reprobe. That's the first case I was mentionning.
> > 
> > > At that point we need to figure out whether this is a good uapi or
> > > not, and that's where the epoch comes in. There's two reasons for an
> > > epoch:
> > > - We need it internally because I'm not goinig to wire a new return
> > > value through hundreds of connector probe functions. It's much easier
> > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > similar functions that update probe state.
> > 
> > I don't think I'm following what issue this is trying to solve
> > internally.
> 
> So I'm assuming that if we handle a hotplug, we only want to generate
> one uevent for that, not one for every little thing that changed.
> There's two ways to implement this logic:
> - With some epoch counter and a helper function you can call everytime
> something changed (e.g. status, or edid, or anything else we care
> about e.g. from dp aux). This won't need much (if any) driver changes,
> because we can just put these into the relevant helper/core functions
> (like edid update, or dp aux reading or whatever).
> - Wiring a new return value through the entire stack (and _all_ the
> kms drivers) so that the probe helpers could aggregate this like they
> currently do.
> 
> One of these is a lot less typing.
> 
> > > - If userspace misses an event and there's no epoch, we're forcing
> > > userspace to reprobe everything. Use case would be if a compositor is
> > > switched away we probably don't want to piss of the current compositor
> > > by blocking it's own probe kernel calls by doing our own (probe is
> > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > it can read the epoch property (which it can do without forcing a
> > > reprobe) userspace would know which connectors it needs to check and
> > > reprobe.
> > > 
> > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > also require that userspace needs to keep parsing all uevents and make
> > > a list of all connectors it needs to reprobe when it's back to being
> > > the active compositor. But just comparing a current epoch with the one
> > > you cached from the last full probe is much easier.
> > 
> > Fair enough, I think it's a fine idea for robustness yes, but I think
> > we could also provide extra info in the uevent when relevant and not
> > rely on that entirely.
> 
> See above, with drmGetConnectorCurrent there's no need to provide more
> than what's needed in the uevent, since userspace can get everything
> else at the cost of one ioctl, without reprobing. With a bit of
> engineering work we could even avoid taking the expensive
> dev->mode_config.mutex lock for this fastpath.
> 
> > > Another thing: None of this we can for connectors with unreliable hdp.
> > > Or at least you'll piss of users if you cache always. The sad thing is
> > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > need to reprobe when the user asks for it. igt can probably get away
> > > without reprobing.
> > 
> > I wonder how that is handled currently and how a user action can solve
> > the issue without any notification from the kernel. Maybe a need a
> > better understanding of that case to have a clearer idea.
> 
> User opens the screen configuration tool -> usually at that point the
> tool/compositor force a full reprobe, which then often triggers the
> automatic reconfiguring. E.g. on one laptop I have here when I plug in
> random shit projectors at conferences nothing happens, until I run
> xrandr, which triggers the full reprobe, which then makes the kernel
> realize something change, sending and uevent, which starts the
> automatic reconfigure machinery.
> 
> There's also the issue that there's machines with hpd storms (even on
> DP, where you really need hpd to work to be compliant), and we have to
> turn of the hpd irq to keep the machine useable.

Note that xrandr only works on X11. On Wayland, it won't.

Whether the user can actually do anything depends on the compositor. On
GNOME the D-Bus interface could probably force a re-probe when a
configuration tool is started or maybe with a "Rescan connectors"
button (not sure they'd like to have this in their UI). On KDE, Weston
and wlroots there is no way to do it.

As compositor writers, do we really need to provide a way for users to
force a reprobe? Can't the kernel do anything to handle these bad
screens?

> Cheers, Daniel
> 
> > Cheers,
> > 
> > Paul
> > 
> > > -Daniel
> > > 
> > > > Then we still have the legacy case:
> > > > HOTPLUG=1
> > > > 
> > > > where userspace is expected to reprobe all the connectors.
> > > > 
> > > > I think this would deserve to be a separate series on its own. So I am
> > > > proposing to take this one off your plate and come up with another
> > > > seres implementing this proposal. What do you think?
> > > > 
> > > > Cheers,
> > > > 
> > > > Paul
> > > > 
> > > > > v2:
> > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > v3:
> > > > >   Check the property is really attached with connector [Daniel]
> > > > > 
> > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > ---
> > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > @@ -21,6 +21,7 @@
> > > > >  #include <drm/drm_sysfs.h>
> > > > >  #include <drm/drmP.h>
> > > > >  #include "drm_internal.h"
> > > > > +#include "drm_crtc_internal.h"
> > > > > 
> > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > >   * deal with other types of events.
> > > > > + *
> > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > + * for uevents on connector status change.
> > > > >   */
> > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > >  {
> > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > >  }
> > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > 
> > > > > +/**
> > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > + * property status change
> > > > > + * @connector: connector on which property status changed
> > > > > + * @property: connector property whoes status changed.
> > > > > + *
> > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > + * related to the status change.
> > > > > + */
> > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > +                                   struct drm_property *property)
> > > > > +{
> > > > > +     struct drm_device *dev = connector->dev;
> > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > +
> > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > +                                        property->base.id));
> > > > > +
> > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > +              "PROPERTY=%u", property->base.id);
> > > > > +
> > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > +
> > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > +}
> > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > +
> > > > >  static void drm_sysfs_release(struct device *dev)
> > > > >  {
> > > > >       kfree(dev);
> > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > --- a/include/drm/drm_sysfs.h
> > > > > +++ b/include/drm/drm_sysfs.h
> > > > > @@ -4,10 +4,13 @@
> > > > > 
> > > > >  struct drm_device;
> > > > >  struct device;
> > > > > +struct drm_connector;
> > > > > +struct drm_property;
> > > > > 
> > > > >  int drm_class_device_register(struct device *dev);
> > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > 
> > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > -
> > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > +                                   struct drm_property *property);
> > > > >  #endif
> > > > --
> > > > Paul Kocialkowski, Bootlin
> > > > Embedded Linux and kernel engineering
> > > > https://bootlin.com
> > > > 
> > --
> > Paul Kocialkowski, Bootlin
> > Embedded Linux and kernel engineering
> > https://bootlin.com
> > 
> 
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13 10:11           ` Ser, Simon
@ 2019-05-13 15:04             ` Daniel Vetter
  2019-05-14  6:18               ` Ser, Simon
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-13 15:04 UTC (permalink / raw)
  To: Ser, Simon
  Cc: airlied, maxime.ripard, daniel.vetter, intel-gfx, dri-devel,
	paul.kocialkowski, ppaalanen, thomas.petazzoni, Vetter, Daniel

On Mon, May 13, 2019 at 10:11:01AM +0000, Ser, Simon wrote:
> On Mon, 2019-05-13 at 11:34 +0200, Daniel Vetter wrote:
> > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hi,
> > > 
> > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > Hi,
> > > > > 
> > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > property.
> > > > > > 
> > > > > > This uevent will have following details related to the status change:
> > > > > > 
> > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > 
> > > > > > Need ACK from this uevent from userspace consumer.
> > > > > 
> > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > issue and came up with similar ideas:
> > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > 
> > > > > The conclusions of these discussions so far would be to have a more or
> > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > point is that we need to cover different cases:
> > > > > - one or more properties changed;
> > > > > - the connector status changed;
> > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > 
> > > > > For the first case, we can send out:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > PROPERTY=<id>
> > > > > 
> > > > > and no reprobe is required.
> > > > > 
> > > > > For the second one, something like:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > STATUS=Connected/Disconnected
> > > > > 
> > > > > and a connector probe is needed for connected, but not for
> > > > > disconnected;
> > > > > 
> > > > > For the third one, we can only indicate the connector:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > 
> > > > > and a reprobe of the connector is always needed
> > > > 
> > > > There's no material difference between this one and the previous one.
> > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > 
> > > That's the idea, but we need to handle status changes differently than
> > > properties, since as far as I know, connected/unconnected status is not
> > > exposed as a prop for the connector.
> > 
> > Oops, totally missed that. "Everything is a property" is kinda
> > new-ish, at least compared to kms. Kinda tempted to just make status
> > into a property. Or another excuse why we should expose the epoch
> > property :-)
> > 
> > > > Here's why:
> > > > - A side effect of forcing a probe on a connector is that you get to
> > > > read all the properties, so supplying them is kinda pointless.
> > > 
> > > Agreed, except for the status case where it's useful to know it's a
> > > disconnect, because we don't need any probe step in that case.
> > > 
> > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > reasonable unfortunately, but oh well.
> > > 
> > > How would that be retreived then? From the looks of it, that's a
> > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > does the full reprobe.
> > 
> > drmGetConnector vs drmGetConnectorCurrent.
> > 
> > > Not sure what issues could arise in case of disconnect without reprobe
> > > -- at least I don't see why userspace should have to do anything in
> > > particular except no longer using the connector, even in complex DP MST
> > > cases.
> > 
> > connector->status might be a lie without a full reprobe, and wrongly
> > indicate that the connector is disconnected while there's still
> > something plugged in. I'm not sure we've fixed those bugs by now
> > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > connected, and we can't break this because every intel platform ever
> > shipped has a few devices where this is somehow broken, irrespective
> > of the sink).
> > 
> > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > everything with the current ioctl and implementations. Having an
> > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > almost all cases).
> > > 
> > > Agreed.
> > > 
> > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > needs to reprobe this connector.
> > > 
> > > I thought we could access the props alone, which avoids doing a reprobe
> > > when the kernel knows that only a prop or a set of props changed and do
> > > not require a full reprobe. That's the first case I was mentionning.
> > > 
> > > > At that point we need to figure out whether this is a good uapi or
> > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > epoch:
> > > > - We need it internally because I'm not goinig to wire a new return
> > > > value through hundreds of connector probe functions. It's much easier
> > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > similar functions that update probe state.
> > > 
> > > I don't think I'm following what issue this is trying to solve
> > > internally.
> > 
> > So I'm assuming that if we handle a hotplug, we only want to generate
> > one uevent for that, not one for every little thing that changed.
> > There's two ways to implement this logic:
> > - With some epoch counter and a helper function you can call everytime
> > something changed (e.g. status, or edid, or anything else we care
> > about e.g. from dp aux). This won't need much (if any) driver changes,
> > because we can just put these into the relevant helper/core functions
> > (like edid update, or dp aux reading or whatever).
> > - Wiring a new return value through the entire stack (and _all_ the
> > kms drivers) so that the probe helpers could aggregate this like they
> > currently do.
> > 
> > One of these is a lot less typing.
> > 
> > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > switched away we probably don't want to piss of the current compositor
> > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > it can read the epoch property (which it can do without forcing a
> > > > reprobe) userspace would know which connectors it needs to check and
> > > > reprobe.
> > > > 
> > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > also require that userspace needs to keep parsing all uevents and make
> > > > a list of all connectors it needs to reprobe when it's back to being
> > > > the active compositor. But just comparing a current epoch with the one
> > > > you cached from the last full probe is much easier.
> > > 
> > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > we could also provide extra info in the uevent when relevant and not
> > > rely on that entirely.
> > 
> > See above, with drmGetConnectorCurrent there's no need to provide more
> > than what's needed in the uevent, since userspace can get everything
> > else at the cost of one ioctl, without reprobing. With a bit of
> > engineering work we could even avoid taking the expensive
> > dev->mode_config.mutex lock for this fastpath.
> > 
> > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > need to reprobe when the user asks for it. igt can probably get away
> > > > without reprobing.
> > > 
> > > I wonder how that is handled currently and how a user action can solve
> > > the issue without any notification from the kernel. Maybe a need a
> > > better understanding of that case to have a clearer idea.
> > 
> > User opens the screen configuration tool -> usually at that point the
> > tool/compositor force a full reprobe, which then often triggers the
> > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > random shit projectors at conferences nothing happens, until I run
> > xrandr, which triggers the full reprobe, which then makes the kernel
> > realize something change, sending and uevent, which starts the
> > automatic reconfigure machinery.
> > 
> > There's also the issue that there's machines with hpd storms (even on
> > DP, where you really need hpd to work to be compliant), and we have to
> > turn of the hpd irq to keep the machine useable.
> 
> Note that xrandr only works on X11. On Wayland, it won't.
> 
> Whether the user can actually do anything depends on the compositor. On
> GNOME the D-Bus interface could probably force a re-probe when a
> configuration tool is started or maybe with a "Rescan connectors"
> button (not sure they'd like to have this in their UI). On KDE, Weston
> and wlroots there is no way to do it.
> 
> As compositor writers, do we really need to provide a way for users to
> force a reprobe? Can't the kernel do anything to handle these bad
> screens?

Yeah, we defensively fall back to polling. Which isn't great from a power
usage pov.

btw as long as compositors use drmGetConnector and not just
drmGetConnectorCurrent you can trigger a full reprobe. If there's not way
to trigger that they'll all have to add a "force probe" button sooner or
later. But usually it's enough if you do a full reprobe when the user
starts your config tool.
-Daniel


> > Cheers, Daniel
> > 
> > > Cheers,
> > > 
> > > Paul
> > > 
> > > > -Daniel
> > > > 
> > > > > Then we still have the legacy case:
> > > > > HOTPLUG=1
> > > > > 
> > > > > where userspace is expected to reprobe all the connectors.
> > > > > 
> > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > proposing to take this one off your plate and come up with another
> > > > > seres implementing this proposal. What do you think?
> > > > > 
> > > > > Cheers,
> > > > > 
> > > > > Paul
> > > > > 
> > > > > > v2:
> > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > v3:
> > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > 
> > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > ---
> > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > @@ -21,6 +21,7 @@
> > > > > >  #include <drm/drm_sysfs.h>
> > > > > >  #include <drm/drmP.h>
> > > > > >  #include "drm_internal.h"
> > > > > > +#include "drm_crtc_internal.h"
> > > > > > 
> > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > >   * deal with other types of events.
> > > > > > + *
> > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > + * for uevents on connector status change.
> > > > > >   */
> > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > >  {
> > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > >  }
> > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > 
> > > > > > +/**
> > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > + * property status change
> > > > > > + * @connector: connector on which property status changed
> > > > > > + * @property: connector property whoes status changed.
> > > > > > + *
> > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > + * related to the status change.
> > > > > > + */
> > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > +                                   struct drm_property *property)
> > > > > > +{
> > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > +
> > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > +                                        property->base.id));
> > > > > > +
> > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > +
> > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > +
> > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > +
> > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > >  {
> > > > > >       kfree(dev);
> > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > @@ -4,10 +4,13 @@
> > > > > > 
> > > > > >  struct drm_device;
> > > > > >  struct device;
> > > > > > +struct drm_connector;
> > > > > > +struct drm_property;
> > > > > > 
> > > > > >  int drm_class_device_register(struct device *dev);
> > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > 
> > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > -
> > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > +                                   struct drm_property *property);
> > > > > >  #endif
> > > > > --
> > > > > Paul Kocialkowski, Bootlin
> > > > > Embedded Linux and kernel engineering
> > > > > https://bootlin.com
> > > > > 
> > > --
> > > Paul Kocialkowski, Bootlin
> > > Embedded Linux and kernel engineering
> > > https://bootlin.com
> > > 
> > 
> > 

-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13  9:34         ` Daniel Vetter
  2019-05-13 10:11           ` Ser, Simon
@ 2019-05-13 17:14           ` Paul Kocialkowski
  2019-05-14 11:09             ` Daniel Vetter
  2019-05-14  8:02           ` Pekka Paalanen
  2 siblings, 1 reply; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-13 17:14 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

Hey,

Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> > Hi,
> > 
> > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hi,
> > > > 
> > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > DRM API for generating uevent for a status changes of connector's
> > > > > property.
> > > > > 
> > > > > This uevent will have following details related to the status change:
> > > > > 
> > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > 
> > > > > Need ACK from this uevent from userspace consumer.
> > > > 
> > > > So we just had some discussions over on IRC and at about the hotplug
> > > > issue and came up with similar ideas:
> > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > 
> > > > The conclusions of these discussions so far would be to have a more or
> > > > less fine grain of uevent reporting depending on what happened. The
> > > > point is that we need to cover different cases:
> > > > - one or more properties changed;
> > > > - the connector status changed;
> > > > - something else about the connector changed (e.g. EDID/modes)
> > > > 
> > > > For the first case, we can send out:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > PROPERTY=<id>
> > > > 
> > > > and no reprobe is required.
> > > > 
> > > > For the second one, something like:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > STATUS=Connected/Disconnected
> > > > 
> > > > and a connector probe is needed for connected, but not for
> > > > disconnected;
> > > > 
> > > > For the third one, we can only indicate the connector:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > 
> > > > and a reprobe of the connector is always needed
> > > 
> > > There's no material difference between this one and the previous one.
> > > Plus there's no beenfit in supplying the actual value of the property,
> > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > 
> > That's the idea, but we need to handle status changes differently than
> > properties, since as far as I know, connected/unconnected status is not
> > exposed as a prop for the connector.
> 
> Oops, totally missed that. "Everything is a property" is kinda
> new-ish, at least compared to kms. Kinda tempted to just make status
> into a property. Or another excuse why we should expose the epoch
> property :-)

Well I think it would make sense anyway, as long as we can make sure it
stays consistent with the one reported in the connector struct.

> > > Here's why:
> > > - A side effect of forcing a probe on a connector is that you get to
> > > read all the properties, so supplying them is kinda pointless.
> > 
> > Agreed, except for the status case where it's useful to know it's a
> > disconnect, because we don't need any probe step in that case.
> > 
> > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > reasonable unfortunately, but oh well.
> > 
> > How would that be retreived then? From the looks of it, that's a
> > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > does the full reprobe.
> 
> drmGetConnector vs drmGetConnectorCurrent.

Ah right, forgot about that one, thanks.

> > Not sure what issues could arise in case of disconnect without reprobe
> > -- at least I don't see why userspace should have to do anything in
> > particular except no longer using the connector, even in complex DP MST
> > cases.
> 
> connector->status might be a lie without a full reprobe, and wrongly
> indicate that the connector is disconnected while there's still
> something plugged in. I'm not sure we've fixed those bugs by now
> (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> connected, and we can't break this because every intel platform ever
> shipped has a few devices where this is somehow broken, irrespective
> of the sink).

Mhh either way, I think it's up to the driver to report that and make
it consistent. I think we have poll helpers to make up for cases where
hotplug is not available too. So I'm not sure why a full reprobe would
be needed: drivers just need to do the right thing.

> > > - There's no way to only reprobe status, you can only ever reprobe
> > > everything with the current ioctl and implementations. Having an
> > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > almost all cases).
> > 
> > Agreed.
> > 
> > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > needs to reprobe this connector.
> > 
> > I thought we could access the props alone, which avoids doing a reprobe
> > when the kernel knows that only a prop or a set of props changed and do
> > not require a full reprobe. That's the first case I was mentionning.
> > 
> > > At that point we need to figure out whether this is a good uapi or
> > > not, and that's where the epoch comes in. There's two reasons for an
> > > epoch:
> > > - We need it internally because I'm not goinig to wire a new return
> > > value through hundreds of connector probe functions. It's much easier
> > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > similar functions that update probe state.
> > 
> > I don't think I'm following what issue this is trying to solve
> > internally.
> 
> So I'm assuming that if we handle a hotplug, we only want to generate
> one uevent for that, not one for every little thing that changed.
> There's two ways to implement this logic:
> - With some epoch counter and a helper function you can call everytime
> something changed (e.g. status, or edid, or anything else we care
> about e.g. from dp aux). This won't need much (if any) driver changes,
> because we can just put these into the relevant helper/core functions
> (like edid update, or dp aux reading or whatever).
> - Wiring a new return value through the entire stack (and _all_ the
> kms drivers) so that the probe helpers could aggregate this like they
> currently do.
> 
> One of these is a lot less typing.

Oh I had missed this issue. Yeah of course if we start reporting
property changes, a hotplug will be lots of such changes.

So an epoch counter property would indeed also solve the reprobing
problem. But I think it would be nice to keep the ability to be
notified of what changed precisely via uevent. I'm not really buying
the "missing uevent" thing so much and I think we can reasonably expect
that it will be useful. Events could be aggregated (which the epoch
counter would probably also allow) and sent out altogether when the
connector status changes (along with the status information). I think
we're under-using uevent currently, and feel like this should be fixed
regardless of the full reprobe issue.

With that, I agree that a global epoch counter from the connector would
be a good quick way for userspace to tell if a connector changed or not
since the last time it checked.

> > > - If userspace misses an event and there's no epoch, we're forcing
> > > userspace to reprobe everything. Use case would be if a compositor is
> > > switched away we probably don't want to piss of the current compositor
> > > by blocking it's own probe kernel calls by doing our own (probe is
> > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > it can read the epoch property (which it can do without forcing a
> > > reprobe) userspace would know which connectors it needs to check and
> > > reprobe.
> > > 
> > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > also require that userspace needs to keep parsing all uevents and make
> > > a list of all connectors it needs to reprobe when it's back to being
> > > the active compositor. But just comparing a current epoch with the one
> > > you cached from the last full probe is much easier.
> > 
> > Fair enough, I think it's a fine idea for robustness yes, but I think
> > we could also provide extra info in the uevent when relevant and not
> > rely on that entirely.
> 
> See above, with drmGetConnectorCurrent there's no need to provide more
> than what's needed in the uevent, since userspace can get everything
> else at the cost of one ioctl, without reprobing. With a bit of
> engineering work we could even avoid taking the expensive
> dev->mode_config.mutex lock for this fastpath.
> 
> > > Another thing: None of this we can for connectors with unreliable hdp.
> > > Or at least you'll piss of users if you cache always. The sad thing is
> > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > need to reprobe when the user asks for it. igt can probably get away
> > > without reprobing.
> > 
> > I wonder how that is handled currently and how a user action can solve
> > the issue without any notification from the kernel. Maybe a need a
> > better understanding of that case to have a clearer idea.
> 
> User opens the screen configuration tool -> usually at that point the
> tool/compositor force a full reprobe, which then often triggers the
> automatic reconfiguring. E.g. on one laptop I have here when I plug in
> random shit projectors at conferences nothing happens, until I run
> xrandr, which triggers the full reprobe, which then makes the kernel
> realize something change, sending and uevent, which starts the
> automatic reconfigure machinery.

Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
to get me out of an off-panel situation much too often.

> There's also the issue that there's machines with hpd storms (even on
> DP, where you really need hpd to work to be compliant), and we have to
> turn of the hpd irq to keep the machine useable.

I was under the impression that we switch to polling when a hpd storm
is detected in i915 (but that's a vague memory from my summer
internship at Intel 2 years ago).

Cheers,

Paul

> Cheers, Daniel
> 
> > Cheers,
> > 
> > Paul
> > 
> > > -Daniel
> > > 
> > > > Then we still have the legacy case:
> > > > HOTPLUG=1
> > > > 
> > > > where userspace is expected to reprobe all the connectors.
> > > > 
> > > > I think this would deserve to be a separate series on its own. So I am
> > > > proposing to take this one off your plate and come up with another
> > > > seres implementing this proposal. What do you think?
> > > > 
> > > > Cheers,
> > > > 
> > > > Paul
> > > > 
> > > > > v2:
> > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > v3:
> > > > >   Check the property is really attached with connector [Daniel]
> > > > > 
> > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > ---
> > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > @@ -21,6 +21,7 @@
> > > > >  #include <drm/drm_sysfs.h>
> > > > >  #include <drm/drmP.h>
> > > > >  #include "drm_internal.h"
> > > > > +#include "drm_crtc_internal.h"
> > > > > 
> > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > >   * deal with other types of events.
> > > > > + *
> > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > + * for uevents on connector status change.
> > > > >   */
> > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > >  {
> > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > >  }
> > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > 
> > > > > +/**
> > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > + * property status change
> > > > > + * @connector: connector on which property status changed
> > > > > + * @property: connector property whoes status changed.
> > > > > + *
> > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > + * related to the status change.
> > > > > + */
> > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > +                                   struct drm_property *property)
> > > > > +{
> > > > > +     struct drm_device *dev = connector->dev;
> > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > +
> > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > +                                        property->base.id));
> > > > > +
> > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > +              "PROPERTY=%u", property->base.id);
> > > > > +
> > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > +
> > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > +}
> > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > +
> > > > >  static void drm_sysfs_release(struct device *dev)
> > > > >  {
> > > > >       kfree(dev);
> > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > --- a/include/drm/drm_sysfs.h
> > > > > +++ b/include/drm/drm_sysfs.h
> > > > > @@ -4,10 +4,13 @@
> > > > > 
> > > > >  struct drm_device;
> > > > >  struct device;
> > > > > +struct drm_connector;
> > > > > +struct drm_property;
> > > > > 
> > > > >  int drm_class_device_register(struct device *dev);
> > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > 
> > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > -
> > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > +                                   struct drm_property *property);
> > > > >  #endif
> > > > --
> > > > Paul Kocialkowski, Bootlin
> > > > Embedded Linux and kernel engineering
> > > > https://bootlin.com
> > > > 
> > --
> > Paul Kocialkowski, Bootlin
> > Embedded Linux and kernel engineering
> > https://bootlin.com
> > 
> 
> 

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-10 12:12   ` Paul Kocialkowski
  2019-05-10 14:54     ` Daniel Vetter
@ 2019-05-13 21:20     ` Lyude Paul
  2019-05-14 11:12       ` Daniel Vetter
  1 sibling, 1 reply; 70+ messages in thread
From: Lyude Paul @ 2019-05-13 21:20 UTC (permalink / raw)
  To: Paul Kocialkowski, Ramalingam C, intel-gfx, dri-devel, daniel.vetter
  Cc: David Airlie, Maxime Ripard, Daniel Vetter, Ser, Simon,
	Pekka Paalanen, Thomas Petazzoni

Hi-just wanted to give some general thoughts here.

First off I'm 100% behind the epoch idea, that was one of the ideas I had been
thinking of proposing here in the first place but probably forgot at some
point down the road.

A couple of other things:
 * I think it would also probably be good to have events for when connectors
   are added or removed from the system (mainly for MST)
 * Have we considered having any sort of SYNC event, like what evdev uses for
   signaling the end of a frame of events for input devices?

On Fri, 2019-05-10 at 14:12 +0200, Paul Kocialkowski wrote:
> Hi,
> 
> On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > DRM API for generating uevent for a status changes of connector's
> > property.
> > 
> > This uevent will have following details related to the status change:
> > 
> >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > 
> > Need ACK from this uevent from userspace consumer.
> 
> So we just had some discussions over on IRC and at about the hotplug
> issue and came up with similar ideas:
> https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> 
> The conclusions of these discussions so far would be to have a more or
> less fine grain of uevent reporting depending on what happened. The
> point is that we need to cover different cases:
> - one or more properties changed;
> - the connector status changed;
> - something else about the connector changed (e.g. EDID/modes)
> 
> For the first case, we can send out:
> HOTPLUG=1
> CONNECTOR=<id>
> PROPERTY=<id>
> 
> and no reprobe is required.
> 
> For the second one, something like:
> HOTPLUG=1
> CONNECTOR=<id>
> STATUS=Connected/Disconnected
> 
> and a connector probe is needed for connected, but not for
> disconnected;
> 
> For the third one, we can only indicate the connector:
> HOTPLUG=1
> CONNECTOR=<id>
> 
> and a reprobe of the connector is always needed
> 
> Then we still have the legacy case:
> HOTPLUG=1
> 
> where userspace is expected to reprobe all the connectors.
> 
> I think this would deserve to be a separate series on its own. So I am
> proposing to take this one off your plate and come up with another
> seres implementing this proposal. What do you think?
> 
> Cheers,
> 
> Paul
> 
> > v2:
> >   Minor fixes at KDoc comments [Daniel]
> > v3:
> >   Check the property is really attached with connector [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> >  include/drm/drm_sysfs.h     |  5 ++++-
> >  2 files changed, 39 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index 18b1ac442997..63fa951a20db 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -21,6 +21,7 @@
> >  #include <drm/drm_sysfs.h>
> >  #include <drm/drmP.h>
> >  #include "drm_internal.h"
> > +#include "drm_crtc_internal.h"
> >  
> >  #define to_drm_minor(d) dev_get_drvdata(d)
> >  #define to_drm_connector(d) dev_get_drvdata(d)
> > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> >   * deal with other types of events.
> > + *
> > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > + * for uevents on connector status change.
> >   */
> >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  {
> > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  }
> >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> >  
> > +/**
> > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > + * property status change
> > + * @connector: connector on which property status changed
> > + * @property: connector property whoes status changed.
> > + *
> > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > + * set HOTPLUG=1 and connector id along with the attached property id
> > + * related to the status change.
> > + */
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +				      struct drm_property *property)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > +
> > +	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > +					   property->base.id));
> > +
> > +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> > +		 "CONNECTOR=%u", connector->base.id);
> > +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> > +		 "PROPERTY=%u", property->base.id);
> > +
> > +	DRM_DEBUG("generating connector status event\n");
> > +
> > +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > +}
> > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > +
> >  static void drm_sysfs_release(struct device *dev)
> >  {
> >  	kfree(dev);
> > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > index 4f311e836cdc..d454ef617b2c 100644
> > --- a/include/drm/drm_sysfs.h
> > +++ b/include/drm/drm_sysfs.h
> > @@ -4,10 +4,13 @@
> >  
> >  struct drm_device;
> >  struct device;
> > +struct drm_connector;
> > +struct drm_property;
> >  
> >  int drm_class_device_register(struct device *dev);
> >  void drm_class_device_unregister(struct device *dev);
> >  
> >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > -
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +				      struct drm_property *property);
> >  #endif
-- 
Cheers,
	Lyude Paul

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13 15:04             ` Daniel Vetter
@ 2019-05-14  6:18               ` Ser, Simon
  0 siblings, 0 replies; 70+ messages in thread
From: Ser, Simon @ 2019-05-14  6:18 UTC (permalink / raw)
  To: daniel
  Cc: airlied, maxime.ripard, intel-gfx, dri-devel, Mun, Gwan-gyeong,
	paul.kocialkowski, thomas.petazzoni, daniel.vetter, Vetter,
	Daniel, sean

On Mon, 2019-05-13 at 17:04 +0200, Daniel Vetter wrote:
> On Mon, May 13, 2019 at 10:11:01AM +0000, Ser, Simon wrote:
> > On Mon, 2019-05-13 at 11:34 +0200, Daniel Vetter wrote:
> > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hi,
> > > > 
> > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > Hi,
> > > > > > 
> > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > property.
> > > > > > > 
> > > > > > > This uevent will have following details related to the status change:
> > > > > > > 
> > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > 
> > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > 
> > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > issue and came up with similar ideas:
> > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > 
> > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > point is that we need to cover different cases:
> > > > > > - one or more properties changed;
> > > > > > - the connector status changed;
> > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > 
> > > > > > For the first case, we can send out:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > PROPERTY=<id>
> > > > > > 
> > > > > > and no reprobe is required.
> > > > > > 
> > > > > > For the second one, something like:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > STATUS=Connected/Disconnected
> > > > > > 
> > > > > > and a connector probe is needed for connected, but not for
> > > > > > disconnected;
> > > > > > 
> > > > > > For the third one, we can only indicate the connector:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > 
> > > > > > and a reprobe of the connector is always needed
> > > > > 
> > > > > There's no material difference between this one and the previous one.
> > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > 
> > > > That's the idea, but we need to handle status changes differently than
> > > > properties, since as far as I know, connected/unconnected status is not
> > > > exposed as a prop for the connector.
> > > 
> > > Oops, totally missed that. "Everything is a property" is kinda
> > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > into a property. Or another excuse why we should expose the epoch
> > > property :-)
> > > 
> > > > > Here's why:
> > > > > - A side effect of forcing a probe on a connector is that you get to
> > > > > read all the properties, so supplying them is kinda pointless.
> > > > 
> > > > Agreed, except for the status case where it's useful to know it's a
> > > > disconnect, because we don't need any probe step in that case.
> > > > 
> > > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > > reasonable unfortunately, but oh well.
> > > > 
> > > > How would that be retreived then? From the looks of it, that's a
> > > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > > does the full reprobe.
> > > 
> > > drmGetConnector vs drmGetConnectorCurrent.
> > > 
> > > > Not sure what issues could arise in case of disconnect without reprobe
> > > > -- at least I don't see why userspace should have to do anything in
> > > > particular except no longer using the connector, even in complex DP MST
> > > > cases.
> > > 
> > > connector->status might be a lie without a full reprobe, and wrongly
> > > indicate that the connector is disconnected while there's still
> > > something plugged in. I'm not sure we've fixed those bugs by now
> > > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > > connected, and we can't break this because every intel platform ever
> > > shipped has a few devices where this is somehow broken, irrespective
> > > of the sink).
> > > 
> > > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > > everything with the current ioctl and implementations. Having an
> > > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > > almost all cases).
> > > > 
> > > > Agreed.
> > > > 
> > > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > > needs to reprobe this connector.
> > > > 
> > > > I thought we could access the props alone, which avoids doing a reprobe
> > > > when the kernel knows that only a prop or a set of props changed and do
> > > > not require a full reprobe. That's the first case I was mentionning.
> > > > 
> > > > > At that point we need to figure out whether this is a good uapi or
> > > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > > epoch:
> > > > > - We need it internally because I'm not goinig to wire a new return
> > > > > value through hundreds of connector probe functions. It's much easier
> > > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > > similar functions that update probe state.
> > > > 
> > > > I don't think I'm following what issue this is trying to solve
> > > > internally.
> > > 
> > > So I'm assuming that if we handle a hotplug, we only want to generate
> > > one uevent for that, not one for every little thing that changed.
> > > There's two ways to implement this logic:
> > > - With some epoch counter and a helper function you can call everytime
> > > something changed (e.g. status, or edid, or anything else we care
> > > about e.g. from dp aux). This won't need much (if any) driver changes,
> > > because we can just put these into the relevant helper/core functions
> > > (like edid update, or dp aux reading or whatever).
> > > - Wiring a new return value through the entire stack (and _all_ the
> > > kms drivers) so that the probe helpers could aggregate this like they
> > > currently do.
> > > 
> > > One of these is a lot less typing.
> > > 
> > > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > > switched away we probably don't want to piss of the current compositor
> > > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > > it can read the epoch property (which it can do without forcing a
> > > > > reprobe) userspace would know which connectors it needs to check and
> > > > > reprobe.
> > > > > 
> > > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > > also require that userspace needs to keep parsing all uevents and make
> > > > > a list of all connectors it needs to reprobe when it's back to being
> > > > > the active compositor. But just comparing a current epoch with the one
> > > > > you cached from the last full probe is much easier.
> > > > 
> > > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > > we could also provide extra info in the uevent when relevant and not
> > > > rely on that entirely.
> > > 
> > > See above, with drmGetConnectorCurrent there's no need to provide more
> > > than what's needed in the uevent, since userspace can get everything
> > > else at the cost of one ioctl, without reprobing. With a bit of
> > > engineering work we could even avoid taking the expensive
> > > dev->mode_config.mutex lock for this fastpath.
> > > 
> > > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > > need to reprobe when the user asks for it. igt can probably get away
> > > > > without reprobing.
> > > > 
> > > > I wonder how that is handled currently and how a user action can solve
> > > > the issue without any notification from the kernel. Maybe a need a
> > > > better understanding of that case to have a clearer idea.
> > > 
> > > User opens the screen configuration tool -> usually at that point the
> > > tool/compositor force a full reprobe, which then often triggers the
> > > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > > random shit projectors at conferences nothing happens, until I run
> > > xrandr, which triggers the full reprobe, which then makes the kernel
> > > realize something change, sending and uevent, which starts the
> > > automatic reconfigure machinery.
> > > 
> > > There's also the issue that there's machines with hpd storms (even on
> > > DP, where you really need hpd to work to be compliant), and we have to
> > > turn of the hpd irq to keep the machine useable.
> > 
> > Note that xrandr only works on X11. On Wayland, it won't.
> > 
> > Whether the user can actually do anything depends on the compositor. On
> > GNOME the D-Bus interface could probably force a re-probe when a
> > configuration tool is started or maybe with a "Rescan connectors"
> > button (not sure they'd like to have this in their UI). On KDE, Weston
> > and wlroots there is no way to do it.
> > 
> > As compositor writers, do we really need to provide a way for users to
> > force a reprobe? Can't the kernel do anything to handle these bad
> > screens?
> 
> Yeah, we defensively fall back to polling. Which isn't great from a power
> usage pov.
> 
> btw as long as compositors use drmGetConnector and not just
> drmGetConnectorCurrent you can trigger a full reprobe. If there's not way
> to trigger that they'll all have to add a "force probe" button sooner or
> later. But usually it's enough if you do a full reprobe when the user
> starts your config tool.

FWIW, some compositors (Weston, wlroots-based ones) don't have a
"graphical config tool", either because it's command-line (and event-
based, not poll-based) or because screen configuration is static (but
hotplug is supported). I guess we would need to expose some kind of
"rescan" command, which nobody will know about. Sigh.

> > > Cheers, Daniel
> > > 
> > > > Cheers,
> > > > 
> > > > Paul
> > > > 
> > > > > -Daniel
> > > > > 
> > > > > > Then we still have the legacy case:
> > > > > > HOTPLUG=1
> > > > > > 
> > > > > > where userspace is expected to reprobe all the connectors.
> > > > > > 
> > > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > > proposing to take this one off your plate and come up with another
> > > > > > seres implementing this proposal. What do you think?
> > > > > > 
> > > > > > Cheers,
> > > > > > 
> > > > > > Paul
> > > > > > 
> > > > > > > v2:
> > > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > > v3:
> > > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > > 
> > > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > @@ -21,6 +21,7 @@
> > > > > > >  #include <drm/drm_sysfs.h>
> > > > > > >  #include <drm/drmP.h>
> > > > > > >  #include "drm_internal.h"
> > > > > > > +#include "drm_crtc_internal.h"
> > > > > > > 
> > > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > > >   * deal with other types of events.
> > > > > > > + *
> > > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > > + * for uevents on connector status change.
> > > > > > >   */
> > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > >  {
> > > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > >  }
> > > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > > 
> > > > > > > +/**
> > > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > > + * property status change
> > > > > > > + * @connector: connector on which property status changed
> > > > > > > + * @property: connector property whoes status changed.
> > > > > > > + *
> > > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > > + * related to the status change.
> > > > > > > + */
> > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > +                                   struct drm_property *property)
> > > > > > > +{
> > > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > > +
> > > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > > +                                        property->base.id));
> > > > > > > +
> > > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > > +
> > > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > > +
> > > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > > +}
> > > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > > +
> > > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > > >  {
> > > > > > >       kfree(dev);
> > > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > > @@ -4,10 +4,13 @@
> > > > > > > 
> > > > > > >  struct drm_device;
> > > > > > >  struct device;
> > > > > > > +struct drm_connector;
> > > > > > > +struct drm_property;
> > > > > > > 
> > > > > > >  int drm_class_device_register(struct device *dev);
> > > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > > 
> > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > > -
> > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > +                                   struct drm_property *property);
> > > > > > >  #endif
> > > > > > --
> > > > > > Paul Kocialkowski, Bootlin
> > > > > > Embedded Linux and kernel engineering
> > > > > > https://bootlin.com
> > > > > > 
> > > > --
> > > > Paul Kocialkowski, Bootlin
> > > > Embedded Linux and kernel engineering
> > > > https://bootlin.com
> > > > 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13  9:34         ` Daniel Vetter
  2019-05-13 10:11           ` Ser, Simon
  2019-05-13 17:14           ` Paul Kocialkowski
@ 2019-05-14  8:02           ` Pekka Paalanen
  2019-05-14  8:18             ` Ser, Simon
  2 siblings, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-14  8:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, Maxime Ripard, intel-gfx, dri-devel,
	Paul Kocialkowski, David Airlie, Thomas Petazzoni, Daniel Vetter


[-- Attachment #1.1: Type: text/plain, Size: 3580 bytes --]

On Mon, 13 May 2019 11:34:58 +0200
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> >
> > Hi,
> >
> > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:  
> > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > Hi,
> > > >
> > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:  
> > > > > DRM API for generating uevent for a status changes of connector's
> > > > > property.
> > > > >
> > > > > This uevent will have following details related to the status change:
> > > > >
> > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > >
> > > > > Need ACK from this uevent from userspace consumer.  
> > > >
> > > > So we just had some discussions over on IRC and at about the hotplug
> > > > issue and came up with similar ideas:
> > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > >
> > > > The conclusions of these discussions so far would be to have a more or
> > > > less fine grain of uevent reporting depending on what happened. The
> > > > point is that we need to cover different cases:
> > > > - one or more properties changed;
> > > > - the connector status changed;
> > > > - something else about the connector changed (e.g. EDID/modes)
> > > >
> > > > For the first case, we can send out:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > PROPERTY=<id>
> > > >
> > > > and no reprobe is required.
> > > >
> > > > For the second one, something like:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > > STATUS=Connected/Disconnected
> > > >
> > > > and a connector probe is needed for connected, but not for
> > > > disconnected;
> > > >
> > > > For the third one, we can only indicate the connector:
> > > > HOTPLUG=1
> > > > CONNECTOR=<id>
> > > >
> > > > and a reprobe of the connector is always needed  
> > >
> > > There's no material difference between this one and the previous one.
> > > Plus there's no beenfit in supplying the actual value of the property,
> > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.  
> >
> > That's the idea, but we need to handle status changes differently than
> > properties, since as far as I know, connected/unconnected status is not
> > exposed as a prop for the connector.  
> 
> Oops, totally missed that. "Everything is a property" is kinda
> new-ish, at least compared to kms. Kinda tempted to just make status
> into a property. Or another excuse why we should expose the epoch
> property :-)

Hi Daniel,

just to clarify the first case, specific to one very particular
property:

With HDCP, there is a property that may change dynamically at runtime
(the undesired/desired/enabled tristate). Userspace must be notified
when it changes, I do not want userspace have to poll that property
with a timer.

When that property alone changes, and userspace is prepared to handle
that property changing alone, it must not trigger a reprobe of the
connector. There is no reason to reprobe at that point AFAIU.

How do you ensure that userspace can avoid triggering a reprobe with the
epoch approach or with any alternate uevent design?

We need an event to userspace that indicates that re-reading the
properties is enough and reprobe of the connector is not necessary.
This is complementary to indicating to userspace that only some
connectors need to be reprobed instead of everything.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14  8:02           ` Pekka Paalanen
@ 2019-05-14  8:18             ` Ser, Simon
  2019-05-14 11:02               ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Ser, Simon @ 2019-05-14  8:18 UTC (permalink / raw)
  To: daniel.vetter, ppaalanen
  Cc: airlied, maxime.ripard, intel-gfx, dri-devel, Mun, Gwan-gyeong,
	paul.kocialkowski, thomas.petazzoni, Vetter, Daniel, sean

On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:
> On Mon, 13 May 2019 11:34:58 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> 
> > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hi,
> > > 
> > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:  
> > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > > Hi,
> > > > > 
> > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:  
> > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > property.
> > > > > > 
> > > > > > This uevent will have following details related to the status change:
> > > > > > 
> > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > 
> > > > > > Need ACK from this uevent from userspace consumer.  
> > > > > 
> > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > issue and came up with similar ideas:
> > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > 
> > > > > The conclusions of these discussions so far would be to have a more or
> > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > point is that we need to cover different cases:
> > > > > - one or more properties changed;
> > > > > - the connector status changed;
> > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > 
> > > > > For the first case, we can send out:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > PROPERTY=<id>
> > > > > 
> > > > > and no reprobe is required.
> > > > > 
> > > > > For the second one, something like:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > STATUS=Connected/Disconnected
> > > > > 
> > > > > and a connector probe is needed for connected, but not for
> > > > > disconnected;
> > > > > 
> > > > > For the third one, we can only indicate the connector:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > 
> > > > > and a reprobe of the connector is always needed  
> > > > 
> > > > There's no material difference between this one and the previous one.
> > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.  
> > > 
> > > That's the idea, but we need to handle status changes differently than
> > > properties, since as far as I know, connected/unconnected status is not
> > > exposed as a prop for the connector.  
> > 
> > Oops, totally missed that. "Everything is a property" is kinda
> > new-ish, at least compared to kms. Kinda tempted to just make status
> > into a property. Or another excuse why we should expose the epoch
> > property :-)
> 
> Hi Daniel,
> 
> just to clarify the first case, specific to one very particular
> property:
> 
> With HDCP, there is a property that may change dynamically at runtime
> (the undesired/desired/enabled tristate). Userspace must be notified
> when it changes, I do not want userspace have to poll that property
> with a timer.
> 
> When that property alone changes, and userspace is prepared to handle
> that property changing alone, it must not trigger a reprobe of the
> connector. There is no reason to reprobe at that point AFAIU.
> 
> How do you ensure that userspace can avoid triggering a reprobe with the
> epoch approach or with any alternate uevent design?
> 
> We need an event to userspace that indicates that re-reading the
> properties is enough and reprobe of the connector is not necessary.
> This is complementary to indicating to userspace that only some
> connectors need to be reprobed instead of everything.

Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
reprobing. Would that work?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14  8:18             ` Ser, Simon
@ 2019-05-14 11:02               ` Daniel Vetter
  2019-05-14 13:36                 ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-14 11:02 UTC (permalink / raw)
  To: Ser, Simon
  Cc: airlied, maxime.ripard, intel-gfx, dri-devel, Mun, Gwan-gyeong,
	paul.kocialkowski, thomas.petazzoni, Vetter, Daniel, sean

On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:
>
> On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:
> > On Mon, 13 May 2019 11:34:58 +0200
> > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >
> > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hi,
> > > >
> > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > Hi,
> > > > > >
> > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > property.
> > > > > > >
> > > > > > > This uevent will have following details related to the status change:
> > > > > > >
> > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > >
> > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > >
> > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > issue and came up with similar ideas:
> > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > >
> > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > point is that we need to cover different cases:
> > > > > > - one or more properties changed;
> > > > > > - the connector status changed;
> > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > >
> > > > > > For the first case, we can send out:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > PROPERTY=<id>
> > > > > >
> > > > > > and no reprobe is required.
> > > > > >
> > > > > > For the second one, something like:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > STATUS=Connected/Disconnected
> > > > > >
> > > > > > and a connector probe is needed for connected, but not for
> > > > > > disconnected;
> > > > > >
> > > > > > For the third one, we can only indicate the connector:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > >
> > > > > > and a reprobe of the connector is always needed
> > > > >
> > > > > There's no material difference between this one and the previous one.
> > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > >
> > > > That's the idea, but we need to handle status changes differently than
> > > > properties, since as far as I know, connected/unconnected status is not
> > > > exposed as a prop for the connector.
> > >
> > > Oops, totally missed that. "Everything is a property" is kinda
> > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > into a property. Or another excuse why we should expose the epoch
> > > property :-)
> >
> > Hi Daniel,
> >
> > just to clarify the first case, specific to one very particular
> > property:
> >
> > With HDCP, there is a property that may change dynamically at runtime
> > (the undesired/desired/enabled tristate). Userspace must be notified
> > when it changes, I do not want userspace have to poll that property
> > with a timer.
> >
> > When that property alone changes, and userspace is prepared to handle
> > that property changing alone, it must not trigger a reprobe of the
> > connector. There is no reason to reprobe at that point AFAIU.
> >
> > How do you ensure that userspace can avoid triggering a reprobe with the
> > epoch approach or with any alternate uevent design?
> >
> > We need an event to userspace that indicates that re-reading the
> > properties is enough and reprobe of the connector is not necessary.
> > This is complementary to indicating to userspace that only some
> > connectors need to be reprobed instead of everything.
>
> Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> reprobing. Would that work?

Yes that's the idea, depending upon which property you get you know
it's a sink change (needs full reprobe) or something else like hdcp
state machinery update.

Wrt avoiding the full reprobe for sink changes: I think we should
indeed decouple that from the per-connector event for sink changes.
That along is a good win already, since you know for which connector
you need to call drmGetConnector (which forces the reprobe). It would
be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
historically speaking every time we tried to rely on this we ended up
regretting things.
-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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13 17:14           ` Paul Kocialkowski
@ 2019-05-14 11:09             ` Daniel Vetter
  2019-05-14 14:12               ` Paul Kocialkowski
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-14 11:09 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

On Mon, May 13, 2019 at 7:14 PM Paul Kocialkowski
<paul.kocialkowski@bootlin.com> wrote:
>
> Hey,
>
> Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hi,
> > >
> > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > Hi,
> > > > >
> > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > property.
> > > > > >
> > > > > > This uevent will have following details related to the status change:
> > > > > >
> > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > >
> > > > > > Need ACK from this uevent from userspace consumer.
> > > > >
> > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > issue and came up with similar ideas:
> > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > >
> > > > > The conclusions of these discussions so far would be to have a more or
> > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > point is that we need to cover different cases:
> > > > > - one or more properties changed;
> > > > > - the connector status changed;
> > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > >
> > > > > For the first case, we can send out:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > PROPERTY=<id>
> > > > >
> > > > > and no reprobe is required.
> > > > >
> > > > > For the second one, something like:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > > STATUS=Connected/Disconnected
> > > > >
> > > > > and a connector probe is needed for connected, but not for
> > > > > disconnected;
> > > > >
> > > > > For the third one, we can only indicate the connector:
> > > > > HOTPLUG=1
> > > > > CONNECTOR=<id>
> > > > >
> > > > > and a reprobe of the connector is always needed
> > > >
> > > > There's no material difference between this one and the previous one.
> > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > >
> > > That's the idea, but we need to handle status changes differently than
> > > properties, since as far as I know, connected/unconnected status is not
> > > exposed as a prop for the connector.
> >
> > Oops, totally missed that. "Everything is a property" is kinda
> > new-ish, at least compared to kms. Kinda tempted to just make status
> > into a property. Or another excuse why we should expose the epoch
> > property :-)
>
> Well I think it would make sense anyway, as long as we can make sure it
> stays consistent with the one reported in the connector struct.
>
> > > > Here's why:
> > > > - A side effect of forcing a probe on a connector is that you get to
> > > > read all the properties, so supplying them is kinda pointless.
> > >
> > > Agreed, except for the status case where it's useful to know it's a
> > > disconnect, because we don't need any probe step in that case.
> > >
> > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > reasonable unfortunately, but oh well.
> > >
> > > How would that be retreived then? From the looks of it, that's a
> > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > does the full reprobe.
> >
> > drmGetConnector vs drmGetConnectorCurrent.
>
> Ah right, forgot about that one, thanks.
>
> > > Not sure what issues could arise in case of disconnect without reprobe
> > > -- at least I don't see why userspace should have to do anything in
> > > particular except no longer using the connector, even in complex DP MST
> > > cases.
> >
> > connector->status might be a lie without a full reprobe, and wrongly
> > indicate that the connector is disconnected while there's still
> > something plugged in. I'm not sure we've fixed those bugs by now
> > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > connected, and we can't break this because every intel platform ever
> > shipped has a few devices where this is somehow broken, irrespective
> > of the sink).
>
> Mhh either way, I think it's up to the driver to report that and make
> it consistent. I think we have poll helpers to make up for cases where
> hotplug is not available too. So I'm not sure why a full reprobe would
> be needed: drivers just need to do the right thing.
>
> > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > everything with the current ioctl and implementations. Having an
> > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > almost all cases).
> > >
> > > Agreed.
> > >
> > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > needs to reprobe this connector.
> > >
> > > I thought we could access the props alone, which avoids doing a reprobe
> > > when the kernel knows that only a prop or a set of props changed and do
> > > not require a full reprobe. That's the first case I was mentionning.
> > >
> > > > At that point we need to figure out whether this is a good uapi or
> > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > epoch:
> > > > - We need it internally because I'm not goinig to wire a new return
> > > > value through hundreds of connector probe functions. It's much easier
> > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > similar functions that update probe state.
> > >
> > > I don't think I'm following what issue this is trying to solve
> > > internally.
> >
> > So I'm assuming that if we handle a hotplug, we only want to generate
> > one uevent for that, not one for every little thing that changed.
> > There's two ways to implement this logic:
> > - With some epoch counter and a helper function you can call everytime
> > something changed (e.g. status, or edid, or anything else we care
> > about e.g. from dp aux). This won't need much (if any) driver changes,
> > because we can just put these into the relevant helper/core functions
> > (like edid update, or dp aux reading or whatever).
> > - Wiring a new return value through the entire stack (and _all_ the
> > kms drivers) so that the probe helpers could aggregate this like they
> > currently do.
> >
> > One of these is a lot less typing.
>
> Oh I had missed this issue. Yeah of course if we start reporting
> property changes, a hotplug will be lots of such changes.
>
> So an epoch counter property would indeed also solve the reprobing
> problem. But I think it would be nice to keep the ability to be
> notified of what changed precisely via uevent. I'm not really buying
> the "missing uevent" thing so much and I think we can reasonably expect
> that it will be useful. Events could be aggregated (which the epoch
> counter would probably also allow) and sent out altogether when the
> connector status changes (along with the status information). I think
> we're under-using uevent currently, and feel like this should be fixed
> regardless of the full reprobe issue.

I see two options:

1) kernel aggregates uevents a bit, and sends out one (per connector
that changed) indicating that sink related state changed. Userspace
listens to that, and does a drmGetConnector as a result to update
itself. Most of this code needs to exist anyway.

2) kernel sends out updates as we go, userspace reassembles everything
again (and not really an idea when all the updates are in, see Lyude's
question. Plus userspace still needs to have the drmGetConnector path,
at least for initial setup.

I don't see why 2) is any better than 1), and it has some clear downsides.

> With that, I agree that a global epoch counter from the connector would
> be a good quick way for userspace to tell if a connector changed or not
> since the last time it checked.
>
> > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > switched away we probably don't want to piss of the current compositor
> > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > it can read the epoch property (which it can do without forcing a
> > > > reprobe) userspace would know which connectors it needs to check and
> > > > reprobe.
> > > >
> > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > also require that userspace needs to keep parsing all uevents and make
> > > > a list of all connectors it needs to reprobe when it's back to being
> > > > the active compositor. But just comparing a current epoch with the one
> > > > you cached from the last full probe is much easier.
> > >
> > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > we could also provide extra info in the uevent when relevant and not
> > > rely on that entirely.
> >
> > See above, with drmGetConnectorCurrent there's no need to provide more
> > than what's needed in the uevent, since userspace can get everything
> > else at the cost of one ioctl, without reprobing. With a bit of
> > engineering work we could even avoid taking the expensive
> > dev->mode_config.mutex lock for this fastpath.
> >
> > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > need to reprobe when the user asks for it. igt can probably get away
> > > > without reprobing.
> > >
> > > I wonder how that is handled currently and how a user action can solve
> > > the issue without any notification from the kernel. Maybe a need a
> > > better understanding of that case to have a clearer idea.
> >
> > User opens the screen configuration tool -> usually at that point the
> > tool/compositor force a full reprobe, which then often triggers the
> > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > random shit projectors at conferences nothing happens, until I run
> > xrandr, which triggers the full reprobe, which then makes the kernel
> > realize something change, sending and uevent, which starts the
> > automatic reconfigure machinery.
>
> Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
> to get me out of an off-panel situation much too often.
>
> > There's also the issue that there's machines with hpd storms (even on
> > DP, where you really need hpd to work to be compliant), and we have to
> > turn of the hpd irq to keep the machine useable.
>
> I was under the impression that we switch to polling when a hpd storm
> is detected in i915 (but that's a vague memory from my summer
> internship at Intel 2 years ago).

We do poll, but the issue is still that polling doesn't do the same
thing as full reprobe. One just calls ->detect, the other ->detect +
->get_modes. This is a bit a silliness of the helpers and source of
lots of confusion. A possible fix might be to always call both.

Plus even when that mess is sorted there's still the issue of broken
hw, and we have no idea how much/where/which exactly. Except that
every time we relied on hpd status, we got regression reports and had
to revert.
-Daniel

> Cheers,
>
> Paul
>
> > Cheers, Daniel
> >
> > > Cheers,
> > >
> > > Paul
> > >
> > > > -Daniel
> > > >
> > > > > Then we still have the legacy case:
> > > > > HOTPLUG=1
> > > > >
> > > > > where userspace is expected to reprobe all the connectors.
> > > > >
> > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > proposing to take this one off your plate and come up with another
> > > > > seres implementing this proposal. What do you think?
> > > > >
> > > > > Cheers,
> > > > >
> > > > > Paul
> > > > >
> > > > > > v2:
> > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > v3:
> > > > > >   Check the property is really attached with connector [Daniel]
> > > > > >
> > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > ---
> > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > @@ -21,6 +21,7 @@
> > > > > >  #include <drm/drm_sysfs.h>
> > > > > >  #include <drm/drmP.h>
> > > > > >  #include "drm_internal.h"
> > > > > > +#include "drm_crtc_internal.h"
> > > > > >
> > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > >   * deal with other types of events.
> > > > > > + *
> > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > + * for uevents on connector status change.
> > > > > >   */
> > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > >  {
> > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > >  }
> > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > >
> > > > > > +/**
> > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > + * property status change
> > > > > > + * @connector: connector on which property status changed
> > > > > > + * @property: connector property whoes status changed.
> > > > > > + *
> > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > + * related to the status change.
> > > > > > + */
> > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > +                                   struct drm_property *property)
> > > > > > +{
> > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > +
> > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > +                                        property->base.id));
> > > > > > +
> > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > +
> > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > +
> > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > +
> > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > >  {
> > > > > >       kfree(dev);
> > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > @@ -4,10 +4,13 @@
> > > > > >
> > > > > >  struct drm_device;
> > > > > >  struct device;
> > > > > > +struct drm_connector;
> > > > > > +struct drm_property;
> > > > > >
> > > > > >  int drm_class_device_register(struct device *dev);
> > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > >
> > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > -
> > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > +                                   struct drm_property *property);
> > > > > >  #endif
> > > > > --
> > > > > Paul Kocialkowski, Bootlin
> > > > > Embedded Linux and kernel engineering
> > > > > https://bootlin.com
> > > > >
> > > --
> > > Paul Kocialkowski, Bootlin
> > > Embedded Linux and kernel engineering
> > > https://bootlin.com
> > >
> >
> >
>


-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-13 21:20     ` Lyude Paul
@ 2019-05-14 11:12       ` Daniel Vetter
  0 siblings, 0 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-14 11:12 UTC (permalink / raw)
  To: Lyude Paul
  Cc: Ser, Simon, Maxime Ripard, intel-gfx, dri-devel, Gwan-gyeong Mun,
	Paul Kocialkowski, David Airlie, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

On Mon, May 13, 2019 at 11:20 PM Lyude Paul <lyude@redhat.com> wrote:
>
> Hi-just wanted to give some general thoughts here.
>
> First off I'm 100% behind the epoch idea, that was one of the ideas I had been
> thinking of proposing here in the first place but probably forgot at some
> point down the road.
>
> A couple of other things:
>  * I think it would also probably be good to have events for when connectors
>    are added or removed from the system (mainly for MST)

Current uevent + userspace looks at the connector list from
drmGetResources? That should be enough to figure this out I think ...

>  * Have we considered having any sort of SYNC event, like what evdev uses for
>    signaling the end of a frame of events for input devices?

If we go with just 1 event, then that's the natural sync marker
stating "everything we updated for this connector is now updated". For
more global events the global uevent could serve that role (I guess
this is useful for hotpluggin/unpluggin entire mst chains - we might
want to coalesce these indeed).

I also don't think we need to make this an uapi guarantee, just best
effort kernel implementation - userspace needs to always be able to
deal with an event right after the one it's just processing.
-Daniel

>
> On Fri, 2019-05-10 at 14:12 +0200, Paul Kocialkowski wrote:
> > Hi,
> >
> > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > DRM API for generating uevent for a status changes of connector's
> > > property.
> > >
> > > This uevent will have following details related to the status change:
> > >
> > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > >
> > > Need ACK from this uevent from userspace consumer.
> >
> > So we just had some discussions over on IRC and at about the hotplug
> > issue and came up with similar ideas:
> > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> >
> > The conclusions of these discussions so far would be to have a more or
> > less fine grain of uevent reporting depending on what happened. The
> > point is that we need to cover different cases:
> > - one or more properties changed;
> > - the connector status changed;
> > - something else about the connector changed (e.g. EDID/modes)
> >
> > For the first case, we can send out:
> > HOTPLUG=1
> > CONNECTOR=<id>
> > PROPERTY=<id>
> >
> > and no reprobe is required.
> >
> > For the second one, something like:
> > HOTPLUG=1
> > CONNECTOR=<id>
> > STATUS=Connected/Disconnected
> >
> > and a connector probe is needed for connected, but not for
> > disconnected;
> >
> > For the third one, we can only indicate the connector:
> > HOTPLUG=1
> > CONNECTOR=<id>
> >
> > and a reprobe of the connector is always needed
> >
> > Then we still have the legacy case:
> > HOTPLUG=1
> >
> > where userspace is expected to reprobe all the connectors.
> >
> > I think this would deserve to be a separate series on its own. So I am
> > proposing to take this one off your plate and come up with another
> > seres implementing this proposal. What do you think?
> >
> > Cheers,
> >
> > Paul
> >
> > > v2:
> > >   Minor fixes at KDoc comments [Daniel]
> > > v3:
> > >   Check the property is really attached with connector [Daniel]
> > >
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > >  include/drm/drm_sysfs.h     |  5 ++++-
> > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > index 18b1ac442997..63fa951a20db 100644
> > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > @@ -21,6 +21,7 @@
> > >  #include <drm/drm_sysfs.h>
> > >  #include <drm/drmP.h>
> > >  #include "drm_internal.h"
> > > +#include "drm_crtc_internal.h"
> > >
> > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > >   * deal with other types of events.
> > > + *
> > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > + * for uevents on connector status change.
> > >   */
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  {
> > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  }
> > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > >
> > > +/**
> > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > + * property status change
> > > + * @connector: connector on which property status changed
> > > + * @property: connector property whoes status changed.
> > > + *
> > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > + * related to the status change.
> > > + */
> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +                                 struct drm_property *property)
> > > +{
> > > +   struct drm_device *dev = connector->dev;
> > > +   char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > +   char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > +
> > > +   WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > +                                      property->base.id));
> > > +
> > > +   snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > +            "CONNECTOR=%u", connector->base.id);
> > > +   snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > +            "PROPERTY=%u", property->base.id);
> > > +
> > > +   DRM_DEBUG("generating connector status event\n");
> > > +
> > > +   kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > +}
> > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > +
> > >  static void drm_sysfs_release(struct device *dev)
> > >  {
> > >     kfree(dev);
> > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > index 4f311e836cdc..d454ef617b2c 100644
> > > --- a/include/drm/drm_sysfs.h
> > > +++ b/include/drm/drm_sysfs.h
> > > @@ -4,10 +4,13 @@
> > >
> > >  struct drm_device;
> > >  struct device;
> > > +struct drm_connector;
> > > +struct drm_property;
> > >
> > >  int drm_class_device_register(struct device *dev);
> > >  void drm_class_device_unregister(struct device *dev);
> > >
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > -
> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +                                 struct drm_property *property);
> > >  #endif
> --
> Cheers,
>         Lyude Paul
>


-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 11:02               ` Daniel Vetter
@ 2019-05-14 13:36                 ` Pekka Paalanen
  2019-05-14 13:58                   ` Paul Kocialkowski
  2019-05-14 14:34                   ` Daniel Vetter
  0 siblings, 2 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-14 13:36 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: paul.kocialkowski, maxime.ripard, intel-gfx, dri-devel, Mun,
	Gwan-gyeong, Ser, Simon, airlied, thomas.petazzoni, Vetter,
	Daniel, sean


[-- Attachment #1.1: Type: text/plain, Size: 7309 bytes --]

On Tue, 14 May 2019 13:02:09 +0200
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:
> >
> > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:  
> > > On Mon, 13 May 2019 11:34:58 +0200
> > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >  
> > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > > Hi,
> > > > >
> > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:  
> > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:  
> > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > property.
> > > > > > > >
> > > > > > > > This uevent will have following details related to the status change:
> > > > > > > >
> > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > >
> > > > > > > > Need ACK from this uevent from userspace consumer.  
> > > > > > >
> > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > issue and came up with similar ideas:
> > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > >
> > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > point is that we need to cover different cases:
> > > > > > > - one or more properties changed;
> > > > > > > - the connector status changed;
> > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > >
> > > > > > > For the first case, we can send out:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > > PROPERTY=<id>
> > > > > > >
> > > > > > > and no reprobe is required.
> > > > > > >
> > > > > > > For the second one, something like:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > > STATUS=Connected/Disconnected
> > > > > > >
> > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > disconnected;
> > > > > > >
> > > > > > > For the third one, we can only indicate the connector:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > >
> > > > > > > and a reprobe of the connector is always needed  
> > > > > >
> > > > > > There's no material difference between this one and the previous one.
> > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.  
> > > > >
> > > > > That's the idea, but we need to handle status changes differently than
> > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > exposed as a prop for the connector.  
> > > >
> > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > into a property. Or another excuse why we should expose the epoch
> > > > property :-)  
> > >
> > > Hi Daniel,
> > >
> > > just to clarify the first case, specific to one very particular
> > > property:
> > >
> > > With HDCP, there is a property that may change dynamically at runtime
> > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > when it changes, I do not want userspace have to poll that property
> > > with a timer.
> > >
> > > When that property alone changes, and userspace is prepared to handle
> > > that property changing alone, it must not trigger a reprobe of the
> > > connector. There is no reason to reprobe at that point AFAIU.
> > >
> > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > epoch approach or with any alternate uevent design?
> > >
> > > We need an event to userspace that indicates that re-reading the
> > > properties is enough and reprobe of the connector is not necessary.
> > > This is complementary to indicating to userspace that only some
> > > connectors need to be reprobed instead of everything.  
> >
> > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > reprobing. Would that work?  

Hi,

yes, that would work, if it was acceptable to DRM upstream. The replies
to Paul seemed to be going south so fast that I thought we wouldn't get
any new uevent fields in favour of "epoch counters".

> Yes that's the idea, depending upon which property you get you know
> it's a sink change (needs full reprobe) or something else like hdcp
> state machinery update.

Right.

> Wrt avoiding the full reprobe for sink changes: I think we should
> indeed decouple that from the per-connector event for sink changes.
> That along is a good win already, since you know for which connector
> you need to call drmGetConnector (which forces the reprobe). It would
> be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> historically speaking every time we tried to rely on this we ended up
> regretting things.

What changed? This sounds very much what Paul suggested. Looking at it
from userspace side:

HOTPLUG=1 CONNECTOR=xx PROPERTY=yy

- If yy is "Content Protection", no need to drmModeGetConnector(), just
  re-get the connector properties.

- Kernel probably shouldn't bother sending this for properties where
  re-probe could be necessary, and send the below instead.

HOTPLUG=1 CONNECTOR=xx

- Needs to drmModeGetConnector() on the one connector, no need to probe
  others. Implies that one needs to re-get the connector properties as
  well.

HOTPLUG=1

- Need to do drmModeGetResouces() to discover new/disappeared
  connectors, and need to drmModeGetConnector to re-probe every
  connector. (As always.)

That should be also backwards-compatible: any userspace that doesn't
understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
userspace that doesn't understand PROPERTY or the property it refers to
will fall back to probing either the connector or everything.

I would be happy to get that behaviour into Weston, particularly as the
HDCP feature is brewing for Weston too.

--------

When discussing this in IRC, I had the concern about how uevents are
delivered in userspace. Is there a possibility that they might be
overwritten, contain stale attributes, or get squashed together?

Particularly if a display server is current on the VT and active and
monitoring udev, but stuck doing something and cannot service uevents
very fast, and the kernel sends more than one event before the process
gets back to dispatching. The terminology in libudev API confused me as
an event is a device. Squashing together would make sense if the
uevent were just updating a device attribute list. Previously when we
had just a single kind of uevent, that would not have made a
difference, but if we gain different kinds of uevents like here, it
starts to matter.

However, Paul came to the conclusion that we will be ok as long as the
events come via netlink.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 13:36                 ` Pekka Paalanen
@ 2019-05-14 13:58                   ` Paul Kocialkowski
  2019-05-14 14:34                   ` Daniel Vetter
  1 sibling, 0 replies; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-14 13:58 UTC (permalink / raw)
  To: Pekka Paalanen, Daniel Vetter
  Cc: airlied, maxime.ripard, intel-gfx, dri-devel, Ser, Simon,
	thomas.petazzoni, Vetter, Daniel

Hi,

On Tue, 2019-05-14 at 16:36 +0300, Pekka Paalanen wrote:
> On Tue, 14 May 2019 13:02:09 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> 
> > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:
> > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:  
> > > > On Mon, 13 May 2019 11:34:58 +0200
> > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > >  
> > > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > > > Hi,
> > > > > > 
> > > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:  
> > > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > > <paul.kocialkowski@bootlin.com> wrote:  
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:  
> > > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > > property.
> > > > > > > > > 
> > > > > > > > > This uevent will have following details related to the status change:
> > > > > > > > > 
> > > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > > > 
> > > > > > > > > Need ACK from this uevent from userspace consumer.  
> > > > > > > > 
> > > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > > issue and came up with similar ideas:
> > > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > > > 
> > > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > > point is that we need to cover different cases:
> > > > > > > > - one or more properties changed;
> > > > > > > > - the connector status changed;
> > > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > > > 
> > > > > > > > For the first case, we can send out:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > PROPERTY=<id>
> > > > > > > > 
> > > > > > > > and no reprobe is required.
> > > > > > > > 
> > > > > > > > For the second one, something like:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > STATUS=Connected/Disconnected
> > > > > > > > 
> > > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > > disconnected;
> > > > > > > > 
> > > > > > > > For the third one, we can only indicate the connector:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > 
> > > > > > > > and a reprobe of the connector is always needed  
> > > > > > > 
> > > > > > > There's no material difference between this one and the previous one.
> > > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.  
> > > > > > 
> > > > > > That's the idea, but we need to handle status changes differently than
> > > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > > exposed as a prop for the connector.  
> > > > > 
> > > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > > into a property. Or another excuse why we should expose the epoch
> > > > > property :-)  
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > just to clarify the first case, specific to one very particular
> > > > property:
> > > > 
> > > > With HDCP, there is a property that may change dynamically at runtime
> > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > when it changes, I do not want userspace have to poll that property
> > > > with a timer.
> > > > 
> > > > When that property alone changes, and userspace is prepared to handle
> > > > that property changing alone, it must not trigger a reprobe of the
> > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > 
> > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > epoch approach or with any alternate uevent design?
> > > > 
> > > > We need an event to userspace that indicates that re-reading the
> > > > properties is enough and reprobe of the connector is not necessary.
> > > > This is complementary to indicating to userspace that only some
> > > > connectors need to be reprobed instead of everything.  
> > > 
> > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > reprobing. Would that work?  
> 
> Hi,
> 
> yes, that would work, if it was acceptable to DRM upstream. The replies
> to Paul seemed to be going south so fast that I thought we wouldn't get
> any new uevent fields in favour of "epoch counters".
> 
> > Yes that's the idea, depending upon which property you get you know
> > it's a sink change (needs full reprobe) or something else like hdcp
> > state machinery update.
> 
> Right.
> 
> > Wrt avoiding the full reprobe for sink changes: I think we should
> > indeed decouple that from the per-connector event for sink changes.
> > That along is a good win already, since you know for which connector
> > you need to call drmGetConnector (which forces the reprobe). It would
> > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > historically speaking every time we tried to rely on this we ended up
> > regretting things.
> 
> What changed? This sounds very much what Paul suggested. Looking at it
> from userspace side:
> 
> HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> 
> - If yy is "Content Protection", no need to drmModeGetConnector(), just
>   re-get the connector properties.
> 
> - Kernel probably shouldn't bother sending this for properties where
>   re-probe could be necessary, and send the below instead.
> 
> HOTPLUG=1 CONNECTOR=xx
> 
> - Needs to drmModeGetConnector() on the one connector, no need to probe
>   others. Implies that one needs to re-get the connector properties as
>   well.
> 
> HOTPLUG=1
> 
> - Need to do drmModeGetResouces() to discover new/disappeared
>   connectors, and need to drmModeGetConnector to re-probe every
>   connector. (As always.)
> 
> That should be also backwards-compatible: any userspace that doesn't
> understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> userspace that doesn't understand PROPERTY or the property it refers to
> will fall back to probing either the connector or everything.
> 
> I would be happy to get that behaviour into Weston, particularly as the
> HDCP feature is brewing for Weston too.
> 
> --------
> 
> When discussing this in IRC, I had the concern about how uevents are
> delivered in userspace. Is there a possibility that they might be
> overwritten, contain stale attributes, or get squashed together?
> 
> Particularly if a display server is current on the VT and active and
> monitoring udev, but stuck doing something and cannot service uevents
> very fast, and the kernel sends more than one event before the process
> gets back to dispatching. The terminology in libudev API confused me as
> an event is a device. Squashing together would make sense if the
> uevent were just updating a device attribute list. Previously when we
> had just a single kind of uevent, that would not have made a
> difference, but if we gain different kinds of uevents like here, it
> starts to matter.
> 
> However, Paul came to the conclusion that we will be ok as long as the
> events come via netlink.

Yes, basically netlink is fine and uevent file polling is not. If the
application is too slow to service new udev devices (events), I'm
pretty sure they get queued if they come from netlink. It's only when
not using netlink with udev (not sure when that really happens, and the
info doesn't seem to be exposed to the application) that the latest
contents are read from the uevent file.

The way I see it, we should put the assumption that userspace will get
all our events or just figure it out on its own with the epoch counter.
It's a notification mechanism, and I think we should count on the fact
that userspace can reliably get notified that way (not to say it has to
be the only way, the epoch counter can provide a polling-ish
alternative).

Cheers and thanks for the recap,

Paul

-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 11:09             ` Daniel Vetter
@ 2019-05-14 14:12               ` Paul Kocialkowski
  2019-05-14 14:28                 ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-14 14:12 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel, Ser, Simon,
	Pekka Paalanen, Thomas Petazzoni, Daniel Vetter

Hi,

On Tue, 2019-05-14 at 13:09 +0200, Daniel Vetter wrote:
> On Mon, May 13, 2019 at 7:14 PM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> > Hey,
> > 
> > Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hi,
> > > > 
> > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > Hi,
> > > > > > 
> > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > property.
> > > > > > > 
> > > > > > > This uevent will have following details related to the status change:
> > > > > > > 
> > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > 
> > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > 
> > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > issue and came up with similar ideas:
> > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > 
> > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > point is that we need to cover different cases:
> > > > > > - one or more properties changed;
> > > > > > - the connector status changed;
> > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > 
> > > > > > For the first case, we can send out:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > PROPERTY=<id>
> > > > > > 
> > > > > > and no reprobe is required.
> > > > > > 
> > > > > > For the second one, something like:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > STATUS=Connected/Disconnected
> > > > > > 
> > > > > > and a connector probe is needed for connected, but not for
> > > > > > disconnected;
> > > > > > 
> > > > > > For the third one, we can only indicate the connector:
> > > > > > HOTPLUG=1
> > > > > > CONNECTOR=<id>
> > > > > > 
> > > > > > and a reprobe of the connector is always needed
> > > > > 
> > > > > There's no material difference between this one and the previous one.
> > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > 
> > > > That's the idea, but we need to handle status changes differently than
> > > > properties, since as far as I know, connected/unconnected status is not
> > > > exposed as a prop for the connector.
> > > 
> > > Oops, totally missed that. "Everything is a property" is kinda
> > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > into a property. Or another excuse why we should expose the epoch
> > > property :-)
> > 
> > Well I think it would make sense anyway, as long as we can make sure it
> > stays consistent with the one reported in the connector struct.
> > 
> > > > > Here's why:
> > > > > - A side effect of forcing a probe on a connector is that you get to
> > > > > read all the properties, so supplying them is kinda pointless.
> > > > 
> > > > Agreed, except for the status case where it's useful to know it's a
> > > > disconnect, because we don't need any probe step in that case.
> > > > 
> > > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > > reasonable unfortunately, but oh well.
> > > > 
> > > > How would that be retreived then? From the looks of it, that's a
> > > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > > does the full reprobe.
> > > 
> > > drmGetConnector vs drmGetConnectorCurrent.
> > 
> > Ah right, forgot about that one, thanks.
> > 
> > > > Not sure what issues could arise in case of disconnect without reprobe
> > > > -- at least I don't see why userspace should have to do anything in
> > > > particular except no longer using the connector, even in complex DP MST
> > > > cases.
> > > 
> > > connector->status might be a lie without a full reprobe, and wrongly
> > > indicate that the connector is disconnected while there's still
> > > something plugged in. I'm not sure we've fixed those bugs by now
> > > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > > connected, and we can't break this because every intel platform ever
> > > shipped has a few devices where this is somehow broken, irrespective
> > > of the sink).
> > 
> > Mhh either way, I think it's up to the driver to report that and make
> > it consistent. I think we have poll helpers to make up for cases where
> > hotplug is not available too. So I'm not sure why a full reprobe would
> > be needed: drivers just need to do the right thing.
> > 
> > > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > > everything with the current ioctl and implementations. Having an
> > > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > > almost all cases).
> > > > 
> > > > Agreed.
> > > > 
> > > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > > needs to reprobe this connector.
> > > > 
> > > > I thought we could access the props alone, which avoids doing a reprobe
> > > > when the kernel knows that only a prop or a set of props changed and do
> > > > not require a full reprobe. That's the first case I was mentionning.
> > > > 
> > > > > At that point we need to figure out whether this is a good uapi or
> > > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > > epoch:
> > > > > - We need it internally because I'm not goinig to wire a new return
> > > > > value through hundreds of connector probe functions. It's much easier
> > > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > > similar functions that update probe state.
> > > > 
> > > > I don't think I'm following what issue this is trying to solve
> > > > internally.
> > > 
> > > So I'm assuming that if we handle a hotplug, we only want to generate
> > > one uevent for that, not one for every little thing that changed.
> > > There's two ways to implement this logic:
> > > - With some epoch counter and a helper function you can call everytime
> > > something changed (e.g. status, or edid, or anything else we care
> > > about e.g. from dp aux). This won't need much (if any) driver changes,
> > > because we can just put these into the relevant helper/core functions
> > > (like edid update, or dp aux reading or whatever).
> > > - Wiring a new return value through the entire stack (and _all_ the
> > > kms drivers) so that the probe helpers could aggregate this like they
> > > currently do.
> > > 
> > > One of these is a lot less typing.
> > 
> > Oh I had missed this issue. Yeah of course if we start reporting
> > property changes, a hotplug will be lots of such changes.
> > 
> > So an epoch counter property would indeed also solve the reprobing
> > problem. But I think it would be nice to keep the ability to be
> > notified of what changed precisely via uevent. I'm not really buying
> > the "missing uevent" thing so much and I think we can reasonably expect
> > that it will be useful. Events could be aggregated (which the epoch
> > counter would probably also allow) and sent out altogether when the
> > connector status changes (along with the status information). I think
> > we're under-using uevent currently, and feel like this should be fixed
> > regardless of the full reprobe issue.
> 
> I see two options:
> 
> 1) kernel aggregates uevents a bit, and sends out one (per connector
> that changed) indicating that sink related state changed. Userspace
> listens to that, and does a drmGetConnector as a result to update
> itself. Most of this code needs to exist anyway.
>
> 2) kernel sends out updates as we go, userspace reassembles everything
> again (and not really an idea when all the updates are in, see Lyude's
> question. Plus userspace still needs to have the drmGetConnector path,
> at least for initial setup.
> 
> I don't see why 2) is any better than 1), and it has some clear downsides.

My main point is that when the kernel knows some individual property
changed, it should update its internal state and report what prop
changed *in cases that don't require a full reprobe* and report only
which connector changed when a connector reprobe is needed anyway.

Maybe we could even have quirks for drivers to indicate that common
actions that shouldn't require a reprobe actually do for this driver in
particular, because of whatever instability we want to be confident
about handling. I believe this should be abstracted away in DRM and not
reflected on the userspace API.

So it's not just about providing per-property updates, the updates
reported this way have to be "standalone" and never imply that anything
else about the connector's state could have change. Driver's guarantee.

> > With that, I agree that a global epoch counter from the connector would
> > be a good quick way for userspace to tell if a connector changed or not
> > since the last time it checked.
> > 
> > > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > > switched away we probably don't want to piss of the current compositor
> > > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > > it can read the epoch property (which it can do without forcing a
> > > > > reprobe) userspace would know which connectors it needs to check and
> > > > > reprobe.
> > > > > 
> > > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > > also require that userspace needs to keep parsing all uevents and make
> > > > > a list of all connectors it needs to reprobe when it's back to being
> > > > > the active compositor. But just comparing a current epoch with the one
> > > > > you cached from the last full probe is much easier.
> > > > 
> > > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > > we could also provide extra info in the uevent when relevant and not
> > > > rely on that entirely.
> > > 
> > > See above, with drmGetConnectorCurrent there's no need to provide more
> > > than what's needed in the uevent, since userspace can get everything
> > > else at the cost of one ioctl, without reprobing. With a bit of
> > > engineering work we could even avoid taking the expensive
> > > dev->mode_config.mutex lock for this fastpath.
> > > 
> > > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > > need to reprobe when the user asks for it. igt can probably get away
> > > > > without reprobing.
> > > > 
> > > > I wonder how that is handled currently and how a user action can solve
> > > > the issue without any notification from the kernel. Maybe a need a
> > > > better understanding of that case to have a clearer idea.
> > > 
> > > User opens the screen configuration tool -> usually at that point the
> > > tool/compositor force a full reprobe, which then often triggers the
> > > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > > random shit projectors at conferences nothing happens, until I run
> > > xrandr, which triggers the full reprobe, which then makes the kernel
> > > realize something change, sending and uevent, which starts the
> > > automatic reconfigure machinery.
> > 
> > Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
> > to get me out of an off-panel situation much too often.
> > 
> > > There's also the issue that there's machines with hpd storms (even on
> > > DP, where you really need hpd to work to be compliant), and we have to
> > > turn of the hpd irq to keep the machine useable.
> > 
> > I was under the impression that we switch to polling when a hpd storm
> > is detected in i915 (but that's a vague memory from my summer
> > internship at Intel 2 years ago).
> 
> We do poll, but the issue is still that polling doesn't do the same
> thing as full reprobe. One just calls ->detect, the other ->detect +
> ->get_modes. This is a bit a silliness of the helpers and source of
> lots of confusion. A possible fix might be to always call both.

I think that would make a lot of sense. I don't really get why we have
to wait for userspace to do a reprobe to get the new modes when the
kernel can be absolutely sure that the modes changed and need to be
refreshed.

> Plus even when that mess is sorted there's still the issue of broken
> hw, and we have no idea how much/where/which exactly. Except that
> every time we relied on hpd status, we got regression reports and had
> to revert.

I think we could configure the notification behavior per-driver and
some events that wouldn't require a full probe on some drivers could do
so on other drivers. Userspace should find out whether to reprobe or
not dynamically based on what's in the uevent anyway, so it's not even
an inconsistency in the interface that 2 events be reported differently
in 2 drivers. I think that'd be better than the current situation we're
in anyway. If some drivers want be paranoid and always ask for
a reprobe of the connectors because of unreliable hw, their choice.

Cheers,

Paul

> -Daniel
> 
> > Cheers,
> > 
> > Paul
> > 
> > > Cheers, Daniel
> > > 
> > > > Cheers,
> > > > 
> > > > Paul
> > > > 
> > > > > -Daniel
> > > > > 
> > > > > > Then we still have the legacy case:
> > > > > > HOTPLUG=1
> > > > > > 
> > > > > > where userspace is expected to reprobe all the connectors.
> > > > > > 
> > > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > > proposing to take this one off your plate and come up with another
> > > > > > seres implementing this proposal. What do you think?
> > > > > > 
> > > > > > Cheers,
> > > > > > 
> > > > > > Paul
> > > > > > 
> > > > > > > v2:
> > > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > > v3:
> > > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > > 
> > > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > @@ -21,6 +21,7 @@
> > > > > > >  #include <drm/drm_sysfs.h>
> > > > > > >  #include <drm/drmP.h>
> > > > > > >  #include "drm_internal.h"
> > > > > > > +#include "drm_crtc_internal.h"
> > > > > > > 
> > > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > > >   * deal with other types of events.
> > > > > > > + *
> > > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > > + * for uevents on connector status change.
> > > > > > >   */
> > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > >  {
> > > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > >  }
> > > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > > 
> > > > > > > +/**
> > > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > > + * property status change
> > > > > > > + * @connector: connector on which property status changed
> > > > > > > + * @property: connector property whoes status changed.
> > > > > > > + *
> > > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > > + * related to the status change.
> > > > > > > + */
> > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > +                                   struct drm_property *property)
> > > > > > > +{
> > > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > > +
> > > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > > +                                        property->base.id));
> > > > > > > +
> > > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > > +
> > > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > > +
> > > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > > +}
> > > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > > +
> > > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > > >  {
> > > > > > >       kfree(dev);
> > > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > > @@ -4,10 +4,13 @@
> > > > > > > 
> > > > > > >  struct drm_device;
> > > > > > >  struct device;
> > > > > > > +struct drm_connector;
> > > > > > > +struct drm_property;
> > > > > > > 
> > > > > > >  int drm_class_device_register(struct device *dev);
> > > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > > 
> > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > > -
> > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > +                                   struct drm_property *property);
> > > > > > >  #endif
> > > > > > --
> > > > > > Paul Kocialkowski, Bootlin
> > > > > > Embedded Linux and kernel engineering
> > > > > > https://bootlin.com
> > > > > > 
> > > > --
> > > > Paul Kocialkowski, Bootlin
> > > > Embedded Linux and kernel engineering
> > > > https://bootlin.com
> > > > 
> 
> 
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 14:12               ` Paul Kocialkowski
@ 2019-05-14 14:28                 ` Daniel Vetter
  2019-05-15  7:43                   ` Paul Kocialkowski
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-14 14:28 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel, Ser, Simon,
	Pekka Paalanen, Thomas Petazzoni, Daniel Vetter

On Tue, May 14, 2019 at 4:13 PM Paul Kocialkowski
<paul.kocialkowski@bootlin.com> wrote:
>
> Hi,
>
> On Tue, 2019-05-14 at 13:09 +0200, Daniel Vetter wrote:
> > On Mon, May 13, 2019 at 7:14 PM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hey,
> > >
> > > Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > Hi,
> > > > >
> > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > property.
> > > > > > > >
> > > > > > > > This uevent will have following details related to the status change:
> > > > > > > >
> > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > >
> > > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > >
> > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > issue and came up with similar ideas:
> > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > >
> > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > point is that we need to cover different cases:
> > > > > > > - one or more properties changed;
> > > > > > > - the connector status changed;
> > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > >
> > > > > > > For the first case, we can send out:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > > PROPERTY=<id>
> > > > > > >
> > > > > > > and no reprobe is required.
> > > > > > >
> > > > > > > For the second one, something like:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > > STATUS=Connected/Disconnected
> > > > > > >
> > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > disconnected;
> > > > > > >
> > > > > > > For the third one, we can only indicate the connector:
> > > > > > > HOTPLUG=1
> > > > > > > CONNECTOR=<id>
> > > > > > >
> > > > > > > and a reprobe of the connector is always needed
> > > > > >
> > > > > > There's no material difference between this one and the previous one.
> > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > >
> > > > > That's the idea, but we need to handle status changes differently than
> > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > exposed as a prop for the connector.
> > > >
> > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > into a property. Or another excuse why we should expose the epoch
> > > > property :-)
> > >
> > > Well I think it would make sense anyway, as long as we can make sure it
> > > stays consistent with the one reported in the connector struct.
> > >
> > > > > > Here's why:
> > > > > > - A side effect of forcing a probe on a connector is that you get to
> > > > > > read all the properties, so supplying them is kinda pointless.
> > > > >
> > > > > Agreed, except for the status case where it's useful to know it's a
> > > > > disconnect, because we don't need any probe step in that case.
> > > > >
> > > > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > > > reasonable unfortunately, but oh well.
> > > > >
> > > > > How would that be retreived then? From the looks of it, that's a
> > > > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > > > does the full reprobe.
> > > >
> > > > drmGetConnector vs drmGetConnectorCurrent.
> > >
> > > Ah right, forgot about that one, thanks.
> > >
> > > > > Not sure what issues could arise in case of disconnect without reprobe
> > > > > -- at least I don't see why userspace should have to do anything in
> > > > > particular except no longer using the connector, even in complex DP MST
> > > > > cases.
> > > >
> > > > connector->status might be a lie without a full reprobe, and wrongly
> > > > indicate that the connector is disconnected while there's still
> > > > something plugged in. I'm not sure we've fixed those bugs by now
> > > > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > > > connected, and we can't break this because every intel platform ever
> > > > shipped has a few devices where this is somehow broken, irrespective
> > > > of the sink).
> > >
> > > Mhh either way, I think it's up to the driver to report that and make
> > > it consistent. I think we have poll helpers to make up for cases where
> > > hotplug is not available too. So I'm not sure why a full reprobe would
> > > be needed: drivers just need to do the right thing.
> > >
> > > > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > > > everything with the current ioctl and implementations. Having an
> > > > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > > > almost all cases).
> > > > >
> > > > > Agreed.
> > > > >
> > > > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > > > needs to reprobe this connector.
> > > > >
> > > > > I thought we could access the props alone, which avoids doing a reprobe
> > > > > when the kernel knows that only a prop or a set of props changed and do
> > > > > not require a full reprobe. That's the first case I was mentionning.
> > > > >
> > > > > > At that point we need to figure out whether this is a good uapi or
> > > > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > > > epoch:
> > > > > > - We need it internally because I'm not goinig to wire a new return
> > > > > > value through hundreds of connector probe functions. It's much easier
> > > > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > > > similar functions that update probe state.
> > > > >
> > > > > I don't think I'm following what issue this is trying to solve
> > > > > internally.
> > > >
> > > > So I'm assuming that if we handle a hotplug, we only want to generate
> > > > one uevent for that, not one for every little thing that changed.
> > > > There's two ways to implement this logic:
> > > > - With some epoch counter and a helper function you can call everytime
> > > > something changed (e.g. status, or edid, or anything else we care
> > > > about e.g. from dp aux). This won't need much (if any) driver changes,
> > > > because we can just put these into the relevant helper/core functions
> > > > (like edid update, or dp aux reading or whatever).
> > > > - Wiring a new return value through the entire stack (and _all_ the
> > > > kms drivers) so that the probe helpers could aggregate this like they
> > > > currently do.
> > > >
> > > > One of these is a lot less typing.
> > >
> > > Oh I had missed this issue. Yeah of course if we start reporting
> > > property changes, a hotplug will be lots of such changes.
> > >
> > > So an epoch counter property would indeed also solve the reprobing
> > > problem. But I think it would be nice to keep the ability to be
> > > notified of what changed precisely via uevent. I'm not really buying
> > > the "missing uevent" thing so much and I think we can reasonably expect
> > > that it will be useful. Events could be aggregated (which the epoch
> > > counter would probably also allow) and sent out altogether when the
> > > connector status changes (along with the status information). I think
> > > we're under-using uevent currently, and feel like this should be fixed
> > > regardless of the full reprobe issue.
> >
> > I see two options:
> >
> > 1) kernel aggregates uevents a bit, and sends out one (per connector
> > that changed) indicating that sink related state changed. Userspace
> > listens to that, and does a drmGetConnector as a result to update
> > itself. Most of this code needs to exist anyway.
> >
> > 2) kernel sends out updates as we go, userspace reassembles everything
> > again (and not really an idea when all the updates are in, see Lyude's
> > question. Plus userspace still needs to have the drmGetConnector path,
> > at least for initial setup.
> >
> > I don't see why 2) is any better than 1), and it has some clear downsides.
>
> My main point is that when the kernel knows some individual property
> changed, it should update its internal state and report what prop
> changed *in cases that don't require a full reprobe* and report only
> which connector changed when a connector reprobe is needed anyway.
>
> Maybe we could even have quirks for drivers to indicate that common
> actions that shouldn't require a reprobe actually do for this driver in
> particular, because of whatever instability we want to be confident
> about handling. I believe this should be abstracted away in DRM and not
> reflected on the userspace API.
>
> So it's not just about providing per-property updates, the updates
> reported this way have to be "standalone" and never imply that anything
> else about the connector's state could have change. Driver's guarantee.

I'm not sure what that guarantee buys us. You can never assume that if
you get this event that only that property changed, since other stuff
might have changed meanwhile.
And especially for a sink change we know that a lot of properties
(including stuff like connector->status here that's not yet a
property) will have changed. And event with e.g. PROPERTY=epoch would
simply indicate that all the sink related things have been updated,
and you can get them with drmGetConnectorCurrent.

We also need some way to indicate that an entire batch of updates have
completed if we send out events for every part of this. Sending out
bigger events neatly sidesteps that issue.

> > > With that, I agree that a global epoch counter from the connector would
> > > be a good quick way for userspace to tell if a connector changed or not
> > > since the last time it checked.
> > >
> > > > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > > > switched away we probably don't want to piss of the current compositor
> > > > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > > > it can read the epoch property (which it can do without forcing a
> > > > > > reprobe) userspace would know which connectors it needs to check and
> > > > > > reprobe.
> > > > > >
> > > > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > > > also require that userspace needs to keep parsing all uevents and make
> > > > > > a list of all connectors it needs to reprobe when it's back to being
> > > > > > the active compositor. But just comparing a current epoch with the one
> > > > > > you cached from the last full probe is much easier.
> > > > >
> > > > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > > > we could also provide extra info in the uevent when relevant and not
> > > > > rely on that entirely.
> > > >
> > > > See above, with drmGetConnectorCurrent there's no need to provide more
> > > > than what's needed in the uevent, since userspace can get everything
> > > > else at the cost of one ioctl, without reprobing. With a bit of
> > > > engineering work we could even avoid taking the expensive
> > > > dev->mode_config.mutex lock for this fastpath.
> > > >
> > > > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > > > need to reprobe when the user asks for it. igt can probably get away
> > > > > > without reprobing.
> > > > >
> > > > > I wonder how that is handled currently and how a user action can solve
> > > > > the issue without any notification from the kernel. Maybe a need a
> > > > > better understanding of that case to have a clearer idea.
> > > >
> > > > User opens the screen configuration tool -> usually at that point the
> > > > tool/compositor force a full reprobe, which then often triggers the
> > > > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > > > random shit projectors at conferences nothing happens, until I run
> > > > xrandr, which triggers the full reprobe, which then makes the kernel
> > > > realize something change, sending and uevent, which starts the
> > > > automatic reconfigure machinery.
> > >
> > > Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
> > > to get me out of an off-panel situation much too often.
> > >
> > > > There's also the issue that there's machines with hpd storms (even on
> > > > DP, where you really need hpd to work to be compliant), and we have to
> > > > turn of the hpd irq to keep the machine useable.
> > >
> > > I was under the impression that we switch to polling when a hpd storm
> > > is detected in i915 (but that's a vague memory from my summer
> > > internship at Intel 2 years ago).
> >
> > We do poll, but the issue is still that polling doesn't do the same
> > thing as full reprobe. One just calls ->detect, the other ->detect +
> > ->get_modes. This is a bit a silliness of the helpers and source of
> > lots of confusion. A possible fix might be to always call both.
>
> I think that would make a lot of sense. I don't really get why we have
> to wait for userspace to do a reprobe to get the new modes when the
> kernel can be absolutely sure that the modes changed and need to be
> refreshed.

Don't let the names trick you, it's an entirely arbitrary split,
historically grown :-)

> > Plus even when that mess is sorted there's still the issue of broken
> > hw, and we have no idea how much/where/which exactly. Except that
> > every time we relied on hpd status, we got regression reports and had
> > to revert.
>
> I think we could configure the notification behavior per-driver and
> some events that wouldn't require a full probe on some drivers could do
> so on other drivers. Userspace should find out whether to reprobe or
> not dynamically based on what's in the uevent anyway, so it's not even
> an inconsistency in the interface that 2 events be reported differently
> in 2 drivers. I think that'd be better than the current situation we're
> in anyway. If some drivers want be paranoid and always ask for
> a reprobe of the connectors because of unreliable hw, their choice.

The problem isn't typing the code, it's making sure we don't break the
world with this. Even if you limit this to i915 alone. That's why I'm
suggesting we untangle things as much as possible, makes it easier to
do the (pretty much inevitable) revert.
-Daniel

> Cheers,
>
> Paul
>
> > -Daniel
> >
> > > Cheers,
> > >
> > > Paul
> > >
> > > > Cheers, Daniel
> > > >
> > > > > Cheers,
> > > > >
> > > > > Paul
> > > > >
> > > > > > -Daniel
> > > > > >
> > > > > > > Then we still have the legacy case:
> > > > > > > HOTPLUG=1
> > > > > > >
> > > > > > > where userspace is expected to reprobe all the connectors.
> > > > > > >
> > > > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > > > proposing to take this one off your plate and come up with another
> > > > > > > seres implementing this proposal. What do you think?
> > > > > > >
> > > > > > > Cheers,
> > > > > > >
> > > > > > > Paul
> > > > > > >
> > > > > > > > v2:
> > > > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > > > v3:
> > > > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > > >
> > > > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > @@ -21,6 +21,7 @@
> > > > > > > >  #include <drm/drm_sysfs.h>
> > > > > > > >  #include <drm/drmP.h>
> > > > > > > >  #include "drm_internal.h"
> > > > > > > > +#include "drm_crtc_internal.h"
> > > > > > > >
> > > > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > > > >   * deal with other types of events.
> > > > > > > > + *
> > > > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > > > + * for uevents on connector status change.
> > > > > > > >   */
> > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > >  {
> > > > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > >  }
> > > > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > > >
> > > > > > > > +/**
> > > > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > > > + * property status change
> > > > > > > > + * @connector: connector on which property status changed
> > > > > > > > + * @property: connector property whoes status changed.
> > > > > > > > + *
> > > > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > > > + * related to the status change.
> > > > > > > > + */
> > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > +                                   struct drm_property *property)
> > > > > > > > +{
> > > > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > > > +
> > > > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > > > +                                        property->base.id));
> > > > > > > > +
> > > > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > > > +
> > > > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > > > +
> > > > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > > > +}
> > > > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > > > +
> > > > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > > > >  {
> > > > > > > >       kfree(dev);
> > > > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > > > @@ -4,10 +4,13 @@
> > > > > > > >
> > > > > > > >  struct drm_device;
> > > > > > > >  struct device;
> > > > > > > > +struct drm_connector;
> > > > > > > > +struct drm_property;
> > > > > > > >
> > > > > > > >  int drm_class_device_register(struct device *dev);
> > > > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > > >
> > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > > > -
> > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > +                                   struct drm_property *property);
> > > > > > > >  #endif
> > > > > > > --
> > > > > > > Paul Kocialkowski, Bootlin
> > > > > > > Embedded Linux and kernel engineering
> > > > > > > https://bootlin.com
> > > > > > >
> > > > > --
> > > > > Paul Kocialkowski, Bootlin
> > > > > Embedded Linux and kernel engineering
> > > > > https://bootlin.com
> > > > >
> >
> >
> --
> Paul Kocialkowski, Bootlin
> Embedded Linux and kernel engineering
> https://bootlin.com
>


-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 13:36                 ` Pekka Paalanen
  2019-05-14 13:58                   ` Paul Kocialkowski
@ 2019-05-14 14:34                   ` Daniel Vetter
  2019-05-15  7:37                     ` Pekka Paalanen
  1 sibling, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-14 14:34 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, maxime.ripard, intel-gfx, dri-devel, Mun,
	Gwan-gyeong, paul.kocialkowski, airlied, thomas.petazzoni,
	Vetter, Daniel, sean

On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
>
> On Tue, 14 May 2019 13:02:09 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:
> > >
> > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:
> > > > On Mon, 13 May 2019 11:34:58 +0200
> > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > >
> > > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > Hi,
> > > > > >
> > > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > > property.
> > > > > > > > >
> > > > > > > > > This uevent will have following details related to the status change:
> > > > > > > > >
> > > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > > >
> > > > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > > >
> > > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > > issue and came up with similar ideas:
> > > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > > >
> > > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > > point is that we need to cover different cases:
> > > > > > > > - one or more properties changed;
> > > > > > > > - the connector status changed;
> > > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > > >
> > > > > > > > For the first case, we can send out:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > PROPERTY=<id>
> > > > > > > >
> > > > > > > > and no reprobe is required.
> > > > > > > >
> > > > > > > > For the second one, something like:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > STATUS=Connected/Disconnected
> > > > > > > >
> > > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > > disconnected;
> > > > > > > >
> > > > > > > > For the third one, we can only indicate the connector:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > >
> > > > > > > > and a reprobe of the connector is always needed
> > > > > > >
> > > > > > > There's no material difference between this one and the previous one.
> > > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > > >
> > > > > > That's the idea, but we need to handle status changes differently than
> > > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > > exposed as a prop for the connector.
> > > > >
> > > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > > into a property. Or another excuse why we should expose the epoch
> > > > > property :-)
> > > >
> > > > Hi Daniel,
> > > >
> > > > just to clarify the first case, specific to one very particular
> > > > property:
> > > >
> > > > With HDCP, there is a property that may change dynamically at runtime
> > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > when it changes, I do not want userspace have to poll that property
> > > > with a timer.
> > > >
> > > > When that property alone changes, and userspace is prepared to handle
> > > > that property changing alone, it must not trigger a reprobe of the
> > > > connector. There is no reason to reprobe at that point AFAIU.
> > > >
> > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > epoch approach or with any alternate uevent design?
> > > >
> > > > We need an event to userspace that indicates that re-reading the
> > > > properties is enough and reprobe of the connector is not necessary.
> > > > This is complementary to indicating to userspace that only some
> > > > connectors need to be reprobed instead of everything.
> > >
> > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > reprobing. Would that work?
>
> Hi,
>
> yes, that would work, if it was acceptable to DRM upstream. The replies
> to Paul seemed to be going south so fast that I thought we wouldn't get
> any new uevent fields in favour of "epoch counters".
>
> > Yes that's the idea, depending upon which property you get you know
> > it's a sink change (needs full reprobe) or something else like hdcp
> > state machinery update.
>
> Right.
>
> > Wrt avoiding the full reprobe for sink changes: I think we should
> > indeed decouple that from the per-connector event for sink changes.
> > That along is a good win already, since you know for which connector
> > you need to call drmGetConnector (which forces the reprobe). It would
> > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > historically speaking every time we tried to rely on this we ended up
> > regretting things.
>
> What changed? This sounds very much what Paul suggested. Looking at it
> from userspace side:

This sounds solid, some refinements below:

> HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
>
> - If yy is "Content Protection", no need to drmModeGetConnector(), just
>   re-get the connector properties.
>
> - Kernel probably shouldn't bother sending this for properties where
>   re-probe could be necessary, and send the below instead.


I think we should assert that the kernel can get the new property
values using drmModeGetConnectorCurrent for this case, i.e. the kernel
does not expect a full reprobe. I.e. upgrade your idea from "should"
to "must"

Furthermore different property can indicate different kind of updates,
e.g. hdcp vs general sink change vs. whatever else might come in the
future.

> HOTPLUG=1 CONNECTOR=xx
>
> - Needs to drmModeGetConnector() on the one connector, no need to probe
>   others. Implies that one needs to re-get the connector properties as
>   well.

Sounds good.

> HOTPLUG=1
>
> - Need to do drmModeGetResouces() to discover new/disappeared
>   connectors, and need to drmModeGetConnector to re-probe every
>   connector. (As always.)

Maybe we should clarify that this is also what you get when an entire
connector appears/disappears (for dp mst hotplug).

Maybe we could make an additional rule that if a connector has the
EPOCH property, then it does _not_ need to be reprobe for the global
events. For that case userspace should only check whether there's
new/removed connectors, and then probe the new ones (and disable the
removed ones as needed). We can also use some other flag to indicate
this if we don't add the epoch proprty.

> That should be also backwards-compatible: any userspace that doesn't
> understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> userspace that doesn't understand PROPERTY or the property it refers to
> will fall back to probing either the connector or everything.

Agreed, that should work.

> I would be happy to get that behaviour into Weston, particularly as the
> HDCP feature is brewing for Weston too.
>
> --------
>
> When discussing this in IRC, I had the concern about how uevents are
> delivered in userspace. Is there a possibility that they might be
> overwritten, contain stale attributes, or get squashed together?
>
> Particularly if a display server is current on the VT and active and
> monitoring udev, but stuck doing something and cannot service uevents
> very fast, and the kernel sends more than one event before the process
> gets back to dispatching. The terminology in libudev API confused me as
> an event is a device. Squashing together would make sense if the
> uevent were just updating a device attribute list. Previously when we
> had just a single kind of uevent, that would not have made a
> difference, but if we gain different kinds of uevents like here, it
> starts to matter.
>
> However, Paul came to the conclusion that we will be ok as long as the
> events come via netlink.

Yeah netlink shouldn't drop events on the floor I think. It might
still happen, but then I think you should get an indication of that
error, and you just treat it as a general hotplug event like on older
kernels.
-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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 14:34                   ` Daniel Vetter
@ 2019-05-15  7:37                     ` Pekka Paalanen
  2019-05-15  7:49                       ` Paul Kocialkowski
  2019-05-15  8:24                       ` Daniel Vetter
  0 siblings, 2 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-15  7:37 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, maxime.ripard, intel-gfx, dri-devel, Mun,
	Gwan-gyeong, paul.kocialkowski, airlied, thomas.petazzoni,
	Vetter, Daniel, sean


[-- Attachment #1.1: Type: text/plain, Size: 8490 bytes --]

On Tue, 14 May 2019 16:34:01 +0200
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> >
> > On Tue, 14 May 2019 13:02:09 +0200
> > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >  
> > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:  
> > > >
> > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:  

...

> > > > > Hi Daniel,
> > > > >
> > > > > just to clarify the first case, specific to one very particular
> > > > > property:
> > > > >
> > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > when it changes, I do not want userspace have to poll that property
> > > > > with a timer.
> > > > >
> > > > > When that property alone changes, and userspace is prepared to handle
> > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > >
> > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > epoch approach or with any alternate uevent design?
> > > > >
> > > > > We need an event to userspace that indicates that re-reading the
> > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > This is complementary to indicating to userspace that only some
> > > > > connectors need to be reprobed instead of everything.  
> > > >
> > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > reprobing. Would that work?  
> >
> > Hi,
> >
> > yes, that would work, if it was acceptable to DRM upstream. The replies
> > to Paul seemed to be going south so fast that I thought we wouldn't get
> > any new uevent fields in favour of "epoch counters".
> >  
> > > Yes that's the idea, depending upon which property you get you know
> > > it's a sink change (needs full reprobe) or something else like hdcp
> > > state machinery update.  
> >
> > Right.
> >  
> > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > indeed decouple that from the per-connector event for sink changes.
> > > That along is a good win already, since you know for which connector
> > > you need to call drmGetConnector (which forces the reprobe). It would
> > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > historically speaking every time we tried to rely on this we ended up
> > > regretting things.  
> >
> > What changed? This sounds very much what Paul suggested. Looking at it
> > from userspace side:  
> 
> This sounds solid, some refinements below:
> 
> > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> >
> > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> >   re-get the connector properties.
> >
> > - Kernel probably shouldn't bother sending this for properties where
> >   re-probe could be necessary, and send the below instead.  
> 
> 
> I think we should assert that the kernel can get the new property
> values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> does not expect a full reprobe. I.e. upgrade your idea from "should"
> to "must"

Hi Daniel,

ok, that's good.

> Furthermore different property can indicate different kind of updates,
> e.g. hdcp vs general sink change vs. whatever else might come in the
> future.

What do you mean by different kinds of updates?

Btw. I started thinking, maybe we should completely leave out the "If
yy is "Content Protection"" and require the kernel to guarantee, that
if PROPERTY is set, then drmModeGetConnector() (probing) must not be
necessary based on this event alone.

Writing it down again:

HOTPLUG=1 CONNECTOR=xx PROPERTY=yy

- yy denotes which connector xx property changed.

- Userspace does not need to do drmModeGetConnector(), it only needs to
  drmModeObjectGetProperties() on the connector to receive the new
  updated property values.

- Kernel must not send this event for changes that may require probing
  for correct results, exceptional conditions (buggy hardware, etc.)
  included. Instead, the kernel must send one of the below events.

Is there actually anything interesting that
drmModeGetConnectorCurrent() could guaranteed correctly return that is
not a property already? I'd probably leave this consideration out
completely, and just say do one of the needs-probing events if anything
there changed.

> > HOTPLUG=1 CONNECTOR=xx
> >
> > - Needs to drmModeGetConnector() on the one connector, no need to probe
> >   others. Implies that one needs to re-get the connector properties as
> >   well.  
> 
> Sounds good.
> 
> > HOTPLUG=1
> >
> > - Need to do drmModeGetResouces() to discover new/disappeared
> >   connectors, and need to drmModeGetConnector to re-probe every
> >   connector. (As always.)  
> 
> Maybe we should clarify that this is also what you get when an entire
> connector appears/disappears (for dp mst hotplug).

Yes, that's what I wrote. :-)

Weston implements the discovery of appearing/disappearing connectors
(as opposed to connecting/disconnecting connectors). Not sure anyone
has ever tested it though...

> Maybe we could make an additional rule that if a connector has the
> EPOCH property, then it does _not_ need to be reprobe for the global
> events. For that case userspace should only check whether there's
> new/removed connectors, and then probe the new ones (and disable the
> removed ones as needed). We can also use some other flag to indicate
> this if we don't add the epoch proprty.

Sounds fine to me, though I'm not too clear what the epoch property
is designed to achieve. Is it about avoiding re-probing when re-gaining
DRM master after having let it go, e.g. VT-switching back from another
VT? That would be nice.

> > That should be also backwards-compatible: any userspace that doesn't
> > understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> > userspace that doesn't understand PROPERTY or the property it refers to
> > will fall back to probing either the connector or everything.  
> 
> Agreed, that should work.

Cool. The epoch exception you worded seems to fit backward-compatible
as well.

> 
> > I would be happy to get that behaviour into Weston, particularly as the
> > HDCP feature is brewing for Weston too.
> >
> > --------
> >
> > When discussing this in IRC, I had the concern about how uevents are
> > delivered in userspace. Is there a possibility that they might be
> > overwritten, contain stale attributes, or get squashed together?
> >
> > Particularly if a display server is current on the VT and active and
> > monitoring udev, but stuck doing something and cannot service uevents
> > very fast, and the kernel sends more than one event before the process
> > gets back to dispatching. The terminology in libudev API confused me as
> > an event is a device. Squashing together would make sense if the
> > uevent were just updating a device attribute list. Previously when we
> > had just a single kind of uevent, that would not have made a
> > difference, but if we gain different kinds of uevents like here, it
> > starts to matter.
> >
> > However, Paul came to the conclusion that we will be ok as long as the
> > events come via netlink.  
> 
> Yeah netlink shouldn't drop events on the floor I think. It might
> still happen, but then I think you should get an indication of that
> error, and you just treat it as a general hotplug event like on older
> kernels.

Alright, although reading Paul it sounds like there is another
(fallback?) method as well that wouldn't work. Should userspace worry
about that?

Hmm, get an indication of an error... I don't know how that would be
presented in libudev API and I can't point to any code in Weston that
would deal with it. Does anyone have a clue about that?

Userspace cannot really start taking advantage of any new fine-grained
hotplug events until it can rely on the event delivery. Granted, this
seems purely a userspace issue, but I bet it could be formulated as a
kernel regression: things stop working after upgrading the kernel while
having always used new userspace which was ready for detailed hotplug
events but didn't ensure the delivery in userspace.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-14 14:28                 ` Daniel Vetter
@ 2019-05-15  7:43                   ` Paul Kocialkowski
  2019-05-15  7:48                     ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-15  7:43 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Airlie, Maxime Ripard, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

Hi,

On Tue, 2019-05-14 at 16:28 +0200, Daniel Vetter wrote:
> On Tue, May 14, 2019 at 4:13 PM Paul Kocialkowski
> <paul.kocialkowski@bootlin.com> wrote:
> > Hi,
> > 
> > On Tue, 2019-05-14 at 13:09 +0200, Daniel Vetter wrote:
> > > On Mon, May 13, 2019 at 7:14 PM Paul Kocialkowski
> > > <paul.kocialkowski@bootlin.com> wrote:
> > > > Hey,
> > > > 
> > > > Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> > > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > Hi,
> > > > > > 
> > > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > > property.
> > > > > > > > > 
> > > > > > > > > This uevent will have following details related to the status change:
> > > > > > > > > 
> > > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > > > 
> > > > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > > > 
> > > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > > issue and came up with similar ideas:
> > > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > > > 
> > > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > > point is that we need to cover different cases:
> > > > > > > > - one or more properties changed;
> > > > > > > > - the connector status changed;
> > > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > > > 
> > > > > > > > For the first case, we can send out:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > PROPERTY=<id>
> > > > > > > > 
> > > > > > > > and no reprobe is required.
> > > > > > > > 
> > > > > > > > For the second one, something like:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > STATUS=Connected/Disconnected
> > > > > > > > 
> > > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > > disconnected;
> > > > > > > > 
> > > > > > > > For the third one, we can only indicate the connector:
> > > > > > > > HOTPLUG=1
> > > > > > > > CONNECTOR=<id>
> > > > > > > > 
> > > > > > > > and a reprobe of the connector is always needed
> > > > > > > 
> > > > > > > There's no material difference between this one and the previous one.
> > > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > > > 
> > > > > > That's the idea, but we need to handle status changes differently than
> > > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > > exposed as a prop for the connector.
> > > > > 
> > > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > > into a property. Or another excuse why we should expose the epoch
> > > > > property :-)
> > > > 
> > > > Well I think it would make sense anyway, as long as we can make sure it
> > > > stays consistent with the one reported in the connector struct.
> > > > 
> > > > > > > Here's why:
> > > > > > > - A side effect of forcing a probe on a connector is that you get to
> > > > > > > read all the properties, so supplying them is kinda pointless.
> > > > > > 
> > > > > > Agreed, except for the status case where it's useful to know it's a
> > > > > > disconnect, because we don't need any probe step in that case.
> > > > > > 
> > > > > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > > > > reasonable unfortunately, but oh well.
> > > > > > 
> > > > > > How would that be retreived then? From the looks of it, that's a
> > > > > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > > > > does the full reprobe.
> > > > > 
> > > > > drmGetConnector vs drmGetConnectorCurrent.
> > > > 
> > > > Ah right, forgot about that one, thanks.
> > > > 
> > > > > > Not sure what issues could arise in case of disconnect without reprobe
> > > > > > -- at least I don't see why userspace should have to do anything in
> > > > > > particular except no longer using the connector, even in complex DP MST
> > > > > > cases.
> > > > > 
> > > > > connector->status might be a lie without a full reprobe, and wrongly
> > > > > indicate that the connector is disconnected while there's still
> > > > > something plugged in. I'm not sure we've fixed those bugs by now
> > > > > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > > > > connected, and we can't break this because every intel platform ever
> > > > > shipped has a few devices where this is somehow broken, irrespective
> > > > > of the sink).
> > > > 
> > > > Mhh either way, I think it's up to the driver to report that and make
> > > > it consistent. I think we have poll helpers to make up for cases where
> > > > hotplug is not available too. So I'm not sure why a full reprobe would
> > > > be needed: drivers just need to do the right thing.
> > > > 
> > > > > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > > > > everything with the current ioctl and implementations. Having an
> > > > > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > > > > almost all cases).
> > > > > > 
> > > > > > Agreed.
> > > > > > 
> > > > > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > > > > needs to reprobe this connector.
> > > > > > 
> > > > > > I thought we could access the props alone, which avoids doing a reprobe
> > > > > > when the kernel knows that only a prop or a set of props changed and do
> > > > > > not require a full reprobe. That's the first case I was mentionning.
> > > > > > 
> > > > > > > At that point we need to figure out whether this is a good uapi or
> > > > > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > > > > epoch:
> > > > > > > - We need it internally because I'm not goinig to wire a new return
> > > > > > > value through hundreds of connector probe functions. It's much easier
> > > > > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > > > > similar functions that update probe state.
> > > > > > 
> > > > > > I don't think I'm following what issue this is trying to solve
> > > > > > internally.
> > > > > 
> > > > > So I'm assuming that if we handle a hotplug, we only want to generate
> > > > > one uevent for that, not one for every little thing that changed.
> > > > > There's two ways to implement this logic:
> > > > > - With some epoch counter and a helper function you can call everytime
> > > > > something changed (e.g. status, or edid, or anything else we care
> > > > > about e.g. from dp aux). This won't need much (if any) driver changes,
> > > > > because we can just put these into the relevant helper/core functions
> > > > > (like edid update, or dp aux reading or whatever).
> > > > > - Wiring a new return value through the entire stack (and _all_ the
> > > > > kms drivers) so that the probe helpers could aggregate this like they
> > > > > currently do.
> > > > > 
> > > > > One of these is a lot less typing.
> > > > 
> > > > Oh I had missed this issue. Yeah of course if we start reporting
> > > > property changes, a hotplug will be lots of such changes.
> > > > 
> > > > So an epoch counter property would indeed also solve the reprobing
> > > > problem. But I think it would be nice to keep the ability to be
> > > > notified of what changed precisely via uevent. I'm not really buying
> > > > the "missing uevent" thing so much and I think we can reasonably expect
> > > > that it will be useful. Events could be aggregated (which the epoch
> > > > counter would probably also allow) and sent out altogether when the
> > > > connector status changes (along with the status information). I think
> > > > we're under-using uevent currently, and feel like this should be fixed
> > > > regardless of the full reprobe issue.
> > > 
> > > I see two options:
> > > 
> > > 1) kernel aggregates uevents a bit, and sends out one (per connector
> > > that changed) indicating that sink related state changed. Userspace
> > > listens to that, and does a drmGetConnector as a result to update
> > > itself. Most of this code needs to exist anyway.
> > > 
> > > 2) kernel sends out updates as we go, userspace reassembles everything
> > > again (and not really an idea when all the updates are in, see Lyude's
> > > question. Plus userspace still needs to have the drmGetConnector path,
> > > at least for initial setup.
> > > 
> > > I don't see why 2) is any better than 1), and it has some clear downsides.
> > 
> > My main point is that when the kernel knows some individual property
> > changed, it should update its internal state and report what prop
> > changed *in cases that don't require a full reprobe* and report only
> > which connector changed when a connector reprobe is needed anyway.
> > 
> > Maybe we could even have quirks for drivers to indicate that common
> > actions that shouldn't require a reprobe actually do for this driver in
> > particular, because of whatever instability we want to be confident
> > about handling. I believe this should be abstracted away in DRM and not
> > reflected on the userspace API.
> > 
> > So it's not just about providing per-property updates, the updates
> > reported this way have to be "standalone" and never imply that anything
> > else about the connector's state could have change. Driver's guarantee.
> 
> I'm not sure what that guarantee buys us. You can never assume that if
> you get this event that only that property changed, since other stuff
> might have changed meanwhile.

Then you get a second event notification and act accordingly. And the
kernel will group individual property change events into logical events
that only get reported once, too, so it will be rare in practice. I
don't see what issue we have at hand.

> And especially for a sink change we know that a lot of properties
> (including stuff like connector->status here that's not yet a
> property) will have changed. And event with e.g. PROPERTY=epoch would
> simply indicate that all the sink related things have been updated,
> and you can get them with drmGetConnectorCurrent.

That's what I had in mind with reporting CONNECTOR= without any
PROPERTY. Reporting that epoch change feels weird to me, epoch is more
of a meta-information about the connector that userspace should
probably query on its own.

> We also need some way to indicate that an entire batch of updates have
> completed if we send out events for every part of this. Sending out
> bigger events neatly sidesteps that issue.

As we discussed, grouping property changes into logical changes seems
agreeable to everyone.

> > > > With that, I agree that a global epoch counter from the connector would
> > > > be a good quick way for userspace to tell if a connector changed or not
> > > > since the last time it checked.
> > > > 
> > > > > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > > > > switched away we probably don't want to piss of the current compositor
> > > > > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > > > > it can read the epoch property (which it can do without forcing a
> > > > > > > reprobe) userspace would know which connectors it needs to check and
> > > > > > > reprobe.
> > > > > > > 
> > > > > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > > > > also require that userspace needs to keep parsing all uevents and make
> > > > > > > a list of all connectors it needs to reprobe when it's back to being
> > > > > > > the active compositor. But just comparing a current epoch with the one
> > > > > > > you cached from the last full probe is much easier.
> > > > > > 
> > > > > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > > > > we could also provide extra info in the uevent when relevant and not
> > > > > > rely on that entirely.
> > > > > 
> > > > > See above, with drmGetConnectorCurrent there's no need to provide more
> > > > > than what's needed in the uevent, since userspace can get everything
> > > > > else at the cost of one ioctl, without reprobing. With a bit of
> > > > > engineering work we could even avoid taking the expensive
> > > > > dev->mode_config.mutex lock for this fastpath.
> > > > > 
> > > > > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > > > > need to reprobe when the user asks for it. igt can probably get away
> > > > > > > without reprobing.
> > > > > > 
> > > > > > I wonder how that is handled currently and how a user action can solve
> > > > > > the issue without any notification from the kernel. Maybe a need a
> > > > > > better understanding of that case to have a clearer idea.
> > > > > 
> > > > > User opens the screen configuration tool -> usually at that point the
> > > > > tool/compositor force a full reprobe, which then often triggers the
> > > > > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > > > > random shit projectors at conferences nothing happens, until I run
> > > > > xrandr, which triggers the full reprobe, which then makes the kernel
> > > > > realize something change, sending and uevent, which starts the
> > > > > automatic reconfigure machinery.
> > > > 
> > > > Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
> > > > to get me out of an off-panel situation much too often.
> > > > 
> > > > > There's also the issue that there's machines with hpd storms (even on
> > > > > DP, where you really need hpd to work to be compliant), and we have to
> > > > > turn of the hpd irq to keep the machine useable.
> > > > 
> > > > I was under the impression that we switch to polling when a hpd storm
> > > > is detected in i915 (but that's a vague memory from my summer
> > > > internship at Intel 2 years ago).
> > > 
> > > We do poll, but the issue is still that polling doesn't do the same
> > > thing as full reprobe. One just calls ->detect, the other ->detect +
> > > ->get_modes. This is a bit a silliness of the helpers and source of
> > > lots of confusion. A possible fix might be to always call both.
> > 
> > I think that would make a lot of sense. I don't really get why we have
> > to wait for userspace to do a reprobe to get the new modes when the
> > kernel can be absolutely sure that the modes changed and need to be
> > refreshed.
> 
> Don't let the names trick you, it's an entirely arbitrary split,
> historically grown :-)

Seems like it would be sane to fix that up at this point.

> > > Plus even when that mess is sorted there's still the issue of broken
> > > hw, and we have no idea how much/where/which exactly. Except that
> > > every time we relied on hpd status, we got regression reports and had
> > > to revert.
> > 
> > I think we could configure the notification behavior per-driver and
> > some events that wouldn't require a full probe on some drivers could do
> > so on other drivers. Userspace should find out whether to reprobe or
> > not dynamically based on what's in the uevent anyway, so it's not even
> > an inconsistency in the interface that 2 events be reported differently
> > in 2 drivers. I think that'd be better than the current situation we're
> > in anyway. If some drivers want be paranoid and always ask for
> > a reprobe of the connectors because of unreliable hw, their choice.
> 
> The problem isn't typing the code, it's making sure we don't break the
> world with this. Even if you limit this to i915 alone. That's why I'm
> suggesting we untangle things as much as possible, makes it easier to
> do the (pretty much inevitable) revert.

I really strongly believe that cases of broken hardware should not be a
show-stopper for improving the situation for every other non-broken
case ou there. Sure, there's the policy of no regressions, but it has
limits too. Wanting to support broken hardware is a noble goal, but I
think we should frankly ask ourselves at what cost we want it, and how
much we want to let that degrade the situation for other non-broken
hardware.

And in practice, I still don't see why there have to be regressions. If
a driver aims to support broken setups, it should deal with that itself
and not expect the core to. With what I'm proposing, that could mean
reporting that a full reprobe is needed on basically any event like we
do today. But please, let other drivers do better than that if they
can.

Cheers,

Paul

> -Daniel
> 
> > Cheers,
> > 
> > Paul
> > 
> > > -Daniel
> > > 
> > > > Cheers,
> > > > 
> > > > Paul
> > > > 
> > > > > Cheers, Daniel
> > > > > 
> > > > > > Cheers,
> > > > > > 
> > > > > > Paul
> > > > > > 
> > > > > > > -Daniel
> > > > > > > 
> > > > > > > > Then we still have the legacy case:
> > > > > > > > HOTPLUG=1
> > > > > > > > 
> > > > > > > > where userspace is expected to reprobe all the connectors.
> > > > > > > > 
> > > > > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > > > > proposing to take this one off your plate and come up with another
> > > > > > > > seres implementing this proposal. What do you think?
> > > > > > > > 
> > > > > > > > Cheers,
> > > > > > > > 
> > > > > > > > Paul
> > > > > > > > 
> > > > > > > > > v2:
> > > > > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > > > > v3:
> > > > > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > > > > ---
> > > > > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > > > > 
> > > > > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > @@ -21,6 +21,7 @@
> > > > > > > > >  #include <drm/drm_sysfs.h>
> > > > > > > > >  #include <drm/drmP.h>
> > > > > > > > >  #include "drm_internal.h"
> > > > > > > > > +#include "drm_crtc_internal.h"
> > > > > > > > > 
> > > > > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > > > > >   * deal with other types of events.
> > > > > > > > > + *
> > > > > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > > > > + * for uevents on connector status change.
> > > > > > > > >   */
> > > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > > >  {
> > > > > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > > >  }
> > > > > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > > > > 
> > > > > > > > > +/**
> > > > > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > > > > + * property status change
> > > > > > > > > + * @connector: connector on which property status changed
> > > > > > > > > + * @property: connector property whoes status changed.
> > > > > > > > > + *
> > > > > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > > > > + * related to the status change.
> > > > > > > > > + */
> > > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > > +                                   struct drm_property *property)
> > > > > > > > > +{
> > > > > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > > > > +
> > > > > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > > > > +                                        property->base.id));
> > > > > > > > > +
> > > > > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > > > > +
> > > > > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > > > > +
> > > > > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > > > > +
> > > > > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > > > > >  {
> > > > > > > > >       kfree(dev);
> > > > > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > > > > @@ -4,10 +4,13 @@
> > > > > > > > > 
> > > > > > > > >  struct drm_device;
> > > > > > > > >  struct device;
> > > > > > > > > +struct drm_connector;
> > > > > > > > > +struct drm_property;
> > > > > > > > > 
> > > > > > > > >  int drm_class_device_register(struct device *dev);
> > > > > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > > > > 
> > > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > > > > -
> > > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > > +                                   struct drm_property *property);
> > > > > > > > >  #endif
> > > > > > > > --
> > > > > > > > Paul Kocialkowski, Bootlin
> > > > > > > > Embedded Linux and kernel engineering
> > > > > > > > https://bootlin.com
> > > > > > > > 
> > > > > > --
> > > > > > Paul Kocialkowski, Bootlin
> > > > > > Embedded Linux and kernel engineering
> > > > > > https://bootlin.com
> > > > > > 
> > --
> > Paul Kocialkowski, Bootlin
> > Embedded Linux and kernel engineering
> > https://bootlin.com
> > 
> 
> 
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-15  7:43                   ` Paul Kocialkowski
@ 2019-05-15  7:48                     ` Daniel Vetter
  0 siblings, 0 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-15  7:48 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: David Airlie, Maxime Ripard, Daniel Vetter, intel-gfx, dri-devel,
	Gwan-gyeong Mun, Ser, Simon, Thomas Petazzoni, Daniel Vetter,
	Sean Paul

On Wed, May 15, 2019 at 09:43:24AM +0200, Paul Kocialkowski wrote:
> Hi,
> 
> On Tue, 2019-05-14 at 16:28 +0200, Daniel Vetter wrote:
> > On Tue, May 14, 2019 at 4:13 PM Paul Kocialkowski
> > <paul.kocialkowski@bootlin.com> wrote:
> > > Hi,
> > > 
> > > On Tue, 2019-05-14 at 13:09 +0200, Daniel Vetter wrote:
> > > > On Mon, May 13, 2019 at 7:14 PM Paul Kocialkowski
> > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > Hey,
> > > > > 
> > > > > Le lundi 13 mai 2019 à 11:34 +0200, Daniel Vetter a écrit :
> > > > > > On Mon, May 13, 2019 at 11:02 AM Paul Kocialkowski
> > > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > > Hi,
> > > > > > > 
> > > > > > > On Fri, 2019-05-10 at 16:54 +0200, Daniel Vetter wrote:
> > > > > > > > On Fri, May 10, 2019 at 2:12 PM Paul Kocialkowski
> > > > > > > > <paul.kocialkowski@bootlin.com> wrote:
> > > > > > > > > Hi,
> > > > > > > > > 
> > > > > > > > > On Tue, 2019-05-07 at 21:57 +0530, Ramalingam C wrote:
> > > > > > > > > > DRM API for generating uevent for a status changes of connector's
> > > > > > > > > > property.
> > > > > > > > > > 
> > > > > > > > > > This uevent will have following details related to the status change:
> > > > > > > > > > 
> > > > > > > > > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > > > > > > > > 
> > > > > > > > > > Need ACK from this uevent from userspace consumer.
> > > > > > > > > 
> > > > > > > > > So we just had some discussions over on IRC and at about the hotplug
> > > > > > > > > issue and came up with similar ideas:
> > > > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-May/217408.html
> > > > > > > > > 
> > > > > > > > > The conclusions of these discussions so far would be to have a more or
> > > > > > > > > less fine grain of uevent reporting depending on what happened. The
> > > > > > > > > point is that we need to cover different cases:
> > > > > > > > > - one or more properties changed;
> > > > > > > > > - the connector status changed;
> > > > > > > > > - something else about the connector changed (e.g. EDID/modes)
> > > > > > > > > 
> > > > > > > > > For the first case, we can send out:
> > > > > > > > > HOTPLUG=1
> > > > > > > > > CONNECTOR=<id>
> > > > > > > > > PROPERTY=<id>
> > > > > > > > > 
> > > > > > > > > and no reprobe is required.
> > > > > > > > > 
> > > > > > > > > For the second one, something like:
> > > > > > > > > HOTPLUG=1
> > > > > > > > > CONNECTOR=<id>
> > > > > > > > > STATUS=Connected/Disconnected
> > > > > > > > > 
> > > > > > > > > and a connector probe is needed for connected, but not for
> > > > > > > > > disconnected;
> > > > > > > > > 
> > > > > > > > > For the third one, we can only indicate the connector:
> > > > > > > > > HOTPLUG=1
> > > > > > > > > CONNECTOR=<id>
> > > > > > > > > 
> > > > > > > > > and a reprobe of the connector is always needed
> > > > > > > > 
> > > > > > > > There's no material difference between this one and the previous one.
> > > > > > > > Plus there's no beenfit in supplying the actual value of the property,
> > > > > > > > i.e. we can reuse the same PROPERTY=<id-of-status-property> trick.
> > > > > > > 
> > > > > > > That's the idea, but we need to handle status changes differently than
> > > > > > > properties, since as far as I know, connected/unconnected status is not
> > > > > > > exposed as a prop for the connector.
> > > > > > 
> > > > > > Oops, totally missed that. "Everything is a property" is kinda
> > > > > > new-ish, at least compared to kms. Kinda tempted to just make status
> > > > > > into a property. Or another excuse why we should expose the epoch
> > > > > > property :-)
> > > > > 
> > > > > Well I think it would make sense anyway, as long as we can make sure it
> > > > > stays consistent with the one reported in the connector struct.
> > > > > 
> > > > > > > > Here's why:
> > > > > > > > - A side effect of forcing a probe on a connector is that you get to
> > > > > > > > read all the properties, so supplying them is kinda pointless.
> > > > > > > 
> > > > > > > Agreed, except for the status case where it's useful to know it's a
> > > > > > > disconnect, because we don't need any probe step in that case.
> > > > > > > 
> > > > > > > > - You can read STATUS without forcing a reprobe, if you want to avoid
> > > > > > > > the reprobe for disconnected. I'd kinda not recommend that though,
> > > > > > > > feels a bit like overoptimizing. And for reasonable connectors (i.e.
> > > > > > > > dp) reprobing a disconnected output is fast. HDMI is ... less
> > > > > > > > reasonable unfortunately, but oh well.
> > > > > > > 
> > > > > > > How would that be retreived then? From the looks of it, that's a
> > > > > > > MODE_GETCONNECTOR ioctl and I was under the impression this is what
> > > > > > > does the full reprobe.
> > > > > > 
> > > > > > drmGetConnector vs drmGetConnectorCurrent.
> > > > > 
> > > > > Ah right, forgot about that one, thanks.
> > > > > 
> > > > > > > Not sure what issues could arise in case of disconnect without reprobe
> > > > > > > -- at least I don't see why userspace should have to do anything in
> > > > > > > particular except no longer using the connector, even in complex DP MST
> > > > > > > cases.
> > > > > > 
> > > > > > connector->status might be a lie without a full reprobe, and wrongly
> > > > > > indicate that the connector is disconnected while there's still
> > > > > > something plugged in. I'm not sure we've fixed those bugs by now
> > > > > > (usually it's around "hpd indicates disconnected" vs. "i2c indicates
> > > > > > connected, and we can't break this because every intel platform ever
> > > > > > shipped has a few devices where this is somehow broken, irrespective
> > > > > > of the sink).
> > > > > 
> > > > > Mhh either way, I think it's up to the driver to report that and make
> > > > > it consistent. I think we have poll helpers to make up for cases where
> > > > > hotplug is not available too. So I'm not sure why a full reprobe would
> > > > > be needed: drivers just need to do the right thing.
> > > > > 
> > > > > > > > - There's no way to only reprobe status, you can only ever reprobe
> > > > > > > > everything with the current ioctl and implementations. Having an
> > > > > > > > option to reprobe only parts of it doesn't seem useful to me (we need
> > > > > > > > to read the EDID anyway, and that's the expensive part of reprobing in
> > > > > > > > almost all cases).
> > > > > > > 
> > > > > > > Agreed.
> > > > > > > 
> > > > > > > > In a way PROPERTY=<status-prop-id> simply tells userspace that it
> > > > > > > > needs to reprobe this connector.
> > > > > > > 
> > > > > > > I thought we could access the props alone, which avoids doing a reprobe
> > > > > > > when the kernel knows that only a prop or a set of props changed and do
> > > > > > > not require a full reprobe. That's the first case I was mentionning.
> > > > > > > 
> > > > > > > > At that point we need to figure out whether this is a good uapi or
> > > > > > > > not, and that's where the epoch comes in. There's two reasons for an
> > > > > > > > epoch:
> > > > > > > > - We need it internally because I'm not goinig to wire a new return
> > > > > > > > value through hundreds of connector probe functions. It's much easier
> > > > > > > > to have an epoch counter which we set from e.g. drm_set_edid and
> > > > > > > > similar functions that update probe state.
> > > > > > > 
> > > > > > > I don't think I'm following what issue this is trying to solve
> > > > > > > internally.
> > > > > > 
> > > > > > So I'm assuming that if we handle a hotplug, we only want to generate
> > > > > > one uevent for that, not one for every little thing that changed.
> > > > > > There's two ways to implement this logic:
> > > > > > - With some epoch counter and a helper function you can call everytime
> > > > > > something changed (e.g. status, or edid, or anything else we care
> > > > > > about e.g. from dp aux). This won't need much (if any) driver changes,
> > > > > > because we can just put these into the relevant helper/core functions
> > > > > > (like edid update, or dp aux reading or whatever).
> > > > > > - Wiring a new return value through the entire stack (and _all_ the
> > > > > > kms drivers) so that the probe helpers could aggregate this like they
> > > > > > currently do.
> > > > > > 
> > > > > > One of these is a lot less typing.
> > > > > 
> > > > > Oh I had missed this issue. Yeah of course if we start reporting
> > > > > property changes, a hotplug will be lots of such changes.
> > > > > 
> > > > > So an epoch counter property would indeed also solve the reprobing
> > > > > problem. But I think it would be nice to keep the ability to be
> > > > > notified of what changed precisely via uevent. I'm not really buying
> > > > > the "missing uevent" thing so much and I think we can reasonably expect
> > > > > that it will be useful. Events could be aggregated (which the epoch
> > > > > counter would probably also allow) and sent out altogether when the
> > > > > connector status changes (along with the status information). I think
> > > > > we're under-using uevent currently, and feel like this should be fixed
> > > > > regardless of the full reprobe issue.
> > > > 
> > > > I see two options:
> > > > 
> > > > 1) kernel aggregates uevents a bit, and sends out one (per connector
> > > > that changed) indicating that sink related state changed. Userspace
> > > > listens to that, and does a drmGetConnector as a result to update
> > > > itself. Most of this code needs to exist anyway.
> > > > 
> > > > 2) kernel sends out updates as we go, userspace reassembles everything
> > > > again (and not really an idea when all the updates are in, see Lyude's
> > > > question. Plus userspace still needs to have the drmGetConnector path,
> > > > at least for initial setup.
> > > > 
> > > > I don't see why 2) is any better than 1), and it has some clear downsides.
> > > 
> > > My main point is that when the kernel knows some individual property
> > > changed, it should update its internal state and report what prop
> > > changed *in cases that don't require a full reprobe* and report only
> > > which connector changed when a connector reprobe is needed anyway.
> > > 
> > > Maybe we could even have quirks for drivers to indicate that common
> > > actions that shouldn't require a reprobe actually do for this driver in
> > > particular, because of whatever instability we want to be confident
> > > about handling. I believe this should be abstracted away in DRM and not
> > > reflected on the userspace API.
> > > 
> > > So it's not just about providing per-property updates, the updates
> > > reported this way have to be "standalone" and never imply that anything
> > > else about the connector's state could have change. Driver's guarantee.
> > 
> > I'm not sure what that guarantee buys us. You can never assume that if
> > you get this event that only that property changed, since other stuff
> > might have changed meanwhile.
> 
> Then you get a second event notification and act accordingly. And the
> kernel will group individual property change events into logical events
> that only get reported once, too, so it will be rare in practice. I
> don't see what issue we have at hand.
> 
> > And especially for a sink change we know that a lot of properties
> > (including stuff like connector->status here that's not yet a
> > property) will have changed. And event with e.g. PROPERTY=epoch would
> > simply indicate that all the sink related things have been updated,
> > and you can get them with drmGetConnectorCurrent.
> 
> That's what I had in mind with reporting CONNECTOR= without any
> PROPERTY. Reporting that epoch change feels weird to me, epoch is more
> of a meta-information about the connector that userspace should
> probably query on its own.
> 
> > We also need some way to indicate that an entire batch of updates have
> > completed if we send out events for every part of this. Sending out
> > bigger events neatly sidesteps that issue.
> 
> As we discussed, grouping property changes into logical changes seems
> agreeable to everyone.

Yeah no one's disagreeing on that I guess, it's just that there's ways to
get there that involve more or less typing :-)

> > > > > With that, I agree that a global epoch counter from the connector would
> > > > > be a good quick way for userspace to tell if a connector changed or not
> > > > > since the last time it checked.
> > > > > 
> > > > > > > > - If userspace misses an event and there's no epoch, we're forcing
> > > > > > > > userspace to reprobe everything. Use case would be if a compositor is
> > > > > > > > switched away we probably don't want to piss of the current compositor
> > > > > > > > by blocking it's own probe kernel calls by doing our own (probe is
> > > > > > > > single-threaded in the kernel through the dev->mode_config.mutex). If
> > > > > > > > it can read the epoch property (which it can do without forcing a
> > > > > > > > reprobe) userspace would know which connectors it needs to check and
> > > > > > > > reprobe.
> > > > > > > > 
> > > > > > > > Hence why epoch, it's a bit more robust userspace api. Ofc you could
> > > > > > > > also require that userspace needs to keep parsing all uevents and make
> > > > > > > > a list of all connectors it needs to reprobe when it's back to being
> > > > > > > > the active compositor. But just comparing a current epoch with the one
> > > > > > > > you cached from the last full probe is much easier.
> > > > > > > 
> > > > > > > Fair enough, I think it's a fine idea for robustness yes, but I think
> > > > > > > we could also provide extra info in the uevent when relevant and not
> > > > > > > rely on that entirely.
> > > > > > 
> > > > > > See above, with drmGetConnectorCurrent there's no need to provide more
> > > > > > than what's needed in the uevent, since userspace can get everything
> > > > > > else at the cost of one ioctl, without reprobing. With a bit of
> > > > > > engineering work we could even avoid taking the expensive
> > > > > > dev->mode_config.mutex lock for this fastpath.
> > > > > > 
> > > > > > > > Another thing: None of this we can for connectors with unreliable hdp.
> > > > > > > > Or at least you'll piss of users if you cache always. The sad thing is
> > > > > > > > that HDMI is unreliable, at least on some machines/screen combos (you
> > > > > > > > never get a hpd irq if you plug in/unplug). So real compositors still
> > > > > > > > need to reprobe when the user asks for it. igt can probably get away
> > > > > > > > without reprobing.
> > > > > > > 
> > > > > > > I wonder how that is handled currently and how a user action can solve
> > > > > > > the issue without any notification from the kernel. Maybe a need a
> > > > > > > better understanding of that case to have a clearer idea.
> > > > > > 
> > > > > > User opens the screen configuration tool -> usually at that point the
> > > > > > tool/compositor force a full reprobe, which then often triggers the
> > > > > > automatic reconfiguring. E.g. on one laptop I have here when I plug in
> > > > > > random shit projectors at conferences nothing happens, until I run
> > > > > > xrandr, which triggers the full reprobe, which then makes the kernel
> > > > > > realize something change, sending and uevent, which starts the
> > > > > > automatic reconfigure machinery.
> > > > > 
> > > > > Oh right hehe, I definitely do that blind alt+f2 gnome-control-center
> > > > > to get me out of an off-panel situation much too often.
> > > > > 
> > > > > > There's also the issue that there's machines with hpd storms (even on
> > > > > > DP, where you really need hpd to work to be compliant), and we have to
> > > > > > turn of the hpd irq to keep the machine useable.
> > > > > 
> > > > > I was under the impression that we switch to polling when a hpd storm
> > > > > is detected in i915 (but that's a vague memory from my summer
> > > > > internship at Intel 2 years ago).
> > > > 
> > > > We do poll, but the issue is still that polling doesn't do the same
> > > > thing as full reprobe. One just calls ->detect, the other ->detect +
> > > > ->get_modes. This is a bit a silliness of the helpers and source of
> > > > lots of confusion. A possible fix might be to always call both.
> > > 
> > > I think that would make a lot of sense. I don't really get why we have
> > > to wait for userspace to do a reprobe to get the new modes when the
> > > kernel can be absolutely sure that the modes changed and need to be
> > > refreshed.
> > 
> > Don't let the names trick you, it's an entirely arbitrary split,
> > historically grown :-)
> 
> Seems like it would be sane to fix that up at this point.

Sure, the problem is fixing up everyone.

> > > > Plus even when that mess is sorted there's still the issue of broken
> > > > hw, and we have no idea how much/where/which exactly. Except that
> > > > every time we relied on hpd status, we got regression reports and had
> > > > to revert.
> > > 
> > > I think we could configure the notification behavior per-driver and
> > > some events that wouldn't require a full probe on some drivers could do
> > > so on other drivers. Userspace should find out whether to reprobe or
> > > not dynamically based on what's in the uevent anyway, so it's not even
> > > an inconsistency in the interface that 2 events be reported differently
> > > in 2 drivers. I think that'd be better than the current situation we're
> > > in anyway. If some drivers want be paranoid and always ask for
> > > a reprobe of the connectors because of unreliable hw, their choice.
> > 
> > The problem isn't typing the code, it's making sure we don't break the
> > world with this. Even if you limit this to i915 alone. That's why I'm
> > suggesting we untangle things as much as possible, makes it easier to
> > do the (pretty much inevitable) revert.
> 
> I really strongly believe that cases of broken hardware should not be a
> show-stopper for improving the situation for every other non-broken
> case ou there. Sure, there's the policy of no regressions, but it has
> limits too. Wanting to support broken hardware is a noble goal, but I
> think we should frankly ask ourselves at what cost we want it, and how
> much we want to let that degrade the situation for other non-broken
> hardware.

The policy of "no regression" has pretty much no limits. Either you fix up
everything, or it's not going to happen. Or there's some reasonable
forward-compatible option.
-Daniel

> And in practice, I still don't see why there have to be regressions. If
> a driver aims to support broken setups, it should deal with that itself
> and not expect the core to. With what I'm proposing, that could mean
> reporting that a full reprobe is needed on basically any event like we
> do today. But please, let other drivers do better than that if they
> can.
> 
> Cheers,
> 
> Paul
> 
> > -Daniel
> > 
> > > Cheers,
> > > 
> > > Paul
> > > 
> > > > -Daniel
> > > > 
> > > > > Cheers,
> > > > > 
> > > > > Paul
> > > > > 
> > > > > > Cheers, Daniel
> > > > > > 
> > > > > > > Cheers,
> > > > > > > 
> > > > > > > Paul
> > > > > > > 
> > > > > > > > -Daniel
> > > > > > > > 
> > > > > > > > > Then we still have the legacy case:
> > > > > > > > > HOTPLUG=1
> > > > > > > > > 
> > > > > > > > > where userspace is expected to reprobe all the connectors.
> > > > > > > > > 
> > > > > > > > > I think this would deserve to be a separate series on its own. So I am
> > > > > > > > > proposing to take this one off your plate and come up with another
> > > > > > > > > seres implementing this proposal. What do you think?
> > > > > > > > > 
> > > > > > > > > Cheers,
> > > > > > > > > 
> > > > > > > > > Paul
> > > > > > > > > 
> > > > > > > > > > v2:
> > > > > > > > > >   Minor fixes at KDoc comments [Daniel]
> > > > > > > > > > v3:
> > > > > > > > > >   Check the property is really attached with connector [Daniel]
> > > > > > > > > > 
> > > > > > > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > > > > > ---
> > > > > > > > > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > > > > > > > > >  include/drm/drm_sysfs.h     |  5 ++++-
> > > > > > > > > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > > > > > > > > 
> > > > > > > > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > > index 18b1ac442997..63fa951a20db 100644
> > > > > > > > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > > > > > > > @@ -21,6 +21,7 @@
> > > > > > > > > >  #include <drm/drm_sysfs.h>
> > > > > > > > > >  #include <drm/drmP.h>
> > > > > > > > > >  #include "drm_internal.h"
> > > > > > > > > > +#include "drm_crtc_internal.h"
> > > > > > > > > > 
> > > > > > > > > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > > > > > > > > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > > > > > > > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > > > > > > > > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > > > > > > > > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > > > > > > > > >   * deal with other types of events.
> > > > > > > > > > + *
> > > > > > > > > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > > > > > > > > + * for uevents on connector status change.
> > > > > > > > > >   */
> > > > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > > > >  {
> > > > > > > > > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > > > > > > > > >  }
> > > > > > > > > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > > > > > > > > > 
> > > > > > > > > > +/**
> > > > > > > > > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > > > > > > > > + * property status change
> > > > > > > > > > + * @connector: connector on which property status changed
> > > > > > > > > > + * @property: connector property whoes status changed.
> > > > > > > > > > + *
> > > > > > > > > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > > > > > > > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > > > > > > > > + * related to the status change.
> > > > > > > > > > + */
> > > > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > > > +                                   struct drm_property *property)
> > > > > > > > > > +{
> > > > > > > > > > +     struct drm_device *dev = connector->dev;
> > > > > > > > > > +     char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > > > > > > > > +     char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > > > > > > > > +
> > > > > > > > > > +     WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > > > > > > > > +                                        property->base.id));
> > > > > > > > > > +
> > > > > > > > > > +     snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > > > > > > > > +              "CONNECTOR=%u", connector->base.id);
> > > > > > > > > > +     snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > > > > > > > > +              "PROPERTY=%u", property->base.id);
> > > > > > > > > > +
> > > > > > > > > > +     DRM_DEBUG("generating connector status event\n");
> > > > > > > > > > +
> > > > > > > > > > +     kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > > > > > > > > +}
> > > > > > > > > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > > > > > > > > +
> > > > > > > > > >  static void drm_sysfs_release(struct device *dev)
> > > > > > > > > >  {
> > > > > > > > > >       kfree(dev);
> > > > > > > > > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > > > > > > > > index 4f311e836cdc..d454ef617b2c 100644
> > > > > > > > > > --- a/include/drm/drm_sysfs.h
> > > > > > > > > > +++ b/include/drm/drm_sysfs.h
> > > > > > > > > > @@ -4,10 +4,13 @@
> > > > > > > > > > 
> > > > > > > > > >  struct drm_device;
> > > > > > > > > >  struct device;
> > > > > > > > > > +struct drm_connector;
> > > > > > > > > > +struct drm_property;
> > > > > > > > > > 
> > > > > > > > > >  int drm_class_device_register(struct device *dev);
> > > > > > > > > >  void drm_class_device_unregister(struct device *dev);
> > > > > > > > > > 
> > > > > > > > > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > > > > > > > > -
> > > > > > > > > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > > > > > > > > +                                   struct drm_property *property);
> > > > > > > > > >  #endif
> > > > > > > > > --
> > > > > > > > > Paul Kocialkowski, Bootlin
> > > > > > > > > Embedded Linux and kernel engineering
> > > > > > > > > https://bootlin.com
> > > > > > > > > 
> > > > > > > --
> > > > > > > Paul Kocialkowski, Bootlin
> > > > > > > Embedded Linux and kernel engineering
> > > > > > > https://bootlin.com
> > > > > > > 
> > > --
> > > Paul Kocialkowski, Bootlin
> > > Embedded Linux and kernel engineering
> > > https://bootlin.com
> > > 
> > 
> > 
> -- 
> Paul Kocialkowski, Bootlin
> Embedded Linux and kernel engineering
> https://bootlin.com
> 

-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-15  7:37                     ` Pekka Paalanen
@ 2019-05-15  7:49                       ` Paul Kocialkowski
  2019-05-15  8:24                       ` Daniel Vetter
  1 sibling, 0 replies; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-15  7:49 UTC (permalink / raw)
  To: Pekka Paalanen, Daniel Vetter
  Cc: maxime.ripard, intel-gfx, dri-devel, Mun, Gwan-gyeong, Ser,
	Simon, airlied, thomas.petazzoni, Vetter, Daniel, sean

Hi,

On Wed, 2019-05-15 at 10:37 +0300, Pekka Paalanen wrote:
> On Tue, 14 May 2019 16:34:01 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> 
> > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> > > On Tue, 14 May 2019 13:02:09 +0200
> > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >  
> > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:  
> > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:  
> 
> ...
> 
> > > > > > Hi Daniel,
> > > > > > 
> > > > > > just to clarify the first case, specific to one very particular
> > > > > > property:
> > > > > > 
> > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > with a timer.
> > > > > > 
> > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > 
> > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > epoch approach or with any alternate uevent design?
> > > > > > 
> > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > This is complementary to indicating to userspace that only some
> > > > > > connectors need to be reprobed instead of everything.  
> > > > > 
> > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > reprobing. Would that work?  
> > > 
> > > Hi,
> > > 
> > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > any new uevent fields in favour of "epoch counters".
> > >  
> > > > Yes that's the idea, depending upon which property you get you know
> > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > state machinery update.  
> > > 
> > > Right.
> > >  
> > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > indeed decouple that from the per-connector event for sink changes.
> > > > That along is a good win already, since you know for which connector
> > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > historically speaking every time we tried to rely on this we ended up
> > > > regretting things.  
> > > 
> > > What changed? This sounds very much what Paul suggested. Looking at it
> > > from userspace side:  
> > 
> > This sounds solid, some refinements below:
> > 
> > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > 
> > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > >   re-get the connector properties.
> > > 
> > > - Kernel probably shouldn't bother sending this for properties where
> > >   re-probe could be necessary, and send the below instead.  
> > 
> > I think we should assert that the kernel can get the new property
> > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > to "must"
> 
> Hi Daniel,
> 
> ok, that's good.
> 
> > Furthermore different property can indicate different kind of updates,
> > e.g. hdcp vs general sink change vs. whatever else might come in the
> > future.
> 
> What do you mean by different kinds of updates?
> 
> Btw. I started thinking, maybe we should completely leave out the "If
> yy is "Content Protection"" and require the kernel to guarantee, that
> if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> necessary based on this event alone.

I agree, this is precisely what I had in mind.

> Writing it down again:
> 
> HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> 
> - yy denotes which connector xx property changed.
> 
> - Userspace does not need to do drmModeGetConnector(), it only needs to
>   drmModeObjectGetProperties() on the connector to receive the new
>   updated property values.
> 
> - Kernel must not send this event for changes that may require probing
>   for correct results, exceptional conditions (buggy hardware, etc.)
>   included. Instead, the kernel must send one of the below events.

Agreed, and leave this up to the driver in the end, not the core.

> Is there actually anything interesting that
> drmModeGetConnectorCurrent() could guaranteed correctly return that is
> not a property already? I'd probably leave this consideration out
> completely, and just say do one of the needs-probing events if anything
> there changed.

In the end, I think this should help move to a situation where
userspace would not have to do a reprobe at any point and the kernel
side just does it.

I see no justification for asking userspace to probe anyway, we can
manage all that in-kernel with each driver keeping its connector props
up to date and properly notifying userspace.

On the other hand, it's definitely good to keep the ability for
userspace to voluntarily reprobe at times, but those two ideas can work
fine together.

> > > HOTPLUG=1 CONNECTOR=xx
> > > 
> > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > >   others. Implies that one needs to re-get the connector properties as
> > >   well.  
> > 
> > Sounds good.
> > 
> > > HOTPLUG=1
> > > 
> > > - Need to do drmModeGetResouces() to discover new/disappeared
> > >   connectors, and need to drmModeGetConnector to re-probe every
> > >   connector. (As always.)  
> > 
> > Maybe we should clarify that this is also what you get when an entire
> > connector appears/disappears (for dp mst hotplug).
> 
> Yes, that's what I wrote. :-)
> 
> Weston implements the discovery of appearing/disappearing connectors
> (as opposed to connecting/disconnecting connectors). Not sure anyone
> has ever tested it though...
> 
> > Maybe we could make an additional rule that if a connector has the
> > EPOCH property, then it does _not_ need to be reprobe for the global
> > events. For that case userspace should only check whether there's
> > new/removed connectors, and then probe the new ones (and disable the
> > removed ones as needed). We can also use some other flag to indicate
> > this if we don't add the epoch proprty.
> 
> Sounds fine to me, though I'm not too clear what the epoch property
> is designed to achieve. Is it about avoiding re-probing when re-gaining
> DRM master after having let it go, e.g. VT-switching back from another
> VT? That would be nice.
> 
> > > That should be also backwards-compatible: any userspace that doesn't
> > > understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> > > userspace that doesn't understand PROPERTY or the property it refers to
> > > will fall back to probing either the connector or everything.  
> > 
> > Agreed, that should work.
> 
> Cool. The epoch exception you worded seems to fit backward-compatible
> as well.
> 
> > > I would be happy to get that behaviour into Weston, particularly as the
> > > HDCP feature is brewing for Weston too.
> > > 
> > > --------
> > > 
> > > When discussing this in IRC, I had the concern about how uevents are
> > > delivered in userspace. Is there a possibility that they might be
> > > overwritten, contain stale attributes, or get squashed together?
> > > 
> > > Particularly if a display server is current on the VT and active and
> > > monitoring udev, but stuck doing something and cannot service uevents
> > > very fast, and the kernel sends more than one event before the process
> > > gets back to dispatching. The terminology in libudev API confused me as
> > > an event is a device. Squashing together would make sense if the
> > > uevent were just updating a device attribute list. Previously when we
> > > had just a single kind of uevent, that would not have made a
> > > difference, but if we gain different kinds of uevents like here, it
> > > starts to matter.
> > > 
> > > However, Paul came to the conclusion that we will be ok as long as the
> > > events come via netlink.  
> > 
> > Yeah netlink shouldn't drop events on the floor I think. It might
> > still happen, but then I think you should get an indication of that
> > error, and you just treat it as a general hotplug event like on older
> > kernels.
> 
> Alright, although reading Paul it sounds like there is another
> (fallback?) method as well that wouldn't work. Should userspace worry
> about that?

It's unclear to me when that non-netlink thing is actually used by
systemd. IMO we can just leave this out. I think overall uevent/udev is
reliable enough for us to just expect it to work.

Cheers,

Paul

> Hmm, get an indication of an error... I don't know how that would be
> presented in libudev API and I can't point to any code in Weston that
> would deal with it. Does anyone have a clue about that?
> 
> Userspace cannot really start taking advantage of any new fine-grained
> hotplug events until it can rely on the event delivery. Granted, this
> seems purely a userspace issue, but I bet it could be formulated as a
> kernel regression: things stop working after upgrading the kernel while
> having always used new userspace which was ready for detailed hotplug
> events but didn't ensure the delivery in userspace.
> 
> Thanks,
> pq
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-15  7:37                     ` Pekka Paalanen
  2019-05-15  7:49                       ` Paul Kocialkowski
@ 2019-05-15  8:24                       ` Daniel Vetter
  2019-05-16  8:22                         ` Pekka Paalanen
  1 sibling, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-15  8:24 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, maxime.ripard, Daniel Vetter, intel-gfx, dri-devel,
	paul.kocialkowski, airlied, thomas.petazzoni, Vetter, Daniel

On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:
> On Tue, 14 May 2019 16:34:01 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> 
> > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> > >
> > > On Tue, 14 May 2019 13:02:09 +0200
> > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >  
> > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:  
> > > > >
> > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:  
> 
> ...
> 
> > > > > > Hi Daniel,
> > > > > >
> > > > > > just to clarify the first case, specific to one very particular
> > > > > > property:
> > > > > >
> > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > with a timer.
> > > > > >
> > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > >
> > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > epoch approach or with any alternate uevent design?
> > > > > >
> > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > This is complementary to indicating to userspace that only some
> > > > > > connectors need to be reprobed instead of everything.  
> > > > >
> > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > reprobing. Would that work?  
> > >
> > > Hi,
> > >
> > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > any new uevent fields in favour of "epoch counters".
> > >  
> > > > Yes that's the idea, depending upon which property you get you know
> > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > state machinery update.  
> > >
> > > Right.
> > >  
> > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > indeed decouple that from the per-connector event for sink changes.
> > > > That along is a good win already, since you know for which connector
> > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > historically speaking every time we tried to rely on this we ended up
> > > > regretting things.  
> > >
> > > What changed? This sounds very much what Paul suggested. Looking at it
> > > from userspace side:  
> > 
> > This sounds solid, some refinements below:
> > 
> > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > >
> > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > >   re-get the connector properties.
> > >
> > > - Kernel probably shouldn't bother sending this for properties where
> > >   re-probe could be necessary, and send the below instead.  
> > 
> > 
> > I think we should assert that the kernel can get the new property
> > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > to "must"
> 
> Hi Daniel,
> 
> ok, that's good.
> 
> > Furthermore different property can indicate different kind of updates,
> > e.g. hdcp vs general sink change vs. whatever else might come in the
> > future.
> 
> What do you mean by different kinds of updates?

Atm we're discussing two:

- "Content Protection"
- "sink changed, but you don't need to reprobe" this would be quite a bit
  a catch all from the output detection. Paul thinks differently, but I'm
  not sold on splitting this up more, at least not right now. This would
  include connector status (and related things returned by drmGetConnector
  which currently aren't a property), EDID, the mst path id, that kind of
  stuff.

Ime once we have 2, there's more bound to come :-)

> Btw. I started thinking, maybe we should completely leave out the "If
> yy is "Content Protection"" and require the kernel to guarantee, that
> if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> necessary based on this event alone.
> 
> Writing it down again:
> 
> HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> 
> - yy denotes which connector xx property changed.

Maybe yy denotes which group of properties changed, and part of the uapi
is picking the canonical one. E.g. content protection might also gain more
properties in the future (there's patches, but the userspace won't be open
sourced). And for that case I don't think we should then send an even for
every single individual property, but just for the lead property.

Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
better to use the property id we already have for this.

> - Userspace does not need to do drmModeGetConnector(), it only needs to
>   drmModeObjectGetProperties() on the connector to receive the new
>   updated property values.

drmModeGetConnector(Current) also supplies all the properties already.
This is special with connectors, since the predate the "properties on
everything" design. I'd just mention this function here, and ignore
drmModeObjectGetProperties.

> - Kernel must not send this event for changes that may require probing
>   for correct results, exceptional conditions (buggy hardware, etc.)
>   included. Instead, the kernel must send one of the below events.
> 
> Is there actually anything interesting that
> drmModeGetConnectorCurrent() could guaranteed correctly return that is
> not a property already? I'd probably leave this consideration out
> completely, and just say do one of the needs-probing events if anything
> there changed.

That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
sink related stuff, including the not-properperty-fied stuff is updated,
and will be reported correctly by GetConnectorCurrent.

> > > HOTPLUG=1 CONNECTOR=xx
> > >
> > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > >   others. Implies that one needs to re-get the connector properties as
> > >   well.  
> > 
> > Sounds good.
> > 
> > > HOTPLUG=1
> > >
> > > - Need to do drmModeGetResouces() to discover new/disappeared
> > >   connectors, and need to drmModeGetConnector to re-probe every
> > >   connector. (As always.)  
> > 
> > Maybe we should clarify that this is also what you get when an entire
> > connector appears/disappears (for dp mst hotplug).
> 
> Yes, that's what I wrote. :-)
> 
> Weston implements the discovery of appearing/disappearing connectors
> (as opposed to connecting/disconnecting connectors). Not sure anyone
> has ever tested it though...

From what -modesetting and X drivers do: Expect surprises in real world
usage :-/

> > Maybe we could make an additional rule that if a connector has the
> > EPOCH property, then it does _not_ need to be reprobe for the global
> > events. For that case userspace should only check whether there's
> > new/removed connectors, and then probe the new ones (and disable the
> > removed ones as needed). We can also use some other flag to indicate
> > this if we don't add the epoch proprty.
> 
> Sounds fine to me, though I'm not too clear what the epoch property
> is designed to achieve. Is it about avoiding re-probing when re-gaining
> DRM master after having let it go, e.g. VT-switching back from another
> VT? That would be nice.

Yup, pretty much. Plus I think we need the epoch internally in the kernel
anyway, to figure out what has changed without having to rewrite endless
amounts of output detection code in all drivers to pass up a new status
change return code. Because atm we totally fail to track sink-related
changes from short pulse hpd (i.e. stays connected, but e.g. edid
changed).

> > > That should be also backwards-compatible: any userspace that doesn't
> > > understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> > > userspace that doesn't understand PROPERTY or the property it refers to
> > > will fall back to probing either the connector or everything.  
> > 
> > Agreed, that should work.
> 
> Cool. The epoch exception you worded seems to fit backward-compatible
> as well.
> 
> > 
> > > I would be happy to get that behaviour into Weston, particularly as the
> > > HDCP feature is brewing for Weston too.
> > >
> > > --------
> > >
> > > When discussing this in IRC, I had the concern about how uevents are
> > > delivered in userspace. Is there a possibility that they might be
> > > overwritten, contain stale attributes, or get squashed together?
> > >
> > > Particularly if a display server is current on the VT and active and
> > > monitoring udev, but stuck doing something and cannot service uevents
> > > very fast, and the kernel sends more than one event before the process
> > > gets back to dispatching. The terminology in libudev API confused me as
> > > an event is a device. Squashing together would make sense if the
> > > uevent were just updating a device attribute list. Previously when we
> > > had just a single kind of uevent, that would not have made a
> > > difference, but if we gain different kinds of uevents like here, it
> > > starts to matter.
> > >
> > > However, Paul came to the conclusion that we will be ok as long as the
> > > events come via netlink.  
> > 
> > Yeah netlink shouldn't drop events on the floor I think. It might
> > still happen, but then I think you should get an indication of that
> > error, and you just treat it as a general hotplug event like on older
> > kernels.
> 
> Alright, although reading Paul it sounds like there is another
> (fallback?) method as well that wouldn't work. Should userspace worry
> about that?
> 
> Hmm, get an indication of an error... I don't know how that would be
> presented in libudev API and I can't point to any code in Weston that
> would deal with it. Does anyone have a clue about that?
> 
> Userspace cannot really start taking advantage of any new fine-grained
> hotplug events until it can rely on the event delivery. Granted, this
> seems purely a userspace issue, but I bet it could be formulated as a
> kernel regression: things stop working after upgrading the kernel while
> having always used new userspace which was ready for detailed hotplug
> events but didn't ensure the delivery in userspace.

You have this already (if it's really an issue with netlink reliability,
tbh no idea), you can already miss a global uevent. It's easier to catch
up if you do miss it, since you're forcing a reprobe on everything. That's
why I think the EPOCH thing would be good, userspace could be defensive
and always call GetConnectorCurrent on all connectors if it gets any
hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
not sure that's really required (aside from VT switching).

If we do think this is required I wonder whether we even need the more
specific event at all :-)
-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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-15  8:24                       ` Daniel Vetter
@ 2019-05-16  8:22                         ` Pekka Paalanen
  2019-05-16 12:24                           ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-16  8:22 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, maxime.ripard, Daniel Vetter, intel-gfx, dri-devel,
	paul.kocialkowski, airlied, thomas.petazzoni, Vetter, Daniel


[-- Attachment #1.1: Type: text/plain, Size: 13638 bytes --]

On Wed, 15 May 2019 10:24:49 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:
> > On Tue, 14 May 2019 16:34:01 +0200
> > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >   
> > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:  
> > > >
> > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > >    
> > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:    
> > > > > >
> > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:    
> > 
> > ...
> >   
> > > > > > > Hi Daniel,
> > > > > > >
> > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > property:
> > > > > > >
> > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > with a timer.
> > > > > > >
> > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > >
> > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > epoch approach or with any alternate uevent design?
> > > > > > >
> > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > connectors need to be reprobed instead of everything.    
> > > > > >
> > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > reprobing. Would that work?    
> > > >
> > > > Hi,
> > > >
> > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > any new uevent fields in favour of "epoch counters".
> > > >    
> > > > > Yes that's the idea, depending upon which property you get you know
> > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > state machinery update.    
> > > >
> > > > Right.
> > > >    
> > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > That along is a good win already, since you know for which connector
> > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > historically speaking every time we tried to rely on this we ended up
> > > > > regretting things.    
> > > >
> > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > from userspace side:    
> > > 
> > > This sounds solid, some refinements below:
> > >   
> > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > >
> > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > >   re-get the connector properties.
> > > >
> > > > - Kernel probably shouldn't bother sending this for properties where
> > > >   re-probe could be necessary, and send the below instead.    
> > > 
> > > 
> > > I think we should assert that the kernel can get the new property
> > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > to "must"  
> > 
> > Hi Daniel,
> > 
> > ok, that's good.
> >   
> > > Furthermore different property can indicate different kind of updates,
> > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > future.  
> > 
> > What do you mean by different kinds of updates?  
> 
> Atm we're discussing two:
> 
> - "Content Protection"
> - "sink changed, but you don't need to reprobe" this would be quite a bit
>   a catch all from the output detection. Paul thinks differently, but I'm
>   not sold on splitting this up more, at least not right now. This would
>   include connector status (and related things returned by drmGetConnector
>   which currently aren't a property), EDID, the mst path id, that kind of
>   stuff.
> 
> Ime once we have 2, there's more bound to come :-)

Hi Daniel,

I don't understand what the "sink changed" thing could be, but sure,
there can be more.

> > Btw. I started thinking, maybe we should completely leave out the "If
> > yy is "Content Protection"" and require the kernel to guarantee, that
> > if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> > necessary based on this event alone.
> > 
> > Writing it down again:
> > 
> > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > 
> > - yy denotes which connector xx property changed.  
> 
> Maybe yy denotes which group of properties changed, and part of the uapi
> is picking the canonical one. E.g. content protection might also gain more
> properties in the future (there's patches, but the userspace won't be open
> sourced). And for that case I don't think we should then send an even for
> every single individual property, but just for the lead property.
> 
> Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
> better to use the property id we already have for this.

Indeed, it is not really necessary to identify the exact property.

We could even just use PROPERTY=0 to indicate "something may have
changed, you should re-get the properties, but no need to probe I
promise".

Or like you said, whatever. I don't really care as long as the
semantics are the same.

> > - Userspace does not need to do drmModeGetConnector(), it only needs to
> >   drmModeObjectGetProperties() on the connector to receive the new
> >   updated property values.  
> 
> drmModeGetConnector(Current) also supplies all the properties already.
> This is special with connectors, since the predate the "properties on
> everything" design. I'd just mention this function here, and ignore
> drmModeObjectGetProperties.

To avoid confusion, it would be best to mention all three functions
then. It is very easy to forget about legacy uAPI like properties
through GetConnector.

> > - Kernel must not send this event for changes that may require probing
> >   for correct results, exceptional conditions (buggy hardware, etc.)
> >   included. Instead, the kernel must send one of the below events.
> > 
> > Is there actually anything interesting that
> > drmModeGetConnectorCurrent() could guaranteed correctly return that is
> > not a property already? I'd probably leave this consideration out
> > completely, and just say do one of the needs-probing events if anything
> > there changed.  
> 
> That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
> sink related stuff, including the not-properperty-fied stuff is updated,
> and will be reported correctly by GetConnectorCurrent.

Just because GetConnectorCurrent returns the same properties as
drmModeObjectGetProperties? Ok then. Personally I'm quite firmly in the
land where drmModeObjectGetProperties exists, so don't really care
about the legacy stuff.

> > > > HOTPLUG=1 CONNECTOR=xx
> > > >
> > > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > > >   others. Implies that one needs to re-get the connector properties as
> > > >   well.    
> > > 
> > > Sounds good.
> > >   
> > > > HOTPLUG=1
> > > >
> > > > - Need to do drmModeGetResouces() to discover new/disappeared
> > > >   connectors, and need to drmModeGetConnector to re-probe every
> > > >   connector. (As always.)    
> > > 
> > > Maybe we should clarify that this is also what you get when an entire
> > > connector appears/disappears (for dp mst hotplug).  
> > 
> > Yes, that's what I wrote. :-)
> > 
> > Weston implements the discovery of appearing/disappearing connectors
> > (as opposed to connecting/disconnecting connectors). Not sure anyone
> > has ever tested it though...  
> 
> From what -modesetting and X drivers do: Expect surprises in real world
> usage :-/

I don't know what they do, but sure, always. :-)

As long as no-one uses untested Weston code to scream "kernel
regression"...

> > > Maybe we could make an additional rule that if a connector has the
> > > EPOCH property, then it does _not_ need to be reprobe for the global
> > > events. For that case userspace should only check whether there's
> > > new/removed connectors, and then probe the new ones (and disable the
> > > removed ones as needed). We can also use some other flag to indicate
> > > this if we don't add the epoch proprty.  
> > 
> > Sounds fine to me, though I'm not too clear what the epoch property
> > is designed to achieve. Is it about avoiding re-probing when re-gaining
> > DRM master after having let it go, e.g. VT-switching back from another
> > VT? That would be nice.  
> 
> Yup, pretty much. Plus I think we need the epoch internally in the kernel
> anyway, to figure out what has changed without having to rewrite endless
> amounts of output detection code in all drivers to pass up a new status
> change return code. Because atm we totally fail to track sink-related
> changes from short pulse hpd (i.e. stays connected, but e.g. edid
> changed).

I do not care at all what you might need internally. ;-)

I am solely interested in the uAPI, and will not look at kernel code. I
just don't have the time for that.

> > > > That should be also backwards-compatible: any userspace that doesn't
> > > > understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> > > > userspace that doesn't understand PROPERTY or the property it refers to
> > > > will fall back to probing either the connector or everything.    
> > > 
> > > Agreed, that should work.  
> > 
> > Cool. The epoch exception you worded seems to fit backward-compatible
> > as well.
> >   
> > >   
> > > > I would be happy to get that behaviour into Weston, particularly as the
> > > > HDCP feature is brewing for Weston too.
> > > >
> > > > --------
> > > >
> > > > When discussing this in IRC, I had the concern about how uevents are
> > > > delivered in userspace. Is there a possibility that they might be
> > > > overwritten, contain stale attributes, or get squashed together?
> > > >
> > > > Particularly if a display server is current on the VT and active and
> > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > very fast, and the kernel sends more than one event before the process
> > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > an event is a device. Squashing together would make sense if the
> > > > uevent were just updating a device attribute list. Previously when we
> > > > had just a single kind of uevent, that would not have made a
> > > > difference, but if we gain different kinds of uevents like here, it
> > > > starts to matter.
> > > >
> > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > events come via netlink.    
> > > 
> > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > still happen, but then I think you should get an indication of that
> > > error, and you just treat it as a general hotplug event like on older
> > > kernels.  
> > 
> > Alright, although reading Paul it sounds like there is another
> > (fallback?) method as well that wouldn't work. Should userspace worry
> > about that?
> > 
> > Hmm, get an indication of an error... I don't know how that would be
> > presented in libudev API and I can't point to any code in Weston that
> > would deal with it. Does anyone have a clue about that?
> > 
> > Userspace cannot really start taking advantage of any new fine-grained
> > hotplug events until it can rely on the event delivery. Granted, this
> > seems purely a userspace issue, but I bet it could be formulated as a
> > kernel regression: things stop working after upgrading the kernel while
> > having always used new userspace which was ready for detailed hotplug
> > events but didn't ensure the delivery in userspace.  
> 
> You have this already (if it's really an issue with netlink reliability,
> tbh no idea), you can already miss a global uevent. It's easier to catch
> up if you do miss it, since you're forcing a reprobe on everything. That's
> why I think the EPOCH thing would be good, userspace could be defensive
> and always call GetConnectorCurrent on all connectors if it gets any
> hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> not sure that's really required (aside from VT switching).

No, my concern is not an issue with netlink reliability. It is a
potential issue when userspace chooses to not use netlink, and uses
something else instead. I'm not sure what that else is but Paul says
there is code in libudev and that is completely outside the control of
KMS apps like display servers.

Can you explain how one could miss a global hotplug event when
userspace is using netlink to watch for events? I thought the netlink
path through libudev was reliable. And how does userspace realize it
missed an event?


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-16  8:22                         ` Pekka Paalanen
@ 2019-05-16 12:24                           ` Daniel Vetter
  2019-05-17 10:08                             ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-05-16 12:24 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, thomas.petazzoni, maxime.ripard, Daniel Vetter,
	intel-gfx, dri-devel, paul.kocialkowski, airlied, Vetter, Daniel

On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:
> On Wed, 15 May 2019 10:24:49 +0200
> Daniel Vetter <daniel@ffwll.ch> wrote:
> 
> > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:
> > > On Tue, 14 May 2019 16:34:01 +0200
> > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >   
> > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:  
> > > > >
> > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > >    
> > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:    
> > > > > > >
> > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:    
> > > 
> > > ...
> > >   
> > > > > > > > Hi Daniel,
> > > > > > > >
> > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > property:
> > > > > > > >
> > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > with a timer.
> > > > > > > >
> > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > >
> > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > >
> > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > connectors need to be reprobed instead of everything.    
> > > > > > >
> > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > reprobing. Would that work?    
> > > > >
> > > > > Hi,
> > > > >
> > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > any new uevent fields in favour of "epoch counters".
> > > > >    
> > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > state machinery update.    
> > > > >
> > > > > Right.
> > > > >    
> > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > That along is a good win already, since you know for which connector
> > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > regretting things.    
> > > > >
> > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > from userspace side:    
> > > > 
> > > > This sounds solid, some refinements below:
> > > >   
> > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > >
> > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > >   re-get the connector properties.
> > > > >
> > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > >   re-probe could be necessary, and send the below instead.    
> > > > 
> > > > 
> > > > I think we should assert that the kernel can get the new property
> > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > to "must"  
> > > 
> > > Hi Daniel,
> > > 
> > > ok, that's good.
> > >   
> > > > Furthermore different property can indicate different kind of updates,
> > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > future.  
> > > 
> > > What do you mean by different kinds of updates?  
> > 
> > Atm we're discussing two:
> > 
> > - "Content Protection"
> > - "sink changed, but you don't need to reprobe" this would be quite a bit
> >   a catch all from the output detection. Paul thinks differently, but I'm
> >   not sold on splitting this up more, at least not right now. This would
> >   include connector status (and related things returned by drmGetConnector
> >   which currently aren't a property), EDID, the mst path id, that kind of
> >   stuff.
> > 
> > Ime once we have 2, there's more bound to come :-)
> 
> Hi Daniel,
> 
> I don't understand what the "sink changed" thing could be, but sure,
> there can be more.

So if you have a repeater (hdmi or dp) and you change the thing you plug
into that, then on the computer you don't get a full hotplug, because the
repeater was always connected. Instead you get a short pulse hotplug,
indicating that something with the sink has changed. This could be a
slightly adjusted EDID (e.g. different eld in the audio section), or
something else. That's what I mean with "sink changed". Similar thing can
happen if you unplug and then plug in something else real quick (usually
over suspend/resume), where connector->status stays the same, but the
actual thing plugged in is different. I think for hdmi this is just the
EDID, but we do parse a bunch of things out of the EDID that have further
effects (color space, max clock). With DP there's also dp aux stuff, e.g.
if you switch from a 2 lane to a 4 lane cable then with same screen more
modes can work.

Clearer?

I guess for the documentation for this new uapi we need to make an
exhaustive list of all the things that might have changed for a "sink
changed" event, whatever we actually agree on what that should look like.
Or the PROPERTY=0 fallback you mention below as a fallback idea.

> > > Btw. I started thinking, maybe we should completely leave out the "If
> > > yy is "Content Protection"" and require the kernel to guarantee, that
> > > if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> > > necessary based on this event alone.
> > > 
> > > Writing it down again:
> > > 
> > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > 
> > > - yy denotes which connector xx property changed.  
> > 
> > Maybe yy denotes which group of properties changed, and part of the uapi
> > is picking the canonical one. E.g. content protection might also gain more
> > properties in the future (there's patches, but the userspace won't be open
> > sourced). And for that case I don't think we should then send an even for
> > every single individual property, but just for the lead property.
> > 
> > Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
> > better to use the property id we already have for this.
> 
> Indeed, it is not really necessary to identify the exact property.
> 
> We could even just use PROPERTY=0 to indicate "something may have
> changed, you should re-get the properties, but no need to probe I
> promise".
> 
> Or like you said, whatever. I don't really care as long as the
> semantics are the same.
> 
> > > - Userspace does not need to do drmModeGetConnector(), it only needs to
> > >   drmModeObjectGetProperties() on the connector to receive the new
> > >   updated property values.  
> > 
> > drmModeGetConnector(Current) also supplies all the properties already.
> > This is special with connectors, since the predate the "properties on
> > everything" design. I'd just mention this function here, and ignore
> > drmModeObjectGetProperties.
> 
> To avoid confusion, it would be best to mention all three functions
> then. It is very easy to forget about legacy uAPI like properties
> through GetConnector.
> 
> > > - Kernel must not send this event for changes that may require probing
> > >   for correct results, exceptional conditions (buggy hardware, etc.)
> > >   included. Instead, the kernel must send one of the below events.
> > > 
> > > Is there actually anything interesting that
> > > drmModeGetConnectorCurrent() could guaranteed correctly return that is
> > > not a property already? I'd probably leave this consideration out
> > > completely, and just say do one of the needs-probing events if anything
> > > there changed.  
> > 
> > That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
> > sink related stuff, including the not-properperty-fied stuff is updated,
> > and will be reported correctly by GetConnectorCurrent.
> 
> Just because GetConnectorCurrent returns the same properties as
> drmModeObjectGetProperties? Ok then. Personally I'm quite firmly in the
> land where drmModeObjectGetProperties exists, so don't really care
> about the legacy stuff.

So from a quick skimming GetConnectorCurrent == GetProperties, except you
don't get the non-propertified stuff like mode list, ->status, and a few
other things we parse out from various sources. So for connectors you need
to use GetConnector/Current anyway I think, if you rely on GetProperties
only, you're missing stuff.

Agreed that we need to spell this all out.

> > > > > HOTPLUG=1 CONNECTOR=xx
> > > > >
> > > > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > > > >   others. Implies that one needs to re-get the connector properties as
> > > > >   well.    
> > > > 
> > > > Sounds good.
> > > >   
> > > > > HOTPLUG=1
> > > > >
> > > > > - Need to do drmM odeGetResouces() to discover new/disappeared
> > > > >   connectors, and need to drmModeGetConnector to re-probe every
> > > > >   connector. (As always.)    
> > > > 
> > > > Maybe we should clarify that this is also what you get when an entire
> > > > connector appears/disappears (for dp mst hotplug).  
> > > 
> > > Yes, that's what I wrote. :-)
> > > 
> > > Weston implements the discovery of appearing/disappearing connectors
> > > (as opposed to connecting/disconnecting connectors). Not sure anyone
> > > has ever tested it though...  
> > 
> > From what -modesetting and X drivers do: Expect surprises in real world
> > usage :-/
> 
> I don't know what they do, but sure, always. :-)
> 
> As long as no-one uses untested Weston code to scream "kernel
> regression"...
> 
> > > > Maybe we could make an additional rule that if a connector has the
> > > > EPOCH property, then it does _not_ need to be reprobe for the global
> > > > events. For that case userspace should only check whether there's
> > > > new/removed connectors, and then probe the new ones (and disable the
> > > > removed ones as needed). We can also use some other flag to indicate
> > > > this if we don't add the epoch proprty.  
> > > 
> > > Sounds fine to me, though I'm not too clear what the epoch property
> > > is designed to achieve. Is it about avoiding re-probing when re-gaining
> > > DRM master after having let it go, e.g. VT-switching back from another
> > > VT? That would be nice.  
> > 
> > Yup, pretty much. Plus I think we need the epoch internally in the kernel
> > anyway, to figure out what has changed without having to rewrite endless
> > amounts of output detection code in all drivers to pass up a new status
> > change return code. Because atm we totally fail to track sink-related
> > changes from short pulse hpd (i.e. stays connected, but e.g. edid
> > changed).
> 
> I do not care at all what you might need internally. ;-)
> 
> I am solely interested in the uAPI, and will not look at kernel code. I
> just don't have the time for that.
> 
> > > > > That should be also backwards-compatible: any userspace that doesn't
> > > > > understand CONNECTOR will see HOTPLUG=1 and re-probe everything. Any
> > > > > userspace that doesn't understand PROPERTY or the property it refers to
> > > > > will fall back to probing either the connector or everything.    
> > > > 
> > > > Agreed, that should work.  
> > > 
> > > Cool. The epoch exception you worded seems to fit backward-compatible
> > > as well.
> > >   
> > > >   
> > > > > I would be happy to get that behaviour into Weston, particularly as the
> > > > > HDCP feature is brewing for Weston too.
> > > > >
> > > > > --------
> > > > >
> > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > delivered in userspace. Is there a possibility that they might be
> > > > > overwritten, contain stale attributes, or get squashed together?
> > > > >
> > > > > Particularly if a display server is current on the VT and active and
> > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > very fast, and the kernel sends more than one event before the process
> > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > an event is a device. Squashing together would make sense if the
> > > > > uevent were just updating a device attribute list. Previously when we
> > > > > had just a single kind of uevent, that would not have made a
> > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > starts to matter.
> > > > >
> > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > events come via netlink.    
> > > > 
> > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > still happen, but then I think you should get an indication of that
> > > > error, and you just treat it as a general hotplug event like on older
> > > > kernels.  
> > > 
> > > Alright, although reading Paul it sounds like there is another
> > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > about that?
> > > 
> > > Hmm, get an indication of an error... I don't know how that would be
> > > presented in libudev API and I can't point to any code in Weston that
> > > would deal with it. Does anyone have a clue about that?
> > > 
> > > Userspace cannot really start taking advantage of any new fine-grained
> > > hotplug events until it can rely on the event delivery. Granted, this
> > > seems purely a userspace issue, but I bet it could be formulated as a
> > > kernel regression: things stop working after upgrading the kernel while
> > > having always used new userspace which was ready for detailed hotplug
> > > events but didn't ensure the delivery in userspace.  
> > 
> > You have this already (if it's really an issue with netlink reliability,
> > tbh no idea), you can already miss a global uevent. It's easier to catch
> > up if you do miss it, since you're forcing a reprobe on everything. That's
> > why I think the EPOCH thing would be good, userspace could be defensive
> > and always call GetConnectorCurrent on all connectors if it gets any
> > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > not sure that's really required (aside from VT switching).
> 
> No, my concern is not an issue with netlink reliability. It is a
> potential issue when userspace chooses to not use netlink, and uses
> something else instead. I'm not sure what that else is but Paul says
> there is code in libudev and that is completely outside the control of
> KMS apps like display servers.

afaik this other path only exists because it's the older one, for uapi
backwards compatibility with older userspace. Shouldn't be used for
anything.

> Can you explain how one could miss a global hotplug event when
> userspace is using netlink to watch for events? I thought the netlink
> path through libudev was reliable. And how does userspace realize it
> missed an event?

I thought netlink is supposed to be reliable, but then if you send
bazillion of events and userspace is stuck, eventually you will run out of
memory. I have no idea how netlink signals that, and how that's forwarded
or not in libudev. Also not sure whether we should actually care about
this.
-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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-16 12:24                           ` Daniel Vetter
@ 2019-05-17 10:08                             ` Pekka Paalanen
  2019-05-20 16:11                               ` Daniel Vetter
  0 siblings, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-17 10:08 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, maxime.ripard, Daniel Vetter, intel-gfx, dri-devel,
	paul.kocialkowski, airlied, thomas.petazzoni, Vetter, Daniel


[-- Attachment #1.1: Type: text/plain, Size: 17164 bytes --]

On Thu, 16 May 2019 14:24:55 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:
> > On Wed, 15 May 2019 10:24:49 +0200
> > Daniel Vetter <daniel@ffwll.ch> wrote:
> >   
> > > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:  
> > > > On Tue, 14 May 2019 16:34:01 +0200
> > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > >     
> > > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:    
> > > > > >
> > > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > >      
> > > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:      
> > > > > > > >
> > > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:      
> > > > 
> > > > ...
> > > >     
> > > > > > > > > Hi Daniel,
> > > > > > > > >
> > > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > > property:
> > > > > > > > >
> > > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > > with a timer.
> > > > > > > > >
> > > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > > >
> > > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > > >
> > > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > > connectors need to be reprobed instead of everything.      
> > > > > > > >
> > > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > > reprobing. Would that work?      
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > > any new uevent fields in favour of "epoch counters".
> > > > > >      
> > > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > > state machinery update.      
> > > > > >
> > > > > > Right.
> > > > > >      
> > > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > > That along is a good win already, since you know for which connector
> > > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > > regretting things.      
> > > > > >
> > > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > > from userspace side:      
> > > > > 
> > > > > This sounds solid, some refinements below:
> > > > >     
> > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > >
> > > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > > >   re-get the connector properties.
> > > > > >
> > > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > > >   re-probe could be necessary, and send the below instead.      
> > > > > 
> > > > > 
> > > > > I think we should assert that the kernel can get the new property
> > > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > > to "must"    
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > ok, that's good.
> > > >     
> > > > > Furthermore different property can indicate different kind of updates,
> > > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > > future.    
> > > > 
> > > > What do you mean by different kinds of updates?    
> > > 
> > > Atm we're discussing two:
> > > 
> > > - "Content Protection"
> > > - "sink changed, but you don't need to reprobe" this would be quite a bit
> > >   a catch all from the output detection. Paul thinks differently, but I'm
> > >   not sold on splitting this up more, at least not right now. This would
> > >   include connector status (and related things returned by drmGetConnector
> > >   which currently aren't a property), EDID, the mst path id, that kind of
> > >   stuff.
> > > 
> > > Ime once we have 2, there's more bound to come :-)  
> > 
> > Hi Daniel,
> > 
> > I don't understand what the "sink changed" thing could be, but sure,
> > there can be more.  
> 
> So if you have a repeater (hdmi or dp) and you change the thing you plug
> into that, then on the computer you don't get a full hotplug, because the
> repeater was always connected. Instead you get a short pulse hotplug,
> indicating that something with the sink has changed. This could be a
> slightly adjusted EDID (e.g. different eld in the audio section), or
> something else. That's what I mean with "sink changed". Similar thing can
> happen if you unplug and then plug in something else real quick (usually
> over suspend/resume), where connector->status stays the same, but the
> actual thing plugged in is different. I think for hdmi this is just the
> EDID, but we do parse a bunch of things out of the EDID that have further
> effects (color space, max clock). With DP there's also dp aux stuff, e.g.
> if you switch from a 2 lane to a 4 lane cable then with same screen more
> modes can work.
> 
> Clearer?
> 
> I guess for the documentation for this new uapi we need to make an
> exhaustive list of all the things that might have changed for a "sink
> changed" event, whatever we actually agree on what that should look like.
> Or the PROPERTY=0 fallback you mention below as a fallback idea.

Hi Daniel,

to me all that sounds like userspace would better do a probe and start
from scratch with that one connector. Therefore it would fall into the
'HOTPLUG=1 CONNECTOR=xx' case, no PROPERTY.

I suppose I'm missing something?

But also I don't mind, I have always expected there might be more
properties whose change does not require a probe.

So, the kernel does sometimes do the probe on its own as well, right?
Is that completely invisible to userspace, or could it stall some
userspace operations that are not a probe of the same connector?

I really think the design of the uAPI must start with how userspace is
expected to react to the events. For that there are three cases:
re-deiscover and probe everyting, re-probe one connector, re-read
properties of one connector without probe. Userspace can then discover
what exactly changed, just like it already does.

> > > > Btw. I started thinking, maybe we should completely leave out the "If
> > > > yy is "Content Protection"" and require the kernel to guarantee, that
> > > > if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> > > > necessary based on this event alone.
> > > > 
> > > > Writing it down again:
> > > > 
> > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > 
> > > > - yy denotes which connector xx property changed.    
> > > 
> > > Maybe yy denotes which group of properties changed, and part of the uapi
> > > is picking the canonical one. E.g. content protection might also gain more
> > > properties in the future (there's patches, but the userspace won't be open
> > > sourced). And for that case I don't think we should then send an even for
> > > every single individual property, but just for the lead property.
> > > 
> > > Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
> > > better to use the property id we already have for this.  
> > 
> > Indeed, it is not really necessary to identify the exact property.
> > 
> > We could even just use PROPERTY=0 to indicate "something may have
> > changed, you should re-get the properties, but no need to probe I
> > promise".
> > 
> > Or like you said, whatever. I don't really care as long as the
> > semantics are the same.
> >   
> > > > - Userspace does not need to do drmModeGetConnector(), it only needs to
> > > >   drmModeObjectGetProperties() on the connector to receive the new
> > > >   updated property values.    
> > > 
> > > drmModeGetConnector(Current) also supplies all the properties already.
> > > This is special with connectors, since the predate the "properties on
> > > everything" design. I'd just mention this function here, and ignore
> > > drmModeObjectGetProperties.  
> > 
> > To avoid confusion, it would be best to mention all three functions
> > then. It is very easy to forget about legacy uAPI like properties
> > through GetConnector.
> >   
> > > > - Kernel must not send this event for changes that may require probing
> > > >   for correct results, exceptional conditions (buggy hardware, etc.)
> > > >   included. Instead, the kernel must send one of the below events.
> > > > 
> > > > Is there actually anything interesting that
> > > > drmModeGetConnectorCurrent() could guaranteed correctly return that is
> > > > not a property already? I'd probably leave this consideration out
> > > > completely, and just say do one of the needs-probing events if anything
> > > > there changed.    
> > > 
> > > That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
> > > sink related stuff, including the not-properperty-fied stuff is updated,
> > > and will be reported correctly by GetConnectorCurrent.  
> > 
> > Just because GetConnectorCurrent returns the same properties as
> > drmModeObjectGetProperties? Ok then. Personally I'm quite firmly in the
> > land where drmModeObjectGetProperties exists, so don't really care
> > about the legacy stuff.  
> 
> So from a quick skimming GetConnectorCurrent == GetProperties, except you
> don't get the non-propertified stuff like mode list, ->status, and a few
> other things we parse out from various sources. So for connectors you need
> to use GetConnector/Current anyway I think, if you rely on GetProperties
> only, you're missing stuff.

That was part of my question: the stuff I would be missing, does it
matter?

Most of the stuff I would be missing are things that require a probe to
be up-to-date, which means I will not be missing them, because I will
be calling drmModeGetConnector instead (and not GetConnectorCurrent),
because the kernel driver sent an uevent to tell me to do exactly that.

Is there anything in the set of connector parameters which a) do not
require a probe to be up-to-date, and b) are not actual properties too?

If there are, we have two options: complicate userspace to use a third
function to get some bits (drmModeGetConnectorCurrent), or make the
kernel driver just send the uevent that makes userspace probe anyway.

> Agreed that we need to spell this all out.
> 
> > > > > > HOTPLUG=1 CONNECTOR=xx
> > > > > >
> > > > > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > > > > >   others. Implies that one needs to re-get the connector properties as
> > > > > >   well.      
> > > > > 
> > > > > Sounds good.
> > > > >     
> > > > > > HOTPLUG=1
> > > > > >
> > > > > > - Need to do drmM odeGetResouces() to discover new/disappeared
> > > > > >   connectors, and need to drmModeGetConnector to re-probe every
> > > > > >   connector. (As always.)      

...

> > > > > > --------
> > > > > >
> > > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > > delivered in userspace. Is there a possibility that they might be
> > > > > > overwritten, contain stale attributes, or get squashed together?
> > > > > >
> > > > > > Particularly if a display server is current on the VT and active and
> > > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > > very fast, and the kernel sends more than one event before the process
> > > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > > an event is a device. Squashing together would make sense if the
> > > > > > uevent were just updating a device attribute list. Previously when we
> > > > > > had just a single kind of uevent, that would not have made a
> > > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > > starts to matter.
> > > > > >
> > > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > > events come via netlink.      
> > > > > 
> > > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > > still happen, but then I think you should get an indication of that
> > > > > error, and you just treat it as a general hotplug event like on older
> > > > > kernels.    
> > > > 
> > > > Alright, although reading Paul it sounds like there is another
> > > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > > about that?
> > > > 
> > > > Hmm, get an indication of an error... I don't know how that would be
> > > > presented in libudev API and I can't point to any code in Weston that
> > > > would deal with it. Does anyone have a clue about that?
> > > > 
> > > > Userspace cannot really start taking advantage of any new fine-grained
> > > > hotplug events until it can rely on the event delivery. Granted, this
> > > > seems purely a userspace issue, but I bet it could be formulated as a
> > > > kernel regression: things stop working after upgrading the kernel while
> > > > having always used new userspace which was ready for detailed hotplug
> > > > events but didn't ensure the delivery in userspace.    
> > > 
> > > You have this already (if it's really an issue with netlink reliability,
> > > tbh no idea), you can already miss a global uevent. It's easier to catch
> > > up if you do miss it, since you're forcing a reprobe on everything. That's
> > > why I think the EPOCH thing would be good, userspace could be defensive
> > > and always call GetConnectorCurrent on all connectors if it gets any
> > > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > > not sure that's really required (aside from VT switching).  
> > 
> > No, my concern is not an issue with netlink reliability. It is a
> > potential issue when userspace chooses to not use netlink, and uses
> > something else instead. I'm not sure what that else is but Paul says
> > there is code in libudev and that is completely outside the control of
> > KMS apps like display servers.  
> 
> afaik this other path only exists because it's the older one, for uapi
> backwards compatibility with older userspace. Shouldn't be used for
> anything.

"Shouldn't be used" and someone screaming "kernel regression"... are you
sure that path won't matter?

Like some home-brewn distribution that happens to configure their
libudev and kernel to use the old method, uses already new userspace,
and then upgrades the kernel that starts sending fine-grained hotplug
events, resulting the display server randomly handling hotplug wrong.

Reading Airlie's recent rant about kernel regression handling make this
a scary scenario where you would have no other choice than to rip all
the fine-grained uevents out again.

Is there any difference in the kernel code between the old method and
the netlink method? Would it be possible to send fine-grained hotplug
events only through netlink, and fall back to the old 'HOTPLUG=1' for
the old method?

> > Can you explain how one could miss a global hotplug event when
> > userspace is using netlink to watch for events? I thought the netlink
> > path through libudev was reliable. And how does userspace realize it
> > missed an event?  
> 
> I thought netlink is supposed to be reliable, but then if you send
> bazillion of events and userspace is stuck, eventually you will run out of
> memory. I have no idea how netlink signals that, and how that's forwarded
> or not in libudev. Also not sure whether we should actually care about
> this.

Ok. Let's try to keep the number of events low then, e.g. in the case of

	HOTPLUG=1 CONNECTOR=xx PROPERTY=yy

revert to sending just a single uevent with PROPERTY set to 0 instead
if there are more than one such no-probe property changes for the same
connector.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-17 10:08                             ` Pekka Paalanen
@ 2019-05-20 16:11                               ` Daniel Vetter
  2019-05-20 16:24                                 ` Paul Kocialkowski
  2019-05-21  6:55                                 ` Pekka Paalanen
  0 siblings, 2 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-20 16:11 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, thomas.petazzoni, maxime.ripard, Daniel Vetter,
	intel-gfx, dri-devel, paul.kocialkowski, airlied, Vetter, Daniel

On Fri, May 17, 2019 at 01:08:24PM +0300, Pekka Paalanen wrote:
> On Thu, 16 May 2019 14:24:55 +0200
> Daniel Vetter <daniel@ffwll.ch> wrote:
> 
> > On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:
> > > On Wed, 15 May 2019 10:24:49 +0200
> > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > >   
> > > > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:  
> > > > > On Tue, 14 May 2019 16:34:01 +0200
> > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > >     
> > > > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:    
> > > > > > >
> > > > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > > >      
> > > > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:      
> > > > > > > > >
> > > > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:      
> > > > > 
> > > > > ...
> > > > >     
> > > > > > > > > > Hi Daniel,
> > > > > > > > > >
> > > > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > > > property:
> > > > > > > > > >
> > > > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > > > with a timer.
> > > > > > > > > >
> > > > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > > > >
> > > > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > > > >
> > > > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > > > connectors need to be reprobed instead of everything.      
> > > > > > > > >
> > > > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > > > reprobing. Would that work?      
> > > > > > >
> > > > > > > Hi,
> > > > > > >
> > > > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > > > any new uevent fields in favour of "epoch counters".
> > > > > > >      
> > > > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > > > state machinery update.      
> > > > > > >
> > > > > > > Right.
> > > > > > >      
> > > > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > > > That along is a good win already, since you know for which connector
> > > > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > > > regretting things.      
> > > > > > >
> > > > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > > > from userspace side:      
> > > > > > 
> > > > > > This sounds solid, some refinements below:
> > > > > >     
> > > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > > >
> > > > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > > > >   re-get the connector properties.
> > > > > > >
> > > > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > > > >   re-probe could be necessary, and send the below instead.      
> > > > > > 
> > > > > > 
> > > > > > I think we should assert that the kernel can get the new property
> > > > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > > > to "must"    
> > > > > 
> > > > > Hi Daniel,
> > > > > 
> > > > > ok, that's good.
> > > > >     
> > > > > > Furthermore different property can indicate different kind of updates,
> > > > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > > > future.    
> > > > > 
> > > > > What do you mean by different kinds of updates?    
> > > > 
> > > > Atm we're discussing two:
> > > > 
> > > > - "Content Protection"
> > > > - "sink changed, but you don't need to reprobe" this would be quite a bit
> > > >   a catch all from the output detection. Paul thinks differently, but I'm
> > > >   not sold on splitting this up more, at least not right now. This would
> > > >   include connector status (and related things returned by drmGetConnector
> > > >   which currently aren't a property), EDID, the mst path id, that kind of
> > > >   stuff.
> > > > 
> > > > Ime once we have 2, there's more bound to come :-)  
> > > 
> > > Hi Daniel,
> > > 
> > > I don't understand what the "sink changed" thing could be, but sure,
> > > there can be more.  
> > 
> > So if you have a repeater (hdmi or dp) and you change the thing you plug
> > into that, then on the computer you don't get a full hotplug, because the
> > repeater was always connected. Instead you get a short pulse hotplug,
> > indicating that something with the sink has changed. This could be a
> > slightly adjusted EDID (e.g. different eld in the audio section), or
> > something else. That's what I mean with "sink changed". Similar thing can
> > happen if you unplug and then plug in something else real quick (usually
> > over suspend/resume), where connector->status stays the same, but the
> > actual thing plugged in is different. I think for hdmi this is just the
> > EDID, but we do parse a bunch of things out of the EDID that have further
> > effects (color space, max clock). With DP there's also dp aux stuff, e.g.
> > if you switch from a 2 lane to a 4 lane cable then with same screen more
> > modes can work.
> > 
> > Clearer?
> > 
> > I guess for the documentation for this new uapi we need to make an
> > exhaustive list of all the things that might have changed for a "sink
> > changed" event, whatever we actually agree on what that should look like.
> > Or the PROPERTY=0 fallback you mention below as a fallback idea.
> 
> Hi Daniel,
> 
> to me all that sounds like userspace would better do a probe and start
> from scratch with that one connector. Therefore it would fall into the
> 'HOTPLUG=1 CONNECTOR=xx' case, no PROPERTY.
> 
> I suppose I'm missing something?

Doing a full probe is hella expensive. Atm you always have to do this, but
we're talking about the brave new future where the kernel sucks less, and
the kernel would have done the expensive probing for you already.

> But also I don't mind, I have always expected there might be more
> properties whose change does not require a probe.
> 
> So, the kernel does sometimes do the probe on its own as well, right?
> Is that completely invisible to userspace, or could it stall some
> userspace operations that are not a probe of the same connector?

Major stall because the locking design isn't pretty. If the kernel is
probing right now even your GetConnectorCurrent or GetProperties (on a
connector) will stall for whatever long it takes to read the EDID. Or
whatever else the kernel is doing in the probe paths right now. We could
probably improve this, and make sure that at least GetConnectorCurrent and
GetProperties stop sucking. But needs some serious locking-fu to make that
work.

Aside: Just realized this is another important reason why we need to batch
up property updates. If we don't, then userspace will simply get held up
until the kernel is done anyway.

> I really think the design of the uAPI must start with how userspace is
> expected to react to the events. For that there are three cases:
> re-deiscover and probe everyting, re-probe one connector, re-read
> properties of one connector without probe. Userspace can then discover
> what exactly changed, just like it already does.

Yup, I think on this we all agree.

> > > > > Btw. I started thinking, maybe we should completely leave out the "If
> > > > > yy is "Content Protection"" and require the kernel to guarantee, that
> > > > > if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> > > > > necessary based on this event alone.
> > > > > 
> > > > > Writing it down again:
> > > > > 
> > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > 
> > > > > - yy denotes which connector xx property changed.    
> > > > 
> > > > Maybe yy denotes which group of properties changed, and part of the uapi
> > > > is picking the canonical one. E.g. content protection might also gain more
> > > > properties in the future (there's patches, but the userspace won't be open
> > > > sourced). And for that case I don't think we should then send an even for
> > > > every single individual property, but just for the lead property.
> > > > 
> > > > Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
> > > > better to use the property id we already have for this.  
> > > 
> > > Indeed, it is not really necessary to identify the exact property.
> > > 
> > > We could even just use PROPERTY=0 to indicate "something may have
> > > changed, you should re-get the properties, but no need to probe I
> > > promise".
> > > 
> > > Or like you said, whatever. I don't really care as long as the
> > > semantics are the same.
> > >   
> > > > > - Userspace does not need to do drmModeGetConnector(), it only needs to
> > > > >   drmModeObjectGetProperties() on the connector to receive the new
> > > > >   updated property values.    
> > > > 
> > > > drmModeGetConnector(Current) also supplies all the properties already.
> > > > This is special with connectors, since the predate the "properties on
> > > > everything" design. I'd just mention this function here, and ignore
> > > > drmModeObjectGetProperties.  
> > > 
> > > To avoid confusion, it would be best to mention all three functions
> > > then. It is very easy to forget about legacy uAPI like properties
> > > through GetConnector.
> > >   
> > > > > - Kernel must not send this event for changes that may require probing
> > > > >   for correct results, exceptional conditions (buggy hardware, etc.)
> > > > >   included. Instead, the kernel must send one of the below events.
> > > > > 
> > > > > Is there actually anything interesting that
> > > > > drmModeGetConnectorCurrent() could guaranteed correctly return that is
> > > > > not a property already? I'd probably leave this consideration out
> > > > > completely, and just say do one of the needs-probing events if anything
> > > > > there changed.    
> > > > 
> > > > That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
> > > > sink related stuff, including the not-properperty-fied stuff is updated,
> > > > and will be reported correctly by GetConnectorCurrent.  
> > > 
> > > Just because GetConnectorCurrent returns the same properties as
> > > drmModeObjectGetProperties? Ok then. Personally I'm quite firmly in the
> > > land where drmModeObjectGetProperties exists, so don't really care
> > > about the legacy stuff.  
> > 
> > So from a quick skimming GetConnectorCurrent == GetProperties, except you
> > don't get the non-propertified stuff like mode list, ->status, and a few
> > other things we parse out from various sources. So for connectors you need
> > to use GetConnector/Current anyway I think, if you rely on GetProperties
> > only, you're missing stuff.
> 
> That was part of my question: the stuff I would be missing, does it
> matter?
> 
> Most of the stuff I would be missing are things that require a probe to
> be up-to-date, which means I will not be missing them, because I will
> be calling drmModeGetConnector instead (and not GetConnectorCurrent),
> because the kernel driver sent an uevent to tell me to do exactly that.

Yes currently that's true, because the kernel sucks. But it would be nice
if we could do the expensive probing all upfront, for most connectors, and
(at least eventually) block userspace's uevent handler a bit less.

> Is there anything in the set of connector parameters which a) do not
> require a probe to be up-to-date, and b) are not actual properties too?

Not yet. I'd like to make the kernel suck less though (and at least for
dp/hdmi we should be able to do that with few changes).

> If there are, we have two options: complicate userspace to use a third
> function to get some bits (drmModeGetConnectorCurrent), or make the
> kernel driver just send the uevent that makes userspace probe anyway.

See above, I want to get the expensive probe stuff out of the ueven as
much as possible. Reading an EDID usually means you miss a frame (~20ms
for your average hdmi edid, can be a lot more). Except if you bother with
thread your compositor, and then why does the kernel suck that much :-/

> > Agreed that we need to spell this all out.
> > 
> > > > > > > HOTPLUG=1 CONNECTOR=xx
> > > > > > >
> > > > > > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > > > > > >   others. Implies that one needs to re-get the connector properties as
> > > > > > >   well.      
> > > > > > 
> > > > > > Sounds good.
> > > > > >     
> > > > > > > HOTPLUG=1
> > > > > > >
> > > > > > > - Need to do drmM odeGetResouces() to discover new/disappeared
> > > > > > >   connectors, and need to drmModeGetConnector to re-probe every
> > > > > > >   connector. (As always.)      
> 
> ...
> 
> > > > > > > --------
> > > > > > >
> > > > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > > > delivered in userspace. Is there a possibility that they might be
> > > > > > > overwritten, contain stale attributes, or get squashed together?
> > > > > > >
> > > > > > > Particularly if a display server is current on the VT and active and
> > > > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > > > very fast, and the kernel sends more than one event before the process
> > > > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > > > an event is a device. Squashing together would make sense if the
> > > > > > > uevent were just updating a device attribute list. Previously when we
> > > > > > > had just a single kind of uevent, that would not have made a
> > > > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > > > starts to matter.
> > > > > > >
> > > > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > > > events come via netlink.      
> > > > > > 
> > > > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > > > still happen, but then I think you should get an indication of that
> > > > > > error, and you just treat it as a general hotplug event like on older
> > > > > > kernels.    
> > > > > 
> > > > > Alright, although reading Paul it sounds like there is another
> > > > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > > > about that?
> > > > > 
> > > > > Hmm, get an indication of an error... I don't know how that would be
> > > > > presented in libudev API and I can't point to any code in Weston that
> > > > > would deal with it. Does anyone have a clue about that?
> > > > > 
> > > > > Userspace cannot really start taking advantage of any new fine-grained
> > > > > hotplug events until it can rely on the event delivery. Granted, this
> > > > > seems purely a userspace issue, but I bet it could be formulated as a
> > > > > kernel regression: things stop working after upgrading the kernel while
> > > > > having always used new userspace which was ready for detailed hotplug
> > > > > events but didn't ensure the delivery in userspace.    
> > > > 
> > > > You have this already (if it's really an issue with netlink reliability,
> > > > tbh no idea), you can already miss a global uevent. It's easier to catch
> > > > up if you do miss it, since you're forcing a reprobe on everything. That's
> > > > why I think the EPOCH thing would be good, userspace could be defensive
> > > > and always call GetConnectorCurrent on all connectors if it gets any
> > > > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > > > not sure that's really required (aside from VT switching).  
> > > 
> > > No, my concern is not an issue with netlink reliability. It is a
> > > potential issue when userspace chooses to not use netlink, and uses
> > > something else instead. I'm not sure what that else is but Paul says
> > > there is code in libudev and that is completely outside the control of
> > > KMS apps like display servers.  
> > 
> > afaik this other path only exists because it's the older one, for uapi
> > backwards compatibility with older userspace. Shouldn't be used for
> > anything.
> 
> "Shouldn't be used" and someone screaming "kernel regression"... are you
> sure that path won't matter?
> 
> Like some home-brewn distribution that happens to configure their
> libudev and kernel to use the old method, uses already new userspace,
> and then upgrades the kernel that starts sending fine-grained hotplug
> events, resulting the display server randomly handling hotplug wrong.
> 
> Reading Airlie's recent rant about kernel regression handling make this
> a scary scenario where you would have no other choice than to rip all
> the fine-grained uevents out again.
> 
> Is there any difference in the kernel code between the old method and
> the netlink method? Would it be possible to send fine-grained hotplug
> events only through netlink, and fall back to the old 'HOTPLUG=1' for
> the old method?

There's a lot of grey in kernel regressions, and for fringe setups used by
few people I wouldn't worry about this. If they expect their shit to keep
working when using new stuff and crappy old interfaces, they get to keep
all the pieces.

Dave's recent rant was a bit special, since userspace is clearly smoking
some strong stuff (-modesetting's atomic is seriously not using atomic
correctly), but it was also affecting too many people, and changing the
boot setup meant you'd get a black screen on boot-up already. Instead of
just on the first modeset with more than 1 screen.

There's also a fairly easy fix for that -modesetting issue: We don't
expose atomic if the compositor has a process name of "Xserver". Brutal,
but gets the job done. Once X is fixed, we can give a new "I'm not totally
broken anymore" interface to get back at atomic.

tldr; I'm not worried at all, at least not more than with anything uapi.
Very rarely we'll have regrets.

> > > Can you explain how one could miss a global hotplug event when
> > > userspace is using netlink to watch for events? I thought the netlink
> > > path through libudev was reliable. And how does userspace realize it
> > > missed an event?  
> > 
> > I thought netlink is supposed to be reliable, but then if you send
> > bazillion of events and userspace is stuck, eventually you will run out of
> > memory. I have no idea how netlink signals that, and how that's forwarded
> > or not in libudev. Also not sure whether we should actually care about
> > this.
> 
> Ok. Let's try to keep the number of events low then, e.g. in the case of
> 
> 	HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> 
> revert to sending just a single uevent with PROPERTY set to 0 instead
> if there are more than one such no-probe property changes for the same
> connector.

Yeah PROPERTY=0 would be another option. I think indicates clearly "don't
reprobe" but also "update not for any specific prop, but for all of
them".

Cheers, 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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-20 16:11                               ` Daniel Vetter
@ 2019-05-20 16:24                                 ` Paul Kocialkowski
  2019-05-21  6:55                                 ` Pekka Paalanen
  1 sibling, 0 replies; 70+ messages in thread
From: Paul Kocialkowski @ 2019-05-20 16:24 UTC (permalink / raw)
  To: Daniel Vetter, Pekka Paalanen
  Cc: maxime.ripard, Daniel Vetter, intel-gfx, dri-devel, Ser, Simon,
	airlied, thomas.petazzoni, Vetter, Daniel

Le lundi 20 mai 2019 à 18:11 +0200, Daniel Vetter a écrit :
> On Fri, May 17, 2019 at 01:08:24PM +0300, Pekka Paalanen wrote:
> > On Thu, 16 May 2019 14:24:55 +0200
> > Daniel Vetter <daniel@ffwll.ch> wrote:
> > 
> > > On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:
> > > > On Wed, 15 May 2019 10:24:49 +0200
> > > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > > >   
> > > > > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:  
> > > > > > On Tue, 14 May 2019 16:34:01 +0200
> > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > >     
> > > > > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:    
> > > > > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > > > >      
> > > > > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:      
> > > > > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:      
> > > > > > 
> > > > > > ...
> > > > > >     
> > > > > > > > > > > Hi Daniel,
> > > > > > > > > > > 
> > > > > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > > > > property:
> > > > > > > > > > > 
> > > > > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > > > > with a timer.
> > > > > > > > > > > 
> > > > > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > > > > > 
> > > > > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > > > > > 
> > > > > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > > > > connectors need to be reprobed instead of everything.      
> > > > > > > > > > 
> > > > > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > > > > reprobing. Would that work?      
> > > > > > > > 
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > > > > any new uevent fields in favour of "epoch counters".
> > > > > > > >      
> > > > > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > > > > state machinery update.      
> > > > > > > > 
> > > > > > > > Right.
> > > > > > > >      
> > > > > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > > > > That along is a good win already, since you know for which connector
> > > > > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > > > > regretting things.      
> > > > > > > > 
> > > > > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > > > > from userspace side:      
> > > > > > > 
> > > > > > > This sounds solid, some refinements below:
> > > > > > >     
> > > > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > > > > 
> > > > > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > > > > >   re-get the connector properties.
> > > > > > > > 
> > > > > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > > > > >   re-probe could be necessary, and send the below instead.      
> > > > > > > 
> > > > > > > I think we should assert that the kernel can get the new property
> > > > > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > > > > to "must"    
> > > > > > 
> > > > > > Hi Daniel,
> > > > > > 
> > > > > > ok, that's good.
> > > > > >     
> > > > > > > Furthermore different property can indicate different kind of updates,
> > > > > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > > > > future.    
> > > > > > 
> > > > > > What do you mean by different kinds of updates?    
> > > > > 
> > > > > Atm we're discussing two:
> > > > > 
> > > > > - "Content Protection"
> > > > > - "sink changed, but you don't need to reprobe" this would be quite a bit
> > > > >   a catch all from the output detection. Paul thinks differently, but I'm
> > > > >   not sold on splitting this up more, at least not right now. This would
> > > > >   include connector status (and related things returned by drmGetConnector
> > > > >   which currently aren't a property), EDID, the mst path id, that kind of
> > > > >   stuff.
> > > > > 
> > > > > Ime once we have 2, there's more bound to come :-)  
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > I don't understand what the "sink changed" thing could be, but sure,
> > > > there can be more.  
> > > 
> > > So if you have a repeater (hdmi or dp) and you change the thing you plug
> > > into that, then on the computer you don't get a full hotplug, because the
> > > repeater was always connected. Instead you get a short pulse hotplug,
> > > indicating that something with the sink has changed. This could be a
> > > slightly adjusted EDID (e.g. different eld in the audio section), or
> > > something else. That's what I mean with "sink changed". Similar thing can
> > > happen if you unplug and then plug in something else real quick (usually
> > > over suspend/resume), where connector->status stays the same, but the
> > > actual thing plugged in is different. I think for hdmi this is just the
> > > EDID, but we do parse a bunch of things out of the EDID that have further
> > > effects (color space, max clock). With DP there's also dp aux stuff, e.g.
> > > if you switch from a 2 lane to a 4 lane cable then with same screen more
> > > modes can work.
> > > 
> > > Clearer?
> > > 
> > > I guess for the documentation for this new uapi we need to make an
> > > exhaustive list of all the things that might have changed for a "sink
> > > changed" event, whatever we actually agree on what that should look like.
> > > Or the PROPERTY=0 fallback you mention below as a fallback idea.
> > 
> > Hi Daniel,
> > 
> > to me all that sounds like userspace would better do a probe and start
> > from scratch with that one connector. Therefore it would fall into the
> > 'HOTPLUG=1 CONNECTOR=xx' case, no PROPERTY.
> > 
> > I suppose I'm missing something?
> 
> Doing a full probe is hella expensive. Atm you always have to do this, but
> we're talking about the brave new future where the kernel sucks less, and
> the kernel would have done the expensive probing for you already.
>
> > But also I don't mind, I have always expected there might be more
> > properties whose change does not require a probe.
> > 
> > So, the kernel does sometimes do the probe on its own as well, right?
> > Is that completely invisible to userspace, or could it stall some
> > userspace operations that are not a probe of the same connector?
> 
> Major stall because the locking design isn't pretty. If the kernel is
> probing right now even your GetConnectorCurrent or GetProperties (on a
> connector) will stall for whatever long it takes to read the EDID. Or
> whatever else the kernel is doing in the probe paths right now. We could
> probably improve this, and make sure that at least GetConnectorCurrent and
> GetProperties stop sucking. But needs some serious locking-fu to make that
> work.
> 
> Aside: Just realized this is another important reason why we need to batch
> up property updates. If we don't, then userspace will simply get held up
> until the kernel is done anyway.

I'm all in favor of having the kernel do the probing on its own (and
reworking things to make sure this doesn't stall uapi calls) while
only sending a uevent when we have a new connector state populated and ready.

> > I really think the design of the uAPI must start with how userspace is
> > expected to react to the events. For that there are three cases:
> > re-deiscover and probe everyting, re-probe one connector, re-read
> > properties of one connector without probe. Userspace can then discover
> > what exactly changed, just like it already does.
> 
> Yup, I think on this we all agree.
> 
> > > > > > Btw. I started thinking, maybe we should completely leave out the "If
> > > > > > yy is "Content Protection"" and require the kernel to guarantee, that
> > > > > > if PROPERTY is set, then drmModeGetConnector() (probing) must not be
> > > > > > necessary based on this event alone.
> > > > > > 
> > > > > > Writing it down again:
> > > > > > 
> > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > > 
> > > > > > - yy denotes which connector xx property changed.    
> > > > > 
> > > > > Maybe yy denotes which group of properties changed, and part of the uapi
> > > > > is picking the canonical one. E.g. content protection might also gain more
> > > > > properties in the future (there's patches, but the userspace won't be open
> > > > > sourced). And for that case I don't think we should then send an even for
> > > > > every single individual property, but just for the lead property.
> > > > > 
> > > > > Maybe we should change it to UPDATE_TYPE=<some-unique-string>, but it felt
> > > > > better to use the property id we already have for this.  
> > > > 
> > > > Indeed, it is not really necessary to identify the exact property.
> > > > 
> > > > We could even just use PROPERTY=0 to indicate "something may have
> > > > changed, you should re-get the properties, but no need to probe I
> > > > promise".
> > > > 
> > > > Or like you said, whatever. I don't really care as long as the
> > > > semantics are the same.
> > > >   
> > > > > > - Userspace does not need to do drmModeGetConnector(), it only needs to
> > > > > >   drmModeObjectGetProperties() on the connector to receive the new
> > > > > >   updated property values.    
> > > > > 
> > > > > drmModeGetConnector(Current) also supplies all the properties already.
> > > > > This is special with connectors, since the predate the "properties on
> > > > > everything" design. I'd just mention this function here, and ignore
> > > > > drmModeObjectGetProperties.  
> > > > 
> > > > To avoid confusion, it would be best to mention all three functions
> > > > then. It is very easy to forget about legacy uAPI like properties
> > > > through GetConnector.
> > > >   
> > > > > > - Kernel must not send this event for changes that may require probing
> > > > > >   for correct results, exceptional conditions (buggy hardware, etc.)
> > > > > >   included. Instead, the kernel must send one of the below events.
> > > > > > 
> > > > > > Is there actually anything interesting that
> > > > > > drmModeGetConnectorCurrent() could guaranteed correctly return that is
> > > > > > not a property already? I'd probably leave this consideration out
> > > > > > completely, and just say do one of the needs-probing events if anything
> > > > > > there changed.    
> > > > > 
> > > > > That's why I'm suggesting the PROPERTY=<epoch_prop_id> would indicate all
> > > > > sink related stuff, including the not-properperty-fied stuff is updated,
> > > > > and will be reported correctly by GetConnectorCurrent.  
> > > > 
> > > > Just because GetConnectorCurrent returns the same properties as
> > > > drmModeObjectGetProperties? Ok then. Personally I'm quite firmly in the
> > > > land where drmModeObjectGetProperties exists, so don't really care
> > > > about the legacy stuff.  
> > > 
> > > So from a quick skimming GetConnectorCurrent == GetProperties, except you
> > > don't get the non-propertified stuff like mode list, ->status, and a few
> > > other things we parse out from various sources. So for connectors you need
> > > to use GetConnector/Current anyway I think, if you rely on GetProperties
> > > only, you're missing stuff.
> > 
> > That was part of my question: the stuff I would be missing, does it
> > matter?
> > 
> > Most of the stuff I would be missing are things that require a probe to
> > be up-to-date, which means I will not be missing them, because I will
> > be calling drmModeGetConnector instead (and not GetConnectorCurrent),
> > because the kernel driver sent an uevent to tell me to do exactly that.
> 
> Yes currently that's true, because the kernel sucks. But it would be nice
> if we could do the expensive probing all upfront, for most connectors, and
> (at least eventually) block userspace's uevent handler a bit less.

Agreed.

> > Is there anything in the set of connector parameters which a) do not
> > require a probe to be up-to-date, and b) are not actual properties too?
> 
> Not yet. I'd like to make the kernel suck less though (and at least for
> dp/hdmi we should be able to do that with few changes).
> 
> > If there are, we have two options: complicate userspace to use a third
> > function to get some bits (drmModeGetConnectorCurrent), or make the
> > kernel driver just send the uevent that makes userspace probe anyway.
> 
> See above, I want to get the expensive probe stuff out of the ueven as
> much as possible. Reading an EDID usually means you miss a frame (~20ms
> for your average hdmi edid, can be a lot more). Except if you bother with
> thread your compositor, and then why does the kernel suck that much :-/
> 
> > > Agreed that we need to spell this all out.
> > > 
> > > > > > > > HOTPLUG=1 CONNECTOR=xx
> > > > > > > > 
> > > > > > > > - Needs to drmModeGetConnector() on the one connector, no need to probe
> > > > > > > >   others. Implies that one needs to re-get the connector properties as
> > > > > > > >   well.      
> > > > > > > 
> > > > > > > Sounds good.
> > > > > > >     
> > > > > > > > HOTPLUG=1
> > > > > > > > 
> > > > > > > > - Need to do drmM odeGetResouces() to discover new/disappeared
> > > > > > > >   connectors, and need to drmModeGetConnector to re-probe every
> > > > > > > >   connector. (As always.)      
> > 
> > ...
> > 
> > > > > > > > --------
> > > > > > > > 
> > > > > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > > > > delivered in userspace. Is there a possibility that they might be
> > > > > > > > overwritten, contain stale attributes, or get squashed together?
> > > > > > > > 
> > > > > > > > Particularly if a display server is current on the VT and active and
> > > > > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > > > > very fast, and the kernel sends more than one event before the process
> > > > > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > > > > an event is a device. Squashing together would make sense if the
> > > > > > > > uevent were just updating a device attribute list. Previously when we
> > > > > > > > had just a single kind of uevent, that would not have made a
> > > > > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > > > > starts to matter.
> > > > > > > > 
> > > > > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > > > > events come via netlink.      
> > > > > > > 
> > > > > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > > > > still happen, but then I think you should get an indication of that
> > > > > > > error, and you just treat it as a general hotplug event like on older
> > > > > > > kernels.    
> > > > > > 
> > > > > > Alright, although reading Paul it sounds like there is another
> > > > > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > > > > about that?
> > > > > > 
> > > > > > Hmm, get an indication of an error... I don't know how that would be
> > > > > > presented in libudev API and I can't point to any code in Weston that
> > > > > > would deal with it. Does anyone have a clue about that?
> > > > > > 
> > > > > > Userspace cannot really start taking advantage of any new fine-grained
> > > > > > hotplug events until it can rely on the event delivery. Granted, this
> > > > > > seems purely a userspace issue, but I bet it could be formulated as a
> > > > > > kernel regression: things stop working after upgrading the kernel while
> > > > > > having always used new userspace which was ready for detailed hotplug
> > > > > > events but didn't ensure the delivery in userspace.    
> > > > > 
> > > > > You have this already (if it's really an issue with netlink reliability,
> > > > > tbh no idea), you can already miss a global uevent. It's easier to catch
> > > > > up if you do miss it, since you're forcing a reprobe on everything. That's
> > > > > why I think the EPOCH thing would be good, userspace could be defensive
> > > > > and always call GetConnectorCurrent on all connectors if it gets any
> > > > > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > > > > not sure that's really required (aside from VT switching).  
> > > > 
> > > > No, my concern is not an issue with netlink reliability. It is a
> > > > potential issue when userspace chooses to not use netlink, and uses
> > > > something else instead. I'm not sure what that else is but Paul says
> > > > there is code in libudev and that is completely outside the control of
> > > > KMS apps like display servers.  
> > > 
> > > afaik this other path only exists because it's the older one, for uapi
> > > backwards compatibility with older userspace. Shouldn't be used for
> > > anything.
> > 
> > "Shouldn't be used" and someone screaming "kernel regression"... are you
> > sure that path won't matter?
> > 
> > Like some home-brewn distribution that happens to configure their
> > libudev and kernel to use the old method, uses already new userspace,
> > and then upgrades the kernel that starts sending fine-grained hotplug
> > events, resulting the display server randomly handling hotplug wrong.
> > 
> > Reading Airlie's recent rant about kernel regression handling make this
> > a scary scenario where you would have no other choice than to rip all
> > the fine-grained uevents out again.
> > 
> > Is there any difference in the kernel code between the old method and
> > the netlink method? Would it be possible to send fine-grained hotplug
> > events only through netlink, and fall back to the old 'HOTPLUG=1' for
> > the old method?
> 
> There's a lot of grey in kernel regressions, and for fringe setups used by
> few people I wouldn't worry about this. If they expect their shit to keep
> working when using new stuff and crappy old interfaces, they get to keep
> all the pieces.
> 
> Dave's recent rant was a bit special, since userspace is clearly smoking
> some strong stuff (-modesetting's atomic is seriously not using atomic
> correctly), but it was also affecting too many people, and changing the
> boot setup meant you'd get a black screen on boot-up already. Instead of
> just on the first modeset with more than 1 screen.
> 
> There's also a fairly easy fix for that -modesetting issue: We don't
> expose atomic if the compositor has a process name of "Xserver". Brutal,
> but gets the job done. Once X is fixed, we can give a new "I'm not totally
> broken anymore" interface to get back at atomic.
> 
> tldr; I'm not worried at all, at least not more than with anything uapi.
> Very rarely we'll have regrets.

Cheers to that!

> > > > Can you explain how one could miss a global hotplug event when
> > > > userspace is using netlink to watch for events? I thought the netlink
> > > > path through libudev was reliable. And how does userspace realize it
> > > > missed an event?  
> > > 
> > > I thought netlink is supposed to be reliable, but then if you send
> > > bazillion of events and userspace is stuck, eventually you will run out of
> > > memory. I have no idea how netlink signals that, and how that's forwarded
> > > or not in libudev. Also not sure whether we should actually care about
> > > this.
> > 
> > Ok. Let's try to keep the number of events low then, e.g. in the case of
> > 
> > 	HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > 
> > revert to sending just a single uevent with PROPERTY set to 0 instead
> > if there are more than one such no-probe property changes for the same
> > connector.
> 
> Yeah PROPERTY=0 would be another option. I think indicates clearly "don't
> reprobe" but also "update not for any specific prop, but for all of
> them".

That would make sense, although I think we should also be able to cover
cases where one or a number of properties changed and we know exactly
which ones. If we're going to have an exposed connector state and an
internal one that's being populated with connector changes, that could
be made easier.

Cheers,

Paul

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-20 16:11                               ` Daniel Vetter
  2019-05-20 16:24                                 ` Paul Kocialkowski
@ 2019-05-21  6:55                                 ` Pekka Paalanen
  2019-05-21  7:52                                   ` Daniel Vetter
  1 sibling, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-21  6:55 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, maxime.ripard, Daniel Vetter, intel-gfx, dri-devel,
	Mun, Gwan-gyeong, paul.kocialkowski, airlied, thomas.petazzoni,
	Vetter, Daniel, sean


[-- Attachment #1.1: Type: text/plain, Size: 16630 bytes --]

On Mon, 20 May 2019 18:11:07 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Fri, May 17, 2019 at 01:08:24PM +0300, Pekka Paalanen wrote:
> > On Thu, 16 May 2019 14:24:55 +0200
> > Daniel Vetter <daniel@ffwll.ch> wrote:
> >   
> > > On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:  
> > > > On Wed, 15 May 2019 10:24:49 +0200
> > > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > > >     
> > > > > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:    
> > > > > > On Tue, 14 May 2019 16:34:01 +0200
> > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > >       
> > > > > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:      
> > > > > > > >
> > > > > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > > > >        
> > > > > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:        
> > > > > > > > > >
> > > > > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:        
> > > > > > 
> > > > > > ...
> > > > > >       
> > > > > > > > > > > Hi Daniel,
> > > > > > > > > > >
> > > > > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > > > > property:
> > > > > > > > > > >
> > > > > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > > > > with a timer.
> > > > > > > > > > >
> > > > > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > > > > >
> > > > > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > > > > >
> > > > > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > > > > connectors need to be reprobed instead of everything.        
> > > > > > > > > >
> > > > > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > > > > reprobing. Would that work?        
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > > > > any new uevent fields in favour of "epoch counters".
> > > > > > > >        
> > > > > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > > > > state machinery update.        
> > > > > > > >
> > > > > > > > Right.
> > > > > > > >        
> > > > > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > > > > That along is a good win already, since you know for which connector
> > > > > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > > > > regretting things.        
> > > > > > > >
> > > > > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > > > > from userspace side:        
> > > > > > > 
> > > > > > > This sounds solid, some refinements below:
> > > > > > >       
> > > > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > > > >
> > > > > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > > > > >   re-get the connector properties.
> > > > > > > >
> > > > > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > > > > >   re-probe could be necessary, and send the below instead.        
> > > > > > > 
> > > > > > > 
> > > > > > > I think we should assert that the kernel can get the new property
> > > > > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > > > > to "must"      
> > > > > > 
> > > > > > Hi Daniel,
> > > > > > 
> > > > > > ok, that's good.
> > > > > >       
> > > > > > > Furthermore different property can indicate different kind of updates,
> > > > > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > > > > future.      
> > > > > > 
> > > > > > What do you mean by different kinds of updates?      
> > > > > 
> > > > > Atm we're discussing two:
> > > > > 
> > > > > - "Content Protection"
> > > > > - "sink changed, but you don't need to reprobe" this would be quite a bit
> > > > >   a catch all from the output detection. Paul thinks differently, but I'm
> > > > >   not sold on splitting this up more, at least not right now. This would
> > > > >   include connector status (and related things returned by drmGetConnector
> > > > >   which currently aren't a property), EDID, the mst path id, that kind of
> > > > >   stuff.
> > > > > 
> > > > > Ime once we have 2, there's more bound to come :-)    
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > I don't understand what the "sink changed" thing could be, but sure,
> > > > there can be more.    
> > > 
> > > So if you have a repeater (hdmi or dp) and you change the thing you plug
> > > into that, then on the computer you don't get a full hotplug, because the
> > > repeater was always connected. Instead you get a short pulse hotplug,
> > > indicating that something with the sink has changed. This could be a
> > > slightly adjusted EDID (e.g. different eld in the audio section), or
> > > something else. That's what I mean with "sink changed". Similar thing can
> > > happen if you unplug and then plug in something else real quick (usually
> > > over suspend/resume), where connector->status stays the same, but the
> > > actual thing plugged in is different. I think for hdmi this is just the
> > > EDID, but we do parse a bunch of things out of the EDID that have further
> > > effects (color space, max clock). With DP there's also dp aux stuff, e.g.
> > > if you switch from a 2 lane to a 4 lane cable then with same screen more
> > > modes can work.
> > > 
> > > Clearer?
> > > 
> > > I guess for the documentation for this new uapi we need to make an
> > > exhaustive list of all the things that might have changed for a "sink
> > > changed" event, whatever we actually agree on what that should look like.
> > > Or the PROPERTY=0 fallback you mention below as a fallback idea.  
> > 
> > Hi Daniel,
> > 
> > to me all that sounds like userspace would better do a probe and start
> > from scratch with that one connector. Therefore it would fall into the
> > 'HOTPLUG=1 CONNECTOR=xx' case, no PROPERTY.
> > 
> > I suppose I'm missing something?  
> 
> Doing a full probe is hella expensive. Atm you always have to do this, but
> we're talking about the brave new future where the kernel sucks less, and
> the kernel would have done the expensive probing for you already.
> 
> > But also I don't mind, I have always expected there might be more
> > properties whose change does not require a probe.
> > 
> > So, the kernel does sometimes do the probe on its own as well, right?
> > Is that completely invisible to userspace, or could it stall some
> > userspace operations that are not a probe of the same connector?  
> 
> Major stall because the locking design isn't pretty. If the kernel is
> probing right now even your GetConnectorCurrent or GetProperties (on a
> connector) will stall for whatever long it takes to read the EDID. Or
> whatever else the kernel is doing in the probe paths right now. We could
> probably improve this, and make sure that at least GetConnectorCurrent and
> GetProperties stop sucking. But needs some serious locking-fu to make that
> work.

Hi Daniel,

ok. I was assuming the kernel locking was unfixable, due to e.g.
hardware interfaces that are, well, hardware.

It seems the locking would be the first thing needing to be fixed
before anyone goes adding more automatic probing into the kernel,
because otherwise you risk introducing random timing hickups for
userspace, leading to someone screaming "kernel regression".

> Aside: Just realized this is another important reason why we need to batch
> up property updates. If we don't, then userspace will simply get held up
> until the kernel is done anyway.
> 
> > I really think the design of the uAPI must start with how userspace is
> > expected to react to the events. For that there are three cases:
> > re-deiscover and probe everyting, re-probe one connector, re-read
> > properties of one connector without probe. Userspace can then discover
> > what exactly changed, just like it already does.  
> 
> Yup, I think on this we all agree.
> 

...

> > > > > > > > --------
> > > > > > > >
> > > > > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > > > > delivered in userspace. Is there a possibility that they might be
> > > > > > > > overwritten, contain stale attributes, or get squashed together?
> > > > > > > >
> > > > > > > > Particularly if a display server is current on the VT and active and
> > > > > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > > > > very fast, and the kernel sends more than one event before the process
> > > > > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > > > > an event is a device. Squashing together would make sense if the
> > > > > > > > uevent were just updating a device attribute list. Previously when we
> > > > > > > > had just a single kind of uevent, that would not have made a
> > > > > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > > > > starts to matter.
> > > > > > > >
> > > > > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > > > > events come via netlink.        
> > > > > > > 
> > > > > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > > > > still happen, but then I think you should get an indication of that
> > > > > > > error, and you just treat it as a general hotplug event like on older
> > > > > > > kernels.      
> > > > > > 
> > > > > > Alright, although reading Paul it sounds like there is another
> > > > > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > > > > about that?
> > > > > > 
> > > > > > Hmm, get an indication of an error... I don't know how that would be
> > > > > > presented in libudev API and I can't point to any code in Weston that
> > > > > > would deal with it. Does anyone have a clue about that?
> > > > > > 
> > > > > > Userspace cannot really start taking advantage of any new fine-grained
> > > > > > hotplug events until it can rely on the event delivery. Granted, this
> > > > > > seems purely a userspace issue, but I bet it could be formulated as a
> > > > > > kernel regression: things stop working after upgrading the kernel while
> > > > > > having always used new userspace which was ready for detailed hotplug
> > > > > > events but didn't ensure the delivery in userspace.      
> > > > > 
> > > > > You have this already (if it's really an issue with netlink reliability,
> > > > > tbh no idea), you can already miss a global uevent. It's easier to catch
> > > > > up if you do miss it, since you're forcing a reprobe on everything. That's
> > > > > why I think the EPOCH thing would be good, userspace could be defensive
> > > > > and always call GetConnectorCurrent on all connectors if it gets any
> > > > > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > > > > not sure that's really required (aside from VT switching).    
> > > > 
> > > > No, my concern is not an issue with netlink reliability. It is a
> > > > potential issue when userspace chooses to not use netlink, and uses
> > > > something else instead. I'm not sure what that else is but Paul says
> > > > there is code in libudev and that is completely outside the control of
> > > > KMS apps like display servers.    
> > > 
> > > afaik this other path only exists because it's the older one, for uapi
> > > backwards compatibility with older userspace. Shouldn't be used for
> > > anything.  
> > 
> > "Shouldn't be used" and someone screaming "kernel regression"... are you
> > sure that path won't matter?
> > 
> > Like some home-brewn distribution that happens to configure their
> > libudev and kernel to use the old method, uses already new userspace,
> > and then upgrades the kernel that starts sending fine-grained hotplug
> > events, resulting the display server randomly handling hotplug wrong.
> > 
> > Reading Airlie's recent rant about kernel regression handling make this
> > a scary scenario where you would have no other choice than to rip all
> > the fine-grained uevents out again.
> > 
> > Is there any difference in the kernel code between the old method and
> > the netlink method? Would it be possible to send fine-grained hotplug
> > events only through netlink, and fall back to the old 'HOTPLUG=1' for
> > the old method?  
> 
> There's a lot of grey in kernel regressions, and for fringe setups used by
> few people I wouldn't worry about this. If they expect their shit to keep
> working when using new stuff and crappy old interfaces, they get to keep
> all the pieces.

It didn't sound gray at all, reading Dave Airlie's email about it. If
someone updates the kernel, and something works worse after that, then
it is by definition a kernel regression. Period. And the earliest
regression wins, i.e. if a revert breaks other things, the revert will
be done regardless.

> Dave's recent rant was a bit special, since userspace is clearly smoking
> some strong stuff (-modesetting's atomic is seriously not using atomic
> correctly), but it was also affecting too many people, and changing the
> boot setup meant you'd get a black screen on boot-up already. Instead of
> just on the first modeset with more than 1 screen.

Then I think I missed the context of Dave's email. Reading it again, I
still do not see that context.

Btw. how do you determine "not using atomic correctly"? Has some uAPI
specification for atomic appeared? I wasn't aware there was any uAPI
specs, so there is no "incorrect use" if it happened to work once.

I don't personally really like these rules, but if these are the rules,
then so be it. In my opinion it would be a huge step forward to get and
require uAPI specifications, that people could verify both kernel and
userspace against. Verifying against kernel code with no spec is what
leads to the -modesetting issue by the sounds of it.

Documenting kernel internal interfaces is not it. People reading
DRM internal interface docs would need to know how DRM works internally
before they could map that information into uAPI, which makes it less
useful if not even useless for userspace developers.

> There's also a fairly easy fix for that -modesetting issue: We don't
> expose atomic if the compositor has a process name of "Xserver". Brutal,
> but gets the job done. Once X is fixed, we can give a new "I'm not totally
> broken anymore" interface to get back at atomic.

You mean "Xorg". Or maybe "X". Or maybe the setuid helper? Wait, do you
check against the process issuing ioctl by ioctl, or the process that
opened the device? Which would be logind? What about DRM leasing? ...

> tldr; I'm not worried at all, at least not more than with anything uapi.
> Very rarely we'll have regrets.

If you say so, ok. I'm a pessimist. I will certainly be happy if people
can make progress with fine-grained uevents.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-21  6:55                                 ` Pekka Paalanen
@ 2019-05-21  7:52                                   ` Daniel Vetter
  2019-05-21  9:01                                     ` Pekka Paalanen
  2019-06-03  9:50                                     ` Michel Dänzer
  0 siblings, 2 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-21  7:52 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, maxime.ripard, intel-gfx, dri-devel,
	paul.kocialkowski, airlied, thomas.petazzoni, Vetter, Daniel

On Tue, May 21, 2019 at 8:55 AM Pekka Paalanen <ppaalanen@gmail.com> wrote:
>
> On Mon, 20 May 2019 18:11:07 +0200
> Daniel Vetter <daniel@ffwll.ch> wrote:
>
> > On Fri, May 17, 2019 at 01:08:24PM +0300, Pekka Paalanen wrote:
> > > On Thu, 16 May 2019 14:24:55 +0200
> > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > >
> > > > On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:
> > > > > On Wed, 15 May 2019 10:24:49 +0200
> > > > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > > > >
> > > > > > On Wed, May 15, 2019 at 10:37:31AM +0300, Pekka Paalanen wrote:
> > > > > > > On Tue, 14 May 2019 16:34:01 +0200
> > > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > > >
> > > > > > > > On Tue, May 14, 2019 at 3:36 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> > > > > > > > >
> > > > > > > > > On Tue, 14 May 2019 13:02:09 +0200
> > > > > > > > > Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > > > > > > >
> > > > > > > > > > On Tue, May 14, 2019 at 10:18 AM Ser, Simon <simon.ser@intel.com> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Tue, 2019-05-14 at 11:02 +0300, Pekka Paalanen wrote:
> > > > > > >
> > > > > > > ...
> > > > > > >
> > > > > > > > > > > > Hi Daniel,
> > > > > > > > > > > >
> > > > > > > > > > > > just to clarify the first case, specific to one very particular
> > > > > > > > > > > > property:
> > > > > > > > > > > >
> > > > > > > > > > > > With HDCP, there is a property that may change dynamically at runtime
> > > > > > > > > > > > (the undesired/desired/enabled tristate). Userspace must be notified
> > > > > > > > > > > > when it changes, I do not want userspace have to poll that property
> > > > > > > > > > > > with a timer.
> > > > > > > > > > > >
> > > > > > > > > > > > When that property alone changes, and userspace is prepared to handle
> > > > > > > > > > > > that property changing alone, it must not trigger a reprobe of the
> > > > > > > > > > > > connector. There is no reason to reprobe at that point AFAIU.
> > > > > > > > > > > >
> > > > > > > > > > > > How do you ensure that userspace can avoid triggering a reprobe with the
> > > > > > > > > > > > epoch approach or with any alternate uevent design?
> > > > > > > > > > > >
> > > > > > > > > > > > We need an event to userspace that indicates that re-reading the
> > > > > > > > > > > > properties is enough and reprobe of the connector is not necessary.
> > > > > > > > > > > > This is complementary to indicating to userspace that only some
> > > > > > > > > > > > connectors need to be reprobed instead of everything.
> > > > > > > > > > >
> > > > > > > > > > > Can't you use the PROPERTY hint? If PROPERTY is the HDCP one, skip the
> > > > > > > > > > > reprobing. Would that work?
> > > > > > > > >
> > > > > > > > > Hi,
> > > > > > > > >
> > > > > > > > > yes, that would work, if it was acceptable to DRM upstream. The replies
> > > > > > > > > to Paul seemed to be going south so fast that I thought we wouldn't get
> > > > > > > > > any new uevent fields in favour of "epoch counters".
> > > > > > > > >
> > > > > > > > > > Yes that's the idea, depending upon which property you get you know
> > > > > > > > > > it's a sink change (needs full reprobe) or something else like hdcp
> > > > > > > > > > state machinery update.
> > > > > > > > >
> > > > > > > > > Right.
> > > > > > > > >
> > > > > > > > > > Wrt avoiding the full reprobe for sink changes: I think we should
> > > > > > > > > > indeed decouple that from the per-connector event for sink changes.
> > > > > > > > > > That along is a good win already, since you know for which connector
> > > > > > > > > > you need to call drmGetConnector (which forces the reprobe). It would
> > > > > > > > > > be nice to only call drmGetConnectorCurrent (avoids the reprobe), but
> > > > > > > > > > historically speaking every time we tried to rely on this we ended up
> > > > > > > > > > regretting things.
> > > > > > > > >
> > > > > > > > > What changed? This sounds very much what Paul suggested. Looking at it
> > > > > > > > > from userspace side:
> > > > > > > >
> > > > > > > > This sounds solid, some refinements below:
> > > > > > > >
> > > > > > > > > HOTPLUG=1 CONNECTOR=xx PROPERTY=yy
> > > > > > > > >
> > > > > > > > > - If yy is "Content Protection", no need to drmModeGetConnector(), just
> > > > > > > > >   re-get the connector properties.
> > > > > > > > >
> > > > > > > > > - Kernel probably shouldn't bother sending this for properties where
> > > > > > > > >   re-probe could be necessary, and send the below instead.
> > > > > > > >
> > > > > > > >
> > > > > > > > I think we should assert that the kernel can get the new property
> > > > > > > > values using drmModeGetConnectorCurrent for this case, i.e. the kernel
> > > > > > > > does not expect a full reprobe. I.e. upgrade your idea from "should"
> > > > > > > > to "must"
> > > > > > >
> > > > > > > Hi Daniel,
> > > > > > >
> > > > > > > ok, that's good.
> > > > > > >
> > > > > > > > Furthermore different property can indicate different kind of updates,
> > > > > > > > e.g. hdcp vs general sink change vs. whatever else might come in the
> > > > > > > > future.
> > > > > > >
> > > > > > > What do you mean by different kinds of updates?
> > > > > >
> > > > > > Atm we're discussing two:
> > > > > >
> > > > > > - "Content Protection"
> > > > > > - "sink changed, but you don't need to reprobe" this would be quite a bit
> > > > > >   a catch all from the output detection. Paul thinks differently, but I'm
> > > > > >   not sold on splitting this up more, at least not right now. This would
> > > > > >   include connector status (and related things returned by drmGetConnector
> > > > > >   which currently aren't a property), EDID, the mst path id, that kind of
> > > > > >   stuff.
> > > > > >
> > > > > > Ime once we have 2, there's more bound to come :-)
> > > > >
> > > > > Hi Daniel,
> > > > >
> > > > > I don't understand what the "sink changed" thing could be, but sure,
> > > > > there can be more.
> > > >
> > > > So if you have a repeater (hdmi or dp) and you change the thing you plug
> > > > into that, then on the computer you don't get a full hotplug, because the
> > > > repeater was always connected. Instead you get a short pulse hotplug,
> > > > indicating that something with the sink has changed. This could be a
> > > > slightly adjusted EDID (e.g. different eld in the audio section), or
> > > > something else. That's what I mean with "sink changed". Similar thing can
> > > > happen if you unplug and then plug in something else real quick (usually
> > > > over suspend/resume), where connector->status stays the same, but the
> > > > actual thing plugged in is different. I think for hdmi this is just the
> > > > EDID, but we do parse a bunch of things out of the EDID that have further
> > > > effects (color space, max clock). With DP there's also dp aux stuff, e.g.
> > > > if you switch from a 2 lane to a 4 lane cable then with same screen more
> > > > modes can work.
> > > >
> > > > Clearer?
> > > >
> > > > I guess for the documentation for this new uapi we need to make an
> > > > exhaustive list of all the things that might have changed for a "sink
> > > > changed" event, whatever we actually agree on what that should look like.
> > > > Or the PROPERTY=0 fallback you mention below as a fallback idea.
> > >
> > > Hi Daniel,
> > >
> > > to me all that sounds like userspace would better do a probe and start
> > > from scratch with that one connector. Therefore it would fall into the
> > > 'HOTPLUG=1 CONNECTOR=xx' case, no PROPERTY.
> > >
> > > I suppose I'm missing something?
> >
> > Doing a full probe is hella expensive. Atm you always have to do this, but
> > we're talking about the brave new future where the kernel sucks less, and
> > the kernel would have done the expensive probing for you already.
> >
> > > But also I don't mind, I have always expected there might be more
> > > properties whose change does not require a probe.
> > >
> > > So, the kernel does sometimes do the probe on its own as well, right?
> > > Is that completely invisible to userspace, or could it stall some
> > > userspace operations that are not a probe of the same connector?
> >
> > Major stall because the locking design isn't pretty. If the kernel is
> > probing right now even your GetConnectorCurrent or GetProperties (on a
> > connector) will stall for whatever long it takes to read the EDID. Or
> > whatever else the kernel is doing in the probe paths right now. We could
> > probably improve this, and make sure that at least GetConnectorCurrent and
> > GetProperties stop sucking. But needs some serious locking-fu to make that
> > work.
>
> Hi Daniel,
>
> ok. I was assuming the kernel locking was unfixable, due to e.g.
> hardware interfaces that are, well, hardware.
>
> It seems the locking would be the first thing needing to be fixed
> before anyone goes adding more automatic probing into the kernel,
> because otherwise you risk introducing random timing hickups for
> userspace, leading to someone screaming "kernel regression".

There's is fairly fine-grained locking all over kms, except for the
probe path. That has one lock over all connnectors. Only thing we need
to uncouple that from GetConnectorCurrent is to arrange for some
read-only cache of the last probe state (which might not be the
current stuff).

> > Aside: Just realized this is another important reason why we need to batch
> > up property updates. If we don't, then userspace will simply get held up
> > until the kernel is done anyway.
> >
> > > I really think the design of the uAPI must start with how userspace is
> > > expected to react to the events. For that there are three cases:
> > > re-deiscover and probe everyting, re-probe one connector, re-read
> > > properties of one connector without probe. Userspace can then discover
> > > what exactly changed, just like it already does.
> >
> > Yup, I think on this we all agree.
> >
>
> ...
>
> > > > > > > > > --------
> > > > > > > > >
> > > > > > > > > When discussing this in IRC, I had the concern about how uevents are
> > > > > > > > > delivered in userspace. Is there a possibility that they might be
> > > > > > > > > overwritten, contain stale attributes, or get squashed together?
> > > > > > > > >
> > > > > > > > > Particularly if a display server is current on the VT and active and
> > > > > > > > > monitoring udev, but stuck doing something and cannot service uevents
> > > > > > > > > very fast, and the kernel sends more than one event before the process
> > > > > > > > > gets back to dispatching. The terminology in libudev API confused me as
> > > > > > > > > an event is a device. Squashing together would make sense if the
> > > > > > > > > uevent were just updating a device attribute list. Previously when we
> > > > > > > > > had just a single kind of uevent, that would not have made a
> > > > > > > > > difference, but if we gain different kinds of uevents like here, it
> > > > > > > > > starts to matter.
> > > > > > > > >
> > > > > > > > > However, Paul came to the conclusion that we will be ok as long as the
> > > > > > > > > events come via netlink.
> > > > > > > >
> > > > > > > > Yeah netlink shouldn't drop events on the floor I think. It might
> > > > > > > > still happen, but then I think you should get an indication of that
> > > > > > > > error, and you just treat it as a general hotplug event like on older
> > > > > > > > kernels.
> > > > > > >
> > > > > > > Alright, although reading Paul it sounds like there is another
> > > > > > > (fallback?) method as well that wouldn't work. Should userspace worry
> > > > > > > about that?
> > > > > > >
> > > > > > > Hmm, get an indication of an error... I don't know how that would be
> > > > > > > presented in libudev API and I can't point to any code in Weston that
> > > > > > > would deal with it. Does anyone have a clue about that?
> > > > > > >
> > > > > > > Userspace cannot really start taking advantage of any new fine-grained
> > > > > > > hotplug events until it can rely on the event delivery. Granted, this
> > > > > > > seems purely a userspace issue, but I bet it could be formulated as a
> > > > > > > kernel regression: things stop working after upgrading the kernel while
> > > > > > > having always used new userspace which was ready for detailed hotplug
> > > > > > > events but didn't ensure the delivery in userspace.
> > > > > >
> > > > > > You have this already (if it's really an issue with netlink reliability,
> > > > > > tbh no idea), you can already miss a global uevent. It's easier to catch
> > > > > > up if you do miss it, since you're forcing a reprobe on everything. That's
> > > > > > why I think the EPOCH thing would be good, userspace could be defensive
> > > > > > and always call GetConnectorCurrent on all connectors if it gets any
> > > > > > hotplug uevent, and if it gets an EPOCH change, force a reprobe. But I'm
> > > > > > not sure that's really required (aside from VT switching).
> > > > >
> > > > > No, my concern is not an issue with netlink reliability. It is a
> > > > > potential issue when userspace chooses to not use netlink, and uses
> > > > > something else instead. I'm not sure what that else is but Paul says
> > > > > there is code in libudev and that is completely outside the control of
> > > > > KMS apps like display servers.
> > > >
> > > > afaik this other path only exists because it's the older one, for uapi
> > > > backwards compatibility with older userspace. Shouldn't be used for
> > > > anything.
> > >
> > > "Shouldn't be used" and someone screaming "kernel regression"... are you
> > > sure that path won't matter?
> > >
> > > Like some home-brewn distribution that happens to configure their
> > > libudev and kernel to use the old method, uses already new userspace,
> > > and then upgrades the kernel that starts sending fine-grained hotplug
> > > events, resulting the display server randomly handling hotplug wrong.
> > >
> > > Reading Airlie's recent rant about kernel regression handling make this
> > > a scary scenario where you would have no other choice than to rip all
> > > the fine-grained uevents out again.
> > >
> > > Is there any difference in the kernel code between the old method and
> > > the netlink method? Would it be possible to send fine-grained hotplug
> > > events only through netlink, and fall back to the old 'HOTPLUG=1' for
> > > the old method?
> >
> > There's a lot of grey in kernel regressions, and for fringe setups used by
> > few people I wouldn't worry about this. If they expect their shit to keep
> > working when using new stuff and crappy old interfaces, they get to keep
> > all the pieces.
>
> It didn't sound gray at all, reading Dave Airlie's email about it. If
> someone updates the kernel, and something works worse after that, then
> it is by definition a kernel regression. Period. And the earliest
> regression wins, i.e. if a revert breaks other things, the revert will
> be done regardless.
>
> > Dave's recent rant was a bit special, since userspace is clearly smoking
> > some strong stuff (-modesetting's atomic is seriously not using atomic
> > correctly), but it was also affecting too many people, and changing the
> > boot setup meant you'd get a black screen on boot-up already. Instead of
> > just on the first modeset with more than 1 screen.
>
> Then I think I missed the context of Dave's email. Reading it again, I
> still do not see that context.
>
> Btw. how do you determine "not using atomic correctly"? Has some uAPI
> specification for atomic appeared? I wasn't aware there was any uAPI
> specs, so there is no "incorrect use" if it happened to work once.

-modesetting atomic blows up with more than one screen (even if you
just move that screen between crtc). The breakage was that with the
fastboot changes we've put the one screen onto crtc 1, but by default
modesetting wants it on crtc 0, and it couldn't do that switch
anymore.

All current atomic in -modesetting can do is pageflip and dpms off/on
on the first screen on the first crtc. Anything more fancy goes boom,
like where you change the connector/crtc links.

It's _really_ broken :-)

> I don't personally really like these rules, but if these are the rules,
> then so be it. In my opinion it would be a huge step forward to get and
> require uAPI specifications, that people could verify both kernel and
> userspace against. Verifying against kernel code with no spec is what
> leads to the -modesetting issue by the sounds of it.
>
> Documenting kernel internal interfaces is not it. People reading
> DRM internal interface docs would need to know how DRM works internally
> before they could map that information into uAPI, which makes it less
> useful if not even useless for userspace developers.

vgem is the idea here for validation, but if people ship atomic code
that was never tested except for "boots on my laptop", then nothing is
going to help.

And yes we have a huge gap with uapi documentation. btw for properties
those section are meant to be useful for userspace people too:

https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#standard-connector-properties

and all subsequent chapters. I guess it's a bit burried, but this part
is meant to be the uapi spec for properties. Is that also failing your
expectations?

> > There's also a fairly easy fix for that -modesetting issue: We don't
> > expose atomic if the compositor has a process name of "Xserver". Brutal,
> > but gets the job done. Once X is fixed, we can give a new "I'm not totally
> > broken anymore" interface to get back at atomic.
>
> You mean "Xorg". Or maybe "X". Or maybe the setuid helper? Wait, do you
> check against the process issuing ioctl by ioctl, or the process that
> opened the device? Which would be logind? What about DRM leasing? ...

In the Get/SetCaps ioctl we can do the check, which is called from X,
not logind. We just need some way to tell -modesetting apart from
everything else, and luckily there's not any other atomic X drivers.

> > tldr; I'm not worried at all, at least not more than with anything uapi.
> > Very rarely we'll have regrets.
>
> If you say so, ok. I'm a pessimist. I will certainly be happy if people
> can make progress with fine-grained uevents.

Maybe I've been suffering this for too long :-)
-Daniel
-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-21  7:52                                   ` Daniel Vetter
@ 2019-05-21  9:01                                     ` Pekka Paalanen
  2019-05-21  9:42                                       ` Daniel Vetter
  2019-06-03  9:50                                     ` Michel Dänzer
  1 sibling, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-05-21  9:01 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Ser, Simon, maxime.ripard, intel-gfx, dri-devel, Mun,
	Gwan-gyeong, paul.kocialkowski, airlied, thomas.petazzoni,
	Vetter, Daniel, sean


[-- Attachment #1.1: Type: text/plain, Size: 6111 bytes --]

On Tue, 21 May 2019 09:52:50 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Tue, May 21, 2019 at 8:55 AM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> >
> > On Mon, 20 May 2019 18:11:07 +0200
> > Daniel Vetter <daniel@ffwll.ch> wrote:
> >  
> > > On Fri, May 17, 2019 at 01:08:24PM +0300, Pekka Paalanen wrote:  
> > > > On Thu, 16 May 2019 14:24:55 +0200
> > > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > > >  
> > > > > On Thu, May 16, 2019 at 11:22:11AM +0300, Pekka Paalanen wrote:  

...

> > > > > > No, my concern is not an issue with netlink reliability. It is a
> > > > > > potential issue when userspace chooses to not use netlink, and uses
> > > > > > something else instead. I'm not sure what that else is but Paul says
> > > > > > there is code in libudev and that is completely outside the control of
> > > > > > KMS apps like display servers.  
> > > > >
> > > > > afaik this other path only exists because it's the older one, for uapi
> > > > > backwards compatibility with older userspace. Shouldn't be used for
> > > > > anything.  
> > > >
> > > > "Shouldn't be used" and someone screaming "kernel regression"... are you
> > > > sure that path won't matter?
> > > >
> > > > Like some home-brewn distribution that happens to configure their
> > > > libudev and kernel to use the old method, uses already new userspace,
> > > > and then upgrades the kernel that starts sending fine-grained hotplug
> > > > events, resulting the display server randomly handling hotplug wrong.
> > > >
> > > > Reading Airlie's recent rant about kernel regression handling make this
> > > > a scary scenario where you would have no other choice than to rip all
> > > > the fine-grained uevents out again.
> > > >
> > > > Is there any difference in the kernel code between the old method and
> > > > the netlink method? Would it be possible to send fine-grained hotplug
> > > > events only through netlink, and fall back to the old 'HOTPLUG=1' for
> > > > the old method?  
> > >
> > > There's a lot of grey in kernel regressions, and for fringe setups used by
> > > few people I wouldn't worry about this. If they expect their shit to keep
> > > working when using new stuff and crappy old interfaces, they get to keep
> > > all the pieces.  
> >
> > It didn't sound gray at all, reading Dave Airlie's email about it. If
> > someone updates the kernel, and something works worse after that, then
> > it is by definition a kernel regression. Period. And the earliest
> > regression wins, i.e. if a revert breaks other things, the revert will
> > be done regardless.
> >  
> > > Dave's recent rant was a bit special, since userspace is clearly smoking
> > > some strong stuff (-modesetting's atomic is seriously not using atomic
> > > correctly), but it was also affecting too many people, and changing the
> > > boot setup meant you'd get a black screen on boot-up already. Instead of
> > > just on the first modeset with more than 1 screen.  
> >
> > Then I think I missed the context of Dave's email. Reading it again, I
> > still do not see that context.
> >
> > Btw. how do you determine "not using atomic correctly"? Has some uAPI
> > specification for atomic appeared? I wasn't aware there was any uAPI
> > specs, so there is no "incorrect use" if it happened to work once.  
> 
> -modesetting atomic blows up with more than one screen (even if you
> just move that screen between crtc). The breakage was that with the
> fastboot changes we've put the one screen onto crtc 1, but by default
> modesetting wants it on crtc 0, and it couldn't do that switch
> anymore.

Hi Daniel,

what says the assumption of the only monitor being driven by CRTC 0
was a bad one? :-p

It's probably not obvious that userspace needs to explicitly try to
avoid invalid configuration combinations by inspecting the current full
configuration and not just the one CRTC/connector it wants to use.

> All current atomic in -modesetting can do is pageflip and dpms off/on
> on the first screen on the first crtc. Anything more fancy goes boom,
> like where you change the connector/crtc links.
> 
> It's _really_ broken :-)

But it worked exactly that much, until a kernel change broke it, right?
Yes, I totally see the sillyness, but if it worked and we have these
no-regression rules...

> > I don't personally really like these rules, but if these are the rules,
> > then so be it. In my opinion it would be a huge step forward to get and
> > require uAPI specifications, that people could verify both kernel and
> > userspace against. Verifying against kernel code with no spec is what
> > leads to the -modesetting issue by the sounds of it.
> >
> > Documenting kernel internal interfaces is not it. People reading
> > DRM internal interface docs would need to know how DRM works internally
> > before they could map that information into uAPI, which makes it less
> > useful if not even useless for userspace developers.  
> 
> vgem is the idea here for validation, but if people ship atomic code
> that was never tested except for "boots on my laptop", then nothing is
> going to help.

A testing pattern library with vkms would be awesome indeed.

> And yes we have a huge gap with uapi documentation. btw for properties
> those section are meant to be useful for userspace people too:
> 
> https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#standard-connector-properties
> 
> and all subsequent chapters. I guess it's a bit burried, but this part
> is meant to be the uapi spec for properties. Is that also failing your
> expectations?

Yes: it is hard to find (it is in Driver Developer's Guide, buried
several chapters in), it is interleaved with lots of DRM internal
details, makes references to DRM internal functions, and probably
relies on DRM internals behaviour through the references by not
repeating what they do.

It is useful once you find it, but I don't think it's enough for making
good use in userspace for someone who hasn't been a DRM kernel
developer.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-21  9:01                                     ` Pekka Paalanen
@ 2019-05-21  9:42                                       ` Daniel Vetter
  0 siblings, 0 replies; 70+ messages in thread
From: Daniel Vetter @ 2019-05-21  9:42 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Ser, Simon, thomas.petazzoni, maxime.ripard, intel-gfx,
	dri-devel, Mun, Gwan-gyeong, paul.kocialkowski, airlied, Vetter,
	Daniel, sean

On Tue, May 21, 2019 at 12:01:29PM +0300, Pekka Paalanen wrote:
> Hi Daniel,
> 
> what says the assumption of the only monitor being driven by CRTC 0
> was a bad one? :-p
> 
> It's probably not obvious that userspace needs to explicitly try to
> avoid invalid configuration combinations by inspecting the current full
> configuration and not just the one CRTC/connector it wants to use.

Well the entire point of atomic is that you do set the entire config. The
-modesetting atomic conversation tried to just use the atomic ioctl by 1:1
replacing legacy ioctl calls, and they screwed things up.

If it would have applied the entire configuration in one go, it would
work.

> > All current atomic in -modesetting can do is pageflip and dpms off/on
> > on the first screen on the first crtc. Anything more fancy goes boom,
> > like where you change the connector/crtc links.
> > 
> > It's _really_ broken :-)
> 
> But it worked exactly that much, until a kernel change broke it, right?
> Yes, I totally see the sillyness, but if it worked and we have these
> no-regression rules...

Which is why the offending patch has been reverted. Any the way forward is
to just disable atomic from the kernel for X.org, because the legacy path
actually works. We also have patches to disable atomic in -modesetting,
but they're stuck.

> > > I don't personally really like these rules, but if these are the rules,
> > > then so be it. In my opinion it would be a huge step forward to get and
> > > require uAPI specifications, that people could verify both kernel and
> > > userspace against. Verifying against kernel code with no spec is what
> > > leads to the -modesetting issue by the sounds of it.
> > >
> > > Documenting kernel internal interfaces is not it. People reading
> > > DRM internal interface docs would need to know how DRM works internally
> > > before they could map that information into uAPI, which makes it less
> > > useful if not even useless for userspace developers.  
> > 
> > vgem is the idea here for validation, but if people ship atomic code
> > that was never tested except for "boots on my laptop", then nothing is
> > going to help.
> 
> A testing pattern library with vkms would be awesome indeed.
> 
> > And yes we have a huge gap with uapi documentation. btw for properties
> > those section are meant to be useful for userspace people too:
> > 
> > https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#standard-connector-properties
> > 
> > and all subsequent chapters. I guess it's a bit burried, but this part
> > is meant to be the uapi spec for properties. Is that also failing your
> > expectations?
> 
> Yes: it is hard to find (it is in Driver Developer's Guide, buried
> several chapters in), it is interleaved with lots of DRM internal
> details, makes references to DRM internal functions, and probably
> relies on DRM internals behaviour through the references by not
> repeating what they do.
> 
> It is useful once you find it, but I don't think it's enough for making
> good use in userspace for someone who hasn't been a DRM kernel
> developer.

Summarizing our long irc chat on this: I agree, everyone else agrees, but
it's a question of making it happen and having someone with sufficient
tech writer experience to make it useful.

What we have now is essentially what happens if I type uapi specs (I
pushed for these property docs). As you can see, it ain't pretty :-/

I think at least the process v4l has, where missing docs for uapi causes
the doc build to fail, is sound. I have no idea how to adapt that to what
we do, both from a "this will take a few years to fill the gaps and I
don't know how to write good specs" and more implementation pov -
properties can be created anywhere, no changes to include/uapi required.
So hard to spot automatically.

Cheers, Daniel
-- 
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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-21  7:52                                   ` Daniel Vetter
  2019-05-21  9:01                                     ` Pekka Paalanen
@ 2019-06-03  9:50                                     ` Michel Dänzer
  2019-06-03 15:08                                       ` Daniel Vetter
  1 sibling, 1 reply; 70+ messages in thread
From: Michel Dänzer @ 2019-06-03  9:50 UTC (permalink / raw)
  To: Daniel Vetter, Pekka Paalanen
  Cc: paul.kocialkowski, maxime.ripard, intel-gfx, dri-devel, Ser,
	Simon, airlied, thomas.petazzoni, Vetter, Daniel

On 2019-05-21 9:52 a.m., Daniel Vetter wrote:
> On Tue, May 21, 2019 at 8:55 AM Pekka Paalanen <ppaalanen@gmail.com> wrote:
>> On Mon, 20 May 2019 18:11:07 +0200
>> Daniel Vetter <daniel@ffwll.ch> wrote:
>>
>>> There's also a fairly easy fix for that -modesetting issue: We don't
>>> expose atomic if the compositor has a process name of "Xserver". Brutal,
>>> but gets the job done. Once X is fixed, we can give a new "I'm not totally
>>> broken anymore" interface to get back at atomic.
>>
>> You mean "Xorg". Or maybe "X". Or maybe the setuid helper? Wait, do you
>> check against the process issuing ioctl by ioctl, or the process that
>> opened the device? Which would be logind? What about DRM leasing? ...
> 
> In the Get/SetCaps ioctl we can do the check, which is called from X,
> not logind. We just need some way to tell -modesetting apart from
> everything else, and luckily there's not any other atomic X drivers.

Not yet...

As for a "I'm not totally broken anymore" interface, we did something
like that (though kind of in the other direction) with
RADEON_INFO_ACCEL_WORKING, but later RADEON_INFO_ACCEL_WORKING2 had to
be added, because the former claimed acceleration was "working" in cases
where it really wasn't... That kind of thing could become ugly in the
long run if other Xorg driver start using atomic, and they'll inevitably
be broken in different ways.


-- 
Earthling Michel Dänzer               |              https://www.amd.com
Libre software enthusiast             |             Mesa and X developer
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-06-03  9:50                                     ` Michel Dänzer
@ 2019-06-03 15:08                                       ` Daniel Vetter
  2019-06-03 15:19                                         ` Ser, Simon
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Vetter @ 2019-06-03 15:08 UTC (permalink / raw)
  To: Michel Dänzer
  Cc: paul.kocialkowski, thomas.petazzoni, maxime.ripard, intel-gfx,
	dri-devel, Ser, Simon, airlied, Pekka Paalanen, Vetter, Daniel

On Mon, Jun 03, 2019 at 11:50:53AM +0200, Michel Dänzer wrote:
> On 2019-05-21 9:52 a.m., Daniel Vetter wrote:
> > On Tue, May 21, 2019 at 8:55 AM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> >> On Mon, 20 May 2019 18:11:07 +0200
> >> Daniel Vetter <daniel@ffwll.ch> wrote:
> >>
> >>> There's also a fairly easy fix for that -modesetting issue: We don't
> >>> expose atomic if the compositor has a process name of "Xserver". Brutal,
> >>> but gets the job done. Once X is fixed, we can give a new "I'm not totally
> >>> broken anymore" interface to get back at atomic.
> >>
> >> You mean "Xorg". Or maybe "X". Or maybe the setuid helper? Wait, do you
> >> check against the process issuing ioctl by ioctl, or the process that
> >> opened the device? Which would be logind? What about DRM leasing? ...
> > 
> > In the Get/SetCaps ioctl we can do the check, which is called from X,
> > not logind. We just need some way to tell -modesetting apart from
> > everything else, and luckily there's not any other atomic X drivers.
> 
> Not yet...
> 
> As for a "I'm not totally broken anymore" interface, we did something
> like that (though kind of in the other direction) with
> RADEON_INFO_ACCEL_WORKING, but later RADEON_INFO_ACCEL_WORKING2 had to
> be added, because the former claimed acceleration was "working" in cases
> where it really wasn't... That kind of thing could become ugly in the
> long run if other Xorg driver start using atomic, and they'll inevitably
> be broken in different ways.

It's definitely a very suboptimal situation. Not sure there's a good way
out. The trouble here is that i915 ended up configuring crtc/connectors
differently than -modesetting (to allow fastboot, which I think is still
i915 exclusive). This then highlighted that modesetting can't do atomic
modesets if you try to reassign connectors.

One idea I have is that vgms would help compositors to play out a bunch of
standard scenarios, even automated. But that's not there yet, and every
compositor project needs to care beyond "boots on my laptop, ship it". No
idea that's even possible.
-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] 70+ messages in thread

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-06-03 15:08                                       ` Daniel Vetter
@ 2019-06-03 15:19                                         ` Ser, Simon
  2019-06-04  7:06                                           ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Ser, Simon @ 2019-06-03 15:19 UTC (permalink / raw)
  To: daniel, michel
  Cc: airlied, intel-gfx, dri-devel, paul.kocialkowski, maxime.ripard,
	ppaalanen, thomas.petazzoni, Vetter, Daniel

On Mon, 2019-06-03 at 17:08 +0200, Daniel Vetter wrote:
> On Mon, Jun 03, 2019 at 11:50:53AM +0200, Michel Dänzer wrote:
> > On 2019-05-21 9:52 a.m., Daniel Vetter wrote:
> > > On Tue, May 21, 2019 at 8:55 AM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> > > > On Mon, 20 May 2019 18:11:07 +0200
> > > > Daniel Vetter <daniel@ffwll.ch> wrote:
> > > > 
> > > > > There's also a fairly easy fix for that -modesetting issue: We don't
> > > > > expose atomic if the compositor has a process name of "Xserver". Brutal,
> > > > > but gets the job done. Once X is fixed, we can give a new "I'm not totally
> > > > > broken anymore" interface to get back at atomic.
> > > > 
> > > > You mean "Xorg". Or maybe "X". Or maybe the setuid helper? Wait, do you
> > > > check against the process issuing ioctl by ioctl, or the process that
> > > > opened the device? Which would be logind? What about DRM leasing? ...
> > > 
> > > In the Get/SetCaps ioctl we can do the check, which is called from X,
> > > not logind. We just need some way to tell -modesetting apart from
> > > everything else, and luckily there's not any other atomic X drivers.
> > 
> > Not yet...
> > 
> > As for a "I'm not totally broken anymore" interface, we did something
> > like that (though kind of in the other direction) with
> > RADEON_INFO_ACCEL_WORKING, but later RADEON_INFO_ACCEL_WORKING2 had to
> > be added, because the former claimed acceleration was "working" in cases
> > where it really wasn't... That kind of thing could become ugly in the
> > long run if other Xorg driver start using atomic, and they'll inevitably
> > be broken in different ways.
> 
> It's definitely a very suboptimal situation. Not sure there's a good way
> out. The trouble here is that i915 ended up configuring crtc/connectors
> differently than -modesetting (to allow fastboot, which I think is still
> i915 exclusive). This then highlighted that modesetting can't do atomic
> modesets if you try to reassign connectors.
> 
> One idea I have is that vgms would help compositors to play out a bunch of

Just so people aren't confused: I think Daniel meant "vkms" here :P

> standard scenarios, even automated. But that's not there yet, and every
> compositor project needs to care beyond "boots on my laptop, ship it". No
> idea that's even possible.

Having documentation for userspace is also important IMHO.

Regarding automated compositor testing, it's probably not possible to
have a single place where all compositors are tested: vkms should
probably be included as part of their CI. Thoughts?

Anyway, we could start a discussion to see if compositor people are
interested. Or have you already talked to some compositor maintainers?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-06-03 15:19                                         ` Ser, Simon
@ 2019-06-04  7:06                                           ` Pekka Paalanen
  0 siblings, 0 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-06-04  7:06 UTC (permalink / raw)
  To: Ser, Simon
  Cc: airlied, michel, dri-devel, paul.kocialkowski, maxime.ripard,
	thomas.petazzoni, Vetter, Daniel, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1900 bytes --]

On Mon, 3 Jun 2019 15:19:13 +0000
"Ser, Simon" <simon.ser@intel.com> wrote:

> On Mon, 2019-06-03 at 17:08 +0200, Daniel Vetter wrote:

> > It's definitely a very suboptimal situation. Not sure there's a good way
> > out. The trouble here is that i915 ended up configuring crtc/connectors
> > differently than -modesetting (to allow fastboot, which I think is still
> > i915 exclusive). This then highlighted that modesetting can't do atomic
> > modesets if you try to reassign connectors.
> > 
> > One idea I have is that vgms would help compositors to play out a bunch of  
> 
> Just so people aren't confused: I think Daniel meant "vkms" here :P
> 
> > standard scenarios, even automated. But that's not there yet, and every
> > compositor project needs to care beyond "boots on my laptop, ship it". No
> > idea that's even possible.  
> 
> Having documentation for userspace is also important IMHO.
> 
> Regarding automated compositor testing, it's probably not possible to
> have a single place where all compositors are tested: vkms should
> probably be included as part of their CI. Thoughts?
> 
> Anyway, we could start a discussion to see if compositor people are
> interested. Or have you already talked to some compositor maintainers?

FWIW, I would absolutely *love* to be able to exercise Weston's
DRM-backend in Gitlab CI with anything, even just vkms, at least in
Weston's test suite to test Weston against KMS in general. Once that is
up, kernel people could replicate from that to their own CI for testing
drivers against known userspace.

I think it would be an awesome long term plan, whether uAPI specs
appear or not. Long term, because I have no idea who could work on it
when. In theory, all I would be waiting for is for vkms to be just
featureful enough and to figure out a way how to get that running
inside Gitlab CI.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 07/11] drm: Add Content protection type property
  2019-07-04 11:11   ` Pekka Paalanen
@ 2019-07-04 10:36     ` Ramalingam C
  2019-07-05 13:00       ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-07-04 10:36 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: daniel.vetter, intel-gfx, dri-devel

On 2019-07-04 at 14:11:59 +0300, Pekka Paalanen wrote:
> On Tue,  7 May 2019 21:57:41 +0530
> Ramalingam C <ramalingam.c@intel.com> wrote:
> 
> > This patch adds a DRM ENUM property to the selected connectors.
> > This property is used for mentioning the protected content's type
> > from userspace to kernel HDCP authentication.
> > 
> > Type of the stream is decided by the protected content providers.
> > Type 0 content can be rendered on any HDCP protected display wires.
> > But Type 1 content can be rendered only on HDCP2.2 protected paths.
> > 
> > So when a userspace sets this property to Type 1 and starts the HDCP
> > enable, kernel will honour it only if HDCP2.2 authentication is through
> > for type 1. Else HDCP enable will be failed.
> > 
> > Need ACK for this new conenctor property from userspace consumer.
> > 
> > v2:
> >   cp_content_type is replaced with content_protection_type [daniel]
> >   check at atomic_set_property is removed [Maarten]
> > v3:
> >   %s/content_protection_type/hdcp_content_type [Pekka]
> > v4:
> >   property is created for the first requested connector and then reused.
> > 	[Danvet]
> > v5:
> >   kernel doc nits addressed [Daniel]
> >   Rebased as part of patch reordering.
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
> >  drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
> >  drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
> >  drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
> >  include/drm/drm_connector.h       |  7 ++++++
> >  include/drm/drm_hdcp.h            |  2 +-
> >  include/drm/drm_mode_config.h     |  6 ++++++
> >  include/uapi/drm/drm_mode.h       |  4 ++++
> >  8 files changed, 78 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > index 4131e669785a..a85f3ccfe699 100644
> > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > @@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
> >  			return -EINVAL;
> >  		}
> >  		state->content_protection = val;
> > +	} else if (property == config->hdcp_content_type_property) {
> > +		state->hdcp_content_type = val;
> >  	} else if (property == connector->colorspace_property) {
> >  		state->colorspace = val;
> >  	} else if (property == config->writeback_fb_id_property) {
> > @@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> >  		*val = state->scaling_mode;
> >  	} else if (property == config->content_protection_property) {
> >  		*val = state->content_protection;
> > +	} else if (property == config->hdcp_content_type_property) {
> > +		*val = state->hdcp_content_type;
> >  	} else if (property == config->writeback_fb_id_property) {
> >  		/* Writeback framebuffer is one-shot, write and forget */
> >  		*val = 0;
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 764c7903edf6..de9e06583e8c 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> 
> Hi,
> 
> below I have some comments and questions before I can say whether
> https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> adheres to this specification.
> 
> > @@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
> >   *	  the value transitions from ENABLED to DESIRED. This signifies the link
> >   *	  is no longer protected and userspace should take appropriate action
> >   *	  (whatever that might be).
> > + * HDCP Content Type:
> > + *	This property is used by the userspace to configure the kernel with
> > + *	to be displayed stream's content type. Content Type of a stream is
> > + *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
> > + *
> > + *	The value of the property can be one the below:
> > + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0
> 
> If this doc is meant as the UAPI doc, it needs to use the string names
> for enum property values, not the C language definitions (integers).
kernel documentation for all other properties followed this way. We
could add string associated to the enum state too for this property.
> 
> > + *		HDCP Type0 streams can be transmitted on a link which is
> > + *		encrypted with HDCP 1.4 or HDCP 2.2.
> 
> This wording forbids using any future HDCP version for type0.
We could change it to HDCP1.4 and higher version of HDCP.
> 
> > + *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
> > + *		HDCP Type1 streams can be transmitted on a link which is
> > + *		encrypted only with HDCP 2.2.
> 
> This wording forbids using any future HDCP version for type1.
As of now type 1 is only on HDCP2.2 encrypted link, as no higher version is
available. But as similar to Type 0 we could assume that Type 1 will be
supported on higher HDCP versions too and correct the sentence here.
> 
> > + *
> > + *	Note that the HDCP Content Type property is specific to HDCP 2.2, and
> > + *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.2
> 
> Not possible with a future HDCP version greater than 2.2?
> 
> Is it intended to be possible to add more content types in the future?
Possible. As per HDCP2.2 spec, 8bits are reserved for the content Type.
> 
> > + *	If content type is changed when content_protection is not UNDESIRED,
> > + *	then kernel will disable the HDCP and re-enable with new type in the
> > + *	same atomic commit
> 
> Ok, very good to mention this.
> 
> >   *
> >   * max bpc:
> >   *	This range property is used by userspace to limit the bit depth. When
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > index 0da7b3718bad..75402463466b 100644
> > --- a/drivers/gpu/drm/drm_hdcp.c
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -342,23 +342,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
> >  };
> >  DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
> >  
> > +static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
> > +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> > +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> > +};
> > +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> > +		 drm_hdcp_content_type_enum_list)
> > +
> >  /**
> >   * drm_connector_attach_content_protection_property - attach content protection
> >   * property
> >   *
> >   * @connector: connector to attach CP property on.
> > + * @hdcp_content_type: is HDCP Content Type property needed for connector
> >   *
> >   * This is used to add support for content protection on select connectors.
> >   * Content Protection is intentionally vague to allow for different underlying
> >   * technologies, however it is most implemented by HDCP.
> >   *
> > + * When hdcp_content_type is true enum property called HDCP Content Type is
> > + * created (if it is not already) and attached to the connector.
> > + *
> > + * This property is used for sending the protected content's stream type
> > + * from userspace to kernel on selected connectors. Protected content provider
> > + * will decide their type of their content and declare the same to kernel.
> > + *
> > + * Content type will be used during the HDCP 2.2 authentication.
> > + * Content type will be set to &drm_connector_state.hdcp_content_type.
> > + *
> >   * The content protection will be set to &drm_connector_state.content_protection
> >   *
> >   * Returns:
> >   * Zero on success, negative errno on failure.
> >   */
> >  int drm_connector_attach_content_protection_property(
> > -		struct drm_connector *connector)
> > +		struct drm_connector *connector, bool hdcp_content_type)
> >  {
> >  	struct drm_device *dev = connector->dev;
> >  	struct drm_property *prop =
> > @@ -375,6 +393,22 @@ int drm_connector_attach_content_protection_property(
> >  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> >  	dev->mode_config.content_protection_property = prop;
> >  
> > +	if (!hdcp_content_type)
> > +		return 0;
> > +
> > +	prop = dev->mode_config.hdcp_content_type_property;
> > +	if (!prop)
> > +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> > +					drm_hdcp_content_type_enum_list,
> > +					ARRAY_SIZE(
> > +					drm_hdcp_content_type_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +
> > +	drm_object_attach_property(&connector->base, prop,
> > +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> > +	dev->mode_config.hdcp_content_type_property = prop;
> > +
> >  	return 0;
> >  }
> >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> 
> ...
> 
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 83cd1636b9be..8ac03351fdee 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -209,6 +209,10 @@ extern "C" {
> >  #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
> >  #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
> >  
> > +/* Content Type classification for HDCP2.2 vs others */
> > +#define DRM_MODE_HDCP_CONTENT_TYPE0		0
> > +#define DRM_MODE_HDCP_CONTENT_TYPE1		1
> 
> These should not be in a UAPI header. The C language definitions must
> never be exposed to userspace, or misguided userspace will start using
> them.
> 
> Instead, UAPI uses the string names to discover the integers at runtime.
This is done as per the usual practice for any existing enum property.
> 
> ***
> 
> Questions about the already existing "Content Protection" property:
> 
> - What happens if userspace attempts to write "Enabled" into it?
 *      DRM_MODE_CONTENT_PROTECTION_ENABLED = 2
 *              Userspace has requested content protection, and the link is
 *              protected. Only the driver can set the property to this value.
 *              If userspace attempts to set to ENABLED, kernel will return
 *              -EINVAL.
line number 936 @ drivers/gpu/drm/drm_connector.c

-Ram

> 
> - Where is the UAPI documentation that explains how userspace should be
>   using the property? (e.g. telling that you cannot set it to "Enabled")
> 
> 
> Thanks,
> pq


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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-07-04 11:12   ` Pekka Paalanen
@ 2019-07-04 10:42     ` Ramalingam C
  2019-07-05 13:36       ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-07-04 10:42 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: daniel.vetter, intel-gfx, dri-devel

On 2019-07-04 at 14:12:27 +0300, Pekka Paalanen wrote:
> On Tue,  7 May 2019 21:57:43 +0530
> Ramalingam C <ramalingam.c@intel.com> wrote:
> 
> > DRM API for generating uevent for a status changes of connector's
> > property.
> > 
> > This uevent will have following details related to the status change:
> > 
> >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > 
> > Need ACK from this uevent from userspace consumer.
> > 
> > v2:
> >   Minor fixes at KDoc comments [Daniel]
> > v3:
> >   Check the property is really attached with connector [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> >  include/drm/drm_sysfs.h     |  5 ++++-
> >  2 files changed, 39 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index 18b1ac442997..63fa951a20db 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -21,6 +21,7 @@
> >  #include <drm/drm_sysfs.h>
> >  #include <drm/drmP.h>
> >  #include "drm_internal.h"
> > +#include "drm_crtc_internal.h"
> >  
> >  #define to_drm_minor(d) dev_get_drvdata(d)
> >  #define to_drm_connector(d) dev_get_drvdata(d)
> > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> >   * deal with other types of events.
> > + *
> > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > + * for uevents on connector status change.
> >   */
> >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  {
> > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> >  }
> >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> >  
> > +/**
> > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > + * property status change
> > + * @connector: connector on which property status changed
> > + * @property: connector property whoes status changed.
> > + *
> > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > + * set HOTPLUG=1 and connector id along with the attached property id
> > + * related to the status change.
> > + */
This is the kernel doc added for drm_sysfs_connector_status_event()
similar to drm_sysfs_hotplug_event()

-Ram
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +				      struct drm_property *property)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > +
> > +	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > +					   property->base.id));
> > +
> > +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> > +		 "CONNECTOR=%u", connector->base.id);
> > +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> > +		 "PROPERTY=%u", property->base.id);
> > +
> > +	DRM_DEBUG("generating connector status event\n");
> > +
> > +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > +}
> > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > +
> >  static void drm_sysfs_release(struct device *dev)
> >  {
> >  	kfree(dev);
> > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > index 4f311e836cdc..d454ef617b2c 100644
> > --- a/include/drm/drm_sysfs.h
> > +++ b/include/drm/drm_sysfs.h
> > @@ -4,10 +4,13 @@
> >  
> >  struct drm_device;
> >  struct device;
> > +struct drm_connector;
> > +struct drm_property;
> >  
> >  int drm_class_device_register(struct device *dev);
> >  void drm_class_device_unregister(struct device *dev);
> >  
> >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > -
> > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > +				      struct drm_property *property);
> >  #endif
> 
> Hi,
> 
> this patch is completely missing the UAPI documentation.
> 
> Weston in
> https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> does have good looking code to parse this event.
> 
> 
> Thanks,
> pq


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

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

* Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-05-07 16:27 ` [PATCH v7 04/11] drm: revocation check at drm subsystem Ramalingam C
@ 2019-07-04 10:53   ` Pekka Paalanen
  2019-09-12  0:15   ` Harry Wentland
  1 sibling, 0 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-04 10:53 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel, gwan-gyeong.mun


[-- Attachment #1.1: Type: text/plain, Size: 7644 bytes --]

On Tue,  7 May 2019 21:57:38 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> On every hdcp revocation check request SRM is read from fw file
> /lib/firmware/display_hdcp_srm.bin
> 
> SRM table is parsed and stored at drm_hdcp.c, with functions exported
> for the services for revocation check from drivers (which
> implements the HDCP authentication)
> 
> This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> 
> v2:
>   moved the uAPI to request_firmware_direct() [Daniel]
> v3:
>   kdoc added. [Daniel]
>   srm_header unified and bit field definitions are removed. [Daniel]
>   locking improved. [Daniel]
>   vrl length violation is fixed. [Daniel]
> v4:
>   s/__swab16/be16_to_cpu [Daniel]
>   be24_to_cpu is done through a global func [Daniel]
>   Unused variables are removed. [Daniel]
>   unchecked return values are dropped from static funcs [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
> Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
> ---
>  Documentation/gpu/drm-kms-helpers.rst |   6 +
>  drivers/gpu/drm/Makefile              |   2 +-
>  drivers/gpu/drm/drm_hdcp.c            | 333 ++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_internal.h        |   4 +
>  drivers/gpu/drm/drm_sysfs.c           |   2 +
>  include/drm/drm_hdcp.h                |  24 ++
>  6 files changed, 370 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/drm_hdcp.c
> 
> diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
> index 14102ae035dc..0fe726a6ee67 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -181,6 +181,12 @@ Panel Helper Reference
>  .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
>     :export:
>  
> +HDCP Helper Functions Reference
> +===============================
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
> +   :export:
> +
>  Display Port Helper Functions Reference
>  =======================================
>  

...

> +/**
> + * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
> + *
> + * @drm_dev: drm_device for which HDCP revocation check is requested
> + * @ksvs: List of KSVs (HDCP receiver IDs)
> + * @ksv_count: KSV count passed in through @ksvs
> + *
> + * This function reads the HDCP System renewability Message(SRM Table)
> + * from userspace as a firmware and parses it for the revoked HDCP
> + * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known,
> + * revoked state of the KSVs in the list passed in by display drivers are
> + * decided and response is sent.
> + *
> + * SRM should be presented in the name of "display_hdcp_srm.bin".
> + *
> + * Returns:
> + * TRUE on any of the KSV is revoked, else FALSE.

Hi,

this does not seem to be specifying the file format. Since this file is
expected to be provided by vendors and not the driver developers AFAIU,
I think the file format counts as UAPI and needs to be explicitly and
unambiguously specified. Especially as the file or the file format are
not tied to a specific DRM driver or any driver. A searchable reference
to a particular revision of a public specification document could
suffice if such exists.

This doc comment is only kernel internal API. I would also expect UAPI
documentation for the same reason as above.

The Weston work[1] does not validate the UAPI added in this patch.


[1] https://gitlab.freedesktop.org/wayland/weston/merge_requests/48

Thanks,
pq

> + */
> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
> +				 u32 ksv_count)
> +{
> +	u32 rev_ksv_cnt, cnt, i, j;
> +	u8 *rev_ksv_list;
> +
> +	if (!srm_data)
> +		return false;
> +
> +	mutex_lock(&srm_data->mutex);
> +	drm_hdcp_request_srm(drm_dev);
> +
> +	rev_ksv_cnt = srm_data->revoked_ksv_cnt;
> +	rev_ksv_list = srm_data->revoked_ksv_list;
> +
> +	/* If the Revoked ksv list is empty */
> +	if (!rev_ksv_cnt || !rev_ksv_list) {
> +		mutex_unlock(&srm_data->mutex);
> +		return false;
> +	}
> +
> +	for  (cnt = 0; cnt < ksv_count; cnt++) {
> +		rev_ksv_list = srm_data->revoked_ksv_list;
> +		for (i = 0; i < rev_ksv_cnt; i++) {
> +			for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
> +				if (ksvs[j] != rev_ksv_list[j]) {
> +					break;
> +				} else if (j == (DRM_HDCP_KSV_LEN - 1)) {
> +					DRM_DEBUG("Revoked KSV is ");
> +					drm_hdcp_print_ksv(ksvs);
> +					mutex_unlock(&srm_data->mutex);
> +					return true;
> +				}
> +			/* Move the offset to next KSV in the revoked list */
> +			rev_ksv_list += DRM_HDCP_KSV_LEN;
> +		}
> +
> +		/* Iterate to next ksv_offset */
> +		ksvs += DRM_HDCP_KSV_LEN;
> +	}
> +	mutex_unlock(&srm_data->mutex);
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
> +
> +int drm_setup_hdcp_srm(struct class *drm_class)
> +{
> +	srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> +	if (!srm_data)
> +		return -ENOMEM;
> +	mutex_init(&srm_data->mutex);
> +
> +	return 0;
> +}
> +
> +void drm_teardown_hdcp_srm(struct class *drm_class)
> +{
> +	if (srm_data) {
> +		kfree(srm_data->revoked_ksv_list);
> +		kfree(srm_data);
> +	}
> +}
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index e19ac7ca602d..476a422414f6 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
>  				const struct drm_framebuffer *fb);
>  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> +
> +/* drm_hdcp.c */
> +int drm_setup_hdcp_srm(struct class *drm_class);
> +void drm_teardown_hdcp_srm(struct class *drm_class);
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index ecb7b33002bb..18b1ac442997 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
>  	}
>  
>  	drm_class->devnode = drm_devnode;
> +	drm_setup_hdcp_srm(drm_class);
>  	return 0;
>  }
>  
> @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
>  {
>  	if (IS_ERR_OR_NULL(drm_class))
>  		return;
> +	drm_teardown_hdcp_srm(drm_class);
>  	class_remove_file(drm_class, &class_attr_version.attr);
>  	class_destroy(drm_class);
>  	drm_class = NULL;
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 1cc66df05a43..2f0335d0a50f 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
>  	seq_num[2] = val;
>  }
>  
> +#define DRM_HDCP_SRM_GEN1_MAX_BYTES		(5 * 1024)
> +#define DRM_HDCP_1_4_SRM_ID			0x8
> +#define DRM_HDCP_SRM_ID_MASK			(0xF << 4)
> +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE		3
> +#define DRM_HDCP_1_4_DCP_SIG_SIZE		40
> +#define DRM_HDCP_2_SRM_ID			0x9
> +#define DRM_HDCP_2_INDICATOR			0x1
> +#define DRM_HDCP_2_INDICATOR_MASK		0xF
> +#define DRM_HDCP_2_VRL_LENGTH_SIZE		3
> +#define DRM_HDCP_2_DCP_SIG_SIZE			384
> +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ	4
> +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)	(((byte) & 0xC) >> 6)
> +
> +struct hdcp_srm_header {
> +	u8 srm_id;
> +	u8 reserved;
> +	__be16 srm_version;
> +	u8 srm_gen_no;
> +} __packed;
> +
> +struct drm_device;
> +
> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> +				 u8 *ksvs, u32 ksv_count);
>  #endif


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 10/11] drm/hdcp: update content protection property with uevent
  2019-07-04 11:14   ` Pekka Paalanen
@ 2019-07-04 11:11     ` Ramalingam C
  2019-07-05 13:59       ` Pekka Paalanen
  2019-07-04 23:51     ` Ramalingam C
  1 sibling, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-07-04 11:11 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: daniel.vetter, intel-gfx, dri-devel

On 2019-07-04 at 14:14:19 +0300, Pekka Paalanen wrote:
> On Tue,  7 May 2019 21:57:44 +0530
> Ramalingam C <ramalingam.c@intel.com> wrote:
> 
> > drm function is defined and exported to update a connector's
> > content protection property state and to generate a uevent along
> > with it.
> > 
> > Need ACK for the uevent from userspace consumer.
> > 
> > v2:
> >   Update only when state is different from old one.
> > v3:
> >   KDoc is added [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_hdcp.c | 32 ++++++++++++++++++++++++++++++++
> >  include/drm/drm_hdcp.h     |  2 ++
> >  2 files changed, 34 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > index 75402463466b..f29b7abda51f 100644
> > --- a/drivers/gpu/drm/drm_hdcp.c
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> >   *
> >   * The content protection will be set to &drm_connector_state.content_protection
> >   *
> > + * When kernel triggered content protection state change like DESIRED->ENABLED
> > + * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update
> > + * the content protection state of a connector.
Here we indicated that drm_hdcp_update_content_protection() used for
kernel triggered content protection state change.
> > + *
> >   * Returns:
> >   * Zero on success, negative errno on failure.
> >   */
> > @@ -412,3 +416,31 @@ int drm_connector_attach_content_protection_property(
> >  	return 0;
> >  }
> >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> > +
> > +/**
> > + * drm_hdcp_update_content_protection - Updates the content protection state
> > + * of a connector
> > + *
> > + * @connector: drm_connector on which content protection state needs an update
> > + * @val: New state of the content protection property
> > + *
> > + * This function can be used by display drivers, to update the kernel triggered
> > + * content protection state change of a drm_connector.This function update the
These lines also indicate that this function is used for kernel
triggered content protection state change of a drm_connector.

-Ram
> > + * new state of the property into the connector's state and generate an uevent
> > + * to notify the userspace.
> > + */
> > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > +					u64 val)
> > +{
> 
> Hi,
> 
> don't you need to ensure that 'val' cannot be UNDESIRED?
@ https://patchwork.freedesktop.org/patch/303909/?series=57232&rev=9
caller(I915) of this function is ensuring that.

-Ram
> 
> > +	struct drm_device *dev = connector->dev;
> > +	struct drm_connector_state *state = connector->state;
> > +
> > +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> > +	if (state->content_protection == val)
> > +		return;
> > +
> > +	state->content_protection = val;
> > +	drm_sysfs_connector_status_event(connector,
> > +				 dev->mode_config.content_protection_property);
> > +}
> > +EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > index 2970abdfaf12..dd864ac9ce85 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -292,4 +292,6 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> >  				 u8 *ksvs, u32 ksv_count);
> >  int drm_connector_attach_content_protection_property(
> >  		struct drm_connector *connector, bool hdcp_content_type);
> > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > +					u64 val);
> >  #endif
> 
> This patch is missing all UAPI documentation.
> 
> Particularly important is the detail that the kernel will not send an
> event corresponding to userspace explicitly setting "Content
> Protection" to "Undesired". That is what you explained to me in the
> Weston MR !48, but I don't actually see it in the code here. It would
> be best to enforce that in the shared DRM code.
> 
> 
> Thanks,
> pq


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

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

* Re: [PATCH v7 07/11] drm: Add Content protection type property
  2019-05-07 16:27 ` [PATCH v7 07/11] drm: Add Content protection type property Ramalingam C
@ 2019-07-04 11:11   ` Pekka Paalanen
  2019-07-04 10:36     ` Ramalingam C
  0 siblings, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-04 11:11 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 8939 bytes --]

On Tue,  7 May 2019 21:57:41 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> This patch adds a DRM ENUM property to the selected connectors.
> This property is used for mentioning the protected content's type
> from userspace to kernel HDCP authentication.
> 
> Type of the stream is decided by the protected content providers.
> Type 0 content can be rendered on any HDCP protected display wires.
> But Type 1 content can be rendered only on HDCP2.2 protected paths.
> 
> So when a userspace sets this property to Type 1 and starts the HDCP
> enable, kernel will honour it only if HDCP2.2 authentication is through
> for type 1. Else HDCP enable will be failed.
> 
> Need ACK for this new conenctor property from userspace consumer.
> 
> v2:
>   cp_content_type is replaced with content_protection_type [daniel]
>   check at atomic_set_property is removed [Maarten]
> v3:
>   %s/content_protection_type/hdcp_content_type [Pekka]
> v4:
>   property is created for the first requested connector and then reused.
> 	[Danvet]
> v5:
>   kernel doc nits addressed [Daniel]
>   Rebased as part of patch reordering.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
>  drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
>  drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
>  include/drm/drm_connector.h       |  7 ++++++
>  include/drm/drm_hdcp.h            |  2 +-
>  include/drm/drm_mode_config.h     |  6 ++++++
>  include/uapi/drm/drm_mode.h       |  4 ++++
>  8 files changed, 78 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 4131e669785a..a85f3ccfe699 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>  			return -EINVAL;
>  		}
>  		state->content_protection = val;
> +	} else if (property == config->hdcp_content_type_property) {
> +		state->hdcp_content_type = val;
>  	} else if (property == connector->colorspace_property) {
>  		state->colorspace = val;
>  	} else if (property == config->writeback_fb_id_property) {
> @@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->scaling_mode;
>  	} else if (property == config->content_protection_property) {
>  		*val = state->content_protection;
> +	} else if (property == config->hdcp_content_type_property) {
> +		*val = state->hdcp_content_type;
>  	} else if (property == config->writeback_fb_id_property) {
>  		/* Writeback framebuffer is one-shot, write and forget */
>  		*val = 0;
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 764c7903edf6..de9e06583e8c 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c

Hi,

below I have some comments and questions before I can say whether
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
adheres to this specification.

> @@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
>   *	  the value transitions from ENABLED to DESIRED. This signifies the link
>   *	  is no longer protected and userspace should take appropriate action
>   *	  (whatever that might be).
> + * HDCP Content Type:
> + *	This property is used by the userspace to configure the kernel with
> + *	to be displayed stream's content type. Content Type of a stream is
> + *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
> + *
> + *	The value of the property can be one the below:
> + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0

If this doc is meant as the UAPI doc, it needs to use the string names
for enum property values, not the C language definitions (integers).

> + *		HDCP Type0 streams can be transmitted on a link which is
> + *		encrypted with HDCP 1.4 or HDCP 2.2.

This wording forbids using any future HDCP version for type0.

> + *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
> + *		HDCP Type1 streams can be transmitted on a link which is
> + *		encrypted only with HDCP 2.2.

This wording forbids using any future HDCP version for type1.

> + *
> + *	Note that the HDCP Content Type property is specific to HDCP 2.2, and
> + *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.2

Not possible with a future HDCP version greater than 2.2?

Is it intended to be possible to add more content types in the future?

> + *	If content type is changed when content_protection is not UNDESIRED,
> + *	then kernel will disable the HDCP and re-enable with new type in the
> + *	same atomic commit

Ok, very good to mention this.

>   *
>   * max bpc:
>   *	This range property is used by userspace to limit the bit depth. When
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index 0da7b3718bad..75402463466b 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -342,23 +342,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
>  };
>  DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
>  
> +static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
> +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> +		 drm_hdcp_content_type_enum_list)
> +
>  /**
>   * drm_connector_attach_content_protection_property - attach content protection
>   * property
>   *
>   * @connector: connector to attach CP property on.
> + * @hdcp_content_type: is HDCP Content Type property needed for connector
>   *
>   * This is used to add support for content protection on select connectors.
>   * Content Protection is intentionally vague to allow for different underlying
>   * technologies, however it is most implemented by HDCP.
>   *
> + * When hdcp_content_type is true enum property called HDCP Content Type is
> + * created (if it is not already) and attached to the connector.
> + *
> + * This property is used for sending the protected content's stream type
> + * from userspace to kernel on selected connectors. Protected content provider
> + * will decide their type of their content and declare the same to kernel.
> + *
> + * Content type will be used during the HDCP 2.2 authentication.
> + * Content type will be set to &drm_connector_state.hdcp_content_type.
> + *
>   * The content protection will be set to &drm_connector_state.content_protection
>   *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
>  int drm_connector_attach_content_protection_property(
> -		struct drm_connector *connector)
> +		struct drm_connector *connector, bool hdcp_content_type)
>  {
>  	struct drm_device *dev = connector->dev;
>  	struct drm_property *prop =
> @@ -375,6 +393,22 @@ int drm_connector_attach_content_protection_property(
>  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
>  	dev->mode_config.content_protection_property = prop;
>  
> +	if (!hdcp_content_type)
> +		return 0;
> +
> +	prop = dev->mode_config.hdcp_content_type_property;
> +	if (!prop)
> +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> +					drm_hdcp_content_type_enum_list,
> +					ARRAY_SIZE(
> +					drm_hdcp_content_type_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&connector->base, prop,
> +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> +	dev->mode_config.hdcp_content_type_property = prop;
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);

...

> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 83cd1636b9be..8ac03351fdee 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -209,6 +209,10 @@ extern "C" {
>  #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
>  #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
>  
> +/* Content Type classification for HDCP2.2 vs others */
> +#define DRM_MODE_HDCP_CONTENT_TYPE0		0
> +#define DRM_MODE_HDCP_CONTENT_TYPE1		1

These should not be in a UAPI header. The C language definitions must
never be exposed to userspace, or misguided userspace will start using
them.

Instead, UAPI uses the string names to discover the integers at runtime.

***

Questions about the already existing "Content Protection" property:

- What happens if userspace attempts to write "Enabled" into it?

- Where is the UAPI documentation that explains how userspace should be
  using the property? (e.g. telling that you cannot set it to "Enabled")


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-05-07 16:27 ` [PATCH v7 09/11] drm: uevent for connector status change Ramalingam C
  2019-05-10 12:12   ` Paul Kocialkowski
@ 2019-07-04 11:12   ` Pekka Paalanen
  2019-07-04 10:42     ` Ramalingam C
  1 sibling, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-04 11:12 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 3946 bytes --]

On Tue,  7 May 2019 21:57:43 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> DRM API for generating uevent for a status changes of connector's
> property.
> 
> This uevent will have following details related to the status change:
> 
>   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> 
> Need ACK from this uevent from userspace consumer.
> 
> v2:
>   Minor fixes at KDoc comments [Daniel]
> v3:
>   Check the property is really attached with connector [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
>  include/drm/drm_sysfs.h     |  5 ++++-
>  2 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index 18b1ac442997..63fa951a20db 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -21,6 +21,7 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drmP.h>
>  #include "drm_internal.h"
> +#include "drm_crtc_internal.h"
>  
>  #define to_drm_minor(d) dev_get_drvdata(d)
>  #define to_drm_connector(d) dev_get_drvdata(d)
> @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
>   * Send a uevent for the DRM device specified by @dev.  Currently we only
>   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
>   * deal with other types of events.
> + *
> + * Any new uapi should be using the drm_sysfs_connector_status_event()
> + * for uevents on connector status change.
>   */
>  void drm_sysfs_hotplug_event(struct drm_device *dev)
>  {
> @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
>  }
>  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
>  
> +/**
> + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> + * property status change
> + * @connector: connector on which property status changed
> + * @property: connector property whoes status changed.
> + *
> + * Send a uevent for the DRM device specified by @dev.  Currently we
> + * set HOTPLUG=1 and connector id along with the attached property id
> + * related to the status change.
> + */
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property)
> +{
> +	struct drm_device *dev = connector->dev;
> +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> +
> +	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> +					   property->base.id));
> +
> +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> +		 "CONNECTOR=%u", connector->base.id);
> +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> +		 "PROPERTY=%u", property->base.id);
> +
> +	DRM_DEBUG("generating connector status event\n");
> +
> +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> +}
> +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> +
>  static void drm_sysfs_release(struct device *dev)
>  {
>  	kfree(dev);
> diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> index 4f311e836cdc..d454ef617b2c 100644
> --- a/include/drm/drm_sysfs.h
> +++ b/include/drm/drm_sysfs.h
> @@ -4,10 +4,13 @@
>  
>  struct drm_device;
>  struct device;
> +struct drm_connector;
> +struct drm_property;
>  
>  int drm_class_device_register(struct device *dev);
>  void drm_class_device_unregister(struct device *dev);
>  
>  void drm_sysfs_hotplug_event(struct drm_device *dev);
> -
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property);
>  #endif

Hi,

this patch is completely missing the UAPI documentation.

Weston in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
does have good looking code to parse this event.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 10/11] drm/hdcp: update content protection property with uevent
  2019-05-07 16:27 ` [PATCH v7 10/11] drm/hdcp: update content protection property with uevent Ramalingam C
@ 2019-07-04 11:14   ` Pekka Paalanen
  2019-07-04 11:11     ` Ramalingam C
  2019-07-04 23:51     ` Ramalingam C
  0 siblings, 2 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-04 11:14 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 3573 bytes --]

On Tue,  7 May 2019 21:57:44 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> drm function is defined and exported to update a connector's
> content protection property state and to generate a uevent along
> with it.
> 
> Need ACK for the uevent from userspace consumer.
> 
> v2:
>   Update only when state is different from old one.
> v3:
>   KDoc is added [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_hdcp.c | 32 ++++++++++++++++++++++++++++++++
>  include/drm/drm_hdcp.h     |  2 ++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index 75402463466b..f29b7abda51f 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
>   *
>   * The content protection will be set to &drm_connector_state.content_protection
>   *
> + * When kernel triggered content protection state change like DESIRED->ENABLED
> + * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update
> + * the content protection state of a connector.
> + *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> @@ -412,3 +416,31 @@ int drm_connector_attach_content_protection_property(
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> +
> +/**
> + * drm_hdcp_update_content_protection - Updates the content protection state
> + * of a connector
> + *
> + * @connector: drm_connector on which content protection state needs an update
> + * @val: New state of the content protection property
> + *
> + * This function can be used by display drivers, to update the kernel triggered
> + * content protection state change of a drm_connector. This function update the
> + * new state of the property into the connector's state and generate an uevent
> + * to notify the userspace.
> + */
> +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> +					u64 val)
> +{

Hi,

don't you need to ensure that 'val' cannot be UNDESIRED?

> +	struct drm_device *dev = connector->dev;
> +	struct drm_connector_state *state = connector->state;
> +
> +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> +	if (state->content_protection == val)
> +		return;
> +
> +	state->content_protection = val;
> +	drm_sysfs_connector_status_event(connector,
> +				 dev->mode_config.content_protection_property);
> +}
> +EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 2970abdfaf12..dd864ac9ce85 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -292,4 +292,6 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
>  				 u8 *ksvs, u32 ksv_count);
>  int drm_connector_attach_content_protection_property(
>  		struct drm_connector *connector, bool hdcp_content_type);
> +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> +					u64 val);
>  #endif

This patch is missing all UAPI documentation.

Particularly important is the detail that the kernel will not send an
event corresponding to userspace explicitly setting "Content
Protection" to "Undesired". That is what you explained to me in the
Weston MR !48, but I don't actually see it in the code here. It would
be best to enforce that in the shared DRM code.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 10/11] drm/hdcp: update content protection property with uevent
  2019-07-04 11:14   ` Pekka Paalanen
  2019-07-04 11:11     ` Ramalingam C
@ 2019-07-04 23:51     ` Ramalingam C
  1 sibling, 0 replies; 70+ messages in thread
From: Ramalingam C @ 2019-07-04 23:51 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: daniel.vetter, intel-gfx, dri-devel

On 2019-07-04 at 14:14:19 +0300, Pekka Paalanen wrote:
> On Tue,  7 May 2019 21:57:44 +0530
> Ramalingam C <ramalingam.c@intel.com> wrote:
> 
> > drm function is defined and exported to update a connector's
> > content protection property state and to generate a uevent along
> > with it.
> > 
> > Need ACK for the uevent from userspace consumer.
> > 
> > v2:
> >   Update only when state is different from old one.
> > v3:
> >   KDoc is added [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/drm_hdcp.c | 32 ++++++++++++++++++++++++++++++++
> >  include/drm/drm_hdcp.h     |  2 ++
> >  2 files changed, 34 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > index 75402463466b..f29b7abda51f 100644
> > --- a/drivers/gpu/drm/drm_hdcp.c
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> >   *
> >   * The content protection will be set to &drm_connector_state.content_protection
> >   *
> > + * When kernel triggered content protection state change like DESIRED->ENABLED
> > + * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update
> > + * the content protection state of a connector.
> > + *
> >   * Returns:
> >   * Zero on success, negative errno on failure.
> >   */
> > @@ -412,3 +416,31 @@ int drm_connector_attach_content_protection_property(
> >  	return 0;
> >  }
> >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> > +
> > +/**
> > + * drm_hdcp_update_content_protection - Updates the content protection state
> > + * of a connector
> > + *
> > + * @connector: drm_connector on which content protection state needs an update
> > + * @val: New state of the content protection property
> > + *
> > + * This function can be used by display drivers, to update the kernel triggered
> > + * content protection state change of a drm_connector. This function update the
> > + * new state of the property into the connector's state and generate an uevent
> > + * to notify the userspace.
> > + */
> > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > +					u64 val)
> > +{
> 
> Hi,
> 
> don't you need to ensure that 'val' cannot be UNDESIRED?
> 
> > +	struct drm_device *dev = connector->dev;
> > +	struct drm_connector_state *state = connector->state;
> > +
> > +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> > +	if (state->content_protection == val)
when val==UNDESIRED even the state->content_protection also UNDESIRED.
Hence explicit check is not needed here.

-Ram
> > +		return;
> > +
> > +	state->content_protection = val;
> > +	drm_sysfs_connector_status_event(connector,
> > +				 dev->mode_config.content_protection_property);
> > +}
> > +EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > index 2970abdfaf12..dd864ac9ce85 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -292,4 +292,6 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> >  				 u8 *ksvs, u32 ksv_count);
> >  int drm_connector_attach_content_protection_property(
> >  		struct drm_connector *connector, bool hdcp_content_type);
> > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > +					u64 val);
> >  #endif
> 
> This patch is missing all UAPI documentation.
> 
> Particularly important is the detail that the kernel will not send an
> event corresponding to userspace explicitly setting "Content
> Protection" to "Undesired". That is what you explained to me in the
> Weston MR !48, but I don't actually see it in the code here. It would
> be best to enforce that in the shared DRM code.
> 
> 
> Thanks,
> pq


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

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

* Re: [PATCH v7 07/11] drm: Add Content protection type property
  2019-07-05 13:00       ` Pekka Paalanen
@ 2019-07-05  6:33         ` Ramalingam C
  2019-07-05 14:12           ` Pekka Paalanen
  0 siblings, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-07-05  6:33 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: daniel.vetter, intel-gfx, dri-devel

On 2019-07-05 at 16:00:37 +0300, Pekka Paalanen wrote:
> On Thu, 4 Jul 2019 16:06:05 +0530
> Ramalingam C <ramalingam.c@intel.com> wrote:
> 
> > On 2019-07-04 at 14:11:59 +0300, Pekka Paalanen wrote:
> > > On Tue,  7 May 2019 21:57:41 +0530
> > > Ramalingam C <ramalingam.c@intel.com> wrote:
> > >   
> > > > This patch adds a DRM ENUM property to the selected connectors.
> > > > This property is used for mentioning the protected content's type
> > > > from userspace to kernel HDCP authentication.
> > > > 
> > > > Type of the stream is decided by the protected content providers.
> > > > Type 0 content can be rendered on any HDCP protected display wires.
> > > > But Type 1 content can be rendered only on HDCP2.2 protected paths.
> > > > 
> > > > So when a userspace sets this property to Type 1 and starts the HDCP
> > > > enable, kernel will honour it only if HDCP2.2 authentication is through
> > > > for type 1. Else HDCP enable will be failed.
> > > > 
> > > > Need ACK for this new conenctor property from userspace consumer.
> > > > 
> > > > v2:
> > > >   cp_content_type is replaced with content_protection_type [daniel]
> > > >   check at atomic_set_property is removed [Maarten]
> > > > v3:
> > > >   %s/content_protection_type/hdcp_content_type [Pekka]
> > > > v4:
> > > >   property is created for the first requested connector and then reused.
> > > > 	[Danvet]
> > > > v5:
> > > >   kernel doc nits addressed [Daniel]
> > > >   Rebased as part of patch reordering.
> > > > 
> > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > ---
> > > >  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
> > > >  drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
> > > >  drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
> > > >  drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
> > > >  include/drm/drm_connector.h       |  7 ++++++
> > > >  include/drm/drm_hdcp.h            |  2 +-
> > > >  include/drm/drm_mode_config.h     |  6 ++++++
> > > >  include/uapi/drm/drm_mode.h       |  4 ++++
> > > >  8 files changed, 78 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > > > index 4131e669785a..a85f3ccfe699 100644
> > > > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > > > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > > > @@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
> > > >  			return -EINVAL;
> > > >  		}
> > > >  		state->content_protection = val;
> > > > +	} else if (property == config->hdcp_content_type_property) {
> > > > +		state->hdcp_content_type = val;
> > > >  	} else if (property == connector->colorspace_property) {
> > > >  		state->colorspace = val;
> > > >  	} else if (property == config->writeback_fb_id_property) {
> > > > @@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> > > >  		*val = state->scaling_mode;
> > > >  	} else if (property == config->content_protection_property) {
> > > >  		*val = state->content_protection;
> > > > +	} else if (property == config->hdcp_content_type_property) {
> > > > +		*val = state->hdcp_content_type;
> > > >  	} else if (property == config->writeback_fb_id_property) {
> > > >  		/* Writeback framebuffer is one-shot, write and forget */
> > > >  		*val = 0;
> > > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > > index 764c7903edf6..de9e06583e8c 100644
> > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > +++ b/drivers/gpu/drm/drm_connector.c  
> > > 
> > > Hi,
> > > 
> > > below I have some comments and questions before I can say whether
> > > https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> > > adheres to this specification.
> > >   
> > > > @@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
> > > >   *	  the value transitions from ENABLED to DESIRED. This signifies the link
> > > >   *	  is no longer protected and userspace should take appropriate action
> > > >   *	  (whatever that might be).
> > > > + * HDCP Content Type:
> > > > + *	This property is used by the userspace to configure the kernel with
> > > > + *	to be displayed stream's content type. Content Type of a stream is
> > > > + *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
> > > > + *
> > > > + *	The value of the property can be one the below:
> > > > + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0  
> > > 
> > > If this doc is meant as the UAPI doc, it needs to use the string names
> > > for enum property values, not the C language definitions (integers).  
> 
> > kernel documentation for all other properties followed this way. We
> > could add string associated to the enum state too for this property.
> 
> Hi,
> 
> I don't really care what kernel internal APIs use, this may well be
> correct for them, but the UAPI uses strings.
> 
> Because the kernel internal and UAPI docs are mixed up, it will be hard
> to write proper docs. I guess can't help it this time.
> 
> It would be really good if the enum value strings were explicitly
> presented in the docs, so userspace has something to hook on. Or if not
> in docs, in the UAPI header, see further below.
> 
> I do see the strings in the docs you wrote, but nothing really
> highlights them as the literal strings to be used in the API. Even just
> quotes "" around them would make them more discoverable, especially
> "HDCP Type0" etc.
In the next version I have added the string too in the kernel
docuemntation.

But when we read the property state we read the enum
value which is matched agaist the string based on the enum property
definition. So I feel we should have both detail matched against in the uAPI
doc.
> 
> > >   
> > > > + *		HDCP Type0 streams can be transmitted on a link which is
> > > > + *		encrypted with HDCP 1.4 or HDCP 2.2.  
> > > 
> > > This wording forbids using any future HDCP version for type0.  
> > We could change it to HDCP1.4 and higher version of HDCP.
> > >   
> > > > + *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
> > > > + *		HDCP Type1 streams can be transmitted on a link which is
> > > > + *		encrypted only with HDCP 2.2.  
> > > 
> > > This wording forbids using any future HDCP version for type1.  
> > As of now type 1 is only on HDCP2.2 encrypted link, as no higher version is
> > available. But as similar to Type 0 we could assume that Type 1 will be
> > supported on higher HDCP versions too and correct the sentence here.
> > >   
> > > > + *
> > > > + *	Note that the HDCP Content Type property is specific to HDCP 2.2, and
> > > > + *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.2  
> > > 
> > > Not possible with a future HDCP version greater than 2.2?
> > > 
> > > Is it intended to be possible to add more content types in the future?  
> > Possible. As per HDCP2.2 spec, 8bits are reserved for the content Type.
> 
> Right. All my three notes above are about future-proofing this for the
> "trivial" case of adding one more content type. I think it would be
> wise to do, because the cost is very low (no changes in code, just
> trivial change in spec), and even if the likelyhood of adding more
> types in future might be low, it's not zero.
> 
> I think the Weston implementation under review in MR !48 is
> future-proof as well, in the sense that enum values it does not know
> will be interpreted as Type0.
> 
> I suppose it is a reasonable assumption that HDCP spec will not add a
> new type that would not be at least as secure as Type0, right?
As per my understanding, HDCP spec will add new type if there is a
betterment in next version of HDCP and hence userspace want to mandate
only that spec for it's content. Say Content Type 2 which can be
rendered only on HDCP3.x.

Hopefully next version of this patch has the futureproofing you are
looking for.

-Ram
> 
> > >   
> > > > + *	If content type is changed when content_protection is not UNDESIRED,
> > > > + *	then kernel will disable the HDCP and re-enable with new type in the
> > > > + *	same atomic commit  
> > > 
> > > Ok, very good to mention this.
> > >   
> > > >   *
> > > >   * max bpc:
> > > >   *	This range property is used by userspace to limit the bit depth. When
> > > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > > > index 0da7b3718bad..75402463466b 100644
> > > > --- a/drivers/gpu/drm/drm_hdcp.c
> > > > +++ b/drivers/gpu/drm/drm_hdcp.c
> > > > @@ -342,23 +342,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
> > > >  };
> > > >  DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
> > > >  
> > > > +static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
> > > > +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> > > > +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> > > > +};
> > > > +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> > > > +		 drm_hdcp_content_type_enum_list)
> > > > +
> > > >  /**
> > > >   * drm_connector_attach_content_protection_property - attach content protection
> > > >   * property
> > > >   *
> > > >   * @connector: connector to attach CP property on.
> > > > + * @hdcp_content_type: is HDCP Content Type property needed for connector
> > > >   *
> > > >   * This is used to add support for content protection on select connectors.
> > > >   * Content Protection is intentionally vague to allow for different underlying
> > > >   * technologies, however it is most implemented by HDCP.
> > > >   *
> > > > + * When hdcp_content_type is true enum property called HDCP Content Type is
> > > > + * created (if it is not already) and attached to the connector.
> > > > + *
> > > > + * This property is used for sending the protected content's stream type
> > > > + * from userspace to kernel on selected connectors. Protected content provider
> > > > + * will decide their type of their content and declare the same to kernel.
> > > > + *
> > > > + * Content type will be used during the HDCP 2.2 authentication.
> > > > + * Content type will be set to &drm_connector_state.hdcp_content_type.
> > > > + *
> > > >   * The content protection will be set to &drm_connector_state.content_protection
> > > >   *
> > > >   * Returns:
> > > >   * Zero on success, negative errno on failure.
> > > >   */
> > > >  int drm_connector_attach_content_protection_property(
> > > > -		struct drm_connector *connector)
> > > > +		struct drm_connector *connector, bool hdcp_content_type)
> > > >  {
> > > >  	struct drm_device *dev = connector->dev;
> > > >  	struct drm_property *prop =
> > > > @@ -375,6 +393,22 @@ int drm_connector_attach_content_protection_property(
> > > >  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> > > >  	dev->mode_config.content_protection_property = prop;
> > > >  
> > > > +	if (!hdcp_content_type)
> > > > +		return 0;
> > > > +
> > > > +	prop = dev->mode_config.hdcp_content_type_property;
> > > > +	if (!prop)
> > > > +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> > > > +					drm_hdcp_content_type_enum_list,
> > > > +					ARRAY_SIZE(
> > > > +					drm_hdcp_content_type_enum_list));
> > > > +	if (!prop)
> > > > +		return -ENOMEM;
> > > > +
> > > > +	drm_object_attach_property(&connector->base, prop,
> > > > +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> > > > +	dev->mode_config.hdcp_content_type_property = prop;
> > > > +
> > > >  	return 0;
> > > >  }
> > > >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);  
> > > 
> > > ...
> > >   
> > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > > index 83cd1636b9be..8ac03351fdee 100644
> > > > --- a/include/uapi/drm/drm_mode.h
> > > > +++ b/include/uapi/drm/drm_mode.h
> > > > @@ -209,6 +209,10 @@ extern "C" {
> > > >  #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
> > > >  #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
> > > >  
> > > > +/* Content Type classification for HDCP2.2 vs others */
> > > > +#define DRM_MODE_HDCP_CONTENT_TYPE0		0
> > > > +#define DRM_MODE_HDCP_CONTENT_TYPE1		1  
> > > 
> > > These should not be in a UAPI header. The C language definitions must
> > > never be exposed to userspace, or misguided userspace will start using
> > > them.
> > > 
> > > Instead, UAPI uses the string names to discover the integers at runtime.  
> > This is done as per the usual practice for any existing enum property.
> 
> I suspect this is just the cycle of cargo-culting mistakes. Weston
> MR !48 does not use these defines either.
> 
> Unfortunately the bad examples that are already in the UAPI headers
> cannot be removed.
> 
> However, I think you could start a new good practice:
> 
> #define DRM_MODE_HDCP_CONTENT_TYPE0_STR "HDCP Type0"
> #define DRM_MODE_HDCP_CONTENT_TYPE1_STR "HDCP Type1"
> 
> It would make a lot of sense for the UAPI header to spell out the
> strings that userspace must be using. Even if userspace wouldn't use
> these defines, they would have strong documentary value.
> 
> Danvet, would you agree with me here?
> 
> > > 
> > > ***
> > > 
> > > Questions about the already existing "Content Protection" property:
> > > 
> > > - What happens if userspace attempts to write "Enabled" into it?  
> >  *      DRM_MODE_CONTENT_PROTECTION_ENABLED = 2
> >  *              Userspace has requested content protection, and the link is
> >  *              protected. Only the driver can set the property to this value.
> >  *              If userspace attempts to set to ENABLED, kernel will return
> >  *              -EINVAL.
> > line number 936 @ drivers/gpu/drm/drm_connector.c
> 
> Good, I glossed over the last sentence when reading this before.
> 
> 
> Thanks,
> pq
> 
> > 
> > -Ram
> > 
> > > 
> > > - Where is the UAPI documentation that explains how userspace should be
> > >   using the property? (e.g. telling that you cannot set it to "Enabled")
> > > 
> > > 
> > > Thanks,
> > > pq  
> > 
> > 
> 


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

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

* Re: [PATCH v7 07/11] drm: Add Content protection type property
  2019-07-04 10:36     ` Ramalingam C
@ 2019-07-05 13:00       ` Pekka Paalanen
  2019-07-05  6:33         ` Ramalingam C
  0 siblings, 1 reply; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-05 13:00 UTC (permalink / raw)
  To: Ramalingam C, daniel.vetter; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun


[-- Attachment #1.1: Type: text/plain, Size: 12990 bytes --]

On Thu, 4 Jul 2019 16:06:05 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> On 2019-07-04 at 14:11:59 +0300, Pekka Paalanen wrote:
> > On Tue,  7 May 2019 21:57:41 +0530
> > Ramalingam C <ramalingam.c@intel.com> wrote:
> >   
> > > This patch adds a DRM ENUM property to the selected connectors.
> > > This property is used for mentioning the protected content's type
> > > from userspace to kernel HDCP authentication.
> > > 
> > > Type of the stream is decided by the protected content providers.
> > > Type 0 content can be rendered on any HDCP protected display wires.
> > > But Type 1 content can be rendered only on HDCP2.2 protected paths.
> > > 
> > > So when a userspace sets this property to Type 1 and starts the HDCP
> > > enable, kernel will honour it only if HDCP2.2 authentication is through
> > > for type 1. Else HDCP enable will be failed.
> > > 
> > > Need ACK for this new conenctor property from userspace consumer.
> > > 
> > > v2:
> > >   cp_content_type is replaced with content_protection_type [daniel]
> > >   check at atomic_set_property is removed [Maarten]
> > > v3:
> > >   %s/content_protection_type/hdcp_content_type [Pekka]
> > > v4:
> > >   property is created for the first requested connector and then reused.
> > > 	[Danvet]
> > > v5:
> > >   kernel doc nits addressed [Daniel]
> > >   Rebased as part of patch reordering.
> > > 
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
> > >  drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
> > >  drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
> > >  drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
> > >  include/drm/drm_connector.h       |  7 ++++++
> > >  include/drm/drm_hdcp.h            |  2 +-
> > >  include/drm/drm_mode_config.h     |  6 ++++++
> > >  include/uapi/drm/drm_mode.h       |  4 ++++
> > >  8 files changed, 78 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > > index 4131e669785a..a85f3ccfe699 100644
> > > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > > @@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
> > >  			return -EINVAL;
> > >  		}
> > >  		state->content_protection = val;
> > > +	} else if (property == config->hdcp_content_type_property) {
> > > +		state->hdcp_content_type = val;
> > >  	} else if (property == connector->colorspace_property) {
> > >  		state->colorspace = val;
> > >  	} else if (property == config->writeback_fb_id_property) {
> > > @@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> > >  		*val = state->scaling_mode;
> > >  	} else if (property == config->content_protection_property) {
> > >  		*val = state->content_protection;
> > > +	} else if (property == config->hdcp_content_type_property) {
> > > +		*val = state->hdcp_content_type;
> > >  	} else if (property == config->writeback_fb_id_property) {
> > >  		/* Writeback framebuffer is one-shot, write and forget */
> > >  		*val = 0;
> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > index 764c7903edf6..de9e06583e8c 100644
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c  
> > 
> > Hi,
> > 
> > below I have some comments and questions before I can say whether
> > https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> > adheres to this specification.
> >   
> > > @@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
> > >   *	  the value transitions from ENABLED to DESIRED. This signifies the link
> > >   *	  is no longer protected and userspace should take appropriate action
> > >   *	  (whatever that might be).
> > > + * HDCP Content Type:
> > > + *	This property is used by the userspace to configure the kernel with
> > > + *	to be displayed stream's content type. Content Type of a stream is
> > > + *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
> > > + *
> > > + *	The value of the property can be one the below:
> > > + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0  
> > 
> > If this doc is meant as the UAPI doc, it needs to use the string names
> > for enum property values, not the C language definitions (integers).  

> kernel documentation for all other properties followed this way. We
> could add string associated to the enum state too for this property.

Hi,

I don't really care what kernel internal APIs use, this may well be
correct for them, but the UAPI uses strings.

Because the kernel internal and UAPI docs are mixed up, it will be hard
to write proper docs. I guess can't help it this time.

It would be really good if the enum value strings were explicitly
presented in the docs, so userspace has something to hook on. Or if not
in docs, in the UAPI header, see further below.

I do see the strings in the docs you wrote, but nothing really
highlights them as the literal strings to be used in the API. Even just
quotes "" around them would make them more discoverable, especially
"HDCP Type0" etc.

> >   
> > > + *		HDCP Type0 streams can be transmitted on a link which is
> > > + *		encrypted with HDCP 1.4 or HDCP 2.2.  
> > 
> > This wording forbids using any future HDCP version for type0.  
> We could change it to HDCP1.4 and higher version of HDCP.
> >   
> > > + *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
> > > + *		HDCP Type1 streams can be transmitted on a link which is
> > > + *		encrypted only with HDCP 2.2.  
> > 
> > This wording forbids using any future HDCP version for type1.  
> As of now type 1 is only on HDCP2.2 encrypted link, as no higher version is
> available. But as similar to Type 0 we could assume that Type 1 will be
> supported on higher HDCP versions too and correct the sentence here.
> >   
> > > + *
> > > + *	Note that the HDCP Content Type property is specific to HDCP 2.2, and
> > > + *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.2  
> > 
> > Not possible with a future HDCP version greater than 2.2?
> > 
> > Is it intended to be possible to add more content types in the future?  
> Possible. As per HDCP2.2 spec, 8bits are reserved for the content Type.

Right. All my three notes above are about future-proofing this for the
"trivial" case of adding one more content type. I think it would be
wise to do, because the cost is very low (no changes in code, just
trivial change in spec), and even if the likelyhood of adding more
types in future might be low, it's not zero.

I think the Weston implementation under review in MR !48 is
future-proof as well, in the sense that enum values it does not know
will be interpreted as Type0.

I suppose it is a reasonable assumption that HDCP spec will not add a
new type that would not be at least as secure as Type0, right?

> >   
> > > + *	If content type is changed when content_protection is not UNDESIRED,
> > > + *	then kernel will disable the HDCP and re-enable with new type in the
> > > + *	same atomic commit  
> > 
> > Ok, very good to mention this.
> >   
> > >   *
> > >   * max bpc:
> > >   *	This range property is used by userspace to limit the bit depth. When
> > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > > index 0da7b3718bad..75402463466b 100644
> > > --- a/drivers/gpu/drm/drm_hdcp.c
> > > +++ b/drivers/gpu/drm/drm_hdcp.c
> > > @@ -342,23 +342,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
> > >  };
> > >  DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
> > >  
> > > +static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
> > > +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> > > +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> > > +};
> > > +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> > > +		 drm_hdcp_content_type_enum_list)
> > > +
> > >  /**
> > >   * drm_connector_attach_content_protection_property - attach content protection
> > >   * property
> > >   *
> > >   * @connector: connector to attach CP property on.
> > > + * @hdcp_content_type: is HDCP Content Type property needed for connector
> > >   *
> > >   * This is used to add support for content protection on select connectors.
> > >   * Content Protection is intentionally vague to allow for different underlying
> > >   * technologies, however it is most implemented by HDCP.
> > >   *
> > > + * When hdcp_content_type is true enum property called HDCP Content Type is
> > > + * created (if it is not already) and attached to the connector.
> > > + *
> > > + * This property is used for sending the protected content's stream type
> > > + * from userspace to kernel on selected connectors. Protected content provider
> > > + * will decide their type of their content and declare the same to kernel.
> > > + *
> > > + * Content type will be used during the HDCP 2.2 authentication.
> > > + * Content type will be set to &drm_connector_state.hdcp_content_type.
> > > + *
> > >   * The content protection will be set to &drm_connector_state.content_protection
> > >   *
> > >   * Returns:
> > >   * Zero on success, negative errno on failure.
> > >   */
> > >  int drm_connector_attach_content_protection_property(
> > > -		struct drm_connector *connector)
> > > +		struct drm_connector *connector, bool hdcp_content_type)
> > >  {
> > >  	struct drm_device *dev = connector->dev;
> > >  	struct drm_property *prop =
> > > @@ -375,6 +393,22 @@ int drm_connector_attach_content_protection_property(
> > >  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> > >  	dev->mode_config.content_protection_property = prop;
> > >  
> > > +	if (!hdcp_content_type)
> > > +		return 0;
> > > +
> > > +	prop = dev->mode_config.hdcp_content_type_property;
> > > +	if (!prop)
> > > +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> > > +					drm_hdcp_content_type_enum_list,
> > > +					ARRAY_SIZE(
> > > +					drm_hdcp_content_type_enum_list));
> > > +	if (!prop)
> > > +		return -ENOMEM;
> > > +
> > > +	drm_object_attach_property(&connector->base, prop,
> > > +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> > > +	dev->mode_config.hdcp_content_type_property = prop;
> > > +
> > >  	return 0;
> > >  }
> > >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);  
> > 
> > ...
> >   
> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > index 83cd1636b9be..8ac03351fdee 100644
> > > --- a/include/uapi/drm/drm_mode.h
> > > +++ b/include/uapi/drm/drm_mode.h
> > > @@ -209,6 +209,10 @@ extern "C" {
> > >  #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
> > >  #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
> > >  
> > > +/* Content Type classification for HDCP2.2 vs others */
> > > +#define DRM_MODE_HDCP_CONTENT_TYPE0		0
> > > +#define DRM_MODE_HDCP_CONTENT_TYPE1		1  
> > 
> > These should not be in a UAPI header. The C language definitions must
> > never be exposed to userspace, or misguided userspace will start using
> > them.
> > 
> > Instead, UAPI uses the string names to discover the integers at runtime.  
> This is done as per the usual practice for any existing enum property.

I suspect this is just the cycle of cargo-culting mistakes. Weston
MR !48 does not use these defines either.

Unfortunately the bad examples that are already in the UAPI headers
cannot be removed.

However, I think you could start a new good practice:

#define DRM_MODE_HDCP_CONTENT_TYPE0_STR "HDCP Type0"
#define DRM_MODE_HDCP_CONTENT_TYPE1_STR "HDCP Type1"

It would make a lot of sense for the UAPI header to spell out the
strings that userspace must be using. Even if userspace wouldn't use
these defines, they would have strong documentary value.

Danvet, would you agree with me here?

> > 
> > ***
> > 
> > Questions about the already existing "Content Protection" property:
> > 
> > - What happens if userspace attempts to write "Enabled" into it?  
>  *      DRM_MODE_CONTENT_PROTECTION_ENABLED = 2
>  *              Userspace has requested content protection, and the link is
>  *              protected. Only the driver can set the property to this value.
>  *              If userspace attempts to set to ENABLED, kernel will return
>  *              -EINVAL.
> line number 936 @ drivers/gpu/drm/drm_connector.c

Good, I glossed over the last sentence when reading this before.


Thanks,
pq

> 
> -Ram
> 
> > 
> > - Where is the UAPI documentation that explains how userspace should be
> >   using the property? (e.g. telling that you cannot set it to "Enabled")
> > 
> > 
> > Thanks,
> > pq  
> 
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 09/11] drm: uevent for connector status change
  2019-07-04 10:42     ` Ramalingam C
@ 2019-07-05 13:36       ` Pekka Paalanen
  0 siblings, 0 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-05 13:36 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 5035 bytes --]

On Thu, 4 Jul 2019 16:12:10 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> On 2019-07-04 at 14:12:27 +0300, Pekka Paalanen wrote:
> > On Tue,  7 May 2019 21:57:43 +0530
> > Ramalingam C <ramalingam.c@intel.com> wrote:
> >   
> > > DRM API for generating uevent for a status changes of connector's
> > > property.
> > > 
> > > This uevent will have following details related to the status change:
> > > 
> > >   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> > > 
> > > Need ACK from this uevent from userspace consumer.
> > > 
> > > v2:
> > >   Minor fixes at KDoc comments [Daniel]
> > > v3:
> > >   Check the property is really attached with connector [Daniel]
> > > 
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/drm_sysfs.c | 35 +++++++++++++++++++++++++++++++++++
> > >  include/drm/drm_sysfs.h     |  5 ++++-
> > >  2 files changed, 39 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > index 18b1ac442997..63fa951a20db 100644
> > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > @@ -21,6 +21,7 @@
> > >  #include <drm/drm_sysfs.h>
> > >  #include <drm/drmP.h>
> > >  #include "drm_internal.h"
> > > +#include "drm_crtc_internal.h"
> > >  
> > >  #define to_drm_minor(d) dev_get_drvdata(d)
> > >  #define to_drm_connector(d) dev_get_drvdata(d)
> > > @@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
> > >   * Send a uevent for the DRM device specified by @dev.  Currently we only
> > >   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
> > >   * deal with other types of events.
> > > + *
> > > + * Any new uapi should be using the drm_sysfs_connector_status_event()
> > > + * for uevents on connector status change.
> > >   */
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  {
> > > @@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
> > >  }
> > >  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
> > >  
> > > +/**
> > > + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> > > + * property status change
> > > + * @connector: connector on which property status changed
> > > + * @property: connector property whoes status changed.
> > > + *
> > > + * Send a uevent for the DRM device specified by @dev.  Currently we
> > > + * set HOTPLUG=1 and connector id along with the attached property id
> > > + * related to the status change.
> > > + */  
> This is the kernel doc added for drm_sysfs_connector_status_event()
> similar to drm_sysfs_hotplug_event()

Hi,

yes, it is the kernel internal doc. An UAPI doc would spell out the
attributes "CONNECTOR" and "PROPERTY" and describe their values
explaining what they are, instead of decsribing a kernel-internal
function arguments.

However, as discussed, we cannot have UAPI docs at this time, so I
guess this is the best we can have.


Thanks,
pq


> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +				      struct drm_property *property)
> > > +{
> > > +	struct drm_device *dev = connector->dev;
> > > +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> > > +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> > > +
> > > +	WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
> > > +					   property->base.id));
> > > +
> > > +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> > > +		 "CONNECTOR=%u", connector->base.id);
> > > +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> > > +		 "PROPERTY=%u", property->base.id);
> > > +
> > > +	DRM_DEBUG("generating connector status event\n");
> > > +
> > > +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> > > +}
> > > +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> > > +
> > >  static void drm_sysfs_release(struct device *dev)
> > >  {
> > >  	kfree(dev);
> > > diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> > > index 4f311e836cdc..d454ef617b2c 100644
> > > --- a/include/drm/drm_sysfs.h
> > > +++ b/include/drm/drm_sysfs.h
> > > @@ -4,10 +4,13 @@
> > >  
> > >  struct drm_device;
> > >  struct device;
> > > +struct drm_connector;
> > > +struct drm_property;
> > >  
> > >  int drm_class_device_register(struct device *dev);
> > >  void drm_class_device_unregister(struct device *dev);
> > >  
> > >  void drm_sysfs_hotplug_event(struct drm_device *dev);
> > > -
> > > +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> > > +				      struct drm_property *property);
> > >  #endif  
> > 
> > Hi,
> > 
> > this patch is completely missing the UAPI documentation.
> > 
> > Weston in
> > https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> > does have good looking code to parse this event.
> > 
> > 
> > Thanks,
> > pq  
> 
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 10/11] drm/hdcp: update content protection property with uevent
  2019-07-04 11:11     ` Ramalingam C
@ 2019-07-05 13:59       ` Pekka Paalanen
  0 siblings, 0 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-05 13:59 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel, gwan-gyeong.mun


[-- Attachment #1.1: Type: text/plain, Size: 5989 bytes --]

On Thu, 4 Jul 2019 16:41:15 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> On 2019-07-04 at 14:14:19 +0300, Pekka Paalanen wrote:
> > On Tue,  7 May 2019 21:57:44 +0530
> > Ramalingam C <ramalingam.c@intel.com> wrote:
> >   
> > > drm function is defined and exported to update a connector's
> > > content protection property state and to generate a uevent along
> > > with it.
> > > 
> > > Need ACK for the uevent from userspace consumer.
> > > 
> > > v2:
> > >   Update only when state is different from old one.
> > > v3:
> > >   KDoc is added [Daniel]
> > > 
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/drm_hdcp.c | 32 ++++++++++++++++++++++++++++++++
> > >  include/drm/drm_hdcp.h     |  2 ++
> > >  2 files changed, 34 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > > index 75402463466b..f29b7abda51f 100644
> > > --- a/drivers/gpu/drm/drm_hdcp.c
> > > +++ b/drivers/gpu/drm/drm_hdcp.c
> > > @@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> > >   *
> > >   * The content protection will be set to &drm_connector_state.content_protection
> > >   *
> > > + * When kernel triggered content protection state change like DESIRED->ENABLED
> > > + * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update
> > > + * the content protection state of a connector.  
> Here we indicated that drm_hdcp_update_content_protection() used for
> kernel triggered content protection state change.

Hi,

sure. I don't know how a userspace programmer could guess it is in any
way relevant to when the events are sent and when not. They wouldn't
even read the doc of this function to begin with.

> > > + *
> > >   * Returns:
> > >   * Zero on success, negative errno on failure.
> > >   */
> > > @@ -412,3 +416,31 @@ int drm_connector_attach_content_protection_property(
> > >  	return 0;
> > >  }
> > >  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> > > +
> > > +/**
> > > + * drm_hdcp_update_content_protection - Updates the content protection state
> > > + * of a connector
> > > + *
> > > + * @connector: drm_connector on which content protection state needs an update
> > > + * @val: New state of the content protection property
> > > + *
> > > + * This function can be used by display drivers, to update the kernel triggered
> > > + * content protection state change of a drm_connector.This function update the  
> These lines also indicate that this function is used for kernel
> triggered content protection state change of a drm_connector.

How could any userspace programmer know to decipher what this means
for event sending?

The event semantics must be documented somewhere where userspace people
actually read. In this case it would be with the definition of the
connector property for which the event was added, lacking a proper
place for UAPI docs.

> 
> -Ram
> > > + * new state of the property into the connector's state and generate an uevent
> > > + * to notify the userspace.
> > > + */
> > > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > > +					u64 val)
> > > +{  
> > 
> > Hi,
> > 
> > don't you need to ensure that 'val' cannot be UNDESIRED?  
> @ https://patchwork.freedesktop.org/patch/303909/?series=57232&rev=9
> caller(I915) of this function is ensuring that.

Yes, the caller does that right now. Don't you want to catch other
callers written by someone else who don't know or forget to do the same
check as i915 does?

Isn't that what all the WARN_ON etc. macros are mostly about, to catch
badly written kernel code?

I mean, it is at least a semantic kernel bug if anyone attempts to
call this function with UNDESIRED, right? Because when they do, this
function may send the uevent.

> > > +	struct drm_device *dev = connector->dev;
> > > +	struct drm_connector_state *state = connector->state;
> > > +
> > > +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> > > +	if (state->content_protection == val)  
> when val==UNDESIRED even the state->content_protection also UNDESIRED.
> Hence explicit check is not needed here.

So it accidentally won't cause any visible harm? Until something subtly
changes elsewhere and it does.


Thanks,
pq

> 
> -Ram
> >   
> > > +	struct drm_device *dev = connector->dev;
> > > +	struct drm_connector_state *state = connector->state;
> > > +
> > > +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> > > +	if (state->content_protection == val)
> > > +		return;
> > > +
> > > +	state->content_protection = val;
> > > +	drm_sysfs_connector_status_event(connector,
> > > +				 dev->mode_config.content_protection_property);
> > > +}
> > > +EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> > > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > > index 2970abdfaf12..dd864ac9ce85 100644
> > > --- a/include/drm/drm_hdcp.h
> > > +++ b/include/drm/drm_hdcp.h
> > > @@ -292,4 +292,6 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> > >  				 u8 *ksvs, u32 ksv_count);
> > >  int drm_connector_attach_content_protection_property(
> > >  		struct drm_connector *connector, bool hdcp_content_type);
> > > +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> > > +					u64 val);
> > >  #endif  
> > 
> > This patch is missing all UAPI documentation.
> > 
> > Particularly important is the detail that the kernel will not send an
> > event corresponding to userspace explicitly setting "Content
> > Protection" to "Undesired". That is what you explained to me in the
> > Weston MR !48, but I don't actually see it in the code here. It would
> > be best to enforce that in the shared DRM code.
> > 
> > 
> > Thanks,
> > pq  
> 
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 07/11] drm: Add Content protection type property
  2019-07-05  6:33         ` Ramalingam C
@ 2019-07-05 14:12           ` Pekka Paalanen
  0 siblings, 0 replies; 70+ messages in thread
From: Pekka Paalanen @ 2019-07-05 14:12 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, dri-devel, gwan-gyeong.mun


[-- Attachment #1.1: Type: text/plain, Size: 7105 bytes --]

On Fri, 5 Jul 2019 12:03:18 +0530
Ramalingam C <ramalingam.c@intel.com> wrote:

> On 2019-07-05 at 16:00:37 +0300, Pekka Paalanen wrote:
> > On Thu, 4 Jul 2019 16:06:05 +0530
> > Ramalingam C <ramalingam.c@intel.com> wrote:
> >   
> > > On 2019-07-04 at 14:11:59 +0300, Pekka Paalanen wrote:  
> > > > On Tue,  7 May 2019 21:57:41 +0530
> > > > Ramalingam C <ramalingam.c@intel.com> wrote:
> > > >     
> > > > > This patch adds a DRM ENUM property to the selected connectors.
> > > > > This property is used for mentioning the protected content's type
> > > > > from userspace to kernel HDCP authentication.
> > > > > 
> > > > > Type of the stream is decided by the protected content providers.
> > > > > Type 0 content can be rendered on any HDCP protected display wires.
> > > > > But Type 1 content can be rendered only on HDCP2.2 protected paths.
> > > > > 
> > > > > So when a userspace sets this property to Type 1 and starts the HDCP
> > > > > enable, kernel will honour it only if HDCP2.2 authentication is through
> > > > > for type 1. Else HDCP enable will be failed.
> > > > > 
> > > > > Need ACK for this new conenctor property from userspace consumer.
> > > > > 
> > > > > v2:
> > > > >   cp_content_type is replaced with content_protection_type [daniel]
> > > > >   check at atomic_set_property is removed [Maarten]
> > > > > v3:
> > > > >   %s/content_protection_type/hdcp_content_type [Pekka]
> > > > > v4:
> > > > >   property is created for the first requested connector and then reused.
> > > > > 	[Danvet]
> > > > > v5:
> > > > >   kernel doc nits addressed [Daniel]
> > > > >   Rebased as part of patch reordering.
> > > > > 
> > > > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > ---
> > > > >  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++++
> > > > >  drivers/gpu/drm/drm_connector.c   | 18 ++++++++++++++++
> > > > >  drivers/gpu/drm/drm_hdcp.c        | 36 ++++++++++++++++++++++++++++++-
> > > > >  drivers/gpu/drm/i915/intel_hdcp.c |  4 +++-
> > > > >  include/drm/drm_connector.h       |  7 ++++++
> > > > >  include/drm/drm_hdcp.h            |  2 +-
> > > > >  include/drm/drm_mode_config.h     |  6 ++++++
> > > > >  include/uapi/drm/drm_mode.h       |  4 ++++
> > > > >  8 files changed, 78 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > > > > index 4131e669785a..a85f3ccfe699 100644
> > > > > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > > > > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > > > > @@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
> > > > >  			return -EINVAL;
> > > > >  		}
> > > > >  		state->content_protection = val;
> > > > > +	} else if (property == config->hdcp_content_type_property) {
> > > > > +		state->hdcp_content_type = val;
> > > > >  	} else if (property == connector->colorspace_property) {
> > > > >  		state->colorspace = val;
> > > > >  	} else if (property == config->writeback_fb_id_property) {
> > > > > @@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> > > > >  		*val = state->scaling_mode;
> > > > >  	} else if (property == config->content_protection_property) {
> > > > >  		*val = state->content_protection;
> > > > > +	} else if (property == config->hdcp_content_type_property) {
> > > > > +		*val = state->hdcp_content_type;
> > > > >  	} else if (property == config->writeback_fb_id_property) {
> > > > >  		/* Writeback framebuffer is one-shot, write and forget */
> > > > >  		*val = 0;
> > > > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > > > index 764c7903edf6..de9e06583e8c 100644
> > > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > > +++ b/drivers/gpu/drm/drm_connector.c    
> > > > 
> > > > Hi,
> > > > 
> > > > below I have some comments and questions before I can say whether
> > > > https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
> > > > adheres to this specification.
> > > >     
> > > > > @@ -955,6 +955,24 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
> > > > >   *	  the value transitions from ENABLED to DESIRED. This signifies the link
> > > > >   *	  is no longer protected and userspace should take appropriate action
> > > > >   *	  (whatever that might be).
> > > > > + * HDCP Content Type:
> > > > > + *	This property is used by the userspace to configure the kernel with
> > > > > + *	to be displayed stream's content type. Content Type of a stream is
> > > > > + *	decided by the owner of the stream, as HDCP Type0 or HDCP Type1.
> > > > > + *
> > > > > + *	The value of the property can be one the below:
> > > > > + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0    
> > > > 
> > > > If this doc is meant as the UAPI doc, it needs to use the string names
> > > > for enum property values, not the C language definitions (integers).    
> >   
> > > kernel documentation for all other properties followed this way. We
> > > could add string associated to the enum state too for this property.  
> > 
> > Hi,
> > 
> > I don't really care what kernel internal APIs use, this may well be
> > correct for them, but the UAPI uses strings.
> > 
> > Because the kernel internal and UAPI docs are mixed up, it will be hard
> > to write proper docs. I guess can't help it this time.
> > 
> > It would be really good if the enum value strings were explicitly
> > presented in the docs, so userspace has something to hook on. Or if not
> > in docs, in the UAPI header, see further below.
> > 
> > I do see the strings in the docs you wrote, but nothing really
> > highlights them as the literal strings to be used in the API. Even just
> > quotes "" around them would make them more discoverable, especially
> > "HDCP Type0" etc.  
> In the next version I have added the string too in the kernel
> docuemntation.
> 
> But when we read the property state we read the enum
> value which is matched agaist the string based on the enum property
> definition. So I feel we should have both detail matched against in the uAPI
> doc.

Hi,

I guess so.

When userspace initializes, it will ask the kernel for the kernel
integers corresponding to all of the name strings they both know about.
When userspace sets an enum property to a value, it looks up the kernel
integer from an internal name for the enum value and submits that to
the kernel. When userspace reads an enum property, it receives a kernel
integer, which it looks up in its value table to translate it into an
internal name which it can handle.

At no point is the kernel integer definition needed outside of the
kernel. It is discovered through the UAPI.

So from UAPI perspective, only the name string is appropriate. From
kernel internal API perspective, I suppose the integer is appropriate.

Another unfortunate confusion caused by mixed internal and UAPI docs.


Thanks,
pq

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-05-07 16:27 ` [PATCH v7 04/11] drm: revocation check at drm subsystem Ramalingam C
  2019-07-04 10:53   ` Pekka Paalanen
@ 2019-09-12  0:15   ` Harry Wentland
  2019-09-12  1:14     ` Deucher, Alexander
  2019-09-12  6:54     ` Ramalingam C
  1 sibling, 2 replies; 70+ messages in thread
From: Harry Wentland @ 2019-09-12  0:15 UTC (permalink / raw)
  To: Ramalingam C, intel-gfx, dri-devel, daniel.vetter
  Cc: Deucher, Alexander, Kumar, Ranjeet, Lakha, Bhawanpreet, gwan-gyeong.mun

Adding a couple AMD guys.

I know this is already merged but I have a few questions after some
internal discussions.

On 2019-05-07 12:27 p.m., Ramalingam C wrote:
> On every hdcp revocation check request SRM is read from fw file
> /lib/firmware/display_hdcp_srm.bin
> 

According to section 5 of the HDCP 2.3 spec [1] a device compliant with
HDCP 2.0 and higher must be capable of storing and updating the SRM in
non-volatile memory. Section 5.2 describes how this SRM needs to be
updated when a new version is served alongside protected content.

Isn't /lib/firmware intended for static firmware making updates to the
folder problematic for anyone but the system's package maintainer? I've
heard /lib might even be treated as read-only in certain environments.
This would mean it'd be impossible to support HDCP 2.x on those systems.

Wouldn't it be easier to provide a sysfs entry for SRM that allows
userspace (e.g. system startup/shutdown scripts) to (a) retrieve the SRM
from the HDCP implementation for non-volatile storage and (b) to pass
the SRM to the HDCP implementation for revocation checking?

[1]
https://www.digital-cp.com/sites/default/files/HDCP%20on%20HDMI%20Specification%20Rev2_3.pdf

Thanks,
Harry

> SRM table is parsed and stored at drm_hdcp.c, with functions exported
> for the services for revocation check from drivers (which
> implements the HDCP authentication)
> 
> This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> 
> v2:
>   moved the uAPI to request_firmware_direct() [Daniel]
> v3:
>   kdoc added. [Daniel]
>   srm_header unified and bit field definitions are removed. [Daniel]
>   locking improved. [Daniel]
>   vrl length violation is fixed. [Daniel]
> v4:
>   s/__swab16/be16_to_cpu [Daniel]
>   be24_to_cpu is done through a global func [Daniel]
>   Unused variables are removed. [Daniel]
>   unchecked return values are dropped from static funcs [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
> Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
> ---
>  Documentation/gpu/drm-kms-helpers.rst |   6 +
>  drivers/gpu/drm/Makefile              |   2 +-
>  drivers/gpu/drm/drm_hdcp.c            | 333 ++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_internal.h        |   4 +
>  drivers/gpu/drm/drm_sysfs.c           |   2 +
>  include/drm/drm_hdcp.h                |  24 ++
>  6 files changed, 370 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/drm_hdcp.c
> 
> diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
> index 14102ae035dc..0fe726a6ee67 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -181,6 +181,12 @@ Panel Helper Reference
>  .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
>     :export:
> 
> +HDCP Helper Functions Reference
> +===============================
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
> +   :export:
> +
>  Display Port Helper Functions Reference
>  =======================================
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 72f5036d9bfa..dd02e9dec810 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -17,7 +17,7 @@ drm-y       :=        drm_auth.o drm_cache.o \
>                 drm_plane.o drm_color_mgmt.o drm_print.o \
>                 drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>                 drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> -               drm_atomic_uapi.o
> +               drm_atomic_uapi.o drm_hdcp.o
> 
>  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> new file mode 100644
> index 000000000000..5e5409505c31
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Intel Corporation.
> + *
> + * Authors:
> + * Ramalingam C <ramalingam.c@intel.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gfp.h>
> +#include <linux/export.h>
> +#include <linux/slab.h>
> +#include <linux/firmware.h>
> +
> +#include <drm/drm_hdcp.h>
> +#include <drm/drm_sysfs.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_device.h>
> +
> +struct hdcp_srm {
> +       u32 revoked_ksv_cnt;
> +       u8 *revoked_ksv_list;
> +
> +       /* Mutex to protect above struct member */
> +       struct mutex mutex;
> +} *srm_data;
> +
> +static inline void drm_hdcp_print_ksv(const u8 *ksv)
> +{
> +       DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
> +                 ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
> +}
> +
> +static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
> +{
> +       u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
> +
> +       while (parsed_bytes < vrls_length) {
> +               vrl_ksv_cnt = *buf;
> +               ksv_count += vrl_ksv_cnt;
> +
> +               vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
> +               buf += vrl_sz;
> +               parsed_bytes += vrl_sz;
> +       }
> +
> +       /*
> +        * When vrls are not valid, ksvs are not considered.
> +        * Hence SRM will be discarded.
> +        */
> +       if (parsed_bytes != vrls_length)
> +               ksv_count = 0;
> +
> +       return ksv_count;
> +}
> +
> +static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
> +                                    u32 vrls_length)
> +{
> +       u32 parsed_bytes = 0, ksv_count = 0;
> +       u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
> +
> +       do {
> +               vrl_ksv_cnt = *buf;
> +               vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
> +
> +               buf++;
> +
> +               DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
> +                         vrl_ksv_cnt);
> +               memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
> +
> +               ksv_count += vrl_ksv_cnt;
> +               revoked_ksv_list += vrl_ksv_sz;
> +               buf += vrl_ksv_sz;
> +
> +               parsed_bytes += (vrl_ksv_sz + 1);
> +       } while (parsed_bytes < vrls_length);
> +
> +       return ksv_count;
> +}
> +
> +static inline u32 get_vrl_length(const u8 *buf)
> +{
> +       return drm_hdcp_be24_to_cpu(buf);
> +}
> +
> +static int drm_hdcp_parse_hdcp1_srm(const u8 *buf, size_t count)
> +{
> +       struct hdcp_srm_header *header;
> +       u32 vrl_length, ksv_count;
> +
> +       if (count < (sizeof(struct hdcp_srm_header) +
> +           DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> +               DRM_ERROR("Invalid blob length\n");
> +               return -EINVAL;
> +       }
> +
> +       header = (struct hdcp_srm_header *)buf;
> +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> +                 header->srm_id,
> +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
> +
> +       WARN_ON(header->reserved);
> +
> +       buf = buf + sizeof(*header);
> +       vrl_length = get_vrl_length(buf);
> +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> +           vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> +                         DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> +               DRM_ERROR("Invalid blob length or vrl length\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Length of the all vrls combined */
> +       vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> +                      DRM_HDCP_1_4_DCP_SIG_SIZE);
> +
> +       if (!vrl_length) {
> +               DRM_ERROR("No vrl found\n");
> +               return -EINVAL;
> +       }
> +
> +       buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
> +       ksv_count = drm_hdcp_get_revoked_ksv_count(buf, vrl_length);
> +       if (!ksv_count) {
> +               DRM_DEBUG("Revoked KSV count is 0\n");
> +               return count;
> +       }
> +
> +       kfree(srm_data->revoked_ksv_list);
> +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
> +                                            GFP_KERNEL);
> +       if (!srm_data->revoked_ksv_list) {
> +               DRM_ERROR("Out of Memory\n");
> +               return -ENOMEM;
> +       }
> +
> +       if (drm_hdcp_get_revoked_ksvs(buf, srm_data->revoked_ksv_list,
> +                                     vrl_length) != ksv_count) {
> +               srm_data->revoked_ksv_cnt = 0;
> +               kfree(srm_data->revoked_ksv_list);
> +               return -EINVAL;
> +       }
> +
> +       srm_data->revoked_ksv_cnt = ksv_count;
> +       return count;
> +}
> +
> +static int drm_hdcp_parse_hdcp2_srm(const u8 *buf, size_t count)
> +{
> +       struct hdcp_srm_header *header;
> +       u32 vrl_length, ksv_count, ksv_sz;
> +
> +       if (count < (sizeof(struct hdcp_srm_header) +
> +           DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
> +               DRM_ERROR("Invalid blob length\n");
> +               return -EINVAL;
> +       }
> +
> +       header = (struct hdcp_srm_header *)buf;
> +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> +                 header->srm_id & DRM_HDCP_SRM_ID_MASK,
> +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
> +
> +       if (header->reserved)
> +               return -EINVAL;
> +
> +       buf = buf + sizeof(*header);
> +       vrl_length = get_vrl_length(buf);
> +
> +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> +           vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
> +           DRM_HDCP_2_DCP_SIG_SIZE)) {
> +               DRM_ERROR("Invalid blob length or vrl length\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Length of the all vrls combined */
> +       vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE +
> +                      DRM_HDCP_2_DCP_SIG_SIZE);
> +
> +       if (!vrl_length) {
> +               DRM_ERROR("No vrl found\n");
> +               return -EINVAL;
> +       }
> +
> +       buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
> +       ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
> +       if (!ksv_count) {
> +               DRM_DEBUG("Revoked KSV count is 0\n");
> +               return count;
> +       }
> +
> +       kfree(srm_data->revoked_ksv_list);
> +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
> +                                            GFP_KERNEL);
> +       if (!srm_data->revoked_ksv_list) {
> +               DRM_ERROR("Out of Memory\n");
> +               return -ENOMEM;
> +       }
> +
> +       ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
> +       buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
> +
> +       DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
> +       memcpy(srm_data->revoked_ksv_list, buf, ksv_sz);
> +
> +       srm_data->revoked_ksv_cnt = ksv_count;
> +       return count;
> +}
> +
> +static inline bool is_srm_version_hdcp1(const u8 *buf)
> +{
> +       return *buf == (u8)(DRM_HDCP_1_4_SRM_ID << 4);
> +}
> +
> +static inline bool is_srm_version_hdcp2(const u8 *buf)
> +{
> +       return *buf == (u8)(DRM_HDCP_2_SRM_ID << 4 | DRM_HDCP_2_INDICATOR);
> +}
> +
> +static void drm_hdcp_srm_update(const u8 *buf, size_t count)
> +{
> +       if (count < sizeof(struct hdcp_srm_header))
> +               return;
> +
> +       if (is_srm_version_hdcp1(buf))
> +               drm_hdcp_parse_hdcp1_srm(buf, count);
> +       else if (is_srm_version_hdcp2(buf))
> +               drm_hdcp_parse_hdcp2_srm(buf, count);
> +}
> +
> +void drm_hdcp_request_srm(struct drm_device *drm_dev)
> +{
> +       char fw_name[36] = "display_hdcp_srm.bin";
> +       const struct firmware *fw;
> +
> +       int ret;
> +
> +       ret = request_firmware_direct(&fw, (const char *)fw_name,
> +                                     drm_dev->dev);
> +       if (ret < 0)
> +               goto exit;
> +
> +       if (fw->size && fw->data)
> +               drm_hdcp_srm_update(fw->data, fw->size);
> +
> +exit:
> +       release_firmware(fw);
> +}
> +
> +/**
> + * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
> + *
> + * @drm_dev: drm_device for which HDCP revocation check is requested
> + * @ksvs: List of KSVs (HDCP receiver IDs)
> + * @ksv_count: KSV count passed in through @ksvs
> + *
> + * This function reads the HDCP System renewability Message(SRM Table)
> + * from userspace as a firmware and parses it for the revoked HDCP
> + * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known,
> + * revoked state of the KSVs in the list passed in by display drivers are
> + * decided and response is sent.
> + *
> + * SRM should be presented in the name of "display_hdcp_srm.bin".
> + *
> + * Returns:
> + * TRUE on any of the KSV is revoked, else FALSE.
> + */
> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
> +                                u32 ksv_count)
> +{
> +       u32 rev_ksv_cnt, cnt, i, j;
> +       u8 *rev_ksv_list;
> +
> +       if (!srm_data)
> +               return false;
> +
> +       mutex_lock(&srm_data->mutex);
> +       drm_hdcp_request_srm(drm_dev);
> +
> +       rev_ksv_cnt = srm_data->revoked_ksv_cnt;
> +       rev_ksv_list = srm_data->revoked_ksv_list;
> +
> +       /* If the Revoked ksv list is empty */
> +       if (!rev_ksv_cnt || !rev_ksv_list) {
> +               mutex_unlock(&srm_data->mutex);
> +               return false;
> +       }
> +
> +       for  (cnt = 0; cnt < ksv_count; cnt++) {
> +               rev_ksv_list = srm_data->revoked_ksv_list;
> +               for (i = 0; i < rev_ksv_cnt; i++) {
> +                       for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
> +                               if (ksvs[j] != rev_ksv_list[j]) {
> +                                       break;
> +                               } else if (j == (DRM_HDCP_KSV_LEN - 1)) {
> +                                       DRM_DEBUG("Revoked KSV is ");
> +                                       drm_hdcp_print_ksv(ksvs);
> +                                       mutex_unlock(&srm_data->mutex);
> +                                       return true;
> +                               }
> +                       /* Move the offset to next KSV in the revoked list */
> +                       rev_ksv_list += DRM_HDCP_KSV_LEN;
> +               }
> +
> +               /* Iterate to next ksv_offset */
> +               ksvs += DRM_HDCP_KSV_LEN;
> +       }
> +       mutex_unlock(&srm_data->mutex);
> +       return false;
> +}
> +EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
> +
> +int drm_setup_hdcp_srm(struct class *drm_class)
> +{
> +       srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> +       if (!srm_data)
> +               return -ENOMEM;
> +       mutex_init(&srm_data->mutex);
> +
> +       return 0;
> +}
> +
> +void drm_teardown_hdcp_srm(struct class *drm_class)
> +{
> +       if (srm_data) {
> +               kfree(srm_data->revoked_ksv_list);
> +               kfree(srm_data);
> +       }
> +}
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index e19ac7ca602d..476a422414f6 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
>                                 const struct drm_framebuffer *fb);
>  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> +
> +/* drm_hdcp.c */
> +int drm_setup_hdcp_srm(struct class *drm_class);
> +void drm_teardown_hdcp_srm(struct class *drm_class);
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index ecb7b33002bb..18b1ac442997 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
>         }
> 
>         drm_class->devnode = drm_devnode;
> +       drm_setup_hdcp_srm(drm_class);
>         return 0;
>  }
> 
> @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
>  {
>         if (IS_ERR_OR_NULL(drm_class))
>                 return;
> +       drm_teardown_hdcp_srm(drm_class);
>         class_remove_file(drm_class, &class_attr_version.attr);
>         class_destroy(drm_class);
>         drm_class = NULL;
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 1cc66df05a43..2f0335d0a50f 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
>         seq_num[2] = val;
>  }
> 
> +#define DRM_HDCP_SRM_GEN1_MAX_BYTES            (5 * 1024)
> +#define DRM_HDCP_1_4_SRM_ID                    0x8
> +#define DRM_HDCP_SRM_ID_MASK                   (0xF << 4)
> +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE           3
> +#define DRM_HDCP_1_4_DCP_SIG_SIZE              40
> +#define DRM_HDCP_2_SRM_ID                      0x9
> +#define DRM_HDCP_2_INDICATOR                   0x1
> +#define DRM_HDCP_2_INDICATOR_MASK              0xF
> +#define DRM_HDCP_2_VRL_LENGTH_SIZE             3
> +#define DRM_HDCP_2_DCP_SIG_SIZE                        384
> +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ  4
> +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)    (((byte) & 0xC) >> 6)
> +
> +struct hdcp_srm_header {
> +       u8 srm_id;
> +       u8 reserved;
> +       __be16 srm_version;
> +       u8 srm_gen_no;
> +} __packed;
> +
> +struct drm_device;
> +
> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> +                                u8 *ksvs, u32 ksv_count);
>  #endif
> --
> 2.19.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-09-12  0:15   ` Harry Wentland
@ 2019-09-12  1:14     ` Deucher, Alexander
  2019-09-12  6:54     ` Ramalingam C
  1 sibling, 0 replies; 70+ messages in thread
From: Deucher, Alexander @ 2019-09-12  1:14 UTC (permalink / raw)
  To: Wentland, Harry, Ramalingam C, intel-gfx, dri-devel, daniel.vetter
  Cc: Kumar, Ranjeet, Lakha, Bhawanpreet

> -----Original Message-----
> From: Wentland, Harry <Harry.Wentland@amd.com>
> Sent: Wednesday, September 11, 2019 8:16 PM
> To: Ramalingam C <ramalingam.c@intel.com>; intel-
> gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org;
> daniel.vetter@intel.com
> Cc: gwan-gyeong.mun@intel.com; Kumar, Ranjeet
> <Ranjeet.Kumar@amd.com>; Deucher, Alexander
> <Alexander.Deucher@amd.com>; Lakha, Bhawanpreet
> <Bhawanpreet.Lakha@amd.com>
> Subject: Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
> 
> Adding a couple AMD guys.
> 
> I know this is already merged but I have a few questions after some internal
> discussions.
> 
> On 2019-05-07 12:27 p.m., Ramalingam C wrote:
> > On every hdcp revocation check request SRM is read from fw file
> > /lib/firmware/display_hdcp_srm.bin
> >
> 
> According to section 5 of the HDCP 2.3 spec [1] a device compliant with HDCP
> 2.0 and higher must be capable of storing and updating the SRM in non-
> volatile memory. Section 5.2 describes how this SRM needs to be updated
> when a new version is served alongside protected content.
> 
> Isn't /lib/firmware intended for static firmware making updates to the folder
> problematic for anyone but the system's package maintainer? I've heard /lib
> might even be treated as read-only in certain environments.
> This would mean it'd be impossible to support HDCP 2.x on those systems.
> 
> Wouldn't it be easier to provide a sysfs entry for SRM that allows userspace
> (e.g. system startup/shutdown scripts) to (a) retrieve the SRM from the
> HDCP implementation for non-volatile storage and (b) to pass the SRM to the
> HDCP implementation for revocation checking?

Also, IIRC, for level 1 support, I think the srm parsing has to happen on something other than the CPU, so I'm not sure where need to do any parsing in software, at least for HDCP 2.x.

Alex

> 
> [1]
> https://www.digital-
> cp.com/sites/default/files/HDCP%20on%20HDMI%20Specification%20Rev2_
> 3.pdf
> 
> Thanks,
> Harry
> 
> > SRM table is parsed and stored at drm_hdcp.c, with functions exported
> > for the services for revocation check from drivers (which implements
> > the HDCP authentication)
> >
> > This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> >
> > v2:
> >   moved the uAPI to request_firmware_direct() [Daniel]
> > v3:
> >   kdoc added. [Daniel]
> >   srm_header unified and bit field definitions are removed. [Daniel]
> >   locking improved. [Daniel]
> >   vrl length violation is fixed. [Daniel]
> > v4:
> >   s/__swab16/be16_to_cpu [Daniel]
> >   be24_to_cpu is done through a global func [Daniel]
> >   Unused variables are removed. [Daniel]
> >   unchecked return values are dropped from static funcs [Daniel]
> >
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
> > Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
> > ---
> >  Documentation/gpu/drm-kms-helpers.rst |   6 +
> >  drivers/gpu/drm/Makefile              |   2 +-
> >  drivers/gpu/drm/drm_hdcp.c            | 333
> ++++++++++++++++++++++++++
> >  drivers/gpu/drm/drm_internal.h        |   4 +
> >  drivers/gpu/drm/drm_sysfs.c           |   2 +
> >  include/drm/drm_hdcp.h                |  24 ++
> >  6 files changed, 370 insertions(+), 1 deletion(-)  create mode 100644
> > drivers/gpu/drm/drm_hdcp.c
> >
> > diff --git a/Documentation/gpu/drm-kms-helpers.rst
> > b/Documentation/gpu/drm-kms-helpers.rst
> > index 14102ae035dc..0fe726a6ee67 100644
> > --- a/Documentation/gpu/drm-kms-helpers.rst
> > +++ b/Documentation/gpu/drm-kms-helpers.rst
> > @@ -181,6 +181,12 @@ Panel Helper Reference  .. kernel-doc::
> > drivers/gpu/drm/drm_panel_orientation_quirks.c
> >     :export:
> >
> > +HDCP Helper Functions Reference
> > +===============================
> > +
> > +.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
> > +   :export:
> > +
> >  Display Port Helper Functions Reference
> > =======================================
> >
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index
> > 72f5036d9bfa..dd02e9dec810 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -17,7 +17,7 @@ drm-y       :=        drm_auth.o drm_cache.o \
> >                 drm_plane.o drm_color_mgmt.o drm_print.o \
> >                 drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
> >                 drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> > -               drm_atomic_uapi.o
> > +               drm_atomic_uapi.o drm_hdcp.o
> >
> >  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o
> > drm_context.o drm_dma.o drm_scatter.o drm_lock.o
> >  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o diff --git
> > a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c new file
> > mode 100644 index 000000000000..5e5409505c31
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -0,0 +1,333 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2019 Intel Corporation.
> > + *
> > + * Authors:
> > + * Ramalingam C <ramalingam.c@intel.com>  */
> > +
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gfp.h>
> > +#include <linux/export.h>
> > +#include <linux/slab.h>
> > +#include <linux/firmware.h>
> > +
> > +#include <drm/drm_hdcp.h>
> > +#include <drm/drm_sysfs.h>
> > +#include <drm/drm_print.h>
> > +#include <drm/drm_device.h>
> > +
> > +struct hdcp_srm {
> > +       u32 revoked_ksv_cnt;
> > +       u8 *revoked_ksv_list;
> > +
> > +       /* Mutex to protect above struct member */
> > +       struct mutex mutex;
> > +} *srm_data;
> > +
> > +static inline void drm_hdcp_print_ksv(const u8 *ksv) {
> > +       DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
> > +                 ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]); }
> > +
> > +static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32
> > +vrls_length) {
> > +       u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
> > +
> > +       while (parsed_bytes < vrls_length) {
> > +               vrl_ksv_cnt = *buf;
> > +               ksv_count += vrl_ksv_cnt;
> > +
> > +               vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
> > +               buf += vrl_sz;
> > +               parsed_bytes += vrl_sz;
> > +       }
> > +
> > +       /*
> > +        * When vrls are not valid, ksvs are not considered.
> > +        * Hence SRM will be discarded.
> > +        */
> > +       if (parsed_bytes != vrls_length)
> > +               ksv_count = 0;
> > +
> > +       return ksv_count;
> > +}
> > +
> > +static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8
> *revoked_ksv_list,
> > +                                    u32 vrls_length) {
> > +       u32 parsed_bytes = 0, ksv_count = 0;
> > +       u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
> > +
> > +       do {
> > +               vrl_ksv_cnt = *buf;
> > +               vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
> > +
> > +               buf++;
> > +
> > +               DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
> > +                         vrl_ksv_cnt);
> > +               memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
> > +
> > +               ksv_count += vrl_ksv_cnt;
> > +               revoked_ksv_list += vrl_ksv_sz;
> > +               buf += vrl_ksv_sz;
> > +
> > +               parsed_bytes += (vrl_ksv_sz + 1);
> > +       } while (parsed_bytes < vrls_length);
> > +
> > +       return ksv_count;
> > +}
> > +
> > +static inline u32 get_vrl_length(const u8 *buf) {
> > +       return drm_hdcp_be24_to_cpu(buf); }
> > +
> > +static int drm_hdcp_parse_hdcp1_srm(const u8 *buf, size_t count) {
> > +       struct hdcp_srm_header *header;
> > +       u32 vrl_length, ksv_count;
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) +
> > +           DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       header = (struct hdcp_srm_header *)buf;
> > +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> > +                 header->srm_id,
> > +                 be16_to_cpu(header->srm_version),
> > + header->srm_gen_no);
> > +
> > +       WARN_ON(header->reserved);
> > +
> > +       buf = buf + sizeof(*header);
> > +       vrl_length = get_vrl_length(buf);
> > +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> > +           vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> > +                         DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length or vrl length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Length of the all vrls combined */
> > +       vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> > +                      DRM_HDCP_1_4_DCP_SIG_SIZE);
> > +
> > +       if (!vrl_length) {
> > +               DRM_ERROR("No vrl found\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
> > +       ksv_count = drm_hdcp_get_revoked_ksv_count(buf, vrl_length);
> > +       if (!ksv_count) {
> > +               DRM_DEBUG("Revoked KSV count is 0\n");
> > +               return count;
> > +       }
> > +
> > +       kfree(srm_data->revoked_ksv_list);
> > +       srm_data->revoked_ksv_list = kcalloc(ksv_count,
> DRM_HDCP_KSV_LEN,
> > +                                            GFP_KERNEL);
> > +       if (!srm_data->revoked_ksv_list) {
> > +               DRM_ERROR("Out of Memory\n");
> > +               return -ENOMEM;
> > +       }
> > +
> > +       if (drm_hdcp_get_revoked_ksvs(buf, srm_data->revoked_ksv_list,
> > +                                     vrl_length) != ksv_count) {
> > +               srm_data->revoked_ksv_cnt = 0;
> > +               kfree(srm_data->revoked_ksv_list);
> > +               return -EINVAL;
> > +       }
> > +
> > +       srm_data->revoked_ksv_cnt = ksv_count;
> > +       return count;
> > +}
> > +
> > +static int drm_hdcp_parse_hdcp2_srm(const u8 *buf, size_t count) {
> > +       struct hdcp_srm_header *header;
> > +       u32 vrl_length, ksv_count, ksv_sz;
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) +
> > +           DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE))
> {
> > +               DRM_ERROR("Invalid blob length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       header = (struct hdcp_srm_header *)buf;
> > +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> > +                 header->srm_id & DRM_HDCP_SRM_ID_MASK,
> > +                 be16_to_cpu(header->srm_version),
> > + header->srm_gen_no);
> > +
> > +       if (header->reserved)
> > +               return -EINVAL;
> > +
> > +       buf = buf + sizeof(*header);
> > +       vrl_length = get_vrl_length(buf);
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> > +           vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
> > +           DRM_HDCP_2_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length or vrl length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Length of the all vrls combined */
> > +       vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE +
> > +                      DRM_HDCP_2_DCP_SIG_SIZE);
> > +
> > +       if (!vrl_length) {
> > +               DRM_ERROR("No vrl found\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
> > +       ksv_count = (*buf << 2) |
> DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
> > +       if (!ksv_count) {
> > +               DRM_DEBUG("Revoked KSV count is 0\n");
> > +               return count;
> > +       }
> > +
> > +       kfree(srm_data->revoked_ksv_list);
> > +       srm_data->revoked_ksv_list = kcalloc(ksv_count,
> DRM_HDCP_KSV_LEN,
> > +                                            GFP_KERNEL);
> > +       if (!srm_data->revoked_ksv_list) {
> > +               DRM_ERROR("Out of Memory\n");
> > +               return -ENOMEM;
> > +       }
> > +
> > +       ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
> > +       buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
> > +
> > +       DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
> > +       memcpy(srm_data->revoked_ksv_list, buf, ksv_sz);
> > +
> > +       srm_data->revoked_ksv_cnt = ksv_count;
> > +       return count;
> > +}
> > +
> > +static inline bool is_srm_version_hdcp1(const u8 *buf) {
> > +       return *buf == (u8)(DRM_HDCP_1_4_SRM_ID << 4); }
> > +
> > +static inline bool is_srm_version_hdcp2(const u8 *buf) {
> > +       return *buf == (u8)(DRM_HDCP_2_SRM_ID << 4 |
> > +DRM_HDCP_2_INDICATOR); }
> > +
> > +static void drm_hdcp_srm_update(const u8 *buf, size_t count) {
> > +       if (count < sizeof(struct hdcp_srm_header))
> > +               return;
> > +
> > +       if (is_srm_version_hdcp1(buf))
> > +               drm_hdcp_parse_hdcp1_srm(buf, count);
> > +       else if (is_srm_version_hdcp2(buf))
> > +               drm_hdcp_parse_hdcp2_srm(buf, count); }
> > +
> > +void drm_hdcp_request_srm(struct drm_device *drm_dev) {
> > +       char fw_name[36] = "display_hdcp_srm.bin";
> > +       const struct firmware *fw;
> > +
> > +       int ret;
> > +
> > +       ret = request_firmware_direct(&fw, (const char *)fw_name,
> > +                                     drm_dev->dev);
> > +       if (ret < 0)
> > +               goto exit;
> > +
> > +       if (fw->size && fw->data)
> > +               drm_hdcp_srm_update(fw->data, fw->size);
> > +
> > +exit:
> > +       release_firmware(fw);
> > +}
> > +
> > +/**
> > + * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
> > + *
> > + * @drm_dev: drm_device for which HDCP revocation check is requested
> > + * @ksvs: List of KSVs (HDCP receiver IDs)
> > + * @ksv_count: KSV count passed in through @ksvs
> > + *
> > + * This function reads the HDCP System renewability Message(SRM
> > +Table)
> > + * from userspace as a firmware and parses it for the revoked HDCP
> > + * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are
> > +known,
> > + * revoked state of the KSVs in the list passed in by display drivers
> > +are
> > + * decided and response is sent.
> > + *
> > + * SRM should be presented in the name of "display_hdcp_srm.bin".
> > + *
> > + * Returns:
> > + * TRUE on any of the KSV is revoked, else FALSE.
> > + */
> > +bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8
> *ksvs,
> > +                                u32 ksv_count) {
> > +       u32 rev_ksv_cnt, cnt, i, j;
> > +       u8 *rev_ksv_list;
> > +
> > +       if (!srm_data)
> > +               return false;
> > +
> > +       mutex_lock(&srm_data->mutex);
> > +       drm_hdcp_request_srm(drm_dev);
> > +
> > +       rev_ksv_cnt = srm_data->revoked_ksv_cnt;
> > +       rev_ksv_list = srm_data->revoked_ksv_list;
> > +
> > +       /* If the Revoked ksv list is empty */
> > +       if (!rev_ksv_cnt || !rev_ksv_list) {
> > +               mutex_unlock(&srm_data->mutex);
> > +               return false;
> > +       }
> > +
> > +       for  (cnt = 0; cnt < ksv_count; cnt++) {
> > +               rev_ksv_list = srm_data->revoked_ksv_list;
> > +               for (i = 0; i < rev_ksv_cnt; i++) {
> > +                       for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
> > +                               if (ksvs[j] != rev_ksv_list[j]) {
> > +                                       break;
> > +                               } else if (j == (DRM_HDCP_KSV_LEN - 1)) {
> > +                                       DRM_DEBUG("Revoked KSV is ");
> > +                                       drm_hdcp_print_ksv(ksvs);
> > +                                       mutex_unlock(&srm_data->mutex);
> > +                                       return true;
> > +                               }
> > +                       /* Move the offset to next KSV in the revoked list */
> > +                       rev_ksv_list += DRM_HDCP_KSV_LEN;
> > +               }
> > +
> > +               /* Iterate to next ksv_offset */
> > +               ksvs += DRM_HDCP_KSV_LEN;
> > +       }
> > +       mutex_unlock(&srm_data->mutex);
> > +       return false;
> > +}
> > +EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
> > +
> > +int drm_setup_hdcp_srm(struct class *drm_class) {
> > +       srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> > +       if (!srm_data)
> > +               return -ENOMEM;
> > +       mutex_init(&srm_data->mutex);
> > +
> > +       return 0;
> > +}
> > +
> > +void drm_teardown_hdcp_srm(struct class *drm_class) {
> > +       if (srm_data) {
> > +               kfree(srm_data->revoked_ksv_list);
> > +               kfree(srm_data);
> > +       }
> > +}
> > diff --git a/drivers/gpu/drm/drm_internal.h
> > b/drivers/gpu/drm/drm_internal.h index e19ac7ca602d..476a422414f6
> > 100644
> > --- a/drivers/gpu/drm/drm_internal.h
> > +++ b/drivers/gpu/drm/drm_internal.h
> > @@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device
> > *dev, void *data,  void drm_framebuffer_print_info(struct drm_printer
> *p, unsigned int indent,
> >                                 const struct drm_framebuffer *fb);
> > int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> > +
> > +/* drm_hdcp.c */
> > +int drm_setup_hdcp_srm(struct class *drm_class); void
> > +drm_teardown_hdcp_srm(struct class *drm_class);
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index ecb7b33002bb..18b1ac442997 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
> >         }
> >
> >         drm_class->devnode = drm_devnode;
> > +       drm_setup_hdcp_srm(drm_class);
> >         return 0;
> >  }
> >
> > @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)  {
> >         if (IS_ERR_OR_NULL(drm_class))
> >                 return;
> > +       drm_teardown_hdcp_srm(drm_class);
> >         class_remove_file(drm_class, &class_attr_version.attr);
> >         class_destroy(drm_class);
> >         drm_class = NULL;
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index
> > 1cc66df05a43..2f0335d0a50f 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8
> seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
> >         seq_num[2] = val;
> >  }
> >
> > +#define DRM_HDCP_SRM_GEN1_MAX_BYTES            (5 * 1024)
> > +#define DRM_HDCP_1_4_SRM_ID                    0x8
> > +#define DRM_HDCP_SRM_ID_MASK                   (0xF << 4)
> > +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE           3
> > +#define DRM_HDCP_1_4_DCP_SIG_SIZE              40
> > +#define DRM_HDCP_2_SRM_ID                      0x9
> > +#define DRM_HDCP_2_INDICATOR                   0x1
> > +#define DRM_HDCP_2_INDICATOR_MASK              0xF
> > +#define DRM_HDCP_2_VRL_LENGTH_SIZE             3
> > +#define DRM_HDCP_2_DCP_SIG_SIZE                        384
> > +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ  4
> > +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)    (((byte) & 0xC) >>
> 6)
> > +
> > +struct hdcp_srm_header {
> > +       u8 srm_id;
> > +       u8 reserved;
> > +       __be16 srm_version;
> > +       u8 srm_gen_no;
> > +} __packed;
> > +
> > +struct drm_device;
> > +
> > +bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> > +                                u8 *ksvs, u32 ksv_count);
> >  #endif
> > --
> > 2.19.1
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-09-12  0:15   ` Harry Wentland
  2019-09-12  1:14     ` Deucher, Alexander
@ 2019-09-12  6:54     ` Ramalingam C
  2019-09-12 15:49       ` Harry Wentland
  1 sibling, 1 reply; 70+ messages in thread
From: Ramalingam C @ 2019-09-12  6:54 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Anshuman Gupta, intel-gfx, dri-devel, gwan-gyeong.mun, Deucher,
	Alexander, daniel.vetter, Kumar, Ranjeet, Lakha, Bhawanpreet

On 2019-09-12 at 00:15:32 +0000, Harry Wentland wrote:
> Adding a couple AMD guys.
> 
> I know this is already merged but I have a few questions after some
> internal discussions.
> 
> On 2019-05-07 12:27 p.m., Ramalingam C wrote:
> > On every hdcp revocation check request SRM is read from fw file
> > /lib/firmware/display_hdcp_srm.bin
> > 
> 
> According to section 5 of the HDCP 2.3 spec [1] a device compliant with
> HDCP 2.0 and higher must be capable of storing and updating the SRM in
> non-volatile memory. Section 5.2 describes how this SRM needs to be
> updated when a new version is served alongside protected content.
> 
> Isn't /lib/firmware intended for static firmware making updates to the
> folder problematic for anyone but the system's package maintainer? I've
> heard /lib might even be treated as read-only in certain environments.
> This would mean it'd be impossible to support HDCP 2.x on those systems.
> 
> Wouldn't it be easier to provide a sysfs entry for SRM that allows
> userspace (e.g. system startup/shutdown scripts) to (a) retrieve the SRM
> from the HDCP implementation for non-volatile storage and (b) to pass
> the SRM to the HDCP implementation for revocation checking?

This uAPI is decided considering below points:

userspace will handle the non-volatile storage of the SRM table and it's upgrade
with latest versions received from content providers etc.

Prior to any HDCP auth request userspace will write the latest SRM into
the /lib/firmware.

And regarding the interface, binary sysfs based implementation [1] was opposed by Greg KH.
And after the discussion on different alternate i/fs [2] request
firmware is choosen.

[1]. https://patchwork.freedesktop.org/patch/296442/?series=57232&rev=5uAPI
[2]. https://patchwork.freedesktop.org/patch/296439/?series=57232&rev=5

I hope this addresses the questions above.

-Ram


> 
> [1]
> https://www.digital-cp.com/sites/default/files/HDCP%20on%20HDMI%20Specification%20Rev2_3.pdf
> 
> Thanks,
> Harry
> 
> > SRM table is parsed and stored at drm_hdcp.c, with functions exported
> > for the services for revocation check from drivers (which
> > implements the HDCP authentication)
> > 
> > This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> > 
> > v2:
> >   moved the uAPI to request_firmware_direct() [Daniel]
> > v3:
> >   kdoc added. [Daniel]
> >   srm_header unified and bit field definitions are removed. [Daniel]
> >   locking improved. [Daniel]
> >   vrl length violation is fixed. [Daniel]
> > v4:
> >   s/__swab16/be16_to_cpu [Daniel]
> >   be24_to_cpu is done through a global func [Daniel]
> >   Unused variables are removed. [Daniel]
> >   unchecked return values are dropped from static funcs [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
> > Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
> > ---
> >  Documentation/gpu/drm-kms-helpers.rst |   6 +
> >  drivers/gpu/drm/Makefile              |   2 +-
> >  drivers/gpu/drm/drm_hdcp.c            | 333 ++++++++++++++++++++++++++
> >  drivers/gpu/drm/drm_internal.h        |   4 +
> >  drivers/gpu/drm/drm_sysfs.c           |   2 +
> >  include/drm/drm_hdcp.h                |  24 ++
> >  6 files changed, 370 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/drm_hdcp.c
> > 
> > diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
> > index 14102ae035dc..0fe726a6ee67 100644
> > --- a/Documentation/gpu/drm-kms-helpers.rst
> > +++ b/Documentation/gpu/drm-kms-helpers.rst
> > @@ -181,6 +181,12 @@ Panel Helper Reference
> >  .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
> >     :export:
> > 
> > +HDCP Helper Functions Reference
> > +===============================
> > +
> > +.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
> > +   :export:
> > +
> >  Display Port Helper Functions Reference
> >  =======================================
> > 
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index 72f5036d9bfa..dd02e9dec810 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -17,7 +17,7 @@ drm-y       :=        drm_auth.o drm_cache.o \
> >                 drm_plane.o drm_color_mgmt.o drm_print.o \
> >                 drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
> >                 drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> > -               drm_atomic_uapi.o
> > +               drm_atomic_uapi.o drm_hdcp.o
> > 
> >  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
> >  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > new file mode 100644
> > index 000000000000..5e5409505c31
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -0,0 +1,333 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2019 Intel Corporation.
> > + *
> > + * Authors:
> > + * Ramalingam C <ramalingam.c@intel.com>
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gfp.h>
> > +#include <linux/export.h>
> > +#include <linux/slab.h>
> > +#include <linux/firmware.h>
> > +
> > +#include <drm/drm_hdcp.h>
> > +#include <drm/drm_sysfs.h>
> > +#include <drm/drm_print.h>
> > +#include <drm/drm_device.h>
> > +
> > +struct hdcp_srm {
> > +       u32 revoked_ksv_cnt;
> > +       u8 *revoked_ksv_list;
> > +
> > +       /* Mutex to protect above struct member */
> > +       struct mutex mutex;
> > +} *srm_data;
> > +
> > +static inline void drm_hdcp_print_ksv(const u8 *ksv)
> > +{
> > +       DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
> > +                 ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
> > +}
> > +
> > +static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
> > +{
> > +       u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
> > +
> > +       while (parsed_bytes < vrls_length) {
> > +               vrl_ksv_cnt = *buf;
> > +               ksv_count += vrl_ksv_cnt;
> > +
> > +               vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
> > +               buf += vrl_sz;
> > +               parsed_bytes += vrl_sz;
> > +       }
> > +
> > +       /*
> > +        * When vrls are not valid, ksvs are not considered.
> > +        * Hence SRM will be discarded.
> > +        */
> > +       if (parsed_bytes != vrls_length)
> > +               ksv_count = 0;
> > +
> > +       return ksv_count;
> > +}
> > +
> > +static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
> > +                                    u32 vrls_length)
> > +{
> > +       u32 parsed_bytes = 0, ksv_count = 0;
> > +       u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
> > +
> > +       do {
> > +               vrl_ksv_cnt = *buf;
> > +               vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
> > +
> > +               buf++;
> > +
> > +               DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
> > +                         vrl_ksv_cnt);
> > +               memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
> > +
> > +               ksv_count += vrl_ksv_cnt;
> > +               revoked_ksv_list += vrl_ksv_sz;
> > +               buf += vrl_ksv_sz;
> > +
> > +               parsed_bytes += (vrl_ksv_sz + 1);
> > +       } while (parsed_bytes < vrls_length);
> > +
> > +       return ksv_count;
> > +}
> > +
> > +static inline u32 get_vrl_length(const u8 *buf)
> > +{
> > +       return drm_hdcp_be24_to_cpu(buf);
> > +}
> > +
> > +static int drm_hdcp_parse_hdcp1_srm(const u8 *buf, size_t count)
> > +{
> > +       struct hdcp_srm_header *header;
> > +       u32 vrl_length, ksv_count;
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) +
> > +           DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       header = (struct hdcp_srm_header *)buf;
> > +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> > +                 header->srm_id,
> > +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
> > +
> > +       WARN_ON(header->reserved);
> > +
> > +       buf = buf + sizeof(*header);
> > +       vrl_length = get_vrl_length(buf);
> > +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> > +           vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> > +                         DRM_HDCP_1_4_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length or vrl length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Length of the all vrls combined */
> > +       vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
> > +                      DRM_HDCP_1_4_DCP_SIG_SIZE);
> > +
> > +       if (!vrl_length) {
> > +               DRM_ERROR("No vrl found\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
> > +       ksv_count = drm_hdcp_get_revoked_ksv_count(buf, vrl_length);
> > +       if (!ksv_count) {
> > +               DRM_DEBUG("Revoked KSV count is 0\n");
> > +               return count;
> > +       }
> > +
> > +       kfree(srm_data->revoked_ksv_list);
> > +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
> > +                                            GFP_KERNEL);
> > +       if (!srm_data->revoked_ksv_list) {
> > +               DRM_ERROR("Out of Memory\n");
> > +               return -ENOMEM;
> > +       }
> > +
> > +       if (drm_hdcp_get_revoked_ksvs(buf, srm_data->revoked_ksv_list,
> > +                                     vrl_length) != ksv_count) {
> > +               srm_data->revoked_ksv_cnt = 0;
> > +               kfree(srm_data->revoked_ksv_list);
> > +               return -EINVAL;
> > +       }
> > +
> > +       srm_data->revoked_ksv_cnt = ksv_count;
> > +       return count;
> > +}
> > +
> > +static int drm_hdcp_parse_hdcp2_srm(const u8 *buf, size_t count)
> > +{
> > +       struct hdcp_srm_header *header;
> > +       u32 vrl_length, ksv_count, ksv_sz;
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) +
> > +           DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       header = (struct hdcp_srm_header *)buf;
> > +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
> > +                 header->srm_id & DRM_HDCP_SRM_ID_MASK,
> > +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
> > +
> > +       if (header->reserved)
> > +               return -EINVAL;
> > +
> > +       buf = buf + sizeof(*header);
> > +       vrl_length = get_vrl_length(buf);
> > +
> > +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
> > +           vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
> > +           DRM_HDCP_2_DCP_SIG_SIZE)) {
> > +               DRM_ERROR("Invalid blob length or vrl length\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Length of the all vrls combined */
> > +       vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE +
> > +                      DRM_HDCP_2_DCP_SIG_SIZE);
> > +
> > +       if (!vrl_length) {
> > +               DRM_ERROR("No vrl found\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
> > +       ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
> > +       if (!ksv_count) {
> > +               DRM_DEBUG("Revoked KSV count is 0\n");
> > +               return count;
> > +       }
> > +
> > +       kfree(srm_data->revoked_ksv_list);
> > +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
> > +                                            GFP_KERNEL);
> > +       if (!srm_data->revoked_ksv_list) {
> > +               DRM_ERROR("Out of Memory\n");
> > +               return -ENOMEM;
> > +       }
> > +
> > +       ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
> > +       buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
> > +
> > +       DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
> > +       memcpy(srm_data->revoked_ksv_list, buf, ksv_sz);
> > +
> > +       srm_data->revoked_ksv_cnt = ksv_count;
> > +       return count;
> > +}
> > +
> > +static inline bool is_srm_version_hdcp1(const u8 *buf)
> > +{
> > +       return *buf == (u8)(DRM_HDCP_1_4_SRM_ID << 4);
> > +}
> > +
> > +static inline bool is_srm_version_hdcp2(const u8 *buf)
> > +{
> > +       return *buf == (u8)(DRM_HDCP_2_SRM_ID << 4 | DRM_HDCP_2_INDICATOR);
> > +}
> > +
> > +static void drm_hdcp_srm_update(const u8 *buf, size_t count)
> > +{
> > +       if (count < sizeof(struct hdcp_srm_header))
> > +               return;
> > +
> > +       if (is_srm_version_hdcp1(buf))
> > +               drm_hdcp_parse_hdcp1_srm(buf, count);
> > +       else if (is_srm_version_hdcp2(buf))
> > +               drm_hdcp_parse_hdcp2_srm(buf, count);
> > +}
> > +
> > +void drm_hdcp_request_srm(struct drm_device *drm_dev)
> > +{
> > +       char fw_name[36] = "display_hdcp_srm.bin";
> > +       const struct firmware *fw;
> > +
> > +       int ret;
> > +
> > +       ret = request_firmware_direct(&fw, (const char *)fw_name,
> > +                                     drm_dev->dev);
> > +       if (ret < 0)
> > +               goto exit;
> > +
> > +       if (fw->size && fw->data)
> > +               drm_hdcp_srm_update(fw->data, fw->size);
> > +
> > +exit:
> > +       release_firmware(fw);
> > +}
> > +
> > +/**
> > + * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
> > + *
> > + * @drm_dev: drm_device for which HDCP revocation check is requested
> > + * @ksvs: List of KSVs (HDCP receiver IDs)
> > + * @ksv_count: KSV count passed in through @ksvs
> > + *
> > + * This function reads the HDCP System renewability Message(SRM Table)
> > + * from userspace as a firmware and parses it for the revoked HDCP
> > + * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known,
> > + * revoked state of the KSVs in the list passed in by display drivers are
> > + * decided and response is sent.
> > + *
> > + * SRM should be presented in the name of "display_hdcp_srm.bin".
> > + *
> > + * Returns:
> > + * TRUE on any of the KSV is revoked, else FALSE.
> > + */
> > +bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
> > +                                u32 ksv_count)
> > +{
> > +       u32 rev_ksv_cnt, cnt, i, j;
> > +       u8 *rev_ksv_list;
> > +
> > +       if (!srm_data)
> > +               return false;
> > +
> > +       mutex_lock(&srm_data->mutex);
> > +       drm_hdcp_request_srm(drm_dev);
> > +
> > +       rev_ksv_cnt = srm_data->revoked_ksv_cnt;
> > +       rev_ksv_list = srm_data->revoked_ksv_list;
> > +
> > +       /* If the Revoked ksv list is empty */
> > +       if (!rev_ksv_cnt || !rev_ksv_list) {
> > +               mutex_unlock(&srm_data->mutex);
> > +               return false;
> > +       }
> > +
> > +       for  (cnt = 0; cnt < ksv_count; cnt++) {
> > +               rev_ksv_list = srm_data->revoked_ksv_list;
> > +               for (i = 0; i < rev_ksv_cnt; i++) {
> > +                       for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
> > +                               if (ksvs[j] != rev_ksv_list[j]) {
> > +                                       break;
> > +                               } else if (j == (DRM_HDCP_KSV_LEN - 1)) {
> > +                                       DRM_DEBUG("Revoked KSV is ");
> > +                                       drm_hdcp_print_ksv(ksvs);
> > +                                       mutex_unlock(&srm_data->mutex);
> > +                                       return true;
> > +                               }
> > +                       /* Move the offset to next KSV in the revoked list */
> > +                       rev_ksv_list += DRM_HDCP_KSV_LEN;
> > +               }
> > +
> > +               /* Iterate to next ksv_offset */
> > +               ksvs += DRM_HDCP_KSV_LEN;
> > +       }
> > +       mutex_unlock(&srm_data->mutex);
> > +       return false;
> > +}
> > +EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
> > +
> > +int drm_setup_hdcp_srm(struct class *drm_class)
> > +{
> > +       srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> > +       if (!srm_data)
> > +               return -ENOMEM;
> > +       mutex_init(&srm_data->mutex);
> > +
> > +       return 0;
> > +}
> > +
> > +void drm_teardown_hdcp_srm(struct class *drm_class)
> > +{
> > +       if (srm_data) {
> > +               kfree(srm_data->revoked_ksv_list);
> > +               kfree(srm_data);
> > +       }
> > +}
> > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> > index e19ac7ca602d..476a422414f6 100644
> > --- a/drivers/gpu/drm/drm_internal.h
> > +++ b/drivers/gpu/drm/drm_internal.h
> > @@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
> >  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
> >                                 const struct drm_framebuffer *fb);
> >  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> > +
> > +/* drm_hdcp.c */
> > +int drm_setup_hdcp_srm(struct class *drm_class);
> > +void drm_teardown_hdcp_srm(struct class *drm_class);
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index ecb7b33002bb..18b1ac442997 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
> >         }
> > 
> >         drm_class->devnode = drm_devnode;
> > +       drm_setup_hdcp_srm(drm_class);
> >         return 0;
> >  }
> > 
> > @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
> >  {
> >         if (IS_ERR_OR_NULL(drm_class))
> >                 return;
> > +       drm_teardown_hdcp_srm(drm_class);
> >         class_remove_file(drm_class, &class_attr_version.attr);
> >         class_destroy(drm_class);
> >         drm_class = NULL;
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > index 1cc66df05a43..2f0335d0a50f 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
> >         seq_num[2] = val;
> >  }
> > 
> > +#define DRM_HDCP_SRM_GEN1_MAX_BYTES            (5 * 1024)
> > +#define DRM_HDCP_1_4_SRM_ID                    0x8
> > +#define DRM_HDCP_SRM_ID_MASK                   (0xF << 4)
> > +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE           3
> > +#define DRM_HDCP_1_4_DCP_SIG_SIZE              40
> > +#define DRM_HDCP_2_SRM_ID                      0x9
> > +#define DRM_HDCP_2_INDICATOR                   0x1
> > +#define DRM_HDCP_2_INDICATOR_MASK              0xF
> > +#define DRM_HDCP_2_VRL_LENGTH_SIZE             3
> > +#define DRM_HDCP_2_DCP_SIG_SIZE                        384
> > +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ  4
> > +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)    (((byte) & 0xC) >> 6)
> > +
> > +struct hdcp_srm_header {
> > +       u8 srm_id;
> > +       u8 reserved;
> > +       __be16 srm_version;
> > +       u8 srm_gen_no;
> > +} __packed;
> > +
> > +struct drm_device;
> > +
> > +bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
> > +                                u8 *ksvs, u32 ksv_count);
> >  #endif
> > --
> > 2.19.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v7 04/11] drm: revocation check at drm subsystem
  2019-09-12  6:54     ` Ramalingam C
@ 2019-09-12 15:49       ` Harry Wentland
  0 siblings, 0 replies; 70+ messages in thread
From: Harry Wentland @ 2019-09-12 15:49 UTC (permalink / raw)
  To: Ramalingam C
  Cc: Anshuman Gupta, intel-gfx, dri-devel, gwan-gyeong.mun, Deucher,
	Alexander, daniel.vetter, Kumar, Ranjeet, Lakha, Bhawanpreet

On 2019-09-12 2:54 a.m., Ramalingam C wrote:
> On 2019-09-12 at 00:15:32 +0000, Harry Wentland wrote:
>> Adding a couple AMD guys.
>>
>> I know this is already merged but I have a few questions after some
>> internal discussions.
>>
>> On 2019-05-07 12:27 p.m., Ramalingam C wrote:
>>> On every hdcp revocation check request SRM is read from fw file
>>> /lib/firmware/display_hdcp_srm.bin
>>>
>>
>> According to section 5 of the HDCP 2.3 spec [1] a device compliant with
>> HDCP 2.0 and higher must be capable of storing and updating the SRM in
>> non-volatile memory. Section 5.2 describes how this SRM needs to be
>> updated when a new version is served alongside protected content.
>>
>> Isn't /lib/firmware intended for static firmware making updates to the
>> folder problematic for anyone but the system's package maintainer? I've
>> heard /lib might even be treated as read-only in certain environments.
>> This would mean it'd be impossible to support HDCP 2.x on those systems.
>>
>> Wouldn't it be easier to provide a sysfs entry for SRM that allows
>> userspace (e.g. system startup/shutdown scripts) to (a) retrieve the SRM
>> from the HDCP implementation for non-volatile storage and (b) to pass
>> the SRM to the HDCP implementation for revocation checking?
> 
> This uAPI is decided considering below points:
> 
> userspace will handle the non-volatile storage of the SRM table and it's upgrade
> with latest versions received from content providers etc.
> 
> Prior to any HDCP auth request userspace will write the latest SRM into
> the /lib/firmware.
> 
> And regarding the interface, binary sysfs based implementation [1] was opposed by Greg KH.
> And after the discussion on different alternate i/fs [2] request
> firmware is choosen.
> 
> [1]. https://patchwork.freedesktop.org/patch/296442/?series=57232&rev=5uAPI
> [2]. https://patchwork.freedesktop.org/patch/296439/?series=57232&rev=5
> 
> I hope this addresses the questions above.
> 

Interesting discussion. Thanks for sharing.

It sounds like Greg's main concern was with the fact that DRM parses the
binary.

In our case we'll need to pass the blob to FW without touching it. A
device sysfs sounds like a better use-case for that.

On the other hand certain people are interested to have a non-FW
approach to content protection for which your approach seems to work best.

I still don't know how this solution can get HDCP 2.x certified. I was
under the impression HDCP 2.x required a protected execution environment
with stricter requirements than x86 kernel space can provide.

Harry

> -Ram
> 
> 
>>
>> [1]
>> https://www.digital-cp.com/sites/default/files/HDCP%20on%20HDMI%20Specification%20Rev2_3.pdf
>>
>> Thanks,
>> Harry
>>
>>> SRM table is parsed and stored at drm_hdcp.c, with functions exported
>>> for the services for revocation check from drivers (which
>>> implements the HDCP authentication)
>>>
>>> This patch handles the HDCP1.4 and 2.2 versions of SRM table.
>>>
>>> v2:
>>>   moved the uAPI to request_firmware_direct() [Daniel]
>>> v3:
>>>   kdoc added. [Daniel]
>>>   srm_header unified and bit field definitions are removed. [Daniel]
>>>   locking improved. [Daniel]
>>>   vrl length violation is fixed. [Daniel]
>>> v4:
>>>   s/__swab16/be16_to_cpu [Daniel]
>>>   be24_to_cpu is done through a global func [Daniel]
>>>   Unused variables are removed. [Daniel]
>>>   unchecked return values are dropped from static funcs [Daniel]
>>>
>>> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
>>> Acked-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
>>> Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
>>> ---
>>>  Documentation/gpu/drm-kms-helpers.rst |   6 +
>>>  drivers/gpu/drm/Makefile              |   2 +-
>>>  drivers/gpu/drm/drm_hdcp.c            | 333 ++++++++++++++++++++++++++
>>>  drivers/gpu/drm/drm_internal.h        |   4 +
>>>  drivers/gpu/drm/drm_sysfs.c           |   2 +
>>>  include/drm/drm_hdcp.h                |  24 ++
>>>  6 files changed, 370 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/gpu/drm/drm_hdcp.c
>>>
>>> diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
>>> index 14102ae035dc..0fe726a6ee67 100644
>>> --- a/Documentation/gpu/drm-kms-helpers.rst
>>> +++ b/Documentation/gpu/drm-kms-helpers.rst
>>> @@ -181,6 +181,12 @@ Panel Helper Reference
>>>  .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
>>>     :export:
>>>
>>> +HDCP Helper Functions Reference
>>> +===============================
>>> +
>>> +.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
>>> +   :export:
>>> +
>>>  Display Port Helper Functions Reference
>>>  =======================================
>>>
>>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
>>> index 72f5036d9bfa..dd02e9dec810 100644
>>> --- a/drivers/gpu/drm/Makefile
>>> +++ b/drivers/gpu/drm/Makefile
>>> @@ -17,7 +17,7 @@ drm-y       :=        drm_auth.o drm_cache.o \
>>>                 drm_plane.o drm_color_mgmt.o drm_print.o \
>>>                 drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>>>                 drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
>>> -               drm_atomic_uapi.o
>>> +               drm_atomic_uapi.o drm_hdcp.o
>>>
>>>  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
>>>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
>>> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
>>> new file mode 100644
>>> index 000000000000..5e5409505c31
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/drm_hdcp.c
>>> @@ -0,0 +1,333 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (C) 2019 Intel Corporation.
>>> + *
>>> + * Authors:
>>> + * Ramalingam C <ramalingam.c@intel.com>
>>> + */
>>> +
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gfp.h>
>>> +#include <linux/export.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/firmware.h>
>>> +
>>> +#include <drm/drm_hdcp.h>
>>> +#include <drm/drm_sysfs.h>
>>> +#include <drm/drm_print.h>
>>> +#include <drm/drm_device.h>
>>> +
>>> +struct hdcp_srm {
>>> +       u32 revoked_ksv_cnt;
>>> +       u8 *revoked_ksv_list;
>>> +
>>> +       /* Mutex to protect above struct member */
>>> +       struct mutex mutex;
>>> +} *srm_data;
>>> +
>>> +static inline void drm_hdcp_print_ksv(const u8 *ksv)
>>> +{
>>> +       DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
>>> +                 ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
>>> +}
>>> +
>>> +static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
>>> +{
>>> +       u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
>>> +
>>> +       while (parsed_bytes < vrls_length) {
>>> +               vrl_ksv_cnt = *buf;
>>> +               ksv_count += vrl_ksv_cnt;
>>> +
>>> +               vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
>>> +               buf += vrl_sz;
>>> +               parsed_bytes += vrl_sz;
>>> +       }
>>> +
>>> +       /*
>>> +        * When vrls are not valid, ksvs are not considered.
>>> +        * Hence SRM will be discarded.
>>> +        */
>>> +       if (parsed_bytes != vrls_length)
>>> +               ksv_count = 0;
>>> +
>>> +       return ksv_count;
>>> +}
>>> +
>>> +static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
>>> +                                    u32 vrls_length)
>>> +{
>>> +       u32 parsed_bytes = 0, ksv_count = 0;
>>> +       u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
>>> +
>>> +       do {
>>> +               vrl_ksv_cnt = *buf;
>>> +               vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
>>> +
>>> +               buf++;
>>> +
>>> +               DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
>>> +                         vrl_ksv_cnt);
>>> +               memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
>>> +
>>> +               ksv_count += vrl_ksv_cnt;
>>> +               revoked_ksv_list += vrl_ksv_sz;
>>> +               buf += vrl_ksv_sz;
>>> +
>>> +               parsed_bytes += (vrl_ksv_sz + 1);
>>> +       } while (parsed_bytes < vrls_length);
>>> +
>>> +       return ksv_count;
>>> +}
>>> +
>>> +static inline u32 get_vrl_length(const u8 *buf)
>>> +{
>>> +       return drm_hdcp_be24_to_cpu(buf);
>>> +}
>>> +
>>> +static int drm_hdcp_parse_hdcp1_srm(const u8 *buf, size_t count)
>>> +{
>>> +       struct hdcp_srm_header *header;
>>> +       u32 vrl_length, ksv_count;
>>> +
>>> +       if (count < (sizeof(struct hdcp_srm_header) +
>>> +           DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
>>> +               DRM_ERROR("Invalid blob length\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       header = (struct hdcp_srm_header *)buf;
>>> +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
>>> +                 header->srm_id,
>>> +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
>>> +
>>> +       WARN_ON(header->reserved);
>>> +
>>> +       buf = buf + sizeof(*header);
>>> +       vrl_length = get_vrl_length(buf);
>>> +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
>>> +           vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
>>> +                         DRM_HDCP_1_4_DCP_SIG_SIZE)) {
>>> +               DRM_ERROR("Invalid blob length or vrl length\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       /* Length of the all vrls combined */
>>> +       vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
>>> +                      DRM_HDCP_1_4_DCP_SIG_SIZE);
>>> +
>>> +       if (!vrl_length) {
>>> +               DRM_ERROR("No vrl found\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
>>> +       ksv_count = drm_hdcp_get_revoked_ksv_count(buf, vrl_length);
>>> +       if (!ksv_count) {
>>> +               DRM_DEBUG("Revoked KSV count is 0\n");
>>> +               return count;
>>> +       }
>>> +
>>> +       kfree(srm_data->revoked_ksv_list);
>>> +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
>>> +                                            GFP_KERNEL);
>>> +       if (!srm_data->revoked_ksv_list) {
>>> +               DRM_ERROR("Out of Memory\n");
>>> +               return -ENOMEM;
>>> +       }
>>> +
>>> +       if (drm_hdcp_get_revoked_ksvs(buf, srm_data->revoked_ksv_list,
>>> +                                     vrl_length) != ksv_count) {
>>> +               srm_data->revoked_ksv_cnt = 0;
>>> +               kfree(srm_data->revoked_ksv_list);
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       srm_data->revoked_ksv_cnt = ksv_count;
>>> +       return count;
>>> +}
>>> +
>>> +static int drm_hdcp_parse_hdcp2_srm(const u8 *buf, size_t count)
>>> +{
>>> +       struct hdcp_srm_header *header;
>>> +       u32 vrl_length, ksv_count, ksv_sz;
>>> +
>>> +       if (count < (sizeof(struct hdcp_srm_header) +
>>> +           DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
>>> +               DRM_ERROR("Invalid blob length\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       header = (struct hdcp_srm_header *)buf;
>>> +       DRM_DEBUG("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
>>> +                 header->srm_id & DRM_HDCP_SRM_ID_MASK,
>>> +                 be16_to_cpu(header->srm_version), header->srm_gen_no);
>>> +
>>> +       if (header->reserved)
>>> +               return -EINVAL;
>>> +
>>> +       buf = buf + sizeof(*header);
>>> +       vrl_length = get_vrl_length(buf);
>>> +
>>> +       if (count < (sizeof(struct hdcp_srm_header) + vrl_length) ||
>>> +           vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
>>> +           DRM_HDCP_2_DCP_SIG_SIZE)) {
>>> +               DRM_ERROR("Invalid blob length or vrl length\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       /* Length of the all vrls combined */
>>> +       vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE +
>>> +                      DRM_HDCP_2_DCP_SIG_SIZE);
>>> +
>>> +       if (!vrl_length) {
>>> +               DRM_ERROR("No vrl found\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
>>> +       ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
>>> +       if (!ksv_count) {
>>> +               DRM_DEBUG("Revoked KSV count is 0\n");
>>> +               return count;
>>> +       }
>>> +
>>> +       kfree(srm_data->revoked_ksv_list);
>>> +       srm_data->revoked_ksv_list = kcalloc(ksv_count, DRM_HDCP_KSV_LEN,
>>> +                                            GFP_KERNEL);
>>> +       if (!srm_data->revoked_ksv_list) {
>>> +               DRM_ERROR("Out of Memory\n");
>>> +               return -ENOMEM;
>>> +       }
>>> +
>>> +       ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
>>> +       buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
>>> +
>>> +       DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
>>> +       memcpy(srm_data->revoked_ksv_list, buf, ksv_sz);
>>> +
>>> +       srm_data->revoked_ksv_cnt = ksv_count;
>>> +       return count;
>>> +}
>>> +
>>> +static inline bool is_srm_version_hdcp1(const u8 *buf)
>>> +{
>>> +       return *buf == (u8)(DRM_HDCP_1_4_SRM_ID << 4);
>>> +}
>>> +
>>> +static inline bool is_srm_version_hdcp2(const u8 *buf)
>>> +{
>>> +       return *buf == (u8)(DRM_HDCP_2_SRM_ID << 4 | DRM_HDCP_2_INDICATOR);
>>> +}
>>> +
>>> +static void drm_hdcp_srm_update(const u8 *buf, size_t count)
>>> +{
>>> +       if (count < sizeof(struct hdcp_srm_header))
>>> +               return;
>>> +
>>> +       if (is_srm_version_hdcp1(buf))
>>> +               drm_hdcp_parse_hdcp1_srm(buf, count);
>>> +       else if (is_srm_version_hdcp2(buf))
>>> +               drm_hdcp_parse_hdcp2_srm(buf, count);
>>> +}
>>> +
>>> +void drm_hdcp_request_srm(struct drm_device *drm_dev)
>>> +{
>>> +       char fw_name[36] = "display_hdcp_srm.bin";
>>> +       const struct firmware *fw;
>>> +
>>> +       int ret;
>>> +
>>> +       ret = request_firmware_direct(&fw, (const char *)fw_name,
>>> +                                     drm_dev->dev);
>>> +       if (ret < 0)
>>> +               goto exit;
>>> +
>>> +       if (fw->size && fw->data)
>>> +               drm_hdcp_srm_update(fw->data, fw->size);
>>> +
>>> +exit:
>>> +       release_firmware(fw);
>>> +}
>>> +
>>> +/**
>>> + * drm_hdcp_check_ksvs_revoked - Check the revoked status of the IDs
>>> + *
>>> + * @drm_dev: drm_device for which HDCP revocation check is requested
>>> + * @ksvs: List of KSVs (HDCP receiver IDs)
>>> + * @ksv_count: KSV count passed in through @ksvs
>>> + *
>>> + * This function reads the HDCP System renewability Message(SRM Table)
>>> + * from userspace as a firmware and parses it for the revoked HDCP
>>> + * KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known,
>>> + * revoked state of the KSVs in the list passed in by display drivers are
>>> + * decided and response is sent.
>>> + *
>>> + * SRM should be presented in the name of "display_hdcp_srm.bin".
>>> + *
>>> + * Returns:
>>> + * TRUE on any of the KSV is revoked, else FALSE.
>>> + */
>>> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
>>> +                                u32 ksv_count)
>>> +{
>>> +       u32 rev_ksv_cnt, cnt, i, j;
>>> +       u8 *rev_ksv_list;
>>> +
>>> +       if (!srm_data)
>>> +               return false;
>>> +
>>> +       mutex_lock(&srm_data->mutex);
>>> +       drm_hdcp_request_srm(drm_dev);
>>> +
>>> +       rev_ksv_cnt = srm_data->revoked_ksv_cnt;
>>> +       rev_ksv_list = srm_data->revoked_ksv_list;
>>> +
>>> +       /* If the Revoked ksv list is empty */
>>> +       if (!rev_ksv_cnt || !rev_ksv_list) {
>>> +               mutex_unlock(&srm_data->mutex);
>>> +               return false;
>>> +       }
>>> +
>>> +       for  (cnt = 0; cnt < ksv_count; cnt++) {
>>> +               rev_ksv_list = srm_data->revoked_ksv_list;
>>> +               for (i = 0; i < rev_ksv_cnt; i++) {
>>> +                       for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
>>> +                               if (ksvs[j] != rev_ksv_list[j]) {
>>> +                                       break;
>>> +                               } else if (j == (DRM_HDCP_KSV_LEN - 1)) {
>>> +                                       DRM_DEBUG("Revoked KSV is ");
>>> +                                       drm_hdcp_print_ksv(ksvs);
>>> +                                       mutex_unlock(&srm_data->mutex);
>>> +                                       return true;
>>> +                               }
>>> +                       /* Move the offset to next KSV in the revoked list */
>>> +                       rev_ksv_list += DRM_HDCP_KSV_LEN;
>>> +               }
>>> +
>>> +               /* Iterate to next ksv_offset */
>>> +               ksvs += DRM_HDCP_KSV_LEN;
>>> +       }
>>> +       mutex_unlock(&srm_data->mutex);
>>> +       return false;
>>> +}
>>> +EXPORT_SYMBOL_GPL(drm_hdcp_check_ksvs_revoked);
>>> +
>>> +int drm_setup_hdcp_srm(struct class *drm_class)
>>> +{
>>> +       srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
>>> +       if (!srm_data)
>>> +               return -ENOMEM;
>>> +       mutex_init(&srm_data->mutex);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +void drm_teardown_hdcp_srm(struct class *drm_class)
>>> +{
>>> +       if (srm_data) {
>>> +               kfree(srm_data->revoked_ksv_list);
>>> +               kfree(srm_data);
>>> +       }
>>> +}
>>> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
>>> index e19ac7ca602d..476a422414f6 100644
>>> --- a/drivers/gpu/drm/drm_internal.h
>>> +++ b/drivers/gpu/drm/drm_internal.h
>>> @@ -201,3 +201,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>>>  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
>>>                                 const struct drm_framebuffer *fb);
>>>  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
>>> +
>>> +/* drm_hdcp.c */
>>> +int drm_setup_hdcp_srm(struct class *drm_class);
>>> +void drm_teardown_hdcp_srm(struct class *drm_class);
>>> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
>>> index ecb7b33002bb..18b1ac442997 100644
>>> --- a/drivers/gpu/drm/drm_sysfs.c
>>> +++ b/drivers/gpu/drm/drm_sysfs.c
>>> @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
>>>         }
>>>
>>>         drm_class->devnode = drm_devnode;
>>> +       drm_setup_hdcp_srm(drm_class);
>>>         return 0;
>>>  }
>>>
>>> @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
>>>  {
>>>         if (IS_ERR_OR_NULL(drm_class))
>>>                 return;
>>> +       drm_teardown_hdcp_srm(drm_class);
>>>         class_remove_file(drm_class, &class_attr_version.attr);
>>>         class_destroy(drm_class);
>>>         drm_class = NULL;
>>> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
>>> index 1cc66df05a43..2f0335d0a50f 100644
>>> --- a/include/drm/drm_hdcp.h
>>> +++ b/include/drm/drm_hdcp.h
>>> @@ -265,4 +265,28 @@ void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
>>>         seq_num[2] = val;
>>>  }
>>>
>>> +#define DRM_HDCP_SRM_GEN1_MAX_BYTES            (5 * 1024)
>>> +#define DRM_HDCP_1_4_SRM_ID                    0x8
>>> +#define DRM_HDCP_SRM_ID_MASK                   (0xF << 4)
>>> +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE           3
>>> +#define DRM_HDCP_1_4_DCP_SIG_SIZE              40
>>> +#define DRM_HDCP_2_SRM_ID                      0x9
>>> +#define DRM_HDCP_2_INDICATOR                   0x1
>>> +#define DRM_HDCP_2_INDICATOR_MASK              0xF
>>> +#define DRM_HDCP_2_VRL_LENGTH_SIZE             3
>>> +#define DRM_HDCP_2_DCP_SIG_SIZE                        384
>>> +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ  4
>>> +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)    (((byte) & 0xC) >> 6)
>>> +
>>> +struct hdcp_srm_header {
>>> +       u8 srm_id;
>>> +       u8 reserved;
>>> +       __be16 srm_version;
>>> +       u8 srm_gen_no;
>>> +} __packed;
>>> +
>>> +struct drm_device;
>>> +
>>> +bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
>>> +                                u8 *ksvs, u32 ksv_count);
>>>  #endif
>>> --
>>> 2.19.1
>>>
>>> _______________________________________________
>>> dri-devel mailing list
>>> dri-devel@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2019-09-12 15:49 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-07 16:27 [PATCH v7 00/11] HDCP2.2 Phase II Ramalingam C
2019-05-07 16:27 ` [PATCH v7 01/11] drm: move content protection property to mode_config Ramalingam C
2019-05-07 16:27 ` [PATCH v7 02/11] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
2019-05-07 16:27 ` [PATCH v7 03/11] drm: generic fn converting be24 to cpu and vice versa Ramalingam C
2019-05-07 16:27 ` [PATCH v7 04/11] drm: revocation check at drm subsystem Ramalingam C
2019-07-04 10:53   ` Pekka Paalanen
2019-09-12  0:15   ` Harry Wentland
2019-09-12  1:14     ` Deucher, Alexander
2019-09-12  6:54     ` Ramalingam C
2019-09-12 15:49       ` Harry Wentland
2019-05-07 16:27 ` [PATCH v7 05/11] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
2019-05-07 16:27 ` [PATCH v7 06/11] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
2019-05-07 16:27 ` [PATCH v7 07/11] drm: Add Content protection type property Ramalingam C
2019-07-04 11:11   ` Pekka Paalanen
2019-07-04 10:36     ` Ramalingam C
2019-07-05 13:00       ` Pekka Paalanen
2019-07-05  6:33         ` Ramalingam C
2019-07-05 14:12           ` Pekka Paalanen
2019-05-07 16:27 ` [PATCH v7 08/11] drm/i915: Attach content " Ramalingam C
2019-05-07 16:27 ` [PATCH v7 09/11] drm: uevent for connector status change Ramalingam C
2019-05-10 12:12   ` Paul Kocialkowski
2019-05-10 14:54     ` Daniel Vetter
2019-05-13  9:02       ` Paul Kocialkowski
2019-05-13  9:34         ` Daniel Vetter
2019-05-13 10:11           ` Ser, Simon
2019-05-13 15:04             ` Daniel Vetter
2019-05-14  6:18               ` Ser, Simon
2019-05-13 17:14           ` Paul Kocialkowski
2019-05-14 11:09             ` Daniel Vetter
2019-05-14 14:12               ` Paul Kocialkowski
2019-05-14 14:28                 ` Daniel Vetter
2019-05-15  7:43                   ` Paul Kocialkowski
2019-05-15  7:48                     ` Daniel Vetter
2019-05-14  8:02           ` Pekka Paalanen
2019-05-14  8:18             ` Ser, Simon
2019-05-14 11:02               ` Daniel Vetter
2019-05-14 13:36                 ` Pekka Paalanen
2019-05-14 13:58                   ` Paul Kocialkowski
2019-05-14 14:34                   ` Daniel Vetter
2019-05-15  7:37                     ` Pekka Paalanen
2019-05-15  7:49                       ` Paul Kocialkowski
2019-05-15  8:24                       ` Daniel Vetter
2019-05-16  8:22                         ` Pekka Paalanen
2019-05-16 12:24                           ` Daniel Vetter
2019-05-17 10:08                             ` Pekka Paalanen
2019-05-20 16:11                               ` Daniel Vetter
2019-05-20 16:24                                 ` Paul Kocialkowski
2019-05-21  6:55                                 ` Pekka Paalanen
2019-05-21  7:52                                   ` Daniel Vetter
2019-05-21  9:01                                     ` Pekka Paalanen
2019-05-21  9:42                                       ` Daniel Vetter
2019-06-03  9:50                                     ` Michel Dänzer
2019-06-03 15:08                                       ` Daniel Vetter
2019-06-03 15:19                                         ` Ser, Simon
2019-06-04  7:06                                           ` Pekka Paalanen
2019-05-13 21:20     ` Lyude Paul
2019-05-14 11:12       ` Daniel Vetter
2019-07-04 11:12   ` Pekka Paalanen
2019-07-04 10:42     ` Ramalingam C
2019-07-05 13:36       ` Pekka Paalanen
2019-05-07 16:27 ` [PATCH v7 10/11] drm/hdcp: update content protection property with uevent Ramalingam C
2019-07-04 11:14   ` Pekka Paalanen
2019-07-04 11:11     ` Ramalingam C
2019-07-05 13:59       ` Pekka Paalanen
2019-07-04 23:51     ` Ramalingam C
2019-05-07 16:27 ` [PATCH v7 11/11] drm/i915: update the hdcp state " Ramalingam C
2019-05-07 16:45 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev9) Patchwork
2019-05-07 16:52 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-05-07 17:37 ` ✓ Fi.CI.BAT: success " Patchwork
2019-05-08  0:41 ` ✓ Fi.CI.IGT: " Patchwork

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.