Skip to contentSkip to conversation

media: ipu6: Don't stop or close a stream that failed to start

PATCH Sakari Ailus 2 participants 2 messages Nov 10 1 message not in the archive Media (V4L/DVB)

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

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 commit eb68e9f1c6eb ("media: ipu6: Bridge the gap between streams in V4L2 and IPU6 firmware"), the err_requeue_buffers label in ipu6_isys_csi2_enable_streams() falls through to err_stop_stream_firmware, so the driver then sends STREAM_STOP and STREAM_CLOSE for 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-5
---
 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
index 1525454..ed4e4f6 100644
@@ -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
#2 lore raw

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