Possible start/stop streaming issue

Hello forum,

I found an issue in “vi5_fops.c” in the jetpack6 / l4t 36.4.0 release.
Is it possible to include this bugfix in upstream?

When repeatedly starting streaming with the VIDIOC_STREAMON it might happen that it is not possible to receive images, because tegra_channel_kthread_capture_enqueue aborts because chan->capture_reqs_enqueued has inconsistent value.

vi5_fops.c source

			if ((chan->capture_state == CAPTURE_ERROR)
					|| !(chan->capture_reqs_enqueued
					< (chan->capture_queue_depth * chan->valid_ports))) {
				spin_unlock_irqrestore(
					&chan->capture_state_lock, flags);
				break;
			}

resetting chan->capture_reqs_enqueued when stopping streaming solves this issue (similar to the error recovery routine) 0008-tegra-camera-vi-reset-capture-requests-count-on-chan.txt (1.0 KB)

1 Like

What’s the test and how to observe the issue?

Thanks

Hi ShaneCCC,

I created a small example application in c++ that shows the behaviour.
Without the fix the output of the application will show this message after a few toggles:

Streaming started
Timeout waiting for frame

With the fix the application will just keep running and print this:

Streaming started
Captured frame 0, size: 1240064 bytes
Captured frame 1, size: 1240064 bytes
Captured frame 2, size: 1240064 bytes
Captured frame 3, size: 1240064 bytes
Captured frame 4, size: 1240064 bytes
Captured frame 5, size: 1240064 bytes
Captured frame 6, size: 1240064 bytes
Captured frame 7, size: 1240064 bytes
Captured frame 8, size: 1240064 bytes
Captured frame 9, size: 1240064 bytes
Streaming stopped

main.cpp.txt (4.2 KB)

How about set the capture_reqs_enqueued to 0 in the tegra_channel_init_ring_buffer()?

diff --git a/drivers/media/platform/tegra/camera/vi/channel.c b/drivers/media/platform/tegra/camera/vi/channel.c
index bb60ba4ad6..1026c73d09 100644
--- a/drivers/media/platform/tegra/camera/vi/channel.c
+++ b/drivers/media/platform/tegra/camera/vi/channel.c
@@ -471,6 +471,7 @@ void tegra_channel_init_ring_buffer(struct tegra_channel *chan)
        chan->capture_descr_index = 0;
        chan->capture_descr_sequence = 0;
        chan->queue_error = false;
+        chan->capture_reqs_enqueued = 0;
 }
 EXPORT_SYMBOL(tegra_channel_init_ring_buffer);
1 Like

Yes, that is a better place for that.

Thank you :)