Re: [PATCH v3 4/5] drm/bridge: nwl-dsi: Add error handling of nwl_dsi_mode_set()

Esben Haabendal <[email protected]>
Newsgroups org.freedesktop.lists.dri-devel,dev.linux.lists.sashiko-reviews
Message-ID <[email protected]>
<[email protected]> writes:

> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Unbalanced resource teardown and PM runtime underflow in mode_set error path.
> --
>
> --- Patch [4]: [PATCH v3 4/5] drm/bridge: nwl-dsi: Add error handling of nwl_dsi_mode_set() ---
> commit 0db3c1cc2f73a9bc66aea2633f754029dd76b743
> Author: Esben Haabendal <[email protected]>
>
> drm/bridge: nwl-dsi: Add error handling of nwl_dsi_mode_set()
>
> This commit adds a return value check for nwl_dsi_mode_set() in
> nwl_dsi_bridge_mode_set(), jumping to an error path on failure.
>
>> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
>> index 3fd41212933c8..e90588299c5ea 100644
>> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
>> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
>> @@ -884,7 +884,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
>>  	}
>>
>>  	/* Step 2 from DSI reset-out instructions */
>> -	nwl_dsi_mode_set(dsi);
>> +	ret = nwl_dsi_mode_set(dsi);
>> +	if (ret < 0)
>> +		goto runtime_put;
>
> [Severity: High]
> This is a pre-existing issue, but does taking the runtime_put error path here
> lead to unbalanced resource teardown and PM runtime underflows?

Yes, it looks like it does. Similar to the existing error flows unfortunately.

> Because the drm_bridge_funcs.mode_set callback returns void, failures cannot be
> propagated to the DRM core to abort the commit. If nwl_dsi_mode_set() fails and
> jumps to runtime_put, it calls pm_runtime_put_sync() and returns early.
>
> However, the DRM core still considers the bridge pipeline state to be 'enabled',
> and will unconditionally call nwl_dsi_bridge_atomic_disable() during the next
> pipeline teardown.
>
> When atomic_disable() runs, it unconditionally calls pm_runtime_put(), leading
> to a reference count underflow:
>
> drivers/gpu/drm/bridge/nwl-dsi.c:nwl_dsi_bridge_atomic_disable() {
> 	...
> 	pm_runtime_put(dsi->dev);
> }

Maybe we should use pm_runtime_get_sync() instead of
pm_runtime_resume_and_get() in nwl_dsi_bridge_mode_set(), and then call
pm_request_idle() on error instead of pm_runtime_put_sync(). This way we
can keep the pm_runtime_put() in nwl_dsi_bridge_atomic_disable() without
risk of counter undeflow.

We would need to do something about the initial early return on
nwl_dsi_get_dphy_params() error, to avoid that causing counter
underflow. I think it should be safe to call pm_runtime_get_synmc()
first thing in nwl_dsi_bridge_mode_set().

Is it possible to do this in a follow-up patch series, so that we can
proceed with merging this without causing more complications by dealing
with this tricky pre-existing issue?

> Furthermore, atomic_disable() unconditionally calls nwl_dsi_disable(), which
> blindly attempts to tear down the PHY:
>
> drivers/gpu/drm/bridge/nwl-dsi.c:nwl_dsi_bridge_atomic_disable() {
> 	...
> 	nwl_dsi_disable(dsi);
> 	...
> }
>
> Since nwl_dsi_mode_set() already cleans up its own PHY resources on internal
> failure,
>
> this double-disable pushes the PHY framework's power_count and
> init_count to -1. The next attempt to initialize the display will increment
> these counters to 0, skipping the actual hardware ops->power_on() and
> ops->init() calls, permanently leaving the display broken until the module is
> reloaded.

True. That is a pre-existing issue, but I don't see how it is affected
by this change. In case nwl_dsi_mode_set() fails, it did internal cleanup/disable
of PHY resources before this change, and does so after this change in
the same way.

> While this broken error path already existed for clock initialization failures
> in this function, wiring up nwl_dsi_mode_set's return value to it exposes the
> PHY breakage on a new failure path.

I don't think that is true. The changed behavior in case
nwl_dsi_mode_set() fails is that we are now skipping deassert of rst_esc
and rst_byte and doing pm_runtime_put_sync(), where as before we were
executin g the deassert of rst_esc and rst_byte and not doing
pm_runtime_put_sync(). The PHY double-disable issue is unchanged.

>>
>>  	/* Step 3 from DSI reset-out instructions */
>>  	ret = reset_control_deassert(dsi->rst_esc);
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.