Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TC358743 - NULL pointer dereference on cable plugging #4128

Closed
mdevaev opened this issue Feb 7, 2021 · 61 comments
Closed

TC358743 - NULL pointer dereference on cable plugging #4128

mdevaev opened this issue Feb 7, 2021 · 61 comments

Comments

@mdevaev
Copy link
Contributor

mdevaev commented Feb 7, 2021

Describe the bug
If you connect the cable while the ustreamer is running, the driver may crash. In rarer cases, with the same reproducing method - NULL pointer dereference. Perhaps the nature of both of these bugs is the same, so this is one issue. The bug is not related to image encoding, just getting a RAW stream is enough.

[  228.324204] ------------[ cut here ]------------
[  228.328944] WARNING: CPU: 3 PID: 612 at drivers/media/common/videobuf2/videobuf2-core.c:1945 __vb2_queue_cancel+0x1d0/0x24c [videobuf2_common]
[  228.341870] Modules linked in: usb_f_mass_storage usb_f_hid spidev btsdio bluetooth ecdh_generic ecc brcmfmac snd_soc_spdif_rx brcmutil snd_soc_simple_card snd_soc_simple_card_utils i2c_mux_pinctrl i2c_mux cfg80211 snd_soc_bcm2835_i2s raspberrypi_hwmon bcm2835_unicam snd_soc_core snd_compress snd_pcm_dmaengine i2c_bcm2835 spi_bcm2835 bcm2835_codec(C) bcm2835_isp(C) bcm2835_v4l2(C) v4l2_mem2mem bcm2835_mmal_vchiq(C) videobuf2_dma_contig videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 iproc_rng200 videobuf2_common rng_core rpivid_mem nvmem_rmem uio_pdrv_genirq uio sch_fq_codel i2c_dev snd_bcm2835(C) snd_pcm snd_timer snd tc358743 v4l2_dv_timings v4l2_fwnode videodev mc cec libcomposite dwc2 udc_core roles drm fuse drm_panel_orientation_quirks ip_tables x_tables ipv6
[  228.410770] CPU: 3 PID: 612 Comm: stream Tainted: G         C        5.10.13-2-ARCH #1
[  228.418762] Hardware name: BCM2711
[  228.422221] [<c020f0a0>] (unwind_backtrace) from [<c020ae7c>] (show_stack+0x10/0x14)
[  228.430044] [<c020ae7c>] (show_stack) from [<c0dd60dc>] (dump_stack+0xa4/0xc4)
[  228.437342] [<c0dd60dc>] (dump_stack) from [<c022ae0c>] (__warn+0xec/0x148)
[  228.444372] [<c022ae0c>] (__warn) from [<c0dce37c>] (warn_slowpath_fmt+0x7c/0xac)
[  228.453323] [<c0dce37c>] (warn_slowpath_fmt) from [<bf278bf0>] (__vb2_queue_cancel+0x1d0/0x24c [videobuf2_common])
[  228.466613] [<bf278bf0>] (__vb2_queue_cancel [videobuf2_common]) from [<bf279548>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
[  228.481555] [<bf279548>] (vb2_core_streamoff [videobuf2_common]) from [<bf1d5474>] (__video_do_ioctl+0x238/0x490 [videodev])
[  228.495854] [<bf1d5474>] (__video_do_ioctl [videodev]) from [<bf1d6354>] (video_usercopy+0x170/0x5ac [videodev])
[  228.509073] [<bf1d6354>] (video_usercopy [videodev]) from [<c043ca78>] (sys_ioctl+0x34c/0x904)
[  228.520652] [<c043ca78>] (sys_ioctl) from [<c0200040>] (ret_fast_syscall+0x0/0x4c)
[  228.531168] Exception stack(0xc55e5fa8 to 0xc55e5ff0)
[  228.537691] 5fa0:                   b68de46c 00000004 00000008 40045613 b68dd968 01147638
[  228.548766] 5fc0: b68de46c 00000004 00000000 00000036 40045613 0054c35c b68dd968 00000008
[  228.559827] 5fe0: 0054c11c b68dd944 004f99bc b6c209fc
[  228.566357] ---[ end trace e70ee86b0b0a292c ]---
[  228.572403] videobuf2_common: driver bug: stop_streaming operation is leaving buf fed1a223 in active state

To reproduce
At the moment, it can't be reproduced on Raspbian (only on Arch), as it has not yet built the 5.10.13 kernel and cannot be installed with rpi-update. However the approximate method looks like this:

  • Install ustreamer
  • Load some EDID to the tc358743 device.
  • Run ustreamer --dv-timings --device=/dev/video0 --persistent --format=uyvy --encoder=noop
  • Plug HDMI
  • Stop ustreamer
  • Unplug HDMI
  • Start ustreamer
  • Plug HDMI
  • ...
  • Error

The error may occur after the second or twentieth iteration, it is non-periodic, but it occurs when the cable is connected. In rarer cases, some kind of NULL pointer dereference may occur, but I have not yet managed to catch it in the log, I only saw it briefly in the UART console three times, after which the Pi rebooted. In even rarer cases, something strange happens like double free or 'munmap_chunk(): invalid pointer'. I suppose it's all one problem.

On older 5.4 kernels, I didn't see this. Interestingly, if you now try to reproduce the problem on Raspbian with the kernel 5.10.11, the first connection of the cable will cause segfault in ustreamer, this was also not observed before.

If you need any more information, I'm ready to help as usual.

System

  • Raspberry Pi 4 Model B Rev 1.1
  • Arch Linux ARM
  • firmware: version 99d9a48302e4553cff3688692bb7e9ac760a03fa (clean) (release) (start) / Jan 27 2021 22:19:57
  • Linux pikvm 5.10.13-2-ARCH #1 SMP Fri Feb 5 15:47:26 UTC 2021 armv7l GNU/Linux

Logs
Just dmesg: dmesg1.txt
Another crash (UART log):
screenlog1.txt

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 7, 2021

@6by9 In ancient times, ambassadors with bad news could be killed, but I hope you will spare me in this time :) I brought another nasty bug related to TC358743.

@6by9
Copy link
Contributor

6by9 commented Feb 7, 2021

__vb2_queue_cancel is a warning, not a crash. See the comment at https://elixir.bootlin.com/linux/latest/source/drivers/media/common/videobuf2/videobuf2-core.c#L1939 just before it.

I will look at it again as we should return all queued buffers, but it won't crash the system.

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 7, 2021

Thanks. In this case, I will try to reproduce the NULL pointer dereference.

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 7, 2021

Catched NULL pointer dereference:

[  113.910609] Unable to handle kernel NULL pointer dereference at virtual address 00000122
[  113.918751] pgd = c2ff1852
[  113.921470] [00000122] *pgd=80000000004003, *pmd=00000000
[  113.926905] Internal error: Oops: a06 [#1] SMP ARM

Entering kdb (current=0xc3fada00, pid 140) on processor 0 Oops: (null)
due to oops @ 0xbf2e06e0
CPU: 0 PID: 140 Comm: kworker/0:3 Tainted: G         C        5.10.13-2-ARCH #1
Hardware name: BCM2711
Workqueue: events dbs_work_handler
PC is at unicam_isr+0x2bc/0x360 [bcm2835_unicam]
LR is at 0x122
pc : [<bf2e06e0>]    lr : [<00000122>]    psr: 60000193
sp : c3fa1d10  ip : c25f5e80  fp : eece3c10
r10: eece3000  r9 : 000004fc  r8 : 00000100
r7 : 00000608  r6 : 00000000  r5 : eece34fc  r4 : eece3000
r3 : c25f6280  r2 : 00000122  r1 : 00000000  r0 : c25f6000
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5383d  Table: 02947280  DAC: fffffffd
CPU: 0 PID: 140 Comm: kworker/0:3 Tainted: G         C        5.10.13-2-ARCH #1
Hardware name: BCM2711
Workqueue: events dbs_work_handler
[<c020f0a0>] (unwind_backtrace) from [<c020ae7c>] (show_stack+0x10/0x14)
[<c020ae7c>] (show_stack) from [<c0dd60dc>] (dump_stack+0xa4/0xc4)
[<c0dd60dc>] (dump_stack) from [<c02ffd50>] (kdb_main_loop+0x4bc/0x9a0)
[<c02ffd50>] (kdb_main_loop) from [<c0302e04>] (kdb_stub+0x258/0x458)
[<c0302e04>] (kdb_stub) from [<c02f7f90>] (kgdb_cpu_enter+0x3e0/0x6fc)

... Crash, reboot

And also this, similar as discribed in the first report but with another trace:

[   76.559135] ------------[ cut here ]------------
[   76.563844] WARNING: CPU: 3 PID: 541 at drivers/media/common/videobuf2/videobuf2-core.c:997 unicam_return_buffers+0x84/0xd0 [bcm2835_unicam]
[   76.576556] Modules linked in: usb_f_mass_storage usb_f_hid spidev btsdio bluetooth snd_soc_spdif_rx snd_soc_simple_card ecdh_generic snd_soc_simple_card_utils ecc brcmfmac i2c_mux_pinctrl brcmutil i2c_mux raspberrypi_hwmon bcm2835_unicam cfg80211 snd_soc_bcm2835_i2s snd_soc_core bcm2835_v4l2(C) snd_compress i2c_bcm2835 bcm2835_codec(C) snd_pcm_dmaengine spi_bcm2835 bcm2835_isp(C) bcm2835_mmal_vchiq(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 iproc_rng200 videobuf2_common rng_core rpivid_mem uio_pdrv_genirq nvmem_rmem uio sch_fq_codel i2c_dev snd_bcm2835(C) snd_pcm snd_timer snd tc358743 v4l2_dv_timings v4l2_fwnode videodev mc cec libcomposite dwc2 udc_core roles drm fuse drm_panel_orientation_quirks ip_tables x_tables ipv6
[   76.645367] CPU: 3 PID: 541 Comm: stream Tainted: G         C        5.10.13-2-ARCH #1
[   76.653302] Hardware name: BCM2711
[   76.656722] [<c020f0a0>] (unwind_backtrace) from [<c020ae7c>] (show_stack+0x10/0x14)
[   76.664490] [<c020ae7c>] (show_stack) from [<c0dd60dc>] (dump_stack+0xa4/0xc4)
[   76.671734] [<c0dd60dc>] (dump_stack) from [<c022ae0c>] (__warn+0xec/0x148)
[   76.678716] [<c022ae0c>] (__warn) from [<c0dce37c>] (warn_slowpath_fmt+0x7c/0xac)
[   76.686848] [<c0dce37c>] (warn_slowpath_fmt) from [<bf30c72c>] (unicam_return_buffers+0x84/0xd0 [bcm2835_unicam])
[   76.698427] [<bf30c72c>] (unicam_return_buffers [bcm2835_unicam]) from [<bf214a48>] (__vb2_queue_cancel+0x28/0x24c [videobuf2_common])
[   76.711830] [<bf214a48>] (__vb2_queue_cancel [videobuf2_common]) from [<bf215548>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
[   76.725079] [<bf215548>] (vb2_core_streamoff [videobuf2_common]) from [<bf1d5474>] (__video_do_ioctl+0x238/0x490 [videodev])
[   76.737669] [<bf1d5474>] (__video_do_ioctl [videodev]) from [<bf1d6354>] (video_usercopy+0x170/0x5ac [videodev])
[   76.749188] [<bf1d6354>] (video_usercopy [videodev]) from [<c043ca78>] (sys_ioctl+0x34c/0x904)
[   76.759122] [<c043ca78>] (sys_ioctl) from [<c0200040>] (ret_fast_syscall+0x0/0x4c)
[   76.768026] Exception stack(0xc5599fa8 to 0xc5599ff0)
[   76.773747] 9fa0:                   b16f9474 00000004 0000000c 40045613 b16f8960 009ad660
[   76.783251] 9fc0: b16f9474 00000004 00000000 00000036 40045613 0048e06c b16f8960 0000000c
[   76.792767] 9fe0: 0048de18 b16f893c 00439c08 b6bcd9fc
[   76.798490] ---[ end trace 599a6883e85eaf43 ]---

I use a slightly different command: here, jpeg encoding is enabled for omx and h264 encoding for mmal using zerocopy from the video device. But it seems to me that this is not related, because I added oops and stacktrace as above (not warnings) and without these options.

ustreamer --dv-timings --device /dev/video0 --persistent --format=uyvy --encoder=omx --h264-sink test

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 8, 2021

@6by9 I continued testing attempts and realized that NULL dereference (described in the previous comment) happens stably for about 10-20 attempts to connect the cable. Next, the kernel runs kdbg, but I can't do anything there since the kernel is rebooted after that (probably Arch settings). The command causing the crash is also in the previous comment.

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 13, 2021

Another catch on zero. Crash and warning:

Feb 13 08:07:26 pikvm kernel: ------------[ cut here ]------------
Feb 13 08:07:26 pikvm kernel: WARNING: CPU: 0 PID: 128 at drivers/media/common/videobuf2/videobuf2-core.c:997 unicam_isr+0xdc/0x36c [bcm2835_unicam]
Feb 13 08:07:26 pikvm kernel: Modules linked in: usb_f_mass_storage usb_f_hid brcmfmac brcmutil cfg80211 raspberrypi_hwmon i2c_mux_pinctrl i2c_mux bcm2835_unicam bcm2835_codec(C) bcm2835_v4l2(C) bcm2835_isp(>
Feb 13 08:07:26 pikvm kernel: CPU: 0 PID: 128 Comm: kworker/u2:2 Tainted: G         C        5.10.14-2-ARCH #1
Feb 13 08:07:26 pikvm kernel: Hardware name: BCM2835
Feb 13 08:07:26 pikvm kernel: Workqueue:  0x0 (brcmf_wq/mmc1:0001:1)
Feb 13 08:07:26 pikvm kernel: [<8010ef8c>] (unwind_backtrace) from [<8010ae04>] (show_stack+0x10/0x14)
Feb 13 08:07:26 pikvm kernel: [<8010ae04>] (show_stack) from [<80d03c88>] (dump_stack+0xd0/0xf8)
Feb 13 08:07:26 pikvm kernel: [<80d03c88>] (dump_stack) from [<8012bd1c>] (__warn+0xd4/0x140)
Feb 13 08:07:26 pikvm kernel: [<8012bd1c>] (__warn) from [<80cfb694>] (warn_slowpath_fmt+0x74/0xa8)
Feb 13 08:07:26 pikvm kernel: [<80cfb694>] (warn_slowpath_fmt) from [<7f2bae4c>] (unicam_isr+0xdc/0x36c [bcm2835_unicam])
Feb 13 08:07:26 pikvm kernel: [<7f2bae4c>] (unicam_isr [bcm2835_unicam]) from [<8018eb18>] (__handle_irq_event_percpu+0x48/0x1ec)
Feb 13 08:07:26 pikvm kernel: [<8018eb18>] (__handle_irq_event_percpu) from [<8018eda8>] (handle_irq_event+0x64/0xd8)
Feb 13 08:07:26 pikvm kernel: [<8018eda8>] (handle_irq_event) from [<8019334c>] (handle_level_irq+0xb0/0x1a0)
Feb 13 08:07:26 pikvm kernel: [<8019334c>] (handle_level_irq) from [<8018e430>] (__handle_domain_irq+0x74/0xd4)
Feb 13 08:07:26 pikvm kernel: [<8018e430>] (__handle_domain_irq) from [<8089e644>] (bcm2835_handle_irq+0x2c/0x34)
Feb 13 08:07:26 pikvm kernel: [<8089e644>] (bcm2835_handle_irq) from [<80100af8>] (__irq_svc+0x58/0x74)
Feb 13 08:07:26 pikvm kernel: Exception stack(0x84367e68 to 0x84367eb0)
Feb 13 08:07:26 pikvm kernel: 7e60:                   8306cb00 40000700 0000fde3 00000000 81266b80 00000000
Feb 13 08:07:26 pikvm kernel: 7e80: 8306cb00 9b6d2b80 1a46c000 84220f00 00000000 84367ef4 846e8040 84367eb8
Feb 13 08:07:26 pikvm kernel: 7ea0: 80d0b0d8 80157940 60000013 ffffffff
Feb 13 08:07:26 pikvm kernel: [<80100af8>] (__irq_svc) from [<80157940>] (finish_task_switch+0x7c/0x218)
Feb 13 08:07:26 pikvm kernel: [<80157940>] (finish_task_switch) from [<80d0b0d8>] (__schedule+0x2e4/0xa54)
Feb 13 08:07:26 pikvm kernel: [<80d0b0d8>] (__schedule) from [<80d0b8a8>] (schedule+0x60/0xdc)
Feb 13 08:07:26 pikvm kernel: [<80d0b8a8>] (schedule) from [<80147e74>] (worker_thread+0xcc/0x594)
Feb 13 08:07:26 pikvm kernel: [<80147e74>] (worker_thread) from [<8014dca8>] (kthread+0x130/0x144)
Feb 13 08:07:26 pikvm kernel: [<8014dca8>] (kthread) from [<80100138>] (ret_from_fork+0x14/0x3c)
Feb 13 08:07:26 pikvm kernel: Exception stack(0x84367fb0 to 0x84367ff8)
Feb 13 08:07:26 pikvm kernel: 7fa0:                                     00000000 00000000 00000000 00000000
Feb 13 08:07:26 pikvm kernel: 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Feb 13 08:07:26 pikvm kernel: 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
Feb 13 08:07:26 pikvm kernel: ---[ end trace 1e400d33e83b8123 ]---
...
Feb 13 08:08:06 pikvm kernel: ------------[ cut here ]------------
Feb 13 08:08:06 pikvm kernel: WARNING: CPU: 0 PID: 459 at drivers/media/common/videobuf2/videobuf2-core.c:1945 __vb2_queue_cancel+0x1cc/0x250 [videobuf2_common]
Feb 13 08:08:06 pikvm kernel: Modules linked in: usb_f_mass_storage usb_f_hid brcmfmac brcmutil cfg80211 raspberrypi_hwmon i2c_mux_pinctrl i2c_mux bcm2835_unicam bcm2835_codec(C) bcm2835_v4l2(C) bcm2835_isp(>
Feb 13 08:08:06 pikvm kernel: CPU: 0 PID: 459 Comm: stream Tainted: G        WC        5.10.14-2-ARCH #1
Feb 13 08:08:06 pikvm kernel: Hardware name: BCM2835
Feb 13 08:08:06 pikvm kernel: [<8010ef8c>] (unwind_backtrace) from [<8010ae04>] (show_stack+0x10/0x14)
Feb 13 08:08:06 pikvm kernel: [<8010ae04>] (show_stack) from [<80d03c88>] (dump_stack+0xd0/0xf8)
Feb 13 08:08:06 pikvm kernel: [<80d03c88>] (dump_stack) from [<8012bd1c>] (__warn+0xd4/0x140)
Feb 13 08:08:06 pikvm kernel: [<8012bd1c>] (__warn) from [<80cfb694>] (warn_slowpath_fmt+0x74/0xa8)
Feb 13 08:08:06 pikvm kernel: [<80cfb694>] (warn_slowpath_fmt) from [<7f259a94>] (__vb2_queue_cancel+0x1cc/0x250 [videobuf2_common])
Feb 13 08:08:06 pikvm kernel: [<7f259a94>] (__vb2_queue_cancel [videobuf2_common]) from [<7f25a3f4>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
Feb 13 08:08:06 pikvm kernel: [<7f25a3f4>] (vb2_core_streamoff [videobuf2_common]) from [<7f1a0570>] (__video_do_ioctl+0x228/0x474 [videodev])
Feb 13 08:08:06 pikvm kernel: [<7f1a0570>] (__video_do_ioctl [videodev]) from [<7f1a14b8>] (video_usercopy+0x148/0x598 [videodev])
Feb 13 08:08:06 pikvm kernel: [<7f1a14b8>] (video_usercopy [videodev]) from [<8033aa68>] (sys_ioctl+0x32c/0x92c)
Feb 13 08:08:06 pikvm kernel: [<8033aa68>] (sys_ioctl) from [<80100060>] (ret_fast_syscall+0x0/0x4c)
Feb 13 08:08:06 pikvm kernel: Exception stack(0x833c7fa8 to 0x833c7ff0)
Feb 13 08:08:06 pikvm kernel: 7fa0:                   72600b80 00000004 00000009 40045613 737f8960 02087798
Feb 13 08:08:06 pikvm kernel: 7fc0: 72600b80 00000004 00000000 00000036 40045613 004df06c 737f8960 00000009
Feb 13 08:08:06 pikvm kernel: 7fe0: 004dee18 737f893c 00489bf8 76c9a92c
Feb 13 08:08:06 pikvm kernel: ---[ end trace 1e400d33e83b8124 ]---
Feb 13 08:08:06 pikvm kernel: videobuf2_common: driver bug: stop_streaming operation is leaving buf cbe27ef1 in active state

@mdevaev
Copy link
Contributor Author

mdevaev commented Feb 15, 2021

@6by9 Is there anything I can do to help solve this bug? I get pecked at the head because of the NULL dereference.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 2, 2021

Sup?

@6by9
Copy link
Contributor

6by9 commented Mar 2, 2021

Sorry, still a way down the priority list.

@naushir It looks like there is a path where the unicam driver can return a buffer that isn't queued to it. That's what the videobuf2-core.c:997 warning is about.
TC358743 has no metadata pad, so it should only be the image pad active. It's as if there is a race between unicam_isr and unicam_stop_streaming.

Is it just that we've forgotten to clear UNICAM_ICTL, so the interrupts are still active?

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 2, 2021

@6by9 In this situation, I'm more concerned about the NULL dereference rather than the warning that occurs. Apparently you're right and it's a race, given the diverse range of errors. Most of all, I would like to get rid of crash. Warning is a much lesser evil.

@naushir
Copy link
Contributor

naushir commented Mar 3, 2021

The only way I can see this problem occurring is if unicam_isr were to be preempted by unicam_stop_streaming but can that really happen?? If so, here is a possible (and entirely untested) fix:

diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
index a8b3f5433f04..5496f93aa43c 100644
--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -831,10 +831,12 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                        if (!unicam->node[i].streaming)
                                continue;
 
+                       spin_lock(&unicam->node[i].dma_queue_lock);
                        if (unicam->node[i].cur_frm)
                                unicam_process_buffer_complete(&unicam->node[i],
                                                               sequence);
                        unicam->node[i].cur_frm = unicam->node[i].next_frm;
+                       spin_unlock(&unicam->node[i].dma_queue_lock);
                }
                unicam->sequence++;
        }
@@ -849,6 +851,7 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                        if (!unicam->node[i].streaming)
                                continue;
 
+                       spin_lock(&unicam->node[i].dma_queue_lock);
                        if (unicam->node[i].cur_frm)
                                unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
                                                                ts;
@@ -858,6 +861,7 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                         * from the queue.
                         */
                        unicam_schedule_dummy_buffer(&unicam->node[i]);
+                       spin_unlock(&unicam->node[i].dma_queue_lock);
                }
 
                unicam_queue_event_sof(unicam);

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

@naushir Well, yes, I have reproduced it stably, as you can see :) Can your patch fix NULL dereference, do you think?

@naushir
Copy link
Contributor

naushir commented Mar 3, 2021

The patch above should fix a potential NULL deference, but it may or may not be the one that you have seen triggered, it's difficult to tell. Please do give it a try and let me know.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

@naushir A potential fix is much better than no fix :) Thank you! I'll take care of it immediately.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

@naushir Got this:

[  151.372449] ------------[ cut here ]------------
[  151.377155] WARNING: CPU: 0 PID: 652 at drivers/media/common/videobuf2/videobuf2-core.c:997 unicam_return_buffers+0x58/0xd0 [bcm2835_unicam]
[  151.389868] Modules linked in: usb_f_mass_storage usb_f_hid spidev btsdio snd_soc_spdif_rx bluetooth ecdh_generic ecc snd_soc_simple_card brcmfmac
snd_soc_simple_card_utils brcmutil i2c_mux_pinctrl i2c_mux bcm2835_unicam snd_soc_bcm2835_i2s cfg80211 raspberrypi_hwmon snd_soc_core i2c_bcm2835 snd_
compress spi_bcm2835 snd_pcm_dmaengine bcm2835_codec(C) bcm2835_v4l2(C) bcm2835_isp(C) bcm2835_mmal_vchiq(C) v4l2_mem2mem videobuf2_dma_contig videobu
f2_vmalloc videobuf2_memops iproc_rng200 videobuf2_v4l2 rng_core videobuf2_common rpivid_mem nvmem_rmem uio_pdrv_genirq uio sch_fq_codel i2c_dev snd_b
cm2835(C) snd_pcm snd_timer snd tc358743 v4l2_dv_timings v4l2_fwnode videodev mc cec libcomposite dwc2 udc_core roles drm fuse drm_panel_orientation_q
uirks ip_tables x_tables ipv6
[  151.458693] CPU: 0 PID: 652 Comm: stream Tainted: G         C        5.10.17-2-ARCH #1
[  151.466677] Hardware name: BCM2711
[  151.470132] [<c020f10c>] (unwind_backtrace) from [<c020aed0>] (show_stack+0x10/0x14)
[  151.477954] [<c020aed0>] (show_stack) from [<c0de7864>] (dump_stack+0xa4/0xc4)
[  151.485250] [<c0de7864>] (dump_stack) from [<c022ae9c>] (__warn+0xec/0x148)
[  151.492278] [<c022ae9c>] (__warn) from [<c0ddfb00>] (warn_slowpath_fmt+0x7c/0xac)
[  151.501226] [<c0ddfb00>] (warn_slowpath_fmt) from [<bf54e700>] (unicam_return_buffers+0x58/0xd0 [bcm2835_unicam])
[  151.514436] [<bf54e700>] (unicam_return_buffers [bcm2835_unicam]) from [<bf20fa48>] (__vb2_queue_cancel+0x28/0x24c [videobuf2_common])
[  151.529507] [<bf20fa48>] (__vb2_queue_cancel [videobuf2_common]) from [<bf210548>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
[  151.544455] [<bf210548>] (vb2_core_streamoff [videobuf2_common]) from [<bf1d5474>] (__video_do_ioctl+0x238/0x490 [videodev])
[  151.558797] [<bf1d5474>] (__video_do_ioctl [videodev]) from [<bf1d6354>] (video_usercopy+0x170/0x5ac [videodev])
[  151.572027] [<bf1d6354>] (video_usercopy [videodev]) from [<c043df50>] (sys_ioctl+0x34c/0x904)
[  151.583625] [<c043df50>] (sys_ioctl) from [<c0200040>] (ret_fast_syscall+0x0/0x4c)
[  151.594146] Exception stack(0xc530ffa8 to 0xc530fff0)
[  151.600672] ffa0:                   b0505000 00000004 0000000c 40045613 b16f8960 01d67648
[  151.611754] ffc0: b0505000 00000004 00000000 00000036 40045613 0048f06c b16f8960 0000000c
[  151.622822] ffe0: 0048ee1c b16f893c 00439c08 b6ba59fc
[  151.629321] ---[ end trace 90a2d269f970e9d2 ]---
[  151.635469] ------------[ cut here ]------------
[  151.641586] WARNING: CPU: 0 PID: 652 at drivers/media/common/videobuf2/videobuf2-core.c:1945 __vb2_queue_cancel+0x1d0/0x24c [videobuf2_common]
[  151.656335] Modules linked in: usb_f_mass_storage usb_f_hid spidev btsdio snd_soc_spdif_rx bluetooth ecdh_generic ecc snd_soc_simple_card brcmfmac snd_soc_simple_card_utils brcmutil i2c_mux_pinctrl i2c_mux bcm2835_unicam snd_soc_bcm2835_i2s cfg80211 raspberrypi_hwmon snd_soc_core i2c_bcm2835 snd_compress spi_bcm2835 snd_pcm_dmaengine bcm2835_codec(C) bcm2835_v4l2(C) bcm2835_isp(C) bcm2835_mmal_vchiq(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_vmalloc videobuf2_memops iproc_rng200 videobuf2_v4l2 rng_core videobuf2_common rpivid_mem nvmem_rmem uio_pdrv_genirq uio sch_fq_codel i2c_dev snd_bcm2835(C) snd_pcm snd_timer snd tc358743 v4l2_dv_timings v4l2_fwnode videodev mc cec libcomposite dwc2 udc_core roles drm fuse drm_panel_orientation_quirks ip_tables x_tables ipv6
[  151.731803] CPU: 0 PID: 652 Comm: stream Tainted: G        WC        5.10.17-2-ARCH #1
[  151.741047] Hardware name: BCM2711
[  151.745110] [<c020f10c>] (unwind_backtrace) from [<c020aed0>] (show_stack+0x10/0x14)
[  151.754156] [<c020aed0>] (show_stack) from [<c0de7864>] (dump_stack+0xa4/0xc4)
[  151.762679] [<c0de7864>] (dump_stack) from [<c022ae9c>] (__warn+0xec/0x148)
[  151.770303] [<c022ae9c>] (__warn) from [<c0ddfb00>] (warn_slowpath_fmt+0x7c/0xac)
[  151.779094] [<c0ddfb00>] (warn_slowpath_fmt) from [<bf20fbf0>] (__vb2_queue_cancel+0x1d0/0x24c [videobuf2_common])
[  151.790760] [<bf20fbf0>] (__vb2_queue_cancel [videobuf2_common]) from [<bf210548>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
[  151.803997] [<bf210548>] (vb2_core_streamoff [videobuf2_common]) from [<bf1d5474>] (__video_do_ioctl+0x238/0x490 [videodev])
[  151.816558] [<bf1d5474>] (__video_do_ioctl [videodev]) from [<bf1d6354>] (video_usercopy+0x170/0x5ac [videodev])
[  151.828079] [<bf1d6354>] (video_usercopy [videodev]) from [<c043df50>] (sys_ioctl+0x34c/0x904)
[  151.838018] [<c043df50>] (sys_ioctl) from [<c0200040>] (ret_fast_syscall+0x0/0x4c)
[  151.846950] Exception stack(0xc530ffa8 to 0xc530fff0)
[  151.852662] ffa0:                   b0505000 00000004 0000000c 40045613 b16f8960 01d67648
[  151.862185] ffc0: b0505000 00000004 00000000 00000036 40045613 0048f06c b16f8960 0000000c
[  151.871715] ffe0: 0048ee1c b16f893c 00439c08 b6ba59fc
[  151.877495] ---[ end trace 90a2d269f970e9d3 ]---
[  151.882820] videobuf2_common: driver bug: stop_streaming operation is leaving buf dca779ef in active state

And NULL dereference after ~30 retries:

[  372.258026] 8<--- cut here ---
[  372.261116] Unable to handle kernel NULL pointer dereference at virtual address 00000122
[  372.269256] pgd = a13d13c3
[  372.271977] [00000122] *pgd=80000000004003, *pmd=00000000
[  372.277418] Internal error: Oops: a06 [#1] SMP ARM

Entering kdb (current=0xc14082c0, pid 0) on processor 0 Oops: (null)
due to oops @ 0xbf2c90c4
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G         C        5.10.17-2-ARCH #1
Hardware name: BCM2711
PC is at unicam_isr+0x30c/0x3b0 [bcm2835_unicam]
LR is at 0x122
pc : [<bf2c90c4>]    lr : [<00000122>]    psr: 60080193
sp : c1401e70  ip : c2964680  fp : bf2cab6c
r10: c43be000  r9 : 000004fc  r8 : 00000100
r7 : 00000608  r6 : 00000000  r5 : c43be4fc  r4 : c43be000
r3 : c2969a80  r2 : 00000122  r1 : 00000000  r0 : c2969800
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5383d  Table: 029ae1c0  DAC: fffffffd
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G         C        5.10.17-2-ARCH #1
Hardware name: BCM2711
[<c020f10c>] (unwind_backtrace) from [<c020aed0>] (show_stack+0x10/0x14)
[<c020aed0>] (show_stack) from [<c0de7864>] (dump_stack+0xa4/0xc4)
[<c0de7864>] (dump_stack) from [<c03010a8>] (kdb_main_loop+0x4bc/0x9a0)
[<c03010a8>] (kdb_main_loop) from [<c030415c>] (kdb_stub+0x258/0x458)
[<c030415c>] (kdb_stub) from [<c02f92e8>] (kgdb_cpu_enter+0x3e0/0x6fc)
[<c02f92e8>] (kgdb_cpu_enter) from [<c02f9ca8>] (kgdb_handle_exception+0xe0/0x13c)
more>
(reboot)

@naushir
Copy link
Contributor

naushir commented Mar 3, 2021

Ok, so that potential fix did nothing, which sort of reassures me that unicam_isr is not preempted by unicam_stop_streaming.

Need to continue looking into this one in more detail...

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

If necessary, I can give you access to the device via the serial console.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

@naushir I'm not one hundred percent sure, but could this problem have something to do with using DMA? At least, NULL dereference was played exactly with H264 encoding enabled. It works like this: ustreamer exports v4l2 buffers, then feeds them to the VC. At least so far I haven't been able to reproduce this without h264. But maybe I'm just unlucky.

Hypothesis based on ustreamer behavior:

  • I connect the cable
  • ustreamer exports b4l2 buffers
  • there is some race in the driver
  • inside the exported buffer turns out to be NULL (???)

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

It may be generally unrelated. I'm just informing you of what I'm observing. Perhaps exporting buffers somehow negatively affects the warning that we observe, and with some probability exacerbates the effect.

@6by9
Copy link
Contributor

6by9 commented Mar 3, 2021

I was thinking of unicam_stop_streaming being preempted by unicam_isr.

Supposedly unicam_disable should have shut down the analogue side, but nothing actually clears the interrupt mask register in unicam. unicam_isr can therefore still fire.

[  151.377155] WARNING: CPU: 0 PID: 652 at drivers/media/common/videobuf2/videobuf2-core.c:997 unicam_return_buffers+0x58/0xd0 [bcm2835_unicam]
...
[  151.501226] [<c0ddfb00>] (warn_slowpath_fmt) from [<bf54e700>] (unicam_return_buffers+0x58/0xd0 [bcm2835_unicam])
[  151.514436] [<bf54e700>] (unicam_return_buffers [bcm2835_unicam]) from [<bf20fa48>] (__vb2_queue_cancel+0x28/0x24c [videobuf2_common])
[  151.529507] [<bf20fa48>] (__vb2_queue_cancel [videobuf2_common]) from [<bf210548>] (vb2_core_streamoff+0x18/0xac [videobuf2_common])
[  151.544455] [<bf210548>] (vb2_core_streamoff [videobuf2_common]) from [<bf1d5474>] (__video_do_ioctl+0x238/0x490 [videodev])
[  151.558797] [<bf1d5474>] (__video_do_ioctl [videodev]) from [<bf1d6354>] (video_usercopy+0x170/0x5ac [videodev])

That warn is that the buffer isn't in the ACTIVE state, ie it's not with the driver such that it should be returned.
That sort of implies that something (presumably unicam_isr) has returned a buffer that vb2_core_streamoff calling unicam_return_buffers then tries to return again.

@naushir
Copy link
Contributor

naushir commented Mar 3, 2021

@naushir I'm not one hundred percent sure, but could this problem have something to do with using DMA? At least, NULL dereference was played exactly with H264 encoding enabled. It works like this: ustreamer exports v4l2 buffers, then feeds them to the VC. At least so far I haven't been able to reproduce this without h264. But maybe I'm just unlucky.

It's possible that we might be looking at two separate and unrelated problem here, the NULL dereference during encode, and the vb2_buf asserts.

@naushir
Copy link
Contributor

naushir commented Mar 3, 2021

That warn is that the buffer isn't in the ACTIVE state, ie it's not with the driver such that it should be returned.
That sort of implies that something (presumably unicam_isr) has returned a buffer that vb2_core_streamoff calling unicam_return_buffers then tries to return again.

Yes, that was my thinking, and the patch above should have ensured this cannot happen by testing cur_frame within the lock, but I must have missed something.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 3, 2021

But if it's related, then maybe it's underground knocks, and if you fix the problem with active buffers, it can also disappear. In any case, I am at your disposal for testing.

@naushir
Copy link
Contributor

naushir commented Mar 4, 2021

@mdevaev can you try the below patch (only slightly different from the earlier one) and send me a log if/when you hit the NULL ptr exception? Could you also enable debug logging on the unicam driver with the below command:

sudo su
echo 5 > /sys/module/bcm2835_unicam/parameters/debug
diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
index a8b3f5433f04..03779d656e5b 100644
--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -794,7 +794,7 @@ static void unicam_queue_event_sof(struct unicam_device *unicam)
 static irqreturn_t unicam_isr(int irq, void *dev)
 {
        struct unicam_device *unicam = dev;
-       unsigned int lines_done = unicam_get_lines_done(dev);
+       unsigned int lines_done = 0;
        unsigned int sequence = unicam->sequence;
        unsigned int i;
        u32 ista, sta;
@@ -831,10 +831,12 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                        if (!unicam->node[i].streaming)
                                continue;
 
+                       spin_lock(&unicam->node[i].dma_queue_lock);
                        if (unicam->node[i].cur_frm)
                                unicam_process_buffer_complete(&unicam->node[i],
                                                               sequence);
                        unicam->node[i].cur_frm = unicam->node[i].next_frm;
+                       spin_unlock(&unicam->node[i].dma_queue_lock);
                }
                unicam->sequence++;
        }
@@ -849,6 +851,7 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                        if (!unicam->node[i].streaming)
                                continue;
 
+                       spin_lock(&unicam->node[i].dma_queue_lock);
                        if (unicam->node[i].cur_frm)
                                unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
                                                                ts;
@@ -858,6 +861,7 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                         * from the queue.
                         */
                        unicam_schedule_dummy_buffer(&unicam->node[i]);
+                       spin_unlock(&unicam->node[i].dma_queue_lock);
                }
 
                unicam_queue_event_sof(unicam);
@@ -886,6 +890,9 @@ static irqreturn_t unicam_isr(int irq, void *dev)
                reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
                reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM);
        }
+
+       unicam_dbg(3, unicam, "ISR: End");
+
        return IRQ_HANDLED;
 }
 
@@ -1750,6 +1757,7 @@ static void unicam_stop_streaming(struct vb2_queue *vq)
        struct unicam_node *node = vb2_get_drv_priv(vq);
        struct unicam_device *dev = node->dev;
 
+       unicam_dbg(3, dev, "Stop streaming: Begin");
        node->streaming = false;
 
        if (node->pad_id == IMAGE_PAD) {
@@ -1785,6 +1793,8 @@ static void unicam_stop_streaming(struct vb2_queue *vq)
 
        /* Clear all queued buffers for the node */
        unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
+
+       unicam_dbg(3, dev, "Stop streaming: End");
 }
 
 static int unicam_enum_input(struct file *file, void *priv,

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 4, 2021

@naushir Sure. Can I just ask you to attach it as a file because github messed up the indentation. In the last patch, I had to arrange them manually :)

@naushir
Copy link
Contributor

naushir commented Mar 4, 2021

Sure thing. Here is a zip of the patch file you can apply with git am. I had to zip as github does not allow plaintext attachments.

0001-Unicam-testing.zip

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 4, 2021

Thanks! I'll start building it now. The result will be available in the next hour.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 4, 2021

@naushir Bingo! Got it via UART.
screenlog.txt

@naushir
Copy link
Contributor

naushir commented Mar 4, 2021

Thanks! Would be useful to see the videobuf2_common warning messages as well if you can capture them.

@naushir
Copy link
Contributor

naushir commented Mar 4, 2021

@mdevaev , can I just confirm, you only see the NULL ptr exception if you are doing a H.264 encode? If so, any chance you could try reproducing without encode?

@JakubVanek
Copy link
Contributor

JakubVanek commented Mar 4, 2021

I tried to reproduce this on Raspbian on RPi4B1.4 with the latest commit ec967eb (32bit build) and I wasn't able to trigger the crash nor the warning. I did change some kconfig values, but these were (I suppose) related to kernel debugging. I was using the Auvidea B101 rev 4 board for this.

I will try to test this with the latest official kernel to see if I can reproduce the segfault.

I tried multiple ways of reproducing this:

  • run ustreamer --dv-timings --device=/dev/video0 --persistent --format=uyvy --encoder=noop and repeatedly plug and unplug hdmi
  • run ustreamer --dv-timings --device /dev/video0 --persistent --format=uyvy --encoder=omx --h264-sink test and repeatedly plug and unplug hdmi
  • run ustreamer --dv-timings --device=/dev/video0 --persistent --format=uyvy --encoder=noop and repeatedly upload new edid (this caused the bridge to be redetected on the other side)
  • run ustreamer --dv-timings --device /dev/video0 --persistent --format=uyvy --encoder=omx --h264-sink test and repeatedly upload new edid (this caused the bridge to be redetected on the other side)

EDIT: I trink I also tried stopping ustreamer before plugging the HDMI cable back a few times.

@JakubVanek
Copy link
Contributor

JakubVanek commented Mar 4, 2021

Taking back: I reproduced both the warning and NULL dereference successfully on the official 5.10.17 build, but I had to use another RPi as the signal source.

@JakubVanek
Copy link
Contributor

JakubVanek commented Mar 4, 2021

This is the NULL dereference from a local debug build without the zipped patch applied. Here is a fuller stack trace of it:

KDB stacktrace
[  165.377940] 8<--- cut here ---
[  165.381007] Unable to handle kernel NULL pointer dereference at virtual address 00000104
[  165.389102] pgd = 543cd94e
[  165.391811] [00000104] *pgd=0316a003, *pmd=7ff7d003
[  165.396712] Internal error: Oops: a07 [#1] SMP ARM

Entering kdb (current=0xc3181f00, pid 635) on processor 0 Oops: (null)
due to oops @ 0xbf258ba8
CPU: 0 PID: 635 Comm: stream Tainted: G        WC        5.10.17-v7l+ #1
Hardware name: BCM2711
PC is at unicam_isr+0x2f8/0x3b4 [bcm2835_unicam]
LR is at 0x100
pc : [<bf258ba8>]    lr : [<00000100>]    psr: 60000193
sp : c4073890  ip : 00000100  fp : c40738d4
r10: 00000122  r9 : c18fd000  r8 : 00000608
r7 : 000004fc  r6 : 00000000  r5 : c18fd4fc  r4 : c18fd000
r3 : c31f3280  r2 : 00000122  r1 : 00000000  r0 : c31f3000
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5383d  Table: 03449500  DAC: fffffffd
CPU: 0 PID: 635 Comm: stream Tainted: G        WC        5.10.17-v7l+ #1
Hardware name: BCM2711
Backtrace:
[<c020c3f0>] (dump_backtrace) from [<c020c73c>] (show_stack+0x20/0x24)
 r7:ffffffff r6:00000000 r5:60000193 r4:c12e69fc
[<c020c71c>] (show_stack) from [<c0b7a99c>] (dump_stack+0xcc/0xf8)
[<c0b7a8d0>] (dump_stack) from [<c0208d6c>] (show_regs+0x1c/0x20)
 r10:c120518c r9:00000005 r8:c13842c8 r7:0000000f r6:c1211ee4 r5:c1383e0c
 r4:c1383e10 r3:49c86701
[<c0208d50>] (show_regs) from [<c0305460>] (kdb_main_loop+0x3bc/0x7d8)
[<c03050a4>] (kdb_main_loop) from [<c0308570>] (kdb_stub+0x268/0x474)
 r10:c120518c r9:00000005 r8:c13842c8 r7:00000000 r6:c13845c4 r5:c137f654
 r4:c4073694
[<c0308308>] (kdb_stub) from [<c02fd848>] (kgdb_cpu_enter+0x450/0x7d4)
 r10:00000001 r9:ffffcfc7 r8:ffffe000 r7:00000000 r6:c127d368 r5:c4073694
 r4:c137f640
[<c02fd3f8>] (kgdb_cpu_enter) from [<c02fe378>] (kgdb_handle_exception+0x11c/0x140)
 r10:00000a07 r9:00000001 r8:00000001 r7:0000000b r6:c4073840 r5:00000000
 r4:c1205048
[<c02fe25c>] (kgdb_handle_exception) from [<c0210f9c>] (kgdb_notify+0x40/0x94)
 r9:ffffe000 r8:c0210f5c r7:00000001 r6:c4073738 r5:00000080 r4:20000193
[<c0210f5c>] (kgdb_notify) from [<c02485f4>] (atomic_notifier_call_chain+0x68/0x8c)
 r7:c4073738 r6:00000001 r5:fffffffc r4:00000000
[<c024858c>] (atomic_notifier_call_chain) from [<c0248668>] (notify_die+0x50/0x6c)
 r8:c0e1c778 r7:c4073840 r6:c3181f00 r5:49c86701 r4:c1205048
[<c0248618>] (notify_die) from [<c020c864>] (die+0x124/0x374)
 r5:c120a444 r4:c135631c
[<c020c740>] (die) from [<c0b6ad68>] (__do_kernel_fault.part.0+0x88/0x98)
 r10:00000122 r9:c4072000 r8:ffffe000 r7:c28d3a00 r6:00000a07 r5:c4073840
 r4:00000104
[<c0b6ace0>] (__do_kernel_fault.part.0) from [<c0b85200>] (do_translation_fault+0x0/0x108)
 r7:c28d3a00 r4:c4073840
[<c0b84ef0>] (do_page_fault) from [<c02154d4>] (do_DataAbort+0x40/0xc4)
 r10:00000122 r9:c4072000 r8:c4073840 r7:00000104 r6:c0b84ef0 r5:00000a07
 r4:c120af08
[<c0215494>] (do_DataAbort) from [<c0200a34>] (__dabt_svc+0x54/0x80)
Exception stack(0xc4073840 to 0xc4073888)
3840: c31f3000 00000000 00000122 c31f3280 c18fd000 c18fd4fc 00000000 000004fc
3860: 00000608 c18fd000 00000122 c40738d4 00000100 c4073890 00000100 bf258ba8
3880: 60000193 ffffffff
 r8:00000608 r7:c4073874 r6:ffffffff r5:60000193 r4:bf258ba8
[<bf2588b0>] (unicam_isr [bcm2835_unicam]) from [<c0289c70>] (__handle_irq_event_percpu+0xac/0x258)
 r10:c4073920 r9:c120509c r8:ffffe000 r7:c1abd900 r6:00000000 r5:c1abd96c
 r4:c335bb40
[<c0289bc4>] (__handle_irq_event_percpu) from [<c0289e58>] (handle_irq_event_percpu+0x3c/0x8c)
 r10:00000100 r9:c4072000 r8:c1810800 r7:00000001 r6:c1abd900 r5:c1abd96c
 r4:c1205048
[<c0289e1c>] (handle_irq_event_percpu) from [<c0289efc>] (handle_irq_event+0x54/0x78)
 r6:00000000 r5:c1abd96c r4:c1abd900
[<c0289ea8>] (handle_irq_event) from [<c028ea34>] (handle_fasteoi_irq+0xb8/0x19c)
 r7:00000001 r6:00000000 r5:c1205b3c r4:c1abd900
[<c028e97c>] (handle_fasteoi_irq) from [<c0288c18>] (generic_handle_irq+0x44/0x54)
 r5:00000000 r4:c1094d50
[<c0288bd4>] (generic_handle_irq) from [<c0289368>] (__handle_domain_irq+0x6c/0xc4)
[<c02892fc>] (__handle_domain_irq) from [<c020135c>] (gic_handle_irq+0x90/0xa4)
 r9:c4072000 r8:c1094d5c r7:c40739e0 r6:f081400c r5:f0814000 r4:c1205b3c
[<c02012cc>] (gic_handle_irq) from [<c0200abc>] (__irq_svc+0x5c/0x7c)
Exception stack(0xc40739e0 to 0xc4073a28)
39e0: c0b8494c 80000013 60000093 60000093 80000013 c31f2150 c18fd4c0 c18fd520
3a00: c4073b48 00000000 00000100 c4073a44 c4072000 c4073a30 00000000 c0b84960
3a20: 60000013 ffffffff
 r9:c4072000 r8:c4073b48 r7:c4073a14 r6:ffffffff r5:60000013 r4:c0b84960
[<c0b84910>] (_raw_spin_unlock_irqrestore) from [<bf11384c>] (vb2_core_poll+0x10c/0x1d0 [videobuf2_common])
 r5:c31f2150 r4:c18fd3a8
[<bf113740>] (vb2_core_poll [videobuf2_common]) from [<bf3eca54>] (vb2_poll+0x3c/0x90 [videobuf2_v4l2])
 r7:c18fd520 r6:c18fd3a8 r5:c4073b48 r4:c3f07a80
[<bf3eca18>] (vb2_poll [videobuf2_v4l2]) from [<bf3ecc3c>] (vb2_fop_poll+0x5c/0xec [videobuf2_v4l2])
 r7:c3f07a80 r6:c18fd520 r5:c18fd3a8 r4:c18fd508
[<bf3ecbe0>] (vb2_fop_poll [videobuf2_v4l2]) from [<bf16a20c>] (v4l2_poll+0x54/0x94 [videodev])
 r9:00000020 r8:00000008 r7:00000009 r6:00000100 r5:00000001 r4:c18fd520
[<bf16a1b8>] (v4l2_poll [videodev]) from [<c044716c>] (do_select+0x31c/0x6f0)
 r5:00000001 r4:00000100
[<c0446e50>] (do_select) from [<c0447e18>] (core_sys_select+0x1dc/0x370)
 r10:b69271f8 r9:c4073e04 r8:b6927178 r7:00000009 r6:c1205048 r5:c4073e04
 r4:00000004
[<c0447c3c>] (core_sys_select) from [<c0448098>] (kern_select+0xec/0x138)
 r10:c4073f48 r9:b6927278 r8:b69271f8 r7:b6927178 r6:00000009 r5:c1205048
 r4:b6927110
[<c0447fac>] (kern_select) from [<c0448218>] (sys_select+0x24/0x2c)
 r10:0000008e r9:c4072000 r8:c0200204 r7:0000008e r6:00000009 r5:b69271f8
 r4:b6927110
[<c04481f4>] (sys_select) from [<c0200040>] (ret_fast_syscall+0x0/0x28)
Exception stack(0xc4073fa8 to 0xc4073ff0)
3fa0:                   b6927110 b69271f8 00000009 b6927178 b69271f8 b6927278
3fc0: b6927110 b69271f8 00000009 0000008e 00000000 b6927369 00000008 0007332c
3fe0: 00000002 b69270f0 00000000 b6c246b0
more>
[0]kdb>

The last exception stack likely belongs to ustreamer; this is the symbolized version:

(_raw_spin_unlock_irqrestore) from vb2_core_poll (drivers/media/common/videobuf2/videobuf2-core.c:2415) videobuf2_common
(vb2_core_poll [videobuf2_common]) from vb2_poll (./include/linux/poll.h:50) videobuf2_v4l2
(vb2_poll [videobuf2_v4l2]) from vb2_fop_poll (drivers/media/common/videobuf2/videobuf2-v4l2.c:1204 (discriminator 1)) videobuf2_v4l2
(vb2_fop_poll [videobuf2_v4l2]) from v4l2_poll (drivers/media/v4l2-core/v4l2-dev.c:348) videodev
(v4l2_poll [videodev]) from do_select (./include/linux/file.h:45) 
(do_select) from core_sys_select (fs/select.c:679) 
(core_sys_select) from kern_select (fs/select.c:719) 
(kern_select) from sys_select (fs/select.c:722) 
(sys_select) from ret_fast_syscall (arch/arm/kernel/entry-common.S:82) 

KGDB stacktrace from the ISR:

#0  0xbf258ba8 in __list_del (next=0x100, prev=0x122)
#1  __list_del_entry (entry=0xc31f3280) at ./include/linux/list.h:135
#2  list_del (entry=0xc31f3280) at ./include/linux/list.h:146
#3  unicam_schedule_next_buffer (node=<optimized out>) at drivers/media/platform/bcm2835/bcm2835-unicam.c:745
#4  unicam_isr (irq=<optimized out>, dev=0xc18fd000) at drivers/media/platform/bcm2835/bcm2835-unicam.c:879
#5  0xc0289c70 in __handle_irq_event_percpu (desc=desc@entry=0xc1abd900, flags=flags@entry=0xc4073920) at kernel/irq/handle.c:156
#6  0xc0289e58 in handle_irq_event_percpu (desc=desc@entry=0xc1abd900) at kernel/irq/handle.c:196
#7  0xc0289efc in handle_irq_event (desc=desc@entry=0xc1abd900) at kernel/irq/handle.c:213
#8  0xc028ea34 in handle_fasteoi_irq (desc=0xc1abd900) at kernel/irq/chip.c:714
#9  0xc0288c18 in generic_handle_irq_desc (desc=<optimized out>) at ./include/linux/irqdesc.h:152
#10 generic_handle_irq (irq=<optimized out>) at kernel/irq/irqdesc.c:650
#11 0xc0289368 in __handle_domain_irq (domain=0xc1810800, hwirq=<optimized out>, lookup=lookup@entry=true, regs=regs@entry=0xc40739e0) at kernel/irq/irqdesc.c:687
#12 0xc020135c in handle_domain_irq (regs=0xc40739e0, hwirq=<optimized out>, domain=<optimized out>) at ./include/linux/irqdesc.h:170
#13 gic_handle_irq (regs=0xc40739e0) at drivers/irqchip/irq-gic.c:370
#14 0xc0200abc in __irq_svc () at arch/arm/kernel/entry-armv.S:205

@JakubVanek
Copy link
Contributor

(this was triggered by the original reproducer - ustreamer --dv-timings --device=/dev/video0 --persistent --format=uyvy --encoder=noop)

@JakubVanek
Copy link
Contributor

JakubVanek commented Mar 4, 2021

Contents of the affected unicam_device struct
$13 = {
  kref = {
    refcount = {
      refs = {
        counter = 2
      }
    }
  }, 
  asd = {
    match_type = V4L2_ASYNC_MATCH_FWNODE, 
    match = {
      fwnode = 0xeff68b90, 
      device_name = 0xeff68b90 "", 
      i2c = {
        adapter_id = -269055088, 
        address = 0
      }, 
      custom = {
        match = 0xeff68b90, 
        priv = 0x0
      }
    }, 
    list = {
      next = 0x100, 
      prev = 0x122
    }, 
    asd_list = {
      next = 0xc18fd24c, 
      prev = 0xc18fd24c
    }
  }, 
  base = 0xf0821000, 
  clk_gate_base = 0xf0825004, 
  clock = 0xc335ba40, 
  vpu_clock = 0xc335bac0, 
  clocks_enabled = true, 
  v4l2_dev = {
    dev = 0xc1a4b610, 
    mdev = 0xc18fd090, 
    subdevs = {
      next = 0xc340b0e0, 
      prev = 0xc340b0e0
    }, 
    lock = {
      {
        rlock = {
          raw_lock = {
            {
              slock = 65537, 
              tickets = {
                owner = 1, 
                next = 1
              }
            }
          }
        }
      }
    }, 
    name = "unicam fe801000.csi", '\000' <repeats 16 times>, 
    notify = 0xbf258c64 <unicam_notify>, 
    ctrl_handler = 0x0, 
    prio = {
      prios = {{
          counter = 0
        }, {
          counter = 0
        }, {
          counter = 1
        }, {
          counter = 0
        }}
    }, 
    ref = {
      refcount = {
        refs = {
          counter = 4
        }
      }
    }, 
    release = 0x0
  }, 
  mdev = {
    dev = 0xc1a4b610, 
    devnode = 0xc31ff000, 
    model = "unicam", '\000' <repeats 25 times>, 
    driver_name = '\000' <repeats 31 times>, 
    serial = '\000' <repeats 39 times>, 
    bus_info = "platform:fe801000.csi\000\000\000\000\000\000\000\000\000\000", 
    hw_revision = 0, 
    topology_version = 14, 
    id = 14, 
    entity_internal_idx = {
      xa = {
        xa_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 196611, 
                  tickets = {
                    owner = 3, 
                    next = 3
                  }
                }
              }
            }
          }
        }, 
        xa_flags = 8388613, 
        xa_head = 0x1d
      }
    }, 
    entity_internal_idx_max = 3, 
    entities = {
      next = 0xc340b098, 
      prev = 0xc18fdb30
    }, 
    interfaces = {
      next = 0xc31beb08, 
      prev = 0xc365a1c8
    }, 
    pads = {
      next = 0xc340b15c, 
      prev = 0xc18fde74
    }, 
    links = {
      next = 0xc31beb48, 
      prev = 0xc365a208
    }, 
    entity_notify = {
      next = 0xc18fd164, 
      prev = 0xc18fd164
    }, 
    graph_mutex = {
      owner = {
        counter = 0
      }, 
      wait_lock = {
        {
          rlock = {
            raw_lock = {
              {
                slock = 0, 
                tickets = {
                  owner = 0, 
                  next = 0
                }
              }
            }
          }
        }
      }, 
      osq = {
        tail = {
          counter = 0
        }
      }, 
      wait_list = {
        next = 0xc18fd178, 
        prev = 0xc18fd178
      }
    }, 
    pm_count_walk = {
      stack = {{
          entity = 0x0, 
          link = 0x0
        } <repeats 16 times>}, 
      ent_enum = {
        bmap = 0xc31be640, 
        idx_max = 32
      }, 
      top = 0
    }, 
    source_priv = 0x0, 
    enable_source = 0x0, 
    disable_source = 0x0, 
    ops = 0x0, 
    req_queue_mutex = {
      owner = {
        counter = 0
      }, 
      wait_lock = {
        {
          rlock = {
            raw_lock = {
              {
                slock = 0, 
                tickets = {
                  owner = 0, 
                  next = 0
                }
              }
            }
          }
        }
      }, 
      osq = {
        tail = {
          counter = 0
        }
      }, 
      wait_list = {
        next = 0xc18fd228, 
        prev = 0xc18fd228
      }
    }, 
    request_id = {
      counter = 0
    }
  }, 
  pdev = 0xc1a4b600, 
  notifier = {
    ops = 0xbf25e564 <unicam_async_ops>, 
    v4l2_dev = 0xc18fd034, 
    sd = 0x0, 
    parent = 0x0, 
    asd_list = {
      next = 0xc18fd018, 
      prev = 0xc18fd018
    }, 
    waiting = {
      next = 0xc18fd254, 
      prev = 0xc18fd254
    }, 
    done = {
      next = 0xc340b13c, 
      prev = 0xc340b13c
    }, 
    list = {
      next = 0xbf192118 <notifier_list>, 
      prev = 0xbf192118 <notifier_list>
    }
  }, 
  sequence = 5, 
  sensor = 0xc340b090, 
  sensor_config = 0xc33e5180, 
  bus_type = V4L2_MBUS_CSI2_DPHY, 
  bus_flags = 256, 
  max_data_lanes = 2, 
  active_data_lanes = 2, 
  sensor_embedded_data = false, 
  node = {{
      registered = true, 
      open = 1, 
      streaming = true, 
      pad_id = 0, 
      cur_frm = 0xc31f3000, 
      next_frm = 0xc31f3000, 
      fmt = 0xbf25e09c <formats+80>, 
      v_fmt = {
        type = 1, 
        fmt = {
          pix = {
            width = 1440, 
            height = 900, 
            pixelformat = 1498831189, 
            field = 1, 
            bytesperline = 2880, 
            sizeimage = 2592000, 
            colorspace = 1, 
            priv = 0, 
            flags = 0, 
            {
              ycbcr_enc = 0, 
              hsv_enc = 0
            }, 
            quantization = 0, 
            xfer_func = 0
          }, 
          pix_mp = {
            width = 1440, 
            height = 900, 
            pixelformat = 1498831189, 
            field = 1, 
            colorspace = 2880, 
            plane_fmt = {{
                sizeimage = 2592000, 
                bytesperline = 1, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }}, 
            num_planes = 0 '\000', 
            flags = 0 '\000', 
            {
              ycbcr_enc = 0 '\000', 
              hsv_enc = 0 '\000'
            }, 
            quantization = 0 '\000', 
            xfer_func = 0 '\000', 
            reserved = "\000\000\000\000\000\000"
          }, 
          win = {
            w = {
              left = 1440, 
              top = 900, 
              width = 1498831189, 
              height = 1
            }, 
            field = 2880, 
            chromakey = 2592000, 
            clips = 0x1, 
            clipcount = 0, 
            bitmap = 0x0, 
            global_alpha = 0 '\000'
          }, 
          vbi = {
            sampling_rate = 1440, 
            offset = 900, 
            samples_per_line = 1498831189, 
            sample_format = 1, 
            start = {2880, 2592000}, 
            count = {1, 0}, 
            flags = 0, 
            reserved = {0, 0}
          }, 
          sliced = {
            service_set = 1440, 
            service_lines = {{0, 900, 0, 22869, 22870, 1, 0, 2880, 0, 36096, 39, 1, 0 <repeats 12 times>}, {0 <repeats 24 times>}}, 
            io_size = 0, 
            reserved = {0, 0}
          }, 
          sdr = {
            pixelformat = 1440, 
            buffersize = 900, 
            reserved = "UYVY\001\000\000\000@\v\000\000\000\215'\000\001\000\000\000\000\000\000"
          }, 
          meta = {
            dataformat = 1440, 
            buffersize = 900
          }, 
          raw_data = "\240\005\000\000\204\003\000\000UYVY\001\000\000\000@\v\000\000\000\215'\000\001", '\000' <repeats 174 times>
        }
      }, 
      m_fmt = {
        width = 1440, 
        height = 900, 
        code = 8207, 
        field = 1, 
        colorspace = 1, 
        {
          ycbcr_enc = 0, 
          hsv_enc = 0
        }, 
        quantization = 0, 
        xfer_func = 0, 
        flags = 0, 
        reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
      }, 
      buffer_queue = {
        type = 1, 
        io_modes = 21, 
        dev = 0xc1a4b610, 
        dma_attrs = 0, 
        bidirectional = 0, 
        fileio_read_once = 0, 
        fileio_write_immediately = 0, 
        allow_zero_bytesused = 0, 
        quirk_poll_must_check_waiting_for_buffers = 1, 
        supports_requests = 0, 
        requires_requests = 0, 
        uses_qbuf = 1, 
        uses_requests = 0, 
        allow_cache_hints = 0, 
        lock = 0xc18fd508, 
        owner = 0xc373a580, 
        ops = 0xbf25e310 <unicam_video_qops>, 
        mem_ops = 0xbf1af0f8 <vb2_dma_contig_memops>, 
        buf_ops = 0xbf3ef494 <v4l2_buf_ops>, 
        drv_priv = 0xc18fd290, 
        subsystem_flags = 0, 
        buf_struct_size = 648, 
        timestamp_flags = 8192, 
        gfp_flags = 0, 
        min_buffers_needed = 1, 
        alloc_devs = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
        mmap_lock = {
          owner = {
            counter = 0
          }, 
          wait_lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 0, 
                    tickets = {
                      owner = 0, 
                      next = 0
                    }
                  }
                }
              }
            }
          }, 
          osq = {
            tail = {
              counter = 0
            }
          }, 
          wait_list = {
            next = 0xc18fd414, 
            prev = 0xc18fd414
          }
        }, 
        memory = 1, 
        dma_dir = DMA_FROM_DEVICE, 
        bufs = {0xc31f3000, 0xc31f2c00, 0xc31f2800, 0xc31f2400, 0xc31f2000, 0x0 <repeats 27 times>}, 
        num_buffers = 5, 
        queued_list = {
          next = 0xc31f2d48, 
          prev = 0xc31f2548
        }, 
        queued_count = 5, 
        owned_by_drv_count = {
          counter = 4
        }, 
        done_list = {
          next = 0xc31f2150, 
          prev = 0xc31f2150
        }, 
        done_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 520560391, 
                  tickets = {
                    owner = 7943, 
                    next = 7943
                  }
                }
              }
            }
          }
        }, 
        done_wq = {
          lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 397678516, 
                    tickets = {
                      owner = 6068, 
                      next = 6068
                    }
                  }
                }
              }
            }
          }, 
          head = {
            next = 0xc4073b78, 
            prev = 0xc4073b78
          }
        }, 
        streaming = 1, 
        start_streaming_called = 1, 
        error = 0, 
        waiting_for_buffers = 0, 
        waiting_in_dqbuf = 0, 
        is_multiplanar = 0, 
        is_output = 0, 
        copy_timestamp = 0, 
        last_buffer_dequeued = 0, 
        fileio = 0x0, 
        threadio = 0x0, 
        name = "cap-(ptrval)", '\000' <repeats 19 times>
      }, 
      dma_queue = {
        next = 0xc31f3280, 
        prev = 0xc31f2680
      }, 
      dma_queue_lock = {
        {
          rlock = {
            raw_lock = {
              {
                slock = 648423077, 
                tickets = {
                  owner = 9893, 
                  next = 9894
                }
              }
            }
          }
        }
      }, 
      lock = {
        owner = {
          counter = -1021829376
        }, 
        wait_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 0, 
                  tickets = {
                    owner = 0, 
                    next = 0
                  }
                }
              }
            }
          }
        }, 
        osq = {
          tail = {
            counter = 0
          }
        }, 
        wait_list = {
          next = 0xc18fd514, 
          prev = 0xc18fd514
        }
      }, 
      video_dev = {
        entity = {
          graph_obj = {
            mdev = 0xc18fd090, 
            id = 3, 
            list = {
              next = 0xc18fdb30, 
              prev = 0xc340b098
            }
          }, 
          name = 0xc18fd7e8 "unicam-image", 
          obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE, 
          function = 65537, 
          flags = 1, 
          num_pads = 1, 
          num_links = 1, 
          num_backlinks = 1, 
          internal_idx = 2, 
          pads = 0xc18fd864, 
          links = {
            next = 0xc31bebd0, 
            prev = 0xc31bebd0
          }, 
          ops = 0x0, 
          stream_count = 0, 
          use_count = 0, 
          pipe = 0x0, 
          info = {
            dev = {
              major = 81, 
              minor = 7
            }
          }
        }, 
        intf_devnode = 0xc31beb00, 
        pipe = {
          streaming_count = 0, 
          graph = {
            stack = {{
                entity = 0x0, 
                link = 0x0
              } <repeats 16 times>}, 
            ent_enum = {
              bmap = 0x0, 
              idx_max = 0
            }, 
            top = 0
          }
        }, 
        fops = 0xbf25e340 <unicam_fops>, 
        device_caps = 83886081, 
        dev = {
          kobj = {
            name = 0xc31be880 "video0", 
            entry = {
              next = 0xc18fdc1c, 
              prev = 0xc18172fc
            }, 
            parent = 0xc31be8c0, 
            kset = 0xc1978600, 
            ktype = 0xc12f0948 <device_ktype>, 
            sd = 0xc3494f20, 
            kref = {
              refcount = {
                refs = {
                  counter = 4
                }
              }
            }, 
            state_initialized = 1, 
            state_in_sysfs = 1, 
            state_add_uevent_sent = 1, 
            state_remove_uevent_sent = 0, 
            uevent_suppress = 0
          }, 
          parent = 0xc1a4b610, 
          p = 0xc33e5000, 
          init_name = 0x0, 
          type = 0x0, 
          bus = 0x0, 
          driver = 0x0, 
          platform_data = 0x0, 
          driver_data = 0xc18fd290, 
          mutex = {
            owner = {
              counter = 0
            }, 
            wait_lock = {
              {
                rlock = {
                  raw_lock = {
                    {
                      slock = 0, 
                      tickets = {
                        owner = 0, 
                        next = 0
                      }
                    }
                  }
                }
              }
            }, 
            osq = {
              tail = {
                counter = 0
              }
            }, 
            wait_list = {
              next = 0xc18fd660, 
              prev = 0xc18fd660
            }
          }, 
          links = {
            suppliers = {
              next = 0xc18fd668, 
              prev = 0xc18fd668
            }, 
            consumers = {
              next = 0xc18fd670, 
              prev = 0xc18fd670
            }, 
            needs_suppliers = {
              next = 0xc18fd678, 
              prev = 0xc18fd678
            }, 
            defer_hook = {
              next = 0xc18fd680, 
              prev = 0xc18fd680
            }, 
            need_for_probe = false, 
            status = DL_DEV_NO_DRIVER
          }, 
          power = {
            power_state = {
              event = 0
            }, 
            can_wakeup = 0, 
            async_suspend = 0, 
            in_dpm_list = false, 
            is_prepared = false, 
            is_suspended = false, 
            is_noirq_suspended = false, 
            is_late_suspended = false, 
            no_pm = false, 
            early_init = true, 
            direct_complete = false, 
            driver_flags = 0, 
            lock = {
              {
                rlock = {
                  raw_lock = {
                    {
                      slock = 0, 
                      tickets = {
                        owner = 0, 
                        next = 0
                      }
                    }
                  }
                }
              }
            }, 
            should_wakeup = 0, 
            suspend_timer = {
              node = {
                node = {
                  __rb_parent_color = 3247429288, 
                  rb_right = 0x0, 
                  rb_left = 0x0
                }, 
                expires = 0
              }, 
              _softexpires = 0, 
              function = 0xc0849120 <pm_suspend_timer_fn>, 
              base = 0xeff20680, 
              state = 0 '\000', 
              is_rel = 0 '\000', 
              is_soft = 0 '\000', 
              is_hard = 0 '\000'
            }, 
            timer_expires = 0, 
            work = {
              data = {
                counter = -32
              }, 
              entry = {
                next = 0xc18fd6e4, 
                prev = 0xc18fd6e4
              }, 
              func = 0xc08493a0 <pm_runtime_work>
            }, 
            wait_queue = {
              lock = {
                {
                  rlock = {
                    raw_lock = {
                      {
                        slock = 0, 
                        tickets = {
                          owner = 0, 
                          next = 0
                        }
                      }
                    }
                  }
                }
              }, 
              head = {
                next = 0xc18fd6f4, 
                prev = 0xc18fd6f4
              }
            }, 
            wakeirq = 0x0, 
            usage_count = {
              counter = 0
            }, 
            child_count = {
              counter = 0
            }, 
            disable_depth = 1, 
            idle_notification = 0, 
            request_pending = 0, 
            deferred_resume = 0, 
            runtime_auto = 1, 
            ignore_children = false, 
            no_callbacks = 0, 
            irq_safe = 0, 
            use_autosuspend = 0, 
            timer_autosuspends = 0, 
            memalloc_noio = 0, 
            links_count = 0, 
            request = RPM_REQ_NONE, 
            runtime_status = RPM_SUSPENDED, 
            runtime_error = 0, 
            autosuspend_delay = 0, 
            last_busy = 0, 
            active_time = 0, 
            suspended_time = 0, 
            accounting_timestamp = 0, 
            subsys_data = 0x0, 
            set_latency_tolerance = 0x0, 
            qos = 0x0
          }, 
          pm_domain = 0x0, 
          msi_domain = 0x0, 
          pins = 0x0, 
          msi_list = {
            next = 0xc18fd75c, 
            prev = 0xc18fd75c
          }, 
          dma_ops = 0x0, 
          dma_mask = 0x0, 
          coherent_dma_mask = 0, 
          bus_dma_limit = 0, 
          dma_range_map = 0x0, 
          dma_parms = 0x0, 
          dma_pools = {
            next = 0xc18fd788, 
            prev = 0xc18fd788
          }, 
          dma_mem = 0x0, 
          cma_area = 0x0, 
          archdata = {
            dma_coherent = 0, 
            dma_ops_setup = 0
          }, 
          of_node = 0x0, 
          fwnode = 0x0, 
          devt = 84934663, 
          id = 0, 
          devres_lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 0, 
                    tickets = {
                      owner = 0, 
                      next = 0
                    }
                  }
                }
              }
            }
          }, 
          devres_head = {
            next = 0xc18fd7b0, 
            prev = 0xc18fd7b0
          }, 
          class = 0xbf192014 <video_class>, 
          groups = 0x0, 
          release = 0xbf16a6a0 <v4l2_device_release>, 
          iommu_group = 0x0, 
          iommu = 0x0, 
          offline_disabled = false, 
          offline = false, 
          of_node_reused = false, 
          state_synced = false, 
          dma_coherent = false
        }, 
        cdev = 0xc31be800, 
        v4l2_dev = 0xc18fd034, 
        dev_parent = 0xc1a4b610, 
        ctrl_handler = 0xc18fdea0, 
        queue = 0xc18fd3a8, 
        prio = 0xc18fd074, 
        name = "unicam-image", '\000' <repeats 19 times>, 
        vfl_type = VFL_TYPE_VIDEO, 
        vfl_dir = VFL_DIR_RX, 
        minor = 7, 
        num = 0, 
        flags = 3, 
        index = 0, 
        fh_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 146475195, 
                  tickets = {
                    owner = 2235, 
                    next = 2235
                  }
                }
              }
            }
          }
        }, 
        fh_list = {
          next = 0xc373a580, 
          prev = 0xc373a580
        }, 
        dev_debug = 0, 
        tvnorms = 0, 
        release = 0xbf25c534 <unicam_node_release>, 
        ioctl_ops = 0xbf25e364 <unicam_ioctl_ops>, 
        valid_ioctls = {470778677, 469763056, 1065354201, 156, 0, 0}, 
        lock = 0xc18fd508
      }, 
      dev = 0xc18fd000, 
      pad = {
        graph_obj = {
          mdev = 0xc18fd090, 
          id = 16777220, 
          list = {
            next = 0xc18fde74, 
            prev = 0xc340b15c
          }
        }, 
        entity = 0xc18fd520, 
        index = 0, 
        sig_type = PAD_SIGNAL_DEFAULT, 
        flags = 1
      }, 
      embedded_lines = 0, 
      dummy_buf_cpu_addr = 0xded34000, 
      dummy_buf_dma_addr = 3738386432
    }, {
      registered = true, 
      open = 0, 
      streaming = false, 
      pad_id = 1, 
      cur_frm = 0x0, 
      next_frm = 0x0, 
      fmt = 0xbf25e27c <formats+560>, 
      v_fmt = {
        type = 13, 
        fmt = {
          pix = {
            width = 1397638483, 
            height = 8192, 
            pixelformat = 0, 
            field = 0, 
            bytesperline = 0, 
            sizeimage = 0, 
            colorspace = 0, 
            priv = 0, 
            flags = 0, 
            {
              ycbcr_enc = 0, 
              hsv_enc = 0
            }, 
            quantization = 0, 
            xfer_func = 0
          }, 
          pix_mp = {
            width = 1397638483, 
            height = 8192, 
            pixelformat = 0, 
            field = 0, 
            colorspace = 0, 
            plane_fmt = {{
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }, {
                sizeimage = 0, 
                bytesperline = 0, 
                reserved = {0, 0, 0, 0, 0, 0}
              }}, 
            num_planes = 0 '\000', 
            flags = 0 '\000', 
            {
              ycbcr_enc = 0 '\000', 
              hsv_enc = 0 '\000'
            }, 
            quantization = 0 '\000', 
            xfer_func = 0 '\000', 
            reserved = "\000\000\000\000\000\000"
          }, 
          win = {
            w = {
              left = 1397638483, 
              top = 8192, 
              width = 0, 
              height = 0
            }, 
            field = 0, 
            chromakey = 0, 
            clips = 0x0, 
            clipcount = 0, 
            bitmap = 0x0, 
            global_alpha = 0 '\000'
          }, 
          vbi = {
            sampling_rate = 1397638483, 
            offset = 8192, 
            samples_per_line = 0, 
            sample_format = 0, 
            start = {0, 0}, 
            count = {0, 0}, 
            flags = 0, 
            reserved = {0, 0}
          }, 
          sliced = {
            service_set = 17747, 
            service_lines = {{21326, 8192, 0 <repeats 22 times>}, {0 <repeats 24 times>}}, 
            io_size = 0, 
            reserved = {0, 0}
          }, 
          sdr = {
            pixelformat = 1397638483, 
            buffersize = 8192, 
            reserved = '\000' <repeats 23 times>
          }, 
          meta = {
            dataformat = 1397638483, 
            buffersize = 8192
          }, 
          raw_data = "SENS\000 ", '\000' <repeats 193 times>
        }
      }, 
      m_fmt = {
        width = 3273386880, 
        height = 3278649980, 
        code = 3278649960, 
        field = 3205676232, 
        colorspace = 3225507892, 
        {
          ycbcr_enc = 0, 
          hsv_enc = 0
        }, 
        quantization = 0, 
        xfer_func = 52736, 
        flags = 48914, 
        reserved = {15020, 50028, 14976, 50028, 52736, 48914, 51848, 48914, 0, 0}
      }, 
      buffer_queue = {
        type = 13, 
        io_modes = 21, 
        dev = 0xc1a4b610, 
        dma_attrs = 0, 
        bidirectional = 0, 
        fileio_read_once = 0, 
        fileio_write_immediately = 0, 
        allow_zero_bytesused = 0, 
        quirk_poll_must_check_waiting_for_buffers = 1, 
        supports_requests = 0, 
        requires_requests = 0, 
        uses_qbuf = 0, 
        uses_requests = 0, 
        allow_cache_hints = 0, 
        lock = 0xc18fdb10, 
        owner = 0x0, 
        ops = 0xbf25e310 <unicam_video_qops>, 
        mem_ops = 0xbf1af0f8 <vb2_dma_contig_memops>, 
        buf_ops = 0xbf3ef494 <v4l2_buf_ops>, 
        drv_priv = 0xc18fd898, 
        subsystem_flags = 0, 
        buf_struct_size = 648, 
        timestamp_flags = 8192, 
        gfp_flags = 0, 
        min_buffers_needed = 1, 
        alloc_devs = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
        mmap_lock = {
          owner = {
            counter = 0
          }, 
          wait_lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 0, 
                    tickets = {
                      owner = 0, 
                      next = 0
                    }
                  }
                }
              }
            }
          }, 
          osq = {
            tail = {
              counter = 0
            }
          }, 
          wait_list = {
            next = 0xc18fda1c, 
            prev = 0xc18fda1c
          }
        }, 
        memory = 0, 
        dma_dir = DMA_FROM_DEVICE, 
        bufs = {0x0 <repeats 32 times>}, 
        num_buffers = 0, 
        queued_list = {
          next = 0xc18fdab0, 
          prev = 0xc18fdab0
        }, 
        queued_count = 0, 
        owned_by_drv_count = {
          counter = 0
        }, 
        done_list = {
          next = 0xc18fdac0, 
          prev = 0xc18fdac0
        }, 
        done_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 0, 
                  tickets = {
                    owner = 0, 
                    next = 0
                  }
                }
              }
            }
          }
        }, 
        done_wq = {
          lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 0, 
                    tickets = {
                      owner = 0, 
                      next = 0
                    }
                  }
                }
              }
            }
          }, 
          head = {
            next = 0xc18fdad0, 
            prev = 0xc18fdad0
          }
        }, 
        streaming = 0, 
        start_streaming_called = 0, 
        error = 0, 
        waiting_for_buffers = 0, 
        waiting_in_dqbuf = 0, 
        is_multiplanar = 0, 
        is_output = 0, 
        copy_timestamp = 0, 
        last_buffer_dequeued = 0, 
        fileio = 0x0, 
        threadio = 0x0, 
        name = "cap-(ptrval)", '\000' <repeats 19 times>
      }, 
      dma_queue = {
        next = 0xc18fdb04, 
        prev = 0xc18fdb04
      }, 
      dma_queue_lock = {
        {
          rlock = {
            raw_lock = {
              {
                slock = 0, 
                tickets = {
                  owner = 0, 
                  next = 0
                }
              }
            }
          }
        }
      }, 
      lock = {
        owner = {
          counter = 0
        }, 
        wait_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 0, 
                  tickets = {
                    owner = 0, 
                    next = 0
                  }
                }
              }
            }
          }
        }, 
        osq = {
          tail = {
            counter = 0
          }
        }, 
        wait_list = {
          next = 0xc18fdb1c, 
          prev = 0xc18fdb1c
        }
      }, 
      video_dev = {
        entity = {
          graph_obj = {
            mdev = 0xc18fd090, 
            id = 9, 
            list = {
              next = 0xc18fd144, 
              prev = 0xc18fd528
            }
          }, 
          name = 0xc18fddf0 "unicam-embedded", 
          obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE, 
          function = 65537, 
          flags = 0, 
          num_pads = 1, 
          num_links = 0, 
          num_backlinks = 0, 
          internal_idx = 3, 
          pads = 0xc18fde6c, 
          links = {
            next = 0xc18fdb58, 
            prev = 0xc18fdb58
          }, 
          ops = 0x0, 
          stream_count = 0, 
          use_count = 0, 
          pipe = 0x0, 
          info = {
            dev = {
              major = 81, 
              minor = 8
            }
          }
        }, 
        intf_devnode = 0xc31bee80, 
        pipe = {
          streaming_count = 0, 
          graph = {
            stack = {{
                entity = 0x0, 
                link = 0x0
              } <repeats 16 times>}, 
            ent_enum = {
              bmap = 0x0, 
              idx_max = 0
            }, 
            top = 0
          }
        }, 
        fops = 0xbf25e340 <unicam_fops>, 
        device_caps = 92274688, 
        dev = {
          kobj = {
            name = 0xc31becc0 "video1", 
            entry = {
              next = 0xc340b4f4, 
              prev = 0xc18fd614
            }, 
            parent = 0xc31be8c0, 
            kset = 0xc1978600, 
            ktype = 0xc12f0948 <device_ktype>, 
            sd = 0xc34704d0, 
            kref = {
              refcount = {
                refs = {
                  counter = 3
                }
              }
            }, 
            state_initialized = 1, 
            state_in_sysfs = 1, 
            state_add_uevent_sent = 1, 
            state_remove_uevent_sent = 0, 
            uevent_suppress = 0
          }, 
          parent = 0xc1a4b610, 
          p = 0xc33e5200, 
          init_name = 0x0, 
          type = 0x0, 
          bus = 0x0, 
          driver = 0x0, 
          platform_data = 0x0, 
          driver_data = 0xc18fd898, 
          mutex = {
            owner = {
              counter = 0
            }, 
            wait_lock = {
              {
                rlock = {
                  raw_lock = {
                    {
                      slock = 0, 
                      tickets = {
                        owner = 0, 
                        next = 0
                      }
                    }
                  }
                }
              }
            }, 
            osq = {
              tail = {
                counter = 0
              }
            }, 
            wait_list = {
              next = 0xc18fdc68, 
              prev = 0xc18fdc68
            }
          }, 
          links = {
            suppliers = {
              next = 0xc18fdc70, 
              prev = 0xc18fdc70
            }, 
            consumers = {
              next = 0xc18fdc78, 
              prev = 0xc18fdc78
            }, 
            needs_suppliers = {
              next = 0xc18fdc80, 
              prev = 0xc18fdc80
            }, 
            defer_hook = {
              next = 0xc18fdc88, 
              prev = 0xc18fdc88
            }, 
            need_for_probe = false, 
            status = DL_DEV_NO_DRIVER
          }, 
          power = {
            power_state = {
              event = 0
            }, 
            can_wakeup = 0, 
            async_suspend = 0, 
            in_dpm_list = false, 
            is_prepared = false, 
            is_suspended = false, 
            is_noirq_suspended = false, 
            is_late_suspended = false, 
            no_pm = false, 
            early_init = true, 
            direct_complete = false, 
            driver_flags = 0, 
            lock = {
              {
                rlock = {
                  raw_lock = {
                    {
                      slock = 0, 
                      tickets = {
                        owner = 0, 
                        next = 0
                      }
                    }
                  }
                }
              }
            }, 
            should_wakeup = 0, 
            suspend_timer = {
              node = {
                node = {
                  __rb_parent_color = 3247430832, 
                  rb_right = 0x0, 
                  rb_left = 0x0
                }, 
                expires = 0
              }, 
              _softexpires = 0, 
              function = 0xc0849120 <pm_suspend_timer_fn>, 
              base = 0xeff20680, 
              state = 0 '\000', 
              is_rel = 0 '\000', 
              is_soft = 0 '\000', 
              is_hard = 0 '\000'
            }, 
            timer_expires = 0, 
            work = {
              data = {
                counter = -32
              }, 
              entry = {
                next = 0xc18fdcec, 
                prev = 0xc18fdcec
              }, 
              func = 0xc08493a0 <pm_runtime_work>
            }, 
            wait_queue = {
              lock = {
                {
                  rlock = {
                    raw_lock = {
                      {
                        slock = 0, 
                        tickets = {
                          owner = 0, 
                          next = 0
                        }
                      }
                    }
                  }
                }
              }, 
              head = {
                next = 0xc18fdcfc, 
                prev = 0xc18fdcfc
              }
            }, 
            wakeirq = 0x0, 
            usage_count = {
              counter = 0
            }, 
            child_count = {
              counter = 0
            }, 
            disable_depth = 1, 
            idle_notification = 0, 
            request_pending = 0, 
            deferred_resume = 0, 
            runtime_auto = 1, 
            ignore_children = false, 
            no_callbacks = 0, 
            irq_safe = 0, 
            use_autosuspend = 0, 
            timer_autosuspends = 0, 
            memalloc_noio = 0, 
            links_count = 0, 
            request = RPM_REQ_NONE, 
            runtime_status = RPM_SUSPENDED, 
            runtime_error = 0, 
            autosuspend_delay = 0, 
            last_busy = 0, 
            active_time = 0, 
            suspended_time = 0, 
            accounting_timestamp = 0, 
            subsys_data = 0x0, 
            set_latency_tolerance = 0x0, 
            qos = 0x0
          }, 
          pm_domain = 0x0, 
          msi_domain = 0x0, 
          pins = 0x0, 
          msi_list = {
            next = 0xc18fdd64, 
            prev = 0xc18fdd64
          }, 
          dma_ops = 0x0, 
          dma_mask = 0x0, 
          coherent_dma_mask = 0, 
          bus_dma_limit = 0, 
          dma_range_map = 0x0, 
          dma_parms = 0x0, 
          dma_pools = {
            next = 0xc18fdd90, 
            prev = 0xc18fdd90
          }, 
          dma_mem = 0x0, 
          cma_area = 0x0, 
          archdata = {
            dma_coherent = 0, 
            dma_ops_setup = 0
          }, 
          of_node = 0x0, 
          fwnode = 0x0, 
          devt = 84934664, 
          id = 0, 
          devres_lock = {
            {
              rlock = {
                raw_lock = {
                  {
                    slock = 0, 
                    tickets = {
                      owner = 0, 
                      next = 0
                    }
                  }
                }
              }
            }
          }, 
          devres_head = {
            next = 0xc18fddb8, 
            prev = 0xc18fddb8
          }, 
          class = 0xbf192014 <video_class>, 
          groups = 0x0, 
          release = 0xbf16a6a0 <v4l2_device_release>, 
          iommu_group = 0x0, 
          iommu = 0x0, 
          offline_disabled = false, 
          offline = false, 
          of_node_reused = false, 
          state_synced = false, 
          dma_coherent = false
        }, 
        cdev = 0xc31bec40, 
        v4l2_dev = 0xc18fd034, 
        dev_parent = 0xc1a4b610, 
        ctrl_handler = 0x0, 
        queue = 0xc18fd9b0, 
        prio = 0xc18fd074, 
        name = "unicam-embedded", '\000' <repeats 16 times>, 
        vfl_type = VFL_TYPE_VIDEO, 
        vfl_dir = VFL_DIR_RX, 
        minor = 8, 
        num = 1, 
        flags = 3, 
        index = 1, 
        fh_lock = {
          {
            rlock = {
              raw_lock = {
                {
                  slock = 655370, 
                  tickets = {
                    owner = 10, 
                    next = 10
                  }
                }
              }
            }
          }
        }, 
        fh_list = {
          next = 0xc18fde2c, 
          prev = 0xc18fde2c
        }, 
        dev_debug = 0, 
        tvnorms = 0, 
        release = 0xbf25c534 <unicam_node_release>, 
        ioctl_ops = 0xbf25e364 <unicam_ioctl_ops>, 
        valid_ioctls = {68125493, 192, 1040187481, 0, 0, 0}, 
        lock = 0xc18fdb10
      }, 
      dev = 0xc18fd000, 
      pad = {
        graph_obj = {
          mdev = 0xc18fd090, 
          id = 16777226, 
          list = {
            next = 0xc18fd154, 
            prev = 0xc18fd86c
          }
        }, 
        entity = 0xc18fdb28, 
        index = 0, 
        sig_type = PAD_SIGNAL_DEFAULT, 
        flags = 1
      }, 
      embedded_lines = 1, 
      dummy_buf_cpu_addr = 0xded35000, 
      dummy_buf_dma_addr = 3738390528
    }}, 
  ctrl_handler = {
    _lock = {
      owner = {
        counter = 0
      }, 
      wait_lock = {
        {
          rlock = {
            raw_lock = {
              {
                slock = 0, 
                tickets = {
                  owner = 0, 
                  next = 0
                }
              }
            }
          }
        }
      }, 
      osq = {
        tail = {
          counter = 0
        }
      }, 
      wait_list = {
        next = 0xc18fdeac, 
        prev = 0xc18fdeac
      }
    }, 
    lock = 0xc18fdea0, 
    ctrls = {
      next = 0xc3008cc0, 
      prev = 0xc3008d80
    }, 
    ctrl_refs = {
      next = 0xc31be680, 
      prev = 0xc31be780
    }, 
    cached = 0xc31be780, 
    buckets = 0xc335be00, 
    notify = 0x0, 
    notify_priv = 0x0, 
    nr_of_buckets = 3, 
    error = 0, 
    request_is_queued = false, 
    requests = {
      next = 0xc18fdee4, 
      prev = 0xc18fdee4
    }, 
    requests_queued = {
      next = 0xc18fdeec, 
      prev = 0xc18fdeec
    }, 
    req_obj = {
      ops = 0x0, 
      priv = 0x0, 
      req = 0x0, 
      list = {
        next = 0xc18fdf00, 
        prev = 0xc18fdf00
      }, 
      kref = {
        refcount = {
          refs = {
            counter = 1
          }
        }
      }, 
      completed = false
    }
  }
}
Contents of the unicam buffer that is being deleted (?)
$30 = {
  vb = {
    vb2_buf = {
      vb2_queue = 0xc18fd3a8, 
      index = 0, 
      type = 1, 
      memory = 1, 
      num_planes = 1, 
      timestamp = 165248773034, 
      request = 0x0, 
      req_obj = {
        ops = 0x0, 
        priv = 0x0, 
        req = 0x0, 
        list = {
          next = 0x0, 
          prev = 0x0
        }, 
        kref = {
          refcount = {
            refs = {
              counter = 0
            }
          }
        }, 
        completed = false
      }, 
      state = VB2_BUF_STATE_ACTIVE, 
      synced = 1, 
      prepared = 1, 
      copied_timestamp = 0, 
      need_cache_sync_on_prepare = 1, 
      need_cache_sync_on_finish = 1, 
      planes = {{
          mem_priv = 0xc4015f00, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 2592000, 
          length = 2592000, 
          min_length = 2592000, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }, {
          mem_priv = 0x0, 
          dbuf = 0x0, 
          dbuf_mapped = 0, 
          bytesused = 0, 
          length = 0, 
          min_length = 0, 
          m = {
            offset = 0, 
            userptr = 0, 
            fd = 0
          }, 
          data_offset = 0
        }}, 
      queued_entry = {
        next = 0xc31f2948, 
        prev = 0xc31f2148
      }, 
      done_entry = {
        next = 0x100, 
        prev = 0x122
      }
    }, 
    flags = 0, 
    field = 1, 
    timecode = {
      type = 0, 
      flags = 0, 
      frames = 0 '\000', 
      seconds = 0 '\000', 
      minutes = 0 '\000', 
      hours = 0 '\000', 
      userbits = "\000\000\000"
    }, 
    sequence = 0, 
    request_fd = -1, 
    is_held = false, 
    planes = {{
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 2592000, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }, {
        mem_priv = 0x0, 
        dbuf = 0x0, 
        dbuf_mapped = 0, 
        bytesused = 0, 
        length = 0, 
        min_length = 0, 
        m = {
          offset = 0, 
          userptr = 0, 
          fd = 0
        }, 
        data_offset = 0
      }}, 
    det_state = VB2_BUF_STATE_DEQUEUED
  }, 
  list = {
    next = 0x100, 
    prev = 0x122
  }
}

Suspicious lists:

(gdb) lx-list-check &unicam->node[0].dma_queue
Starting with: {
  next = 0xc31f3280, 
  prev = 0xc31f2680
}
next.prev != current: current@0xc18fd4fc={
  next = 0xc31f3280, 
  prev = 0xc31f2680
} next@0xc31f3280={
  next = 0x100, 
  prev = 0x122
}
(gdb) lx-list-check buf->list # this is the one being deleted from the list
Starting with: {
  next = 0x100, 
  prev = 0x122
}
prev is not accessible: current@0xc31f3280={
  next = 0x100, 
  prev = 0x122
}

I'd be happy to send a complete memory dump, but I couldn't find anything like that apart from kdump, which is likely not working due to its reliance on kexec.

@JakubVanek
Copy link
Contributor

JakubVanek commented Mar 4, 2021

After rebuilding the kernel with list debugging enabled, I received a BUG caused by (potential?) list corruption here (this might be related to the warning instead of the NULL though):

(gdb) bt
#0  0xc0730ad8 in __list_add_valid (new=new@entry=0xc340e680, prev=prev@entry=0xc340e680, next=next@entry=0xc2c084fc) at lib/list_debug.c:29
#1  0xbf1f4748 in __list_add (next=0xc2c084fc, prev=0xc340e680, new=0xc340e680)
#2  list_add_tail (head=0xc2c084fc, new=0xc340e680) at ./include/linux/list.h:100
#3  unicam_buffer_queue (vb=0xc340e400) at drivers/media/platform/bcm2835/bcm2835-unicam.c:1312
#4  0xbf0eac50 in __enqueue_in_driver (vb=vb@entry=0xc340e400)
#5  0xbf0ed398 in vb2_core_qbuf (q=q@entry=0xc2c083a8, index=<optimized out>, pb=pb@entry=0xc367be3c, req=<optimized out>)
#6  0xbf264e8c in vb2_qbuf (q=0xc2c083a8, mdev=<optimized out>, b=0xc367be3c)
#7  0xbf264f20 in vb2_ioctl_qbuf (file=0xc31a9f00, priv=<optimized out>, p=0xc367be3c)
#8  0xbf164ee4 in v4l_qbuf (ops=0xbf1f8364 <unicam_ioctl_ops>, file=file@entry=0xc31a9f00, fh=fh@entry=0xc32d1c00, arg=arg@entry=0xc367be3c) at drivers/media/v4l2-core/v4l2-ioctl.c:2072
#9  0xbf169954 in __video_do_ioctl (file=file@entry=0xc31a9f00, cmd=cmd@entry=3226490383, arg=arg@entry=0xc367be3c) at drivers/media/v4l2-core/v4l2-ioctl.c:2996
#10 0xbf16a408 in video_usercopy (file=0xc31a9f00, orig_cmd=3225703951, arg=3044017664, func=func@entry=0xbf169788 <__video_do_ioctl>) at drivers/media/v4l2-core/v4l2-ioctl.c:3312
#11 0xbf16a888 in video_ioctl2 (file=<optimized out>, cmd=<optimized out>, arg=<optimized out>) at drivers/media/v4l2-core/v4l2-ioctl.c:3349
#12 0xbf161094 in v4l2_ioctl (filp=<optimized out>, cmd=<optimized out>, arg=<optimized out>)
#13 0xc0448dc0 in vfs_ioctl (arg=<optimized out>, cmd=<optimized out>, filp=<optimized out>) at fs/ioctl.c:48
#14 __do_sys_ioctl (arg=3044017664, cmd=3225703951, fd=<optimized out>) at fs/ioctl.c:753
#15 __se_sys_ioctl (fd=<optimized out>, cmd=-1069263345, arg=-1250949632) at fs/ioctl.c:739
#16 0xc0200040 in __idmap_text_end ()

The problem seems to be "list_add double add", as the new and prev arguments of __list_add_valid are the same. Going up the stack frame, it looks like the cause is repeated enqueuing of one buffer to the dma_queue:
source from GDB:

1305	static void unicam_buffer_queue(struct vb2_buffer *vb)
1306	{
1307		struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
1308		struct unicam_buffer *buf = to_unicam_buffer(vb);
1309		unsigned long flags;
1310	
1311		spin_lock_irqsave(&node->dma_queue_lock, flags);
1312		list_add_tail(&buf->list, &node->dma_queue);
1313		spin_unlock_irqrestore(&node->dma_queue_lock, flags);
1314	}

state of the variables:

(gdb) p &$buf->list
$39 = (struct list_head *) 0xc340e680
(gdb) p $node->dma_queue
$40 = {next = 0xc340fe80, prev = 0xc340e680}

@mdevaev mdevaev changed the title TC358743 - crash (or NULL pointer dereference) on cable plugging TC358743 - NULL pointer dereference on cable plugging Mar 5, 2021
@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

@mdevaev and @JakubVanek thank you for the logs and traces you have provided!

I'm afraid I still cannot see where this may be going wrong from the code. Would you be able to capture some more logs for me with the attached patch please? It adds a few more log points to help trace buffer usage. I am weary of adding to much logging, as it could hide the problem. Thanks again for helping to debug this!

With the below patch, there is no need to do echo 5 > /sys/module/bcm2835_unicam/parameters/debug as I bump up the log level in the driver directly.

0001-Unicam-testing.zip

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

Time to build the kernel!

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

Warning without null dereference (first on plug, second on unplug): no-crash.txt

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

Thank you. Ok, I have started to see something strange with the way interrupts occur. It seems this device does not return Unicam Frame End interrupts? Instead we rely on the packet capture PI0 to indicate end of frame? @6by9 can you confirm that?

Additionally, from sequence 2 onward, we only get one isr call per frame, with FS + LC + PI0 which is really not great. After that, our videobuf2 warning occurs. Our buffer handling code is probably not robust enough to handle this sequence, particularly when FE is missing and we rely and PI0.

[  705.473604] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0xC002, sequence 0, lines done 0       <<< FS + PI0
[  705.483659] unicam fe801000.csi: ISR: FE: cur c53c9800, next c53c9800
[  705.508863] unicam fe801000.csi: ISR: End
[  707.203854] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0x4000, sequence 1, lines done 0       <<< FS
[  707.229328] unicam fe801000.csi: ISR: End
[  707.239425] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 1, lines done 0       <<< LC
[  707.244531] unicam fe801000.csi: ISR: End
[  707.253918] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0xC001, sequence 1, lines done 0       <<< FS + PI0
[  707.268064] unicam fe801000.csi: ISR: FE: cur c53c9800, next c53c9000
[  707.292300] unicam fe801000.csi: ISR: End
[  707.302030] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC003, sequence 2, lines done 0       <<< FS + LC + PI0
[  707.316801] unicam fe801000.csi: ISR: FE: cur c53c9000, next c53c8c00
[  707.342066] unicam fe801000.csi: ISR: End
[  707.351564] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC001, sequence 3, lines done 0       <<< FS + LC + PI0
[  707.366263] unicam fe801000.csi: ISR: FE: cur c53c8c00, next c53c8800
[  707.390834] unicam fe801000.csi: ISR: End
[  707.400312] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC003, sequence 4, lines done 0       <<< FS + LC + PI0
[  707.414654] unicam fe801000.csi: ISR: FE: cur c53c8800, next c53c9800
[  707.438182] unicam fe801000.csi: ISR: End
[  707.438196] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC001, sequence 5, lines done 0       <<< FS + LC + PI0
[  707.459265] unicam fe801000.csi: ISR: FE: cur c53c9800, next 00000000
[  707.483773] unicam fe801000.csi: ISR: End
[  707.492739] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC002, sequence 6, lines done 0       <<< FS + LC + PI0
[  707.497458] unicam fe801000.csi: ISR: FE: cur 00000000, next c53c9800
[  707.526747] unicam fe801000.csi: ISR: End
[  707.526757] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC001, sequence 7, lines done 0       <<< FS + LC + PI0
[  707.854294] unicam fe801000.csi: ISR: FE: cur c53c9800, next 00000000
[  707.868427] unicam fe801000.csi: ISR: End

@6by9
Copy link
Contributor

6by9 commented Mar 5, 2021

Based on the original firwmare driver FE detection is sometimes dubious, so CMP0/PI0 is set up to also look for FE (VC = 0 and DT/short packet ID = 1 (FE))

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

I can't catch null dereference right now on the same kernel with the new patch, it seems the new debug logs take up kernel time and reduce the chance of a race.

@6by9
Copy link
Contributor

6by9 commented Mar 5, 2021

The ISR is taking FAR to long to run

[  707.302030] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC003, sequence 2, lines done 0       <<< FS + LC + PI0
[  707.316801] unicam fe801000.csi: ISR: FE: cur c53c9000, next c53c8c00
[  707.342066] unicam fe801000.csi: ISR: End

That looks to be 40ms, which explains why FS + LC + FE/PI0 all occur at the same time. FS+FE/PI0 simultaneously is a condition we can't handle well to determine whether the buffer is actually swapped or not.

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

Based on the original firwmare driver FE detection is sometimes dubious, so CMP0/PI0 is set up to also look for FE (VC = 0 and DT/short packet ID = 1 (FE))

Do you have any experience with this device? It never seems to produce FE interrupts, and often we get only one interrupt per frame with FS + LC + PI0 set together. This is not good as buffer swaps must happen on LC interrupts but only without FE.

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

That looks to be 40ms, which explains why FS + LC + FE/PI0 all occur at the same time. FS+FE/PI0 simultaneously is a condition we can't handle well to determine whether the buffer is actually swapped or not.

Good catch, I missed that. This is likely due to my patch that adds a spinlock wait in that bit of code.

I think the problem starts on the first interrupt where we get FS + PI0. Since LC has not had a chance to swap buffers, cur_buf and next_buf are the same values. We could not do the FE handling if we have a FS + FE simultaneously, but I'm not sure that is the right answer.

@6by9
Copy link
Contributor

6by9 commented Mar 5, 2021

It is Unicam that sometimes fails to trigger on FE, not the CSI2 source failing to produce it.
You'll find the same thing in unicam_lisr with STA & CAM_PI0 -> UNICAM_STAT_FE, and ISTA & CAM_FEI -> UNICAM_STAT_FE.

If you want one of these then I have about 6 here. I need to head past the office and can detour slightly to your place.
(They're generally the Chinese boards from Ebay that come up under a search for "TC358743 Pi", but they work the same as the Auvidea ones for video).

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

I think I have a grasp on the buffer warning now. Hopefully the attached patch should get rid of it. However, I am not convinced that this would also get rid of the NULL deference exception.

@mdevaev can you give this a try whenever you are able to please? I've removed the extra spinlocks so that interrupts should also behave better with this patch.

EDIT: Noticed a typo in the last patch, please reapply this updated one.
0001-Unicam-testing.patch1.zip

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

Building...

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

I had to set debug level to 3 to be able to use ctrl+c.

Also found some interesting thing about i2c (maybe not related):

[  582.917872] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC003, sequence 84, lines done 0
[  582.922439] unicam fe801000.csi: ISR: FE: cur 00000000, next 00000000
[  582.931550] unicam fe801000.csi: Scheduling dummy buffer for node 0
[  582.945364] unicam fe801000.csi: ISR: End
[  582.945371] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 85, lines done 0
[  582.949932] unicam fe801000.csi: schedule_next_buffer: next buf c52fec00, vb c52fec00
[  582.959057] unicam fe801000.csi: ISR: End
[  582.968014] unicam fe801000.csi: ISR: ISTA: 0x5, STA: 0xC003, sequence 85, lines done 0
[  582.972592] unicam fe801000.csi: ISR: FE: cur 00000000, next c52fec00
[  582.981739] unicam fe801000.csi: Scheduling dummy buffer for node 0
[  582.981848] i2c-bcm2835 fe205000.i2c: i2c transfer timed out
[  582.988810] unicam fe801000.csi: ISR: End
[  582.988820] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 86, lines done 0
[  582.995720] tc358743 10-000f: i2c_rd: reading register 0x14 from 0xf failed
[  583.001917] unicam fe801000.csi: schedule_next_buffer: next buf c52fe400, vb c52fe400
[  583.001920] unicam fe801000.csi: ISR: End

Warning and null dereference not yet reproduced

@JakubVanek
Copy link
Contributor

Neither can I reproduce the warning (neither from videobuf2 nor from list corruption) nor the NULL dereference.

Sample dmesg logs with ustreamer using JPEG and H264 encoding: jpeg.log, h264.log.

I think I saw a similar I2C warning earlier, but I cannot get it to appear now.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

It seems the problem is fixed. At least I didn't manage to reproduce it for an hour and a half. I suggest to clean the patch and apply it. It doesn't seem to get any worse :)

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

Good news! I'll prepare a clean commit for a PR soon.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

@naushir If it's not difficult, plz attach the new patch, I will test the final version.

@naushir
Copy link
Contributor

naushir commented Mar 5, 2021

No problem. I will cc you on the PR. Once you confirm it working we will submit it.

However I may not be able to get it ready until later on in the day.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 5, 2021

It's okay, I'll wait. Solving this problem is a top priority for me.

@mdevaev
Copy link
Contributor Author

mdevaev commented Mar 7, 2021

Given the presence of the fix, I think that this issue can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants