media: ipu6: Don't stop or close a stream that failed to start
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Jake,
Please be careful with git send-email arguments in the future.
Quoted 9 lines · Jake Steinman
When
ipu6_isys_start_stream_firmware()fails, the firmware stream is either not open or has already been closed by its own error path. Since commiteb68e9f1c6eb("media: ipu6: Bridge the gap between streams in V4L2 and IPU6 firmware"), theerr_requeue_bufferslabel inipu6_isys_csi2_enable_streams()falls through toerr_stop_stream_firmware, so the driver then sendsSTREAM_STOPandSTREAM_CLOSEfor that stream as well. Each of those waits for a response that never comes.
Quoted 5 lines
On Panther Lake (IPU7.5) I have seen this after the firmware rejected a stream start: stop and close both timed out, a later stream open timed out too, and the ISYS needed a power cycle before anything could stream again.
I wonder if any firmware communication failure, a timeout or other error should trigger the IPU reset (once the users are gone). The functions communicating with the firmware should also probably check that condition. I just sent a PR on IPU reset changes, they probably don't address this problem though.
Quoted 37 lines
Requeue the buffers and go straight to freeing the stream on this path. The CSI-2 receiver error path still stops and closes the stream, which is open there.
Fixes eb68e9f1c6eb ("media: ipu6: Bridge the gap between streams in V4L2 and IPU6 firmware")Assisted-by Claude:claude-opus-5-5Signed-off-by Jake Steinman <[email protected]>--- drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +5
-3@@ -678,8 +678,11 @@ static int ipu6_isys_csi2_enable_streams(struct v4l2_subdev *sd, } ret =ipu6_isys_start_stream_firmware (stream, &bl, &desc); -if (ret) - goto err_requeue_buffers; +if (ret) { +/* The firmware has no open stream to stop or close here. */ +ipu6_isys_buffer_list_queue (&bl,IPU6_ISYS_BUFFER_LIST_FL_INCOMING ,0 ); + goto err_free_stream_firmware; + }if (!csi2->streaming_vc) { ret = (IS_IPU7(isp) || IS_IPU8(isp)) ?@@ -704,7 +707,6 @@ err_stop_stream_csi2:else ipu6_isys_csi2_stream_disable (csi2); -err_requeue_buffers:ipu6_isys_buffer_list_queue (&bl,IPU6_ISYS_BUFFER_LIST_FL_INCOMING ,0 ); err_stop_stream_firmware:
Signature · 3 lines
Regards, Sakari Ailus
Hi Sakari,
Quoted 1 line · Sakari Ailus
Please be careful with git send-email arguments in the future.
Sorry, that was a quoting mistake in my Cc list. It's fixed for future sends.
Quoted 5 lines
I wonder if any firmware communication failure, a timeout or other error should trigger the IPU reset (once the users are gone). The functions communicating with the firmware should also probably check that condition. I just sent a PR on IPU reset changes, they probably don't address this problem though.
Agreed. This patch also applies cleanly on top of your ipu6 branch. With "media: ipu6: Return errors from stream stop and close" there, a failed start already marks need_reset in ipu6_isys_start_stream_firmware(), and this patch only skips the stop and close calls that can't succeed.
One thing I've seen on Panther Lake: the PSYS is a child of the ISYS, and as far as I can tell the ISYS isn't runtime suspended while the PSYS is in use. So need_reset can stay set until the last PSYS user goes away, which in practice means restarting PipeWire.
"media: ipu6: Don't mark need_reset based on returned buffers" covers the IPU7 case from my need_reset RFC, so please drop that one. I'll test your ipu6 branch on Panther Lake and report back.
Jake