Hi, Resending this with the right CC. Also changed my mind in the meantime and my latest proposal is at: https://lists.freedesktop.org/archives/dri-devel/2019-May/217442.html On Fri, 2019-05-10 at 10:06 +0200, Daniel Vetter wrote: > On Fri, May 10, 2019 at 10:01 AM Paul Kocialkowski > <paul.kocialkowski@xxxxxxxxxxx> wrote: > > Hi, > > > > On Fri, 2019-05-10 at 09:56 +0200, Daniel Vetter wrote: > > > On Fri, May 10, 2019 at 9:42 AM Paul Kocialkowski > > > <paul.kocialkowski@xxxxxxxxxxx> wrote: > > > > Hi, > > > > > > > > So this thread has drifted off from IGT to a general DRM improvement, > > > > so renaming the thread and adding some CCs. > > > > > > > > It's about avoiding full reprobes (which may include slow EDID reads, > > > > etc) when a connector change was detected, by providing information > > > > about the connector and the new state to userspace. This way, userspace > > > > can reprobe the changed connector alone (or not reprobe at all in case > > > > of a disconnect). > > > > > > > > It feels like there is growing temptation to have per-driver hacks to > > > > avoid full reprobes when the driver knows that nothing changed, but I > > > > think it makes more sense to fixup the uevent we send to make sure that > > > > userspace knows what to probe exactly. > > > > > > > > On Fri, 2019-05-10 at 06:55 +0000, Ser, Simon wrote: > > > > > On Thu, 2019-05-09 at 11:56 -0400, Lyude Paul wrote: > > > > > > I'm in support of this as well, we really could use better hotplug events. > > > > > > Feel free to cc patches to me for review :) > > > > > > > > > > Any idea(s) how the API would look like? > > > > > > > > From a quick chat on IRC yesterday, it seems that just adding entries > > > > to the uevent would do and would be backwards-compatible (well, > > > > provided that the userspace uevent parsers will not fail if something > > > > extra to "HOTPLUG=1" is provided). > > > > > > > > Currently, the notification is sent globally at each round of detected > > > > connector change (which may concern multiple connectors). So I think we > > > > should just list the connectors that changed in the uevent and their > > > > new state. So my proposal here is something like: > > > > > > > > HOTPLUG=1 > > > > CONNECTOR_ID=47 > > > > STATUS=Connected > > > > CONNECTOR_ID=48 > > > > STATUS=Disconnected > > > > > > > > Where each STATUS entry would refer to the previous CONNECTOR_ID entry. > > > > > > > > What do you think? > > > > > > We have the better uevent already, all we need is wiring up, lots of > > > code, and userspace for it. Ok, not quite, patch is still in flight: > > > > > > https://patchwork.kernel.org/patch/10906677/ > > > > Ah great to see that! > > > > > The real trouble isn't the new event, but making sure it goes out for > > > anything that might have changed. There's a lot more connector status > > > than just the STATUS property. > > > > Why though? I thought this was a hotplug interface, not a general > > "something-about-the-connector-changed". To me, hotplug is pretty > > binary: either it's connected, either it's not. > > > > Do we already send out hotplug uevents when something else than the > > status changed? If so, maybe we should consider handling the rest > > separately from hotplug. > > We have plenty of bugs around "changed screen over s/r and no output". > Imo if we rework hotplug, we should get all the mistakes right. I think suspend/resume is one specific case where hotplug just can't be detected by the driver. I think one solution to that would be to always issue a hotplug even for all connectors on resume. I don't really see how we could do better than that anyway. > > Looking at drm_probe_helper.c's output_poll_execute, my understanding > > is that drm_kms_helper_hotplug_event is only called when the status > > changed, not other props. > > Yeah, and that's why userspace has to reprobe all the time. I'm a bit confused then, how can userspace be notified that something else than the connected status changed if that's the only case where a uevent is issued? If something else changed that needs userspace attention, maybe we could send out a uevent with the CONNECTOR_ID but without the STATUS part so that userspace has to reprobe that connector to know what's what. > One idea > that we floated around is to have an epoche counter, which changes > every time anything with the connector changes wrt hotplug related > state (edid, sink id, whatever). The more specific hotplug uevent > would then give you an event on that epoch counter, so userspace knows > it needs to reprobe that specific connector for all the new state. That would work, but I find that a bit overkill for the issue at hand. At least I'm not convinced that something simpler would be a bad fit. The idea of adding STATUS to the uevent is just to provide a fast-path to avoid reprobe for the basic unplug case. If it's a plug or something more complex that has happened, then I think userspace should do a reprobe of the connector anyway. If we properly notify userspace only when something changed, I don't think we need an epoch counter in particular. Cheers, Paul > -Daniel > > > > Cheers, > > > > Paul > > > > > -Daniel > > > > > > > Cheers, > > > > > > > > Paul > > > > > > > > > > On Thu, 2019-05-09 at 14:24 +0200, Paul Kocialkowski wrote: > > > > > > > Hi, > > > > > > > > > > > > > > On Thu, 2019-05-09 at 15:08 +0300, Imre Deak wrote: > > > > > > > > On Thu, May 09, 2019 at 09:25:41AM +0200, Paul Kocialkowski wrote: > > > > > > > > > On Wed, 2019-05-08 at 11:24 +0300, Imre Deak wrote: > > > > > > > > > > After scheduling an HPD toggle event, make sure that we wait for the > > > > > > > > > > hotplug event for each connector that may be sent by the driver. > > > > > > > > > > > > > > > > > > > > Depending on the scheduling there could be 1 event or as many events > > > > > > > > > > as > > > > > > > > > > connectors we scheduled an HPD toggle event on, depending on the > > > > > > > > > > timing. > > > > > > > > > > So if we don't yet see the expected connector state on a given > > > > > > > > > > connector > > > > > > > > > > try to wait for an additional hotplug event and reprobe/recheck the > > > > > > > > > > state. > > > > > > > > > > > > > > > > > > This changes makes good sense to me, so: > > > > > > > > > > > > > > > > > > Reviewed-By: Paul Kocialkowski <paul.kocialkowski@xxxxxxxxxxx> > > > > > > > > > > > > > > > > > > And it brings back hard feelings about the hotplug interface we have > > > > > > > > > today... > > > > > > > > > > > > > > > > Yes, I was surprised too not find any way to identify which connector(s) > > > > > > > > the hotplug event is associated with. We discussed with Ville if it'd > > > > > > > > make sense to add a connector ID map to the uevent, but not sure if it'd > > > > > > > > be useful outside of this test, or how that would align with Chris' > > > > > > > > connector probe state generation idea. > > > > > > > > > > > > > > Either way, I'm definitely in favor of having something more reliable > > > > > > > to expose to userspace. Having something to correlate each event to one > > > > > > > (or more) connector(s) sounds good to me. > > > > > > > > > > > > > > And I think there is a general need for this, it's not just IGT. > > > > > > > > > > > > > > Currently, every userspace application using DRM has to do a full > > > > > > > reprobe once a hotplug uevent is received, which is really not optimal. > > > > > > > If an entry identifying the connector was also provided, userspace > > > > > > > could only reprobe that connector. The step after that would be having > > > > > > > the indication of whether the connector was connected or disconnected > > > > > > > directly in uevent too, so that no probing needs to be done at all when > > > > > > > a given connector is disconnected. > > > > > > > > > > > > > > Anyway, if you're interested in the idea and that Ville and Chris are > > > > > > > in favor, I really think it would be worth fixing that. And we'd only > > > > > > > be adding new elements to uevent, so that would stay backward- > > > > > > > compatible too. > > > > > > > > > > > > > > Cheers, > > > > > > > > > > > > > > Paul > > > > > > > > > > > > > > > > > v2: > > > > > > > > > > - s/igt_assert(x >= y)/igt_assert_lte(y, x)/ to see the actual limits > > > > > > > > > > in > > > > > > > > > > the debugging output. (Lyude) > > > > > > > > > > > > > > > > > > > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110534 > > > > > > > > > > Cc: Paul Kocialkowski <paul.kocialkowski@xxxxxxxxxxx> > > > > > > > > > > Cc: Lyude Paul <lyude@xxxxxxxxxx> > > > > > > > > > > Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> > > > > > > > > > > Reviewed-by: Lyude Paul <lyude@xxxxxxxxxx> > > > > > > > > > > --- > > > > > > > > > > tests/kms_chamelium.c | 45 +++++++++++++++++++++++++++++++++++++----- > > > > > > > > > > - > > > > > > > > > > 1 file changed, 39 insertions(+), 6 deletions(-) > > > > > > > > > > > > > > > > > > > > diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c > > > > > > > > > > index 714e5e06..502f1efa 100644 > > > > > > > > > > --- a/tests/kms_chamelium.c > > > > > > > > > > +++ b/tests/kms_chamelium.c > > > > > > > > > > @@ -284,11 +284,32 @@ test_edid_read(data_t *data, struct > > > > > > > > > > chamelium_port *port, > > > > > > > > > > drmModeFreeConnector(connector); > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > +/* Wait for hotplug and return the remaining time left from timeout > > > > > > > > > > */ > > > > > > > > > > +static bool wait_for_hotplug(struct udev_monitor *mon, int *timeout) > > > > > > > > > > +{ > > > > > > > > > > + struct timespec start, end; > > > > > > > > > > + int elapsed; > > > > > > > > > > + bool detected; > > > > > > > > > > + > > > > > > > > > > + igt_assert_eq(igt_gettime(&start), 0); > > > > > > > > > > + detected = igt_hotplug_detected(mon, *timeout); > > > > > > > > > > + igt_assert_eq(igt_gettime(&end), 0); > > > > > > > > > > + > > > > > > > > > > + elapsed = igt_time_elapsed(&start, &end); > > > > > > > > > > + igt_assert_lte(0, elapsed); > > > > > > > > > > + *timeout = max(0, *timeout - elapsed); > > > > > > > > > > + > > > > > > > > > > + return detected; > > > > > > > > > > +} > > > > > > > > > > + > > > > > > > > > > static void > > > > > > > > > > try_suspend_resume_hpd(data_t *data, struct chamelium_port *port, > > > > > > > > > > enum igt_suspend_state state, enum > > > > > > > > > > igt_suspend_test test, > > > > > > > > > > struct udev_monitor *mon, bool connected) > > > > > > > > > > { > > > > > > > > > > + drmModeConnection target_state = connected ? > > > > > > > > > > DRM_MODE_DISCONNECTED : > > > > > > > > > > + DRM_MODE_CONNECTE > > > > > > > > > > D; > > > > > > > > > > + int timeout = HOTPLUG_TIMEOUT; > > > > > > > > > > int delay; > > > > > > > > > > int p; > > > > > > > > > > > > > > > > > > > > @@ -310,17 +331,29 @@ try_suspend_resume_hpd(data_t *data, struct > > > > > > > > > > chamelium_port *port, > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > igt_system_suspend_autoresume(state, test); > > > > > > > > > > + igt_assert(wait_for_hotplug(mon, &timeout)); > > > > > > > > > > > > > > > > > > > > - igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT)); > > > > > > > > > > if (port) { > > > > > > > > > > - igt_assert_eq(reprobe_connector(data, port), connected > > > > > > > > > > ? > > > > > > > > > > - DRM_MODE_DISCONNECTED : > > > > > > > > > > DRM_MODE_CONNECTED); > > > > > > > > > > + igt_assert_eq(reprobe_connector(data, port), > > > > > > > > > > target_state); > > > > > > > > > > } else { > > > > > > > > > > for (p = 0; p < data->port_count; p++) { > > > > > > > > > > + drmModeConnection current_state; > > > > > > > > > > + > > > > > > > > > > port = data->ports[p]; > > > > > > > > > > - igt_assert_eq(reprobe_connector(data, port), > > > > > > > > > > connected ? > > > > > > > > > > - DRM_MODE_DISCONNECTED : > > > > > > > > > > - DRM_MODE_CONNECTED); > > > > > > > > > > + /* > > > > > > > > > > + * There could be as many hotplug events sent > > > > > > > > > > by > > > > > > > > > > + * driver as connectors we scheduled an HPD > > > > > > > > > > toggle on > > > > > > > > > > + * above, depending on timing. So if we're not > > > > > > > > > > seeing > > > > > > > > > > + * the expected connector state try to wait > > > > > > > > > > for an HPD > > > > > > > > > > + * event for each connector/port. > > > > > > > > > > + */ > > > > > > > > > > + current_state = reprobe_connector(data, port); > > > > > > > > > > + if (p > 0 && current_state != target_state) { > > > > > > > > > > + igt_assert(wait_for_hotplug(mon, > > > > > > > > > > &timeout)); > > > > > > > > > > + current_state = > > > > > > > > > > reprobe_connector(data, port); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + igt_assert_eq(current_state, target_state); > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > port = NULL; > > > > > > > > > -- > > > > > > > > > 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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel