All of lore.kernel.org
 help / color / mirror / Atom feed
* Regression: DDC I2C Display Freezing for internal displays
@ 2025-04-22 19:44 Felix Richter
  2025-07-17 19:42 ` Felix Richter
  0 siblings, 1 reply; 9+ messages in thread
From: Felix Richter @ 2025-04-22 19:44 UTC (permalink / raw)
  To: Hamza Mahfooz, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 5245 bytes --]

Hi,

it has been quite at while since I first started experiencing this 
particular bug I am about to describe. Suffice it to say during my 
Easter holiday I finally had the time to dig into it. It all started 
with an update of linux LTS from 6.6 to 6.12.

I am a user of the sway tiling window manager and have written a small 
utility to manage my display configuration across different setups. With 
the added twist that I wrote some code to determine which monitor inputs 
is currently in use using the monitor command interface. Anyway the 
interesting detail here is that, starting with kernel 6.12 I started 
running into the following problem. With my display management daemon 
running and attaching my Laptop to an external display my internal 
display would just freeze with no way to bring it back apart from power 
cycling the entire device. When my management daemon was not running 
this would not happen, I would then need to manually configure my 
display setup. Further investigation into the what is triggering the 
display freeze lead me into the part of the code where I am enumerating 
attached displays and am trying to match `i2c` devices to their 
corresponding display.

To get more specific the procedure is as follows, using udev enumerate 
all `i2c` busses and filter them base on some heuristics like device 
name and devices with parent devices drm / graphics device. Sadly this 
is not quite enough to already match an `i2c` command interface to the 
corresponding monitor, in many cases it is required to manually read the 
EDID information via the i2c interface and compare it to the known 
attached displays to get the match. And this is where the trigger for 
the display freeze is to be found.

Here is the output when scanning sysfs for my internal laptop display:
```
# ls -al 
/sys/devices/pci0000:00/0000:00:08.1/0000:04:00.0/drm/card1/card1-eDP-1
total 0
drwxr-xr-x  6 root root    0 22. Apr 18:07 .
drwxr-xr-x 11 root root    0 22. Apr 18:07 ..
drwxr-xr-x  3 root root    0 22. Apr 18:07 amdgpu_bl1
-r--r--r--  1 root root 4096 22. Apr 18:07 connector_id
lrwxrwxrwx  1 root root    0 22. Apr 18:07 ddc -> ../../../i2c-3
lrwxrwxrwx  1 root root    0 22. Apr 18:07 device -> ../../card1
-r--r--r--  1 root root 4096 22. Apr 18:07 dpms
drwxr-xr-x  3 root root    0 22. Apr 18:07 drm_dp_aux0
-r--r--r--  1 root root    0 22. Apr 18:07 edid
-r--r--r--  1 root root 4096 22. Apr 18:07 enabled
drwxr-xr-x  4 root root    0 22. Apr 18:07 i2c-11
-r--r--r--  1 root root 4096 22. Apr 18:07 modes
drwxr-xr-x  2 root root    0 22. Apr 18:07 power
-rw-r--r--  1 root root 4096 22. Apr 18:07 status
lrwxrwxrwx  1 root root    0 22. Apr 18:07 subsystem -> 
../../../../../../../class/drm
-rw-r--r--  1 root root 4096 22. Apr 18:07 uevent
```

As can be seen there are two i2c devices present, i2c-3 (as ddc symlink) 
and i2c-11. Now from the perspective of udev i2c-11 has the parent set 
to card1-eDP-1 while i2c-3 has the parent set to the drm device itself. 
More importantly I can not rule out i2c-3 as a valid command interface 
because in some cases valid command channels are never assigned to the 
corresponding display output directly but only live directly on the drm 
device, this is especially true when monitors are not attached directly 
but via a docking station. So I do have to look at each i2c device on 
its own. The freeze is trigged by trying to read edid from i2c-3: This 
is the code snipped I used to trigger the bug: 
https://github.com/ju6ge/libmonitor/blob/918b2543eafb96aca29f66debc70fd18fa21ee11/examples/via-i2c-dev.rs 
(adjusted target i2c interface accordingly). To be absolutely clear this 
is not the i2c device that is expected to work in every case of trying 
this with kernel 6.6 to 6.12 I get the following error message: 
DdcError(CommunicationError(ReceiveError(EIO: I/O error))). That is 
expected internal laptop displays do not support the command interface 
in most cases anyway. But what I do not expect to happen is that my 
Laptop screen freezes! And since this did not happen with kernel 6.6 but 
started happening with 6.12 this seems to be a software issue and with 
that a regression!

Next I bisected the kernel from 6.6 to 6.12 to determine when this 
regression was introduced. I attached the full bisect log to the email ;)

The offending commit seems to be:

[58a261bfc96763a851cb48b203ed57da37e157b8] drm/amd/display: use a more 
lax vblank enable policy for older ASICs

Since this is quite a small commit I validated this by reverting the 
changes on a newer kernel version (patch attached as well). Testing 
actually shows that reverting the change resolves the screen freezing 
behavior for me.

Now I am not deep enough into graphics drivers to claim that just 
reverting the commit should be considered a valid fix. Just that the 
change is definitely responsible for the screen freezing now as apposed 
to before.

So what should be done here? I can validate any other suggested fixes 
against my setup or provide more information if need be.

Kind regards,
Felix Richter

#regzbot introduced: v6.6..v6.12

[-- Attachment #1.1.2: bisect.log --]
[-- Type: text/x-log, Size: 3284 bytes --]

git bisect start
# Status: warte auf guten und schlechten Commit
# good: [ffc253263a1375a65fa6c9f62a893e9767fbebfa] Linux 6.6
git bisect good ffc253263a1375a65fa6c9f62a893e9767fbebfa
# bad: [adc218676eef25575469234709c2d87185ca223a] Linux 6.12
git bisect bad adc218676eef25575469234709c2d87185ca223a
# good: [7ee04901215b3cab8fa35aa5bf4692d7aa312e36] Merge tag 'drm-next-2024-03-22' of https://gitlab.freedesktop.org/drm/kernel
git bisect good 7ee04901215b3cab8fa35aa5bf4692d7aa312e36
# good: [280e36f0d5b997173d014c07484c03a7f7750668] nsfs: use cleanup guard
git bisect good 280e36f0d5b997173d014c07484c03a7f7750668
# good: [26bb0d3f38a764b743a3ad5c8b6e5b5044d7ceb4] Merge tag 'for-6.12/block-20240913' of git://git.kernel.dk/linux
git bisect good 26bb0d3f38a764b743a3ad5c8b6e5b5044d7ceb4
# bad: [431844b65f4c1b988ccd886f2ed29c138f7bb262] sched_ext: Provide a sysfs enable_seq counter
git bisect bad 431844b65f4c1b988ccd886f2ed29c138f7bb262
# good: [3a7101e9b27fe97240c2fd430c71e61262447dd1] Merge tag 'powerpc-6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
git bisect good 3a7101e9b27fe97240c2fd430c71e61262447dd1
# bad: [ae2c6d8b3b88c176dff92028941a4023f1b4cb91] Merge tag 'drm-xe-next-fixes-2024-09-12' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
git bisect bad ae2c6d8b3b88c176dff92028941a4023f1b4cb91
# good: [34bb7b813ab398106f700b0a6b218509bb0b904c] drm/xe: Use xe_pm_runtime_get in xe_bo_move() if reclaim-safe.
git bisect good 34bb7b813ab398106f700b0a6b218509bb0b904c
# good: [988bfa0bc67d7220ff8d9e2ba3a425727aa98af3] drm/amd/display: Make core_dcn4_g6_temp_read_blackout_table static
git bisect good 988bfa0bc67d7220ff8d9e2ba3a425727aa98af3
# bad: [2bb3fc536d692d43cd55396ecff73c7691eeae85] Merge drm/drm-next into drm-intel-next
git bisect bad 2bb3fc536d692d43cd55396ecff73c7691eeae85
# good: [4461e9e5c374f8c11fee8e4a0e3290b072cfd538] Merge v6.11-rc5 into drm-next
git bisect good 4461e9e5c374f8c11fee8e4a0e3290b072cfd538
# good: [21bb04152a18ac2314ef4186b6dcd46f1b847354] drm/i915/dsb: Convert dewake_scanline to a hw scanline number earlier
git bisect good 21bb04152a18ac2314ef4186b6dcd46f1b847354
# bad: [b290af0500f09577ad40b9f716d551fd65ceff25] drm/tegra: hub: Use fn parameter directly to fix Coccinelle warning
git bisect bad b290af0500f09577ad40b9f716d551fd65ceff25
# bad: [51394119f640423858a2f04076d6f1c3e83fa715] drm/panel-edp: add BOE NE140WUM-N6G panel entry
git bisect bad 51394119f640423858a2f04076d6f1c3e83fa715
# good: [e45b6716de4bf06b628a9f3559f7fc8dd5e94d58] drm/amd/display: use a more lax vblank enable policy for DCN35+
git bisect good e45b6716de4bf06b628a9f3559f7fc8dd5e94d58
# bad: [e794b7b9b92977365c693760a259f8eef940c536] drm: omapdrm: Add missing check for alloc_ordered_workqueue
git bisect bad e794b7b9b92977365c693760a259f8eef940c536
# skip: [6729c73103bd7a0e60b0c980b51b5434010b4502] drm/ttm: fix kernel-doc typo for @trylock_only
git bisect skip 6729c73103bd7a0e60b0c980b51b5434010b4502
# bad: [58a261bfc96763a851cb48b203ed57da37e157b8] drm/amd/display: use a more lax vblank enable policy for older ASICs
git bisect bad 58a261bfc96763a851cb48b203ed57da37e157b8
# first bad commit: [58a261bfc96763a851cb48b203ed57da37e157b8] drm/amd/display: use a more lax vblank enable policy for older ASICs

[-- Attachment #1.1.3: revert-regression.patch --]
[-- Type: text/x-patch, Size: 1069 bytes --]

--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8488,10 +8488,11 @@
 
 	if (acrtc_state) {
 		if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
-		    IP_VERSION(3, 5, 0) ||
-		    acrtc_state->stream->link->psr_settings.psr_version <
-		    DC_PSR_VERSION_UNSUPPORTED ||
-		    !(adev->flags & AMD_IS_APU)) {
+		    IP_VERSION(3, 5, 0)) {
+			drm_crtc_vblank_on(&acrtc->base);
+		} else if (acrtc_state->stream->link->psr_settings.psr_version <
+		           DC_PSR_VERSION_UNSUPPORTED ||
+		           !(adev->flags & AMD_IS_APU)) {
 			timing = &acrtc_state->stream->timing;
 
 			/* at least 2 frames */
@@ -8501,12 +8502,14 @@
 						      timing->pix_clk_100hz);
 
 			config.offdelay_ms = offdelay ?: 30;
+			drm_crtc_vblank_on_config(&acrtc->base,
+						  &config);
 		} else {
 			config.disable_immediate = true;
+			drm_crtc_vblank_on_config(&acrtc->base,
+						  &config);
 		}
 
-		drm_crtc_vblank_on_config(&acrtc->base,
-					  &config);
 	} else {
 		drm_crtc_vblank_off(&acrtc->base);
 	}

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

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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-04-22 19:44 Regression: DDC I2C Display Freezing for internal displays Felix Richter
@ 2025-07-17 19:42 ` Felix Richter
  2025-07-18 18:02   ` Mario Limonciello
  0 siblings, 1 reply; 9+ messages in thread
From: Felix Richter @ 2025-07-17 19:42 UTC (permalink / raw)
  To: Hamza Mahfooz, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas

Hi,

just tested that this Bug still exists in kernel version 6.16-rc6. The 
example trigger from my previous mail still works triggering screen 
freezing shortly after invocation.

I also learned that setting kernel param `amdgpu.dcdebugmask=0x10` works 
as a workaround.

Kind regards,
Felix Richter

On 4/22/25 21:44, Felix Richter wrote:
> Hi,
>
> it has been quite at while since I first started experiencing this 
> particular bug I am about to describe. Suffice it to say during my 
> Easter holiday I finally had the time to dig into it. It all started 
> with an update of linux LTS from 6.6 to 6.12.
>
> I am a user of the sway tiling window manager and have written a small 
> utility to manage my display configuration across different setups. 
> With the added twist that I wrote some code to determine which monitor 
> inputs is currently in use using the monitor command interface. Anyway 
> the interesting detail here is that, starting with kernel 6.12 I 
> started running into the following problem. With my display management 
> daemon running and attaching my Laptop to an external display my 
> internal display would just freeze with no way to bring it back apart 
> from power cycling the entire device. When my management daemon was 
> not running this would not happen, I would then need to manually 
> configure my display setup. Further investigation into the what is 
> triggering the display freeze lead me into the part of the code where 
> I am enumerating attached displays and am trying to match `i2c` 
> devices to their corresponding display.
>
> To get more specific the procedure is as follows, using udev enumerate 
> all `i2c` busses and filter them base on some heuristics like device 
> name and devices with parent devices drm / graphics device. Sadly this 
> is not quite enough to already match an `i2c` command interface to the 
> corresponding monitor, in many cases it is required to manually read 
> the EDID information via the i2c interface and compare it to the known 
> attached displays to get the match. And this is where the trigger for 
> the display freeze is to be found.
>
> Here is the output when scanning sysfs for my internal laptop display:
> ```
> # ls -al 
> /sys/devices/pci0000:00/0000:00:08.1/0000:04:00.0/drm/card1/card1-eDP-1
> total 0
> drwxr-xr-x  6 root root    0 22. Apr 18:07 .
> drwxr-xr-x 11 root root    0 22. Apr 18:07 ..
> drwxr-xr-x  3 root root    0 22. Apr 18:07 amdgpu_bl1
> -r--r--r--  1 root root 4096 22. Apr 18:07 connector_id
> lrwxrwxrwx  1 root root    0 22. Apr 18:07 ddc -> ../../../i2c-3
> lrwxrwxrwx  1 root root    0 22. Apr 18:07 device -> ../../card1
> -r--r--r--  1 root root 4096 22. Apr 18:07 dpms
> drwxr-xr-x  3 root root    0 22. Apr 18:07 drm_dp_aux0
> -r--r--r--  1 root root    0 22. Apr 18:07 edid
> -r--r--r--  1 root root 4096 22. Apr 18:07 enabled
> drwxr-xr-x  4 root root    0 22. Apr 18:07 i2c-11
> -r--r--r--  1 root root 4096 22. Apr 18:07 modes
> drwxr-xr-x  2 root root    0 22. Apr 18:07 power
> -rw-r--r--  1 root root 4096 22. Apr 18:07 status
> lrwxrwxrwx  1 root root    0 22. Apr 18:07 subsystem -> 
> ../../../../../../../class/drm
> -rw-r--r--  1 root root 4096 22. Apr 18:07 uevent
> ```
>
> As can be seen there are two i2c devices present, i2c-3 (as ddc 
> symlink) and i2c-11. Now from the perspective of udev i2c-11 has the 
> parent set to card1-eDP-1 while i2c-3 has the parent set to the drm 
> device itself. More importantly I can not rule out i2c-3 as a valid 
> command interface because in some cases valid command channels are 
> never assigned to the corresponding display output directly but only 
> live directly on the drm device, this is especially true when monitors 
> are not attached directly but via a docking station. So I do have to 
> look at each i2c device on its own. The freeze is trigged by trying to 
> read edid from i2c-3: This is the code snipped I used to trigger the 
> bug: 
> https://github.com/ju6ge/libmonitor/blob/918b2543eafb96aca29f66debc70fd18fa21ee11/examples/via-i2c-dev.rs 
> (adjusted target i2c interface accordingly). To be absolutely clear 
> this is not the i2c device that is expected to work in every case of 
> trying this with kernel 6.6 to 6.12 I get the following error message: 
> DdcError(CommunicationError(ReceiveError(EIO: I/O error))). That is 
> expected internal laptop displays do not support the command interface 
> in most cases anyway. But what I do not expect to happen is that my 
> Laptop screen freezes! And since this did not happen with kernel 6.6 
> but started happening with 6.12 this seems to be a software issue and 
> with that a regression!
>
> Next I bisected the kernel from 6.6 to 6.12 to determine when this 
> regression was introduced. I attached the full bisect log to the email ;)
>
> The offending commit seems to be:
>
> [58a261bfc96763a851cb48b203ed57da37e157b8] drm/amd/display: use a more 
> lax vblank enable policy for older ASICs
>
> Since this is quite a small commit I validated this by reverting the 
> changes on a newer kernel version (patch attached as well). Testing 
> actually shows that reverting the change resolves the screen freezing 
> behavior for me.
>
> Now I am not deep enough into graphics drivers to claim that just 
> reverting the commit should be considered a valid fix. Just that the 
> change is definitely responsible for the screen freezing now as 
> apposed to before.
>
> So what should be done here? I can validate any other suggested fixes 
> against my setup or provide more information if need be.
>
> Kind regards,
> Felix Richter
>
> #regzbot introduced: v6.6..v6.12


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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-17 19:42 ` Felix Richter
@ 2025-07-18 18:02   ` Mario Limonciello
  2025-07-19 10:10     ` Felix Richter
  0 siblings, 1 reply; 9+ messages in thread
From: Mario Limonciello @ 2025-07-18 18:02 UTC (permalink / raw)
  To: Felix Richter, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas

On 7/17/2025 2:42 PM, Felix Richter wrote:
> Hi,
> 
> just tested that this Bug still exists in kernel version 6.16-rc6. The 
> example trigger from my previous mail still works triggering screen 
> freezing shortly after invocation.
> 
> I also learned that setting kernel param `amdgpu.dcdebugmask=0x10` works 
> as a workaround.
> 
> Kind regards,
> Felix Richter
> 
> On 4/22/25 21:44, Felix Richter wrote:
>> Hi,
>>
>> it has been quite at while since I first started experiencing this 
>> particular bug I am about to describe. Suffice it to say during my 
>> Easter holiday I finally had the time to dig into it. It all started 
>> with an update of linux LTS from 6.6 to 6.12.
>>
>> I am a user of the sway tiling window manager and have written a small 
>> utility to manage my display configuration across different setups. 
>> With the added twist that I wrote some code to determine which monitor 
>> inputs is currently in use using the monitor command interface. Anyway 
>> the interesting detail here is that, starting with kernel 6.12 I 
>> started running into the following problem. With my display management 
>> daemon running and attaching my Laptop to an external display my 
>> internal display would just freeze with no way to bring it back apart 
>> from power cycling the entire device. When my management daemon was 
>> not running this would not happen, I would then need to manually 
>> configure my display setup. Further investigation into the what is 
>> triggering the display freeze lead me into the part of the code where 
>> I am enumerating attached displays and am trying to match `i2c` 
>> devices to their corresponding display.
>>
>> To get more specific the procedure is as follows, using udev enumerate 
>> all `i2c` busses and filter them base on some heuristics like device 
>> name and devices with parent devices drm / graphics device. Sadly this 
>> is not quite enough to already match an `i2c` command interface to the 
>> corresponding monitor, in many cases it is required to manually read 
>> the EDID information via the i2c interface and compare it to the known 
>> attached displays to get the match. And this is where the trigger for 
>> the display freeze is to be found.
>>
>> Here is the output when scanning sysfs for my internal laptop display:
>> ```
>> # ls -al /sys/devices/pci0000:00/0000:00:08.1/0000:04:00.0/drm/card1/ 
>> card1-eDP-1
>> total 0
>> drwxr-xr-x  6 root root    0 22. Apr 18:07 .
>> drwxr-xr-x 11 root root    0 22. Apr 18:07 ..
>> drwxr-xr-x  3 root root    0 22. Apr 18:07 amdgpu_bl1
>> -r--r--r--  1 root root 4096 22. Apr 18:07 connector_id
>> lrwxrwxrwx  1 root root    0 22. Apr 18:07 ddc -> ../../../i2c-3
>> lrwxrwxrwx  1 root root    0 22. Apr 18:07 device -> ../../card1
>> -r--r--r--  1 root root 4096 22. Apr 18:07 dpms
>> drwxr-xr-x  3 root root    0 22. Apr 18:07 drm_dp_aux0
>> -r--r--r--  1 root root    0 22. Apr 18:07 edid
>> -r--r--r--  1 root root 4096 22. Apr 18:07 enabled
>> drwxr-xr-x  4 root root    0 22. Apr 18:07 i2c-11
>> -r--r--r--  1 root root 4096 22. Apr 18:07 modes
>> drwxr-xr-x  2 root root    0 22. Apr 18:07 power
>> -rw-r--r--  1 root root 4096 22. Apr 18:07 status
>> lrwxrwxrwx  1 root root    0 22. Apr 18:07 subsystem - 
>> > ../../../../../../../class/drm
>> -rw-r--r--  1 root root 4096 22. Apr 18:07 uevent
>> ```
>>
>> As can be seen there are two i2c devices present, i2c-3 (as ddc 
>> symlink) and i2c-11. Now from the perspective of udev i2c-11 has the 
>> parent set to card1-eDP-1 while i2c-3 has the parent set to the drm 
>> device itself. More importantly I can not rule out i2c-3 as a valid 
>> command interface because in some cases valid command channels are 
>> never assigned to the corresponding display output directly but only 
>> live directly on the drm device, this is especially true when monitors 
>> are not attached directly but via a docking station. So I do have to 
>> look at each i2c device on its own. The freeze is trigged by trying to 
>> read edid from i2c-3: This is the code snipped I used to trigger the 
>> bug: https://github.com/ju6ge/libmonitor/ 
>> blob/918b2543eafb96aca29f66debc70fd18fa21ee11/examples/via-i2c-dev.rs 
>> (adjusted target i2c interface accordingly). To be absolutely clear 
>> this is not the i2c device that is expected to work in every case of 
>> trying this with kernel 6.6 to 6.12 I get the following error message: 
>> DdcError(CommunicationError(ReceiveError(EIO: I/O error))). That is 
>> expected internal laptop displays do not support the command interface 
>> in most cases anyway. But what I do not expect to happen is that my 
>> Laptop screen freezes! And since this did not happen with kernel 6.6 
>> but started happening with 6.12 this seems to be a software issue and 
>> with that a regression!
>>
>> Next I bisected the kernel from 6.6 to 6.12 to determine when this 
>> regression was introduced. I attached the full bisect log to the email ;)
>>
>> The offending commit seems to be:
>>
>> [58a261bfc96763a851cb48b203ed57da37e157b8] drm/amd/display: use a more 
>> lax vblank enable policy for older ASICs
>>
>> Since this is quite a small commit I validated this by reverting the 
>> changes on a newer kernel version (patch attached as well). Testing 
>> actually shows that reverting the change resolves the screen freezing 
>> behavior for me.
>>
>> Now I am not deep enough into graphics drivers to claim that just 
>> reverting the commit should be considered a valid fix. Just that the 
>> change is definitely responsible for the screen freezing now as 
>> apposed to before.
>>
>> So what should be done here? I can validate any other suggested fixes 
>> against my setup or provide more information if need be.
>>
>> Kind regards,
>> Felix Richter
>>
>> #regzbot introduced: v6.6..v6.12
> 
> 

At least to me, this issue sounds like a case that multiple entities are 
trying to communicate with the panel at the same time.

By setting dcdebugmask=0x10 what you're essentially doing is stopping 
the display hardware from trying to put the panel into PSR.  So there is 
"less" I2C traffic to fight with.

*Why* are you using I2C to read the EDID like this?  Could you instead 
use /sys/class/drm/cardX-inputY/edid?  Or even better - can you use the 
information from drm_info to make decisions?

I think the less I2C traffic done directly from userspace the better 
when it comes to synchronization issues..


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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-18 18:02   ` Mario Limonciello
@ 2025-07-19 10:10     ` Felix Richter
  2025-07-19 12:23       ` Mario Limonciello
  0 siblings, 1 reply; 9+ messages in thread
From: Felix Richter @ 2025-07-19 10:10 UTC (permalink / raw)
  To: Mario Limonciello, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas

Thanks for the reply.

I am aware that i can read and `edid` via sysfs from the drm device. I 
did not know about `drm_info` but from a quick look at it I don't think 
it provides the information I need.

The problem is not that I need more information about the attached 
display. The problem is that there is not enough information about the 
what `i2c` device corresponds to which monitors ddc channel. Relying on 
udev hierarchies is not sufficient, because in many cases the relevant 
i2c device has no parent drm output device. So when I have no 
information about the i2c device I need to get more information by 
reading from it. Then I know more and can map the device to the correct 
display. I am happy to change the approach if there is a simpler way for 
me to get this information.

Ultimately I don't think that me accessing the bus should be the issue 
here … This issue did not happen with kernel 6.6, so it definitely 
qualifies as a regression. In my mind it is the job of the driver to 
handle resource allocation, so if the bus is in use by somebody else it 
is the kernels job to handle who uses it. It is not the users job to 
have to worry about some sort of synchronization issue. That is the 
operating systems job.

People have been experiencing similar screen freezing issues randomly on 
this drm issue thread: 
https://gitlab.freedesktop.org/drm/amd/-/issues/4141#note_3016182

This example highlights an issue that can be triggered reliably with a 
very similar effect. It may not be the same issue, but they may be related.


On 7/18/25 20:02, Mario Limonciello wrote:
>
> At least to me, this issue sounds like a case that multiple entities 
> are trying to communicate with the panel at the same time.
>
> By setting dcdebugmask=0x10 what you're essentially doing is stopping 
> the display hardware from trying to put the panel into PSR.  So there 
> is "less" I2C traffic to fight with.
>
> *Why* are you using I2C to read the EDID like this?  Could you instead 
> use /sys/class/drm/cardX-inputY/edid?  Or even better - can you use 
> the information from drm_info to make decisions?
>
> I think the less I2C traffic done directly from userspace the better 
> when it comes to synchronization issues..
>


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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-19 10:10     ` Felix Richter
@ 2025-07-19 12:23       ` Mario Limonciello
  2025-07-19 17:02         ` Felix Richter
  0 siblings, 1 reply; 9+ messages in thread
From: Mario Limonciello @ 2025-07-19 12:23 UTC (permalink / raw)
  To: Felix Richter, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas,
	seanpaul



On 7/19/25 5:10 AM, Felix Richter wrote:
> Thanks for the reply.
> 
> I am aware that i can read and `edid` via sysfs from the drm device. I 
> did not know about `drm_info` but from a quick look at it I don't think 
> it provides the information I need.
> 
> The problem is not that I need more information about the attached 
> display. The problem is that there is not enough information about the 
> what `i2c` device corresponds to which monitors ddc channel. Relying on 
> udev hierarchies is not sufficient, because in many cases the relevant 
> i2c device has no parent drm output device. So when I have no 
> information about the i2c device I need to get more information by 
> reading from it. Then I know more and can map the device to the correct 
> display. I am happy to change the approach if there is a simpler way for 
> me to get this information.

❯ ls -alh /sys/class/drm/*/ddc

> 
> Ultimately I don't think that me accessing the bus should be the issue 
> here … This issue did not happen with kernel 6.6, so it definitely 
> qualifies as a regression. In my mind it is the job of the driver to 
> handle resource allocation, so if the bus is in use by somebody else it 
> is the kernels job to handle who uses it. It is not the users job to 
> have to worry about some sort of synchronization issue. That is the 
> operating systems job.
> 

I get where you're coming from, but there are cases that are ultimately 
impossible to prevent when it comes to "long", or "frequent" sequences 
and responding to interrupts.  There are lots of examples like this in 
the kernel that if you break what a driver is doing with a device from a 
userspace interface you get to pick up the pieces.

I'll give you two examples:

1) You can access R/W PCI config data.
/sys/bus/pci/devices/*/config

You can break power management state machines, bus mastering, really 
anything a device driver can do from a userspace application.  For 
example if I had a userspace app that did something like this:

dd if=/dev/zero of=/sys/bus/pci/devices/${BDF}/config bs=1 count=4096

and it broke how can the kernel do anything about it?

2) There was a case that fwupd was doing something very similar to you 
with a "probe" but with the DP aux character device.  It was trying to 
detect devices with updates and would fight specifically with link 
training.  The outcome was non-functional devices.  The workaround 
currently employed is that fwupd will wait a few seconds (5 or 10, I 
forget) and then do the probe to avoid that fight.  This doesn't solve 
things though because there are pulse interrupts that could still come 
at any time.  The DP spec has response requirements for these.

We talked about it at the display next hackfest this year and the 
decision was this information that fwupd was needing should be pushed 
into the kernel (let fwupd probe a sysfs file that gets cached data the 
driver fetched).


> People have been experiencing similar screen freezing issues randomly on 
> this drm issue thread: https://gitlab.freedesktop.org/drm/amd/-/ 
> issues/4141#note_3016182> > This example highlights an issue that can be triggered reliably with a
> very similar effect. It may not be the same issue, but they may be related.

Yeah; I'm aware of this thread and agree it's an issue with similar 
symptoms.

> 
> 
> On 7/18/25 20:02, Mario Limonciello wrote:
>>
>> At least to me, this issue sounds like a case that multiple entities 
>> are trying to communicate with the panel at the same time.
>>
>> By setting dcdebugmask=0x10 what you're essentially doing is stopping 
>> the display hardware from trying to put the panel into PSR.  So there 
>> is "less" I2C traffic to fight with.
>>
>> *Why* are you using I2C to read the EDID like this?  Could you instead 
>> use /sys/class/drm/cardX-inputY/edid?  Or even better - can you use 
>> the information from drm_info to make decisions?
>>
>> I think the less I2C traffic done directly from userspace the better 
>> when it comes to synchronization issues..
>>
> 


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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-19 12:23       ` Mario Limonciello
@ 2025-07-19 17:02         ` Felix Richter
  2025-07-19 17:36           ` Mario Limonciello
  2025-07-20 15:45           ` Alex Deucher
  0 siblings, 2 replies; 9+ messages in thread
From: Felix Richter @ 2025-07-19 17:02 UTC (permalink / raw)
  To: Mario Limonciello, Harry Wentland, Leo Li
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas,
	seanpaul

On 7/19/25 14:23, Mario Limonciello wrote:
>
> On 7/19/25 5:10 AM, Felix Richter wrote:
>> Thanks for the reply.
>>
>> I am aware that i can read and `edid` via sysfs from the drm device. 
>> I did not know about `drm_info` but from a quick look at it I don't 
>> think it provides the information I need.
>>
>> The problem is not that I need more information about the attached 
>> display. The problem is that there is not enough information about 
>> the what `i2c` device corresponds to which monitors ddc channel. 
>> Relying on udev hierarchies is not sufficient, because in many cases 
>> the relevant i2c device has no parent drm output device. So when I 
>> have no information about the i2c device I need to get more 
>> information by reading from it. Then I know more and can map the 
>> device to the correct display. I am happy to change the approach if 
>> there is a simpler way for me to get this information.
>
> ❯ ls -alh /sys/class/drm/*/ddc
Nice, I will consider adding that information to the logic for matching 
i2c devices to displays. But I do have to tell you that still is not 
sufficient in every case. It probably works for all direct interfaces 
that are always present on the device. But it fails to match i2c ddc 
channels when monitors are attached via a docking station using USB-C. 
Those monitors will not even show up in the command you provided. This 
again leads me to having to probe the i2c device directly anyway.

> I get where you're coming from, but there are cases that are 
> ultimately impossible to prevent when it comes to "long", or 
> "frequent" sequences and responding to interrupts. There are lots of 
> examples like this in the kernel that if you break what a driver is 
> doing with a device from a userspace interface you get to pick up the 
> pieces.
>
> I'll give you two examples:
>
> 1) You can access R/W PCI config data.
> /sys/bus/pci/devices/*/config
>
> You can break power management state machines, bus mastering, really 
> anything a device driver can do from a userspace application.  For 
> example if I had a userspace app that did something like this:
>
> dd if=/dev/zero of=/sys/bus/pci/devices/${BDF}/config bs=1 count=4096
>
> and it broke how can the kernel do anything about it?
>
> 2) There was a case that fwupd was doing something very similar to you 
> with a "probe" but with the DP aux character device.  It was trying to 
> detect devices with updates and would fight specifically with link 
> training.  The outcome was non-functional devices.  The workaround 
> currently employed is that fwupd will wait a few seconds (5 or 10, I 
> forget) and then do the probe to avoid that fight.  This doesn't solve 
> things though because there are pulse interrupts that could still come 
> at any time. The DP spec has response requirements for these.
>
> We talked about it at the display next hackfest this year and the 
> decision was this information that fwupd was needing should be pushed 
> into the kernel (let fwupd probe a sysfs file that gets cached data 
> the driver fetched).
>
I get that you can not protect against every case of malicious use. I am 
not sure that my example qualifies as that extreme though. I am only 
trying to read some data, that is in no way comparable to actively 
changing values.
>
>> People have been experiencing similar screen freezing issues randomly 
>> on this drm issue thread: https://gitlab.freedesktop.org/drm/amd/-/ 
>> issues/4141#note_3016182> > This example highlights an issue that can 
>> be triggered reliably with a
>> very similar effect. It may not be the same issue, but they may be 
>> related.
>
> Yeah; I'm aware of this thread and agree it's an issue with similar 
> symptoms.

At the very least I hope that my example code for triggering a similar 
issue can help figure out what is going on there ;)

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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-19 17:02         ` Felix Richter
@ 2025-07-19 17:36           ` Mario Limonciello
  2025-07-20 15:45           ` Alex Deucher
  1 sibling, 0 replies; 9+ messages in thread
From: Mario Limonciello @ 2025-07-19 17:36 UTC (permalink / raw)
  To: Leo Li, Felix Richter
  Cc: Linux regressions mailing list, amd-gfx, dri-devel, jonas,
	seanpaul, Harry Wentland



On 7/19/25 12:02 PM, Felix Richter wrote:
> On 7/19/25 14:23, Mario Limonciello wrote:
>>
>> On 7/19/25 5:10 AM, Felix Richter wrote:
>>> Thanks for the reply.
>>>
>>> I am aware that i can read and `edid` via sysfs from the drm device. 
>>> I did not know about `drm_info` but from a quick look at it I don't 
>>> think it provides the information I need.
>>>
>>> The problem is not that I need more information about the attached 
>>> display. The problem is that there is not enough information about 
>>> the what `i2c` device corresponds to which monitors ddc channel. 
>>> Relying on udev hierarchies is not sufficient, because in many cases 
>>> the relevant i2c device has no parent drm output device. So when I 
>>> have no information about the i2c device I need to get more 
>>> information by reading from it. Then I know more and can map the 
>>> device to the correct display. I am happy to change the approach if 
>>> there is a simpler way for me to get this information.
>>
>> ❯ ls -alh /sys/class/drm/*/ddc
> Nice, I will consider adding that information to the logic for matching 
> i2c devices to displays. But I do have to tell you that still is not 
> sufficient in every case. It probably works for all direct interfaces 
> that are always present on the device. But it fails to match i2c ddc 
> channels when monitors are attached via a docking station using USB-C. 
> Those monitors will not even show up in the command you provided. This 
> again leads me to having to probe the i2c device directly anyway.

Presumably you're meaning with a dock that has an MST hub?

I suppose an optimization that you can do to avoid hitting this issue 
you've raised is exclude the matches to eDP panels from /sys/class/drm/.

> 
>> I get where you're coming from, but there are cases that are 
>> ultimately impossible to prevent when it comes to "long", or 
>> "frequent" sequences and responding to interrupts. There are lots of 
>> examples like this in the kernel that if you break what a driver is 
>> doing with a device from a userspace interface you get to pick up the 
>> pieces.
>>
>> I'll give you two examples:
>>
>> 1) You can access R/W PCI config data.
>> /sys/bus/pci/devices/*/config
>>
>> You can break power management state machines, bus mastering, really 
>> anything a device driver can do from a userspace application.  For 
>> example if I had a userspace app that did something like this:
>>
>> dd if=/dev/zero of=/sys/bus/pci/devices/${BDF}/config bs=1 count=4096
>>
>> and it broke how can the kernel do anything about it?
>>
>> 2) There was a case that fwupd was doing something very similar to you 
>> with a "probe" but with the DP aux character device.  It was trying to 
>> detect devices with updates and would fight specifically with link 
>> training.  The outcome was non-functional devices.  The workaround 
>> currently employed is that fwupd will wait a few seconds (5 or 10, I 
>> forget) and then do the probe to avoid that fight.  This doesn't solve 
>> things though because there are pulse interrupts that could still come 
>> at any time. The DP spec has response requirements for these.
>>
>> We talked about it at the display next hackfest this year and the 
>> decision was this information that fwupd was needing should be pushed 
>> into the kernel (let fwupd probe a sysfs file that gets cached data 
>> the driver fetched).
>>
> I get that you can not protect against every case of malicious use. I am 
> not sure that my example qualifies as that extreme though. I am only 
> trying to read some data, that is in no way comparable to actively 
> changing values.

Reading a lot of data (such as an EDID) can take a "while".  If you're 
in the middle of the I2C transactions and the driver tries to put it 
into PSR I guess that's where things are going wrong.

Maybe what we need in this case is to actively block PSR while userspace 
I2C traffic is happening?

This is a better question for Leo if that's feasible (or reasonable).

>>
>>> People have been experiencing similar screen freezing issues randomly 
>>> on this drm issue thread: https://gitlab.freedesktop.org/drm/amd/-/ 
>>> issues/4141#note_3016182> > This example highlights an issue that can 
>>> be triggered reliably with a
>>> very similar effect. It may not be the same issue, but they may be 
>>> related.
>>
>> Yeah; I'm aware of this thread and agree it's an issue with similar 
>> symptoms.
> 
> At the very least I hope that my example code for triggering a similar 
> issue can help figure out what is going on there ;)


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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-19 17:02         ` Felix Richter
  2025-07-19 17:36           ` Mario Limonciello
@ 2025-07-20 15:45           ` Alex Deucher
  2025-07-24 19:41             ` Felix Richter
  1 sibling, 1 reply; 9+ messages in thread
From: Alex Deucher @ 2025-07-20 15:45 UTC (permalink / raw)
  To: Felix Richter
  Cc: Mario Limonciello, Harry Wentland, Leo Li,
	Linux regressions mailing list, amd-gfx, dri-devel, jonas,
	seanpaul

On Sat, Jul 19, 2025 at 1:38 PM Felix Richter <judge@felixrichter.tech> wrote:
>
> On 7/19/25 14:23, Mario Limonciello wrote:
> >
> > On 7/19/25 5:10 AM, Felix Richter wrote:
> >> Thanks for the reply.
> >>
> >> I am aware that i can read and `edid` via sysfs from the drm device.
> >> I did not know about `drm_info` but from a quick look at it I don't
> >> think it provides the information I need.
> >>
> >> The problem is not that I need more information about the attached
> >> display. The problem is that there is not enough information about
> >> the what `i2c` device corresponds to which monitors ddc channel.
> >> Relying on udev hierarchies is not sufficient, because in many cases
> >> the relevant i2c device has no parent drm output device. So when I
> >> have no information about the i2c device I need to get more
> >> information by reading from it. Then I know more and can map the
> >> device to the correct display. I am happy to change the approach if
> >> there is a simpler way for me to get this information.
> >
> > ❯ ls -alh /sys/class/drm/*/ddc
> Nice, I will consider adding that information to the logic for matching
> i2c devices to displays. But I do have to tell you that still is not
> sufficient in every case. It probably works for all direct interfaces
> that are always present on the device. But it fails to match i2c ddc
> channels when monitors are attached via a docking station using USB-C.
> Those monitors will not even show up in the command you provided. This
> again leads me to having to probe the i2c device directly anyway.
>

DP (and all of its variants, eDP, USB-C thunderbolt) doesn't actually
use i2c directly.  It's aux; you can do i2c over aux, but in the case
of MST, it's more like a network for displays so naively messing with
i2c buses from userspace won't do what you expect.  For MST, you have
a single set of i2c/aux pins for the connector which may have several
monitors on the other end.

Alex

> > I get where you're coming from, but there are cases that are
> > ultimately impossible to prevent when it comes to "long", or
> > "frequent" sequences and responding to interrupts. There are lots of
> > examples like this in the kernel that if you break what a driver is
> > doing with a device from a userspace interface you get to pick up the
> > pieces.
> >
> > I'll give you two examples:
> >
> > 1) You can access R/W PCI config data.
> > /sys/bus/pci/devices/*/config
> >
> > You can break power management state machines, bus mastering, really
> > anything a device driver can do from a userspace application.  For
> > example if I had a userspace app that did something like this:
> >
> > dd if=/dev/zero of=/sys/bus/pci/devices/${BDF}/config bs=1 count=4096
> >
> > and it broke how can the kernel do anything about it?
> >
> > 2) There was a case that fwupd was doing something very similar to you
> > with a "probe" but with the DP aux character device.  It was trying to
> > detect devices with updates and would fight specifically with link
> > training.  The outcome was non-functional devices.  The workaround
> > currently employed is that fwupd will wait a few seconds (5 or 10, I
> > forget) and then do the probe to avoid that fight.  This doesn't solve
> > things though because there are pulse interrupts that could still come
> > at any time. The DP spec has response requirements for these.
> >
> > We talked about it at the display next hackfest this year and the
> > decision was this information that fwupd was needing should be pushed
> > into the kernel (let fwupd probe a sysfs file that gets cached data
> > the driver fetched).
> >
> I get that you can not protect against every case of malicious use. I am
> not sure that my example qualifies as that extreme though. I am only
> trying to read some data, that is in no way comparable to actively
> changing values.

DP is a two way communications channel.  You may have the driver
training a link or communicating with other devices on the DP network
(MST hubs, monitors, etc.).  You can also get requests from the
monitor to the driver via hpd interrupts.  Many of these processes do
not do well if interrupted.

Alex

> >
> >> People have been experiencing similar screen freezing issues randomly
> >> on this drm issue thread: https://gitlab.freedesktop.org/drm/amd/-/
> >> issues/4141#note_3016182> > This example highlights an issue that can
> >> be triggered reliably with a
> >> very similar effect. It may not be the same issue, but they may be
> >> related.
> >
> > Yeah; I'm aware of this thread and agree it's an issue with similar
> > symptoms.
>
> At the very least I hope that my example code for triggering a similar
> issue can help figure out what is going on there ;)

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

* Re: Regression: DDC I2C Display Freezing for internal displays
  2025-07-20 15:45           ` Alex Deucher
@ 2025-07-24 19:41             ` Felix Richter
  0 siblings, 0 replies; 9+ messages in thread
From: Felix Richter @ 2025-07-24 19:41 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mario Limonciello, Harry Wentland, Leo Li,
	Linux regressions mailing list, amd-gfx, dri-devel, jonas,
	seanpaul

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


On 7/20/25 17:45, Alex Deucher wrote:
> DP (and all of its variants, eDP, USB-C thunderbolt) doesn't actually
> use i2c directly.  It's aux; you can do i2c over aux, but in the case
> of MST, it's more like a network for displays so naively messing with
> i2c buses from userspace won't do what you expect.  For MST, you have
> a single set of i2c/aux pins for the connector which may have several
> monitors on the other end.
> DP is a two way communications channel.  You may have the driver
> training a link or communicating with other devices on the DP network
> (MST hubs, monitors, etc.).  You can also get requests from the
> monitor to the driver via hpd interrupts.  Many of these processes do
> not do well if interrupted.
>
> Alex
>

I get that this is a part of a very complicated protocol. I am still 
irritated that the points you mention are relevant from the perspective 
of userspace. From my perspective there is no expectation that the 
kernel should just interrupt ongoing procedures when I access an i2c 
link. I am happy to wait for the kernel to schedule the operation for 
when it is convenient. After all the point of abstraction is not having 
to worry about the layers underneath. And if the drm device exposes an 
i2c device that I access it is the job of the drm driver to handle how 
and when that transmission takes place.

Also I would like to point out that the bug I am experiencing does not 
materialize in case of any external displays attached via an MST hub. It 
happens with the internal display even when nothing is attached. The 
point about MST Hubs is only relevant because those i2c interface can 
not be matched via udev to the corresponding display. Though the can be 
matched when reading edid from the device. Those interfaces then work 
just fine when I use ddc to read/set monitor inputs. So those points do 
not seem to really be relevant in case of the screen freezing trigger.

Anyway that is just my thoughts on the matter. I'll look into writing a 
workaround to maybe avoid some i2c devices that could be problematic.

And there still might be a relation to the other screen freezing issues.

Felix

[-- Attachment #2: Type: text/html, Size: 2890 bytes --]

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

end of thread, other threads:[~2025-07-25  7:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-22 19:44 Regression: DDC I2C Display Freezing for internal displays Felix Richter
2025-07-17 19:42 ` Felix Richter
2025-07-18 18:02   ` Mario Limonciello
2025-07-19 10:10     ` Felix Richter
2025-07-19 12:23       ` Mario Limonciello
2025-07-19 17:02         ` Felix Richter
2025-07-19 17:36           ` Mario Limonciello
2025-07-20 15:45           ` Alex Deucher
2025-07-24 19:41             ` Felix Richter

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.