* [PATCH v7 0/2] Pass down hot-plug CONNECTOR ID to user-space
@ 2026-02-17 19:00 Nicolas Frattaroli
2026-02-17 19:00 ` [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector Nicolas Frattaroli
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Nicolas Frattaroli @ 2026-02-17 19:00 UTC (permalink / raw)
To: Ville Syrjälä, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Louis Chauvet,
Haneen Mohammed, Melissa Wen, Daniel Stone, Ian Forbes,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, kernel, Nicolas Frattaroli, Marius Vlad
I will be taking over this series from Marius Vlad.
This series addresses a shortcoming whereby a hot plug event is sent
without it being passed the actual connector that caused it. This takes
into consideration both the polling path and the HPD (Hot Plug Detect)
path. It also adds support for the vkms driver (using ConfigFS) for
propagating the connector ID when changing the connector's status.
The motivation is that user-space applications such as Weston would
previously receive non-connector-specific hotplug events, and then have
to figure out themselves which connector needs to have a modeset
executed on. This notably did not work when the hotplug events came in
too fast, resulting in Weston missing an on-off-on transition of a
connector, seeing that its state was unchanged from "on" so can't be the
one that was hotplugged, and skipping reinitialising it as it looks
through the other connectors that could've caused it.
The real world implication is that on setups with slightly sketchy HDMI
connections, a brief flicker in the HPD signal could result in video
output bidding farewell entirely until a manual proper re-plug was
performed.
By sending connector specific hotplug events, this ambiguity is
resolved without any change to the user-space API.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Changes in v7:
- Drop the two vkms patches, as I don't want them to be blocked on
review. I still think they're correct, but they're not essential and
don't need to block this series.
- Link to v6: https://lore.kernel.org/r/20260123-hot-plug-passup-v6-0-aaaf61d960bb@collabora.com
Changes in v6:
- Rewrote cover letter to explain the motivation for this series more
plainly
- Rename "status_changed" to "pending_hp"
- Set "pending_hp" in the existing path that would also affect
epoch_counter
- No longer set the boolean in drm_helper_probe_single_connector_modes,
as it does not appear to be necessary
- Reword commits to better justify the changes
- Link to v5: https://lore.kernel.org/r/20251111162338.15141-1-marius.vlad@collabora.com/
Changes in v5:
- vkms: add support for sending the CONNECTOR ID when hot-plugging through
ConfigFS - as reported by Louis, vkms can now make use of ConfigFS to
simulate connector status.
- vkms: add a small change to ignore previous/old drm connector status
when sending out hot-plug uevent.
- Link to v4: https://lore.kernel.org/r/20251103174558.7709-1-marius.vlad@collabora.com/
Changes in v4:
- removed the "This patch" bit - Dmitry
- added a short note when the flag is set and cleared - Dmitry
- address double dead-locking detected - kbot: https://lore.kernel.org/dri-devel/202509251410.fdfbcac3-lkp@intel.com/
- virtual connectors do not seem have any kind of hotplug - added
polling in vkms - as noted by Ian
- Link to v3: https://lore.kernel.org/r/20250923083636.4749-1-marius.vlad@collabora.com/
Changes in v3:
- Address comments from Dmitry:
- guard connector status write with mode_config.mutex
- avoid setting up the connector status and immediately unset it. Do the
unset in drm_kms_helper_hotplug_event/drm_kms_helper_connector_hotplug_event
- Link to v2: https://lore.kernel.org/r/20250729165708.9947-1-marius.vlad@collabora.com/
Changes in v2:
- Address comments from Daniel:
- split patch into 2, one that introduces a bool to track connector
connection status change and a patch that uses that to be able to send
hot plug events with the proper CONNECTOR ID to udev and further pass
that down to user-space
- nuke out mutex when iterating connector list
- fix typo
- Link to v1: https://lore.kernel.org/r/20250627131751.2004-1-marius.vlad@collabora.com/
Marius Vlad (4):
drm: Introduce a new connector status
drm: Propagate connector status change
vkms: Do not send hotplug events for same connector status
vkms: Pass the vkms connector as opposed to the vkms device
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_probe_helper.c | 39 +++++++++++++++++++++++----
drivers/gpu/drm/drm_sysfs.c | 1 +
drivers/gpu/drm/vkms/vkms_configfs.c | 12 +++++++--
drivers/gpu/drm/vkms/vkms_connector.c | 6 ++---
drivers/gpu/drm/vkms/vkms_connector.h | 4 +--
include/drm/drm_connector.h | 3 +++
7 files changed, 54 insertions(+), 12 deletions(-)
--
2.47.2
---
Marius Vlad (2):
drm: Introduce pending_hp to drm_connector
drm: Send per-connector hotplug events
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_probe_helper.c | 39 +++++++++++++++++++++++++++++++++-----
drivers/gpu/drm/drm_sysfs.c | 2 ++
include/drm/drm_connector.h | 3 +++
4 files changed, 40 insertions(+), 5 deletions(-)
---
base-commit: e66c64e4f12e55cad35c680f1e328a7c7ee92cab
change-id: 20260121-hot-plug-passup-f8ed03f7c202
Best regards,
--
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector
2026-02-17 19:00 [PATCH v7 0/2] Pass down hot-plug CONNECTOR ID to user-space Nicolas Frattaroli
@ 2026-02-17 19:00 ` Nicolas Frattaroli
2026-02-17 20:43 ` Claude review: " Claude Code Review Bot
2026-02-17 19:00 ` [PATCH v7 2/2] drm: Send per-connector hotplug events Nicolas Frattaroli
2026-02-17 20:43 ` Claude review: Pass down hot-plug CONNECTOR ID to user-space Claude Code Review Bot
2 siblings, 1 reply; 6+ messages in thread
From: Nicolas Frattaroli @ 2026-02-17 19:00 UTC (permalink / raw)
To: Ville Syrjälä, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Louis Chauvet,
Haneen Mohammed, Melissa Wen, Daniel Stone, Ian Forbes,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, kernel, Nicolas Frattaroli, Marius Vlad
From: Marius Vlad <marius.vlad@collabora.com>
Introduce a new boolean variable used to track whether a connector has
changed its status since the last hotplug event for it was sent to
userspace. It is used by both the polling and HPD path.
A subsequent change will make use of this new member to propagate
per-connector udev hotplug events to userspace, rather than sending a
global hotplug event.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_probe_helper.c | 17 +++++++++++++++++
drivers/gpu/drm/drm_sysfs.c | 2 ++
include/drm/drm_connector.h | 3 +++
4 files changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index aec05adbc889..67497d0e41f1 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -274,6 +274,7 @@ static int drm_connector_init_only(struct drm_device *dev,
/* provide ddc symlink in sysfs */
connector->ddc = ddc;
+ connector->pending_hp = false;
INIT_LIST_HEAD(&connector->head);
INIT_LIST_HEAD(&connector->global_connector_list_entry);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index d4dc8cb45bce..f8cbd6713960 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -732,6 +732,17 @@ EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
*/
void drm_kms_helper_hotplug_event(struct drm_device *dev)
{
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+
+ mutex_lock(&dev->mode_config.mutex);
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ connector->pending_hp = false;
+ }
+ drm_connector_list_iter_end(&conn_iter);
+ mutex_unlock(&dev->mode_config.mutex);
+
drm_sysfs_hotplug_event(dev);
drm_client_dev_hotplug(dev);
}
@@ -748,6 +759,10 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
+ mutex_lock(&dev->mode_config.mutex);
+ connector->pending_hp = false;
+ mutex_unlock(&dev->mode_config.mutex);
+
drm_sysfs_connector_hotplug_event(connector);
drm_client_dev_hotplug(dev);
}
@@ -837,6 +852,7 @@ static void output_poll_execute(struct work_struct *work)
old_epoch_counter, connector->epoch_counter);
changed = true;
+ connector->pending_hp = true;
}
}
drm_connector_list_iter_end(&conn_iter);
@@ -1101,6 +1117,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
first_changed_connector = connector;
}
+ connector->pending_hp = true;
changed++;
}
}
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index b01ffa4d6509..53076c2afd12 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -216,6 +216,8 @@ static ssize_t status_store(struct device *device,
connector->base.id, connector->name,
old_force, connector->force);
+ connector->pending_hp = true;
+
connector->funcs->fill_modes(connector,
dev->mode_config.max_width,
dev->mode_config.max_height);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index c18be8c19de0..cd9787c54425 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2191,6 +2191,9 @@ struct drm_connector {
/** @force: a DRM_FORCE_<foo> state for forced mode sets */
enum drm_connector_force force;
+ /** @pending_hp: true if connector changed since last hotplug event */
+ bool pending_hp;
+
/**
* @edid_override: Override EDID set via debugfs.
*
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Claude review: drm: Introduce pending_hp to drm_connector
2026-02-17 19:00 ` [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector Nicolas Frattaroli
@ 2026-02-17 20:43 ` Claude Code Review Bot
0 siblings, 0 replies; 6+ messages in thread
From: Claude Code Review Bot @ 2026-02-17 20:43 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
This patch adds the `pending_hp` boolean to `drm_connector`, initializes it to false, and sets it to true wherever a connector status change is detected: the polling path, the HPD IRQ path, and the sysfs `status_store` path. It also clears `pending_hp` in both `drm_kms_helper_hotplug_event` and `drm_kms_helper_connector_hotplug_event` so it is reset when the event is actually sent.
> + connector->pending_hp = false;
Initialization in `drm_connector_init_only` is correct; `drm_connector` is often kzalloc'd so this would be zero anyway, but explicit initialization is fine for documentation purposes.
> + mutex_lock(&dev->mode_config.mutex);
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + connector->pending_hp = false;
> + }
> + drm_connector_list_iter_end(&conn_iter);
> + mutex_unlock(&dev->mode_config.mutex);
Clearing all connectors' `pending_hp` in `drm_kms_helper_hotplug_event` is appropriate -- this function sends a global event, so all pending per-connector notifications are subsumed.
> + mutex_lock(&dev->mode_config.mutex);
> + connector->pending_hp = false;
> + mutex_unlock(&dev->mode_config.mutex);
Clearing `pending_hp` in `drm_kms_helper_connector_hotplug_event` under the mutex is consistent.
> connector->pending_hp = true;
The `status_store` path in `drm_sysfs.c` sets `pending_hp = true` under `mode_config.mutex`, which is correct. However, `status_store` does not send a hotplug event itself -- it calls `fill_modes` and returns. Who consumes this `pending_hp`? Looking at the code, if polling is enabled, the next poll cycle will pick it up because `fill_modes` (which calls `drm_helper_probe_single_connector_modes`) will set `delayed_event = true` when it detects the status change, which schedules the poll worker. But as discussed in the patch 2 review, the `delayed_event` path has an issue with the new code.
No other issues with patch 1.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v7 2/2] drm: Send per-connector hotplug events
2026-02-17 19:00 [PATCH v7 0/2] Pass down hot-plug CONNECTOR ID to user-space Nicolas Frattaroli
2026-02-17 19:00 ` [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector Nicolas Frattaroli
@ 2026-02-17 19:00 ` Nicolas Frattaroli
2026-02-17 20:43 ` Claude review: " Claude Code Review Bot
2026-02-17 20:43 ` Claude review: Pass down hot-plug CONNECTOR ID to user-space Claude Code Review Bot
2 siblings, 1 reply; 6+ messages in thread
From: Nicolas Frattaroli @ 2026-02-17 19:00 UTC (permalink / raw)
To: Ville Syrjälä, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Louis Chauvet,
Haneen Mohammed, Melissa Wen, Daniel Stone, Ian Forbes,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, kernel, Nicolas Frattaroli, Marius Vlad
From: Marius Vlad <marius.vlad@collabora.com>
Use the new pending_hp member of drm_connector to always send
per-connector hotplug events for those connectors that need it, rather
than sending a global event, or only an event for one connector.
On the HPD (Hot Plug Detect) path this change notifies all connectors,
rather than just first changed connector.
The polling path is changed to no longer send a connector-less hotplug
event, but similarly send a hotplug event for each changed connector.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/drm_probe_helper.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index f8cbd6713960..5c39f27ada1d 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -860,8 +860,14 @@ static void output_poll_execute(struct work_struct *work)
mutex_unlock(&dev->mode_config.mutex);
out:
- if (changed)
- drm_kms_helper_hotplug_event(dev);
+ if (changed) {
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ if (connector->pending_hp)
+ drm_kms_helper_connector_hotplug_event(connector);
+ }
+ drm_connector_list_iter_end(&conn_iter);
+ }
if (repoll)
schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
@@ -1124,10 +1130,16 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
drm_connector_list_iter_end(&conn_iter);
mutex_unlock(&dev->mode_config.mutex);
- if (changed == 1)
+ if (changed == 1) {
drm_kms_helper_connector_hotplug_event(first_changed_connector);
- else if (changed > 0)
- drm_kms_helper_hotplug_event(dev);
+ } else if (changed > 0) {
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ if (connector->pending_hp)
+ drm_kms_helper_connector_hotplug_event(connector);
+ }
+ drm_connector_list_iter_end(&conn_iter);
+ }
if (first_changed_connector)
drm_connector_put(first_changed_connector);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Claude review: drm: Send per-connector hotplug events
2026-02-17 19:00 ` [PATCH v7 2/2] drm: Send per-connector hotplug events Nicolas Frattaroli
@ 2026-02-17 20:43 ` Claude Code Review Bot
0 siblings, 0 replies; 6+ messages in thread
From: Claude Code Review Bot @ 2026-02-17 20:43 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
This patch converts both the polling and HPD paths to send per-connector hotplug events instead of global ones.
**Bug: `delayed_event` path drops hotplug notifications**
> - if (changed)
> - drm_kms_helper_hotplug_event(dev);
> + if (changed) {
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + if (connector->pending_hp)
> + drm_kms_helper_connector_hotplug_event(connector);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> + }
In `output_poll_execute`, `changed` can become true via two paths: (1) the connector iteration loop detects an epoch counter change and sets both `changed = true` and `connector->pending_hp = true`, or (2) `delayed_event` was already set at the top of the function:
```c
changed = dev->mode_config.delayed_event;
dev->mode_config.delayed_event = false;
```
The `delayed_event` path is triggered from `drm_helper_probe_single_connector_modes` when userspace probes a connector and finds its status changed. In this case, `changed` is true but no connector has `pending_hp` set, so the new loop will iterate all connectors, find none with `pending_hp`, and send no hotplug event at all. The old code called `drm_kms_helper_hotplug_event(dev)` which would have sent a global uevent.
This is a regression: connector status changes detected through userspace-initiated probing will no longer generate hotplug events.
One possible fix: set `pending_hp = true` on the connector in `drm_helper_probe_single_connector_modes` where `delayed_event` is set. Alternatively, fall back to the global `drm_kms_helper_hotplug_event(dev)` when `changed` is true but the connector loop sends zero events.
**Performance: `drm_client_dev_hotplug` called per-connector**
Each call to `drm_kms_helper_connector_hotplug_event` calls `drm_client_dev_hotplug(dev)`, which iterates all DRM clients and invokes their hotplug callback. When multiple connectors change simultaneously, this means the client hotplug callbacks (e.g., fbdev emulation) run N times instead of once. For the common case of a dock with multiple outputs, this is redundant work. It is not a correctness bug, but it may be worth noting.
**HPD path: the `changed == 1` fast path**
> - if (changed == 1)
> + if (changed == 1) {
> drm_kms_helper_connector_hotplug_event(first_changed_connector);
> - else if (changed > 0)
> - drm_kms_helper_hotplug_event(dev);
> + } else if (changed > 0) {
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + if (connector->pending_hp)
> + drm_kms_helper_connector_hotplug_event(connector);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> + }
The HPD path in `drm_helper_hpd_irq_event` looks correct. When `changed == 1`, it uses `first_changed_connector` directly (which also has `pending_hp` set, so `drm_kms_helper_connector_hotplug_event` will clear it). When `changed > 1`, it iterates and sends individual events. The `pending_hp` flag was set under `mode_config.mutex` and read here after the mutex was dropped -- this is fine because this is single-threaded within this function and the writes are already committed.
**Reading `pending_hp` without the mutex**
In both the polling and HPD paths, `connector->pending_hp` is read without holding `mode_config.mutex`. The write happened under the mutex and the read happens on the same thread after the mutex was dropped, so the value will be visible. Concurrent writers (e.g., `status_store` on another CPU) could theoretically set `pending_hp` on a connector between the mutex drop and the iteration, but this is benign -- it just means an extra connector event may fire, which is harmless.
No other issues found in this patch beyond the `delayed_event` bug described above.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 6+ messages in thread
* Claude review: Pass down hot-plug CONNECTOR ID to user-space
2026-02-17 19:00 [PATCH v7 0/2] Pass down hot-plug CONNECTOR ID to user-space Nicolas Frattaroli
2026-02-17 19:00 ` [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector Nicolas Frattaroli
2026-02-17 19:00 ` [PATCH v7 2/2] drm: Send per-connector hotplug events Nicolas Frattaroli
@ 2026-02-17 20:43 ` Claude Code Review Bot
2 siblings, 0 replies; 6+ messages in thread
From: Claude Code Review Bot @ 2026-02-17 20:43 UTC (permalink / raw)
To: dri-devel-reviews
Overall Series Review
Subject: Pass down hot-plug CONNECTOR ID to user-space
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Patches: 3
Reviewed: 2026-02-18T06:43:45.823156
---
This two-patch series adds per-connector hotplug event reporting to the DRM subsystem. Instead of sending a single global hotplug uevent (which forces userspace to re-probe all connectors), it sends individual uevents identifying the specific connector(s) that changed. The motivation is well-described: compositors like Weston can miss rapid on-off-on transitions when they have to guess which connector caused the event.
The approach is straightforward: patch 1 adds a `pending_hp` boolean to `drm_connector` that tracks whether a connector has a status change pending notification, and patch 2 converts the polling and HPD paths to iterate over connectors with `pending_hp` set and send individual events for each.
There is one bug in the series: the `delayed_event` path in `output_poll_execute` sets `changed = true` without any connector having `pending_hp` set, so the new connector-iterating loop will silently drop the hotplug notification. This is a functional regression. There is also a performance concern around `drm_client_dev_hotplug()` being invoked N times instead of once when N connectors change simultaneously.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-17 20:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-17 19:00 [PATCH v7 0/2] Pass down hot-plug CONNECTOR ID to user-space Nicolas Frattaroli
2026-02-17 19:00 ` [PATCH v7 1/2] drm: Introduce pending_hp to drm_connector Nicolas Frattaroli
2026-02-17 20:43 ` Claude review: " Claude Code Review Bot
2026-02-17 19:00 ` [PATCH v7 2/2] drm: Send per-connector hotplug events Nicolas Frattaroli
2026-02-17 20:43 ` Claude review: " Claude Code Review Bot
2026-02-17 20:43 ` Claude review: Pass down hot-plug CONNECTOR ID to user-space Claude Code Review Bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox