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

media: bcm2835-unicam: Correctly handle error states on stream on/off #3984

Merged
merged 2 commits into from
Dec 2, 2020

Conversation

naushir
Copy link
Contributor

@naushir naushir commented Dec 2, 2020

On a failure in start_streaming(), the error code would not propagate to
the calling function on all conditions. This would cause the userland
caller to not know of the failure.

Additionally, clk_disable_unprepare() was called unconditionally in
stop_streaming(). This is incorrect in the cases where start_streaming()
fails, and unprepares all clocks as part of the failure cleanup. Ensure
that clk_disable_unprepare() is only called in stop_streaming() if the
clocks are in a prepared state.

Signed-off-by: Naushir Patuck naush@raspberrypi.com

@naushir
Copy link
Contributor Author

naushir commented Dec 2, 2020

@6by9 and @kbingham

return 0;

err_disable_unicam:
unicam_disable(dev);
clk_disable_unprepare(dev->clock);
err_vpu_clock:
ret = clk_set_min_rate(dev->vpu_clock, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ouch - that's subtle!
Good spot ;-)

@6by9
Copy link
Contributor

6by9 commented Dec 2, 2020

This should really be two patches, but never mind.

With the start_streaming fixed to return an error, does the framework actually call stop_streaming if VIDIOC_STREAMOFF is called multiple times? I don't think it will as https://elixir.bootlin.com/linux/latest/source/drivers/media/common/videobuf2/videobuf2-core.c#L1925 will block it.

However isn't it easier to do a

if (!vb2_is_streaming(vq))
   return 0;

at the start of the function, rather than keeping our own internal state? We should never exit start_streaming without either succeeding, or having undone all changes.

@naushir
Copy link
Contributor Author

naushir commented Dec 2, 2020

With the start_streaming fixed to return an error, does the framework actually call stop_streaming if VIDIOC_STREAMOFF is called multiple times? I don't think it will as https://elixir.bootlin.com/linux/latest/source/drivers/media/common/videobuf2/videobuf2-core.c#L1925 will block it.

It does seem to go into stop_streaming() with the error return value fixed. I get the clock_disable_unprepare() errors thrown into the kernel logs.

However isn't it easier to do a

if (!vb2_is_streaming(vq))
   return 0;

at the start of the function, rather than keeping our own internal state? We should never exit start_streaming without either succeeding, or having undone all changes.

Sure, I can make that change and push a new version.

On a failure in start_streaming(), the error code would not propagate to
the calling function on all conditions. This would cause the userland
caller to not know of the failure.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
@naushir
Copy link
Contributor Author

naushir commented Dec 2, 2020

However isn't it easier to do a

if (!vb2_is_streaming(vq))
   return 0;

at the start of the function, rather than keeping our own internal state? We should never exit start_streaming without either succeeding, or having undone all changes.

Turns out, this is not the case :)

In unicam_start_streaming, if both nodes are not set to streaming, we pretend the request was successful without touching clocks:

	node->streaming = true;
	if (!(dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming &&
	      (!dev->node[METADATA_PAD].open ||
	       dev->node[METADATA_PAD].streaming))) {
		/*
		 * Metadata pad must be enabled before image pad if it is
		 * wanted.
		 */
		unicam_dbg(3, dev, "Not all nodes are streaming yet.");
		return 0;
	}

This causes the internal vb2 state to think we are streaming, so the suggested test in unicam_stop_streaming using the vb2 state will pass, and we go and mess around with the clocks when we should not. Having the state tracked in unicam itself does seem to be the cleanest thing to do.

@6by9
Copy link
Contributor

6by9 commented Dec 2, 2020

Ah, that annoying second device node. Who thought that was a good idea?! ;-)

@naushir
Copy link
Contributor Author

naushir commented Dec 2, 2020

Ah, that annoying second device node. Who thought that was a good idea?! ;-)

Indeed. I'll push an update with the existing changes split into 2 patches.

@kbingham
Copy link
Contributor

kbingham commented Dec 2, 2020

Ah, that annoying second device node. Who thought that was a good idea?! ;-)

I'm with you there. I wish metadata travelled with/was associated with the buffer it's representing directly somehow.
Synchronising multiple device nodes for that is such a pain.

@naushir
Copy link
Contributor Author

naushir commented Dec 2, 2020

Synchronising multiple device nodes for that is such a pain.

Tell me about it!

clk_disable_unprepare() is called unconditionally in stop_streaming().
This is incorrect in the cases where start_streaming() fails, and
unprepares all clocks as part of the failure cleanup. To avoid this,
ensure that clk_disable_unprepare() is only called in stop_streaming()
if the clocks are in a prepared state.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Copy link
Contributor

@kbingham kbingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, not quite used to github yet, I thought this was just on the single return bug fix patch, but it looks like here it's on both ;-)
Both look ok to me though I think.

Reviewed-by: Kieran Bingham kieran.bingham@ideasonboard.com

@pelwell pelwell merged commit 52e76d9 into raspberrypi:rpi-5.4.y Dec 2, 2020
@naushir naushir deleted the unicam_clock branch December 2, 2020 16:28
popcornmix added a commit to Hexxeh/rpi-firmware that referenced this pull request Dec 7, 2020
kernel: overlays: Add PCF85063 and PCF85063A to i2c-rtc

kernel: configs: Add RTC_DRV_PCF85063=m

kernel: ARM: dts: CM4 audio pins are not connected

kernel: PCI: brcmstb: Advertise MSI-X support

kernel: media: bcm2835-unicam: Clear clock state when stopping streaming
See: raspberrypi/linux#3986

kernel: media: bcm2835-unicam: Correctly handle error states on stream on/off
See: raspberrypi/linux#3984

kernel: media: i2c: imx219: Selection compliance fixes
See: raspberrypi/linux#3983

kernel: drm/vc4: Correct DSI register definition
See: raspberrypi/linux#3980

firmware: arm_dt: Handle parent interrupt controllers when masking

firmware: config: Add cm4 and pi400 config section filters

firmware: MMAL/IL/ISP component: Set the ISP boost frequency once on open

firmware: sdcard: Remove legacy NOOBS support to support booting from primary partition 4

firmware: arm_loader: Move 2711 RAM to PCIe address 16GB

firmware: video_decode: Add parameter to disable timestamp validation

firmware: Imx477 camera tuning fixes
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032#p1770287
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032&start=25#p1771066
popcornmix added a commit to raspberrypi/firmware that referenced this pull request Dec 7, 2020
kernel: overlays: Add PCF85063 and PCF85063A to i2c-rtc

kernel: configs: Add RTC_DRV_PCF85063=m

kernel: ARM: dts: CM4 audio pins are not connected

kernel: PCI: brcmstb: Advertise MSI-X support

kernel: media: bcm2835-unicam: Clear clock state when stopping streaming
See: raspberrypi/linux#3986

kernel: media: bcm2835-unicam: Correctly handle error states on stream on/off
See: raspberrypi/linux#3984

kernel: media: i2c: imx219: Selection compliance fixes
See: raspberrypi/linux#3983

kernel: drm/vc4: Correct DSI register definition
See: raspberrypi/linux#3980

firmware: arm_dt: Handle parent interrupt controllers when masking

firmware: config: Add cm4 and pi400 config section filters

firmware: MMAL/IL/ISP component: Set the ISP boost frequency once on open

firmware: sdcard: Remove legacy NOOBS support to support booting from primary partition 4

firmware: arm_loader: Move 2711 RAM to PCIe address 16GB

firmware: video_decode: Add parameter to disable timestamp validation

firmware: Imx477 camera tuning fixes
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032#p1770287
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032&start=25#p1771066
popcornmix added a commit to raspberrypi/firmware that referenced this pull request Dec 8, 2020
kernel: overlays: Add PCF85063 and PCF85063A to i2c-rtc

kernel: configs: Add RTC_DRV_PCF85063=m

kernel: ARM: dts: CM4 audio pins are not connected

kernel: media: bcm2835-unicam: Clear clock state when stopping streaming
See: raspberrypi/linux#3986

kernel: media: bcm2835-unicam: Correctly handle error states on stream on/off
See: raspberrypi/linux#3984

kernel: media: i2c: imx219: Selection compliance fixes
See: raspberrypi/linux#3983

firmware: arm_dt: Handle parent interrupt controllers when masking

firmware: config: Add cm4 and pi400 config section filters

firmware: MMAL/IL/ISP component: Set the ISP boost frequency once on open

firmware: sdcard: Remove legacy NOOBS support to support booting from primary partition 4

firmware: arm_loader: Move 2711 RAM to PCIe address 16GB

firmware: video_decode: Add parameter to disable timestamp validation

firmware: Imx477 camera tuning fixes
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032#p1770287
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032&start=25#p1771066
popcornmix added a commit to Hexxeh/rpi-firmware that referenced this pull request Dec 9, 2020
kernel: overlays: Add PCF85063 and PCF85063A to i2c-rtc

kernel: configs: Add RTC_DRV_PCF85063=m

kernel: ARM: dts: CM4 audio pins are not connected

kernel: media: bcm2835-unicam: Clear clock state when stopping streaming
See: raspberrypi/linux#3986

kernel: media: bcm2835-unicam: Correctly handle error states on stream on/off
See: raspberrypi/linux#3984

kernel: media: i2c: imx219: Selection compliance fixes
See: raspberrypi/linux#3983

firmware: arm_dt: Handle parent interrupt controllers when masking

firmware: config: Add cm4 and pi400 config section filters

firmware: MMAL/IL/ISP component: Set the ISP boost frequency once on open

firmware: sdcard: Remove legacy NOOBS support to support booting from primary partition 4

firmware: arm_loader: Move 2711 RAM to PCIe address 16GB

firmware: video_decode: Add parameter to disable timestamp validation

firmware: Imx477 camera tuning fixes
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032#p1770287
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=291032&start=25#p1771066
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

Successfully merging this pull request may close these issues.

4 participants