-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Unicam dummy buffer overrun fix #5157
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
Conversation
The second patch is mostly speculative, but does no harm... apart from using up a bit more cma memory! |
Both look reasonable, but it would be nice to get response from kralo on #5138 before merging. |
"Circular" is misspelled in the second commit message, and the replicated /2 is a bit clunky - I prefer my buffer size vs padded size approach - but otherwise it looks OK. |
Some feedback would be nice, but LGTM. |
out of ~100 boot runs today, I got the guard word overwritten in every case, but the system never crashed.
Quite interesting, as you note it really happens by chance and not on every dummy buffer write. I support merging this patch. My two comments on this patch:
I suggest not to write "circular buffer", but "dummy buffer". A circular buffer is to me a data structure that has an organized wrap-around on or after the last writable (entry/byte). This does not seem to be the case here, it is really just a dummy area that gets written to "at will" of the hardware.
Your sizing of the dummy buffer currently encodes one known "maximum" case. I would suggest you program the size restrictions, so that upon driver additions or downstream changes, everyone gets a warning. For example (pseudocode!):
or do a hard-wired check
|
It is a circular buffer in the hardware. |
Thanks for testing this, and confirming the fix!
This dummy buffer does act like a circular buffer to Unicam. Unicam ought to reset it's write pointer to the start of the buffer if it thinks it will write past the end address - although it clearly doesn't in certain conditions as we see here...
Using |
Aha! Thank you both for the explanation. |
I'm just compiling a kernel with these mods to see how far the OV9281 is actually overwriting. My other thought is to program the end address to be the stride, not |
EDIT: Ignore that. Setting DUMMY_BUF_SIZE to MAX_BYTESPERLINE is enough. |
Added some extra debug to log how much of the buffer gets corrupted. I've also deliberately added in a sleep in the app before calling QBUF, so we are deliberately dropping buffers. Setting IBEA to BPL (1280 as this is ~180fps 1280x720 Y8), we get an overrun of 256 bytes. (Base buffer address dad42000, corruption starts at dad42500, and ends at dad42600). Setting IBEA to BPL*2, we still get an overrun of 256 bytes. (Base buffer address dad42000, corruption starts at dad42a00, and ends at dad42b00). Setting IBEA to BPL*2 and Y10, we still get an overrun of 256 bytes. (Base buffer address dad42000, corruption starts at dad42c80, and ends at dad42d80). Requesting a stride of 1632 and Y10, still has an overrun of 256 bytes (Base buffer address dad42000, corruption starts at dad42cc0, and ends at dad42dc0). Docs say that IBEA must be a multiple of 16. Using 2*BPL - 16 works without corruption for both 8 and 10 bit, but that feels a little nasty. I have noted that the original script implies the use of CAM0 (address fe800000), but I'm reproducing this on CAM1 anyway. |
Edit: I forgot that it was only running at 60fps, so the delay in the app needed to be increased. |
So IMX462, 1920x1080 RAW10, bytesperline 2400, IBEA sized as BPL. Following discussions I've just tried reducing the buffer size programmed into the hardware to 256 bytes. |
A length of 0 seems "purer" in some way, and is the least-magic magic number. If anything, hitting the same block repeatedly ought to be more efficient, not less. |
What stride value did you use for buffer size of 0? |
Standard as defined by bytesperline. UNICAM_IBLS is only set in unicam_start_rx. |
The Unicam hardware has been observed to cause a buffer overrun when using the dummy buffer as a circular buffer. The conditions that cause the overrun are not fully known, but it seems to occur when the memory bus is heavily loaded. To avoid the overrun, program the hardware with a buffer size of 0 when using the dummy buffer. This will cause overrun into the allocated dummy buffer, but avoid out of bounds writes. Signed-off-by: Naushir Patuck <[email protected]>
Latest revision sets the programmed dummy buffer size to 0, but keeps the allocation at a single page size. |
kernel: configs: Add LAN7430 driver on BCM2711 See: raspberrypi/linux#4117 kernel: Add a pullup/down parameter to PPS DTBO See: raspberrypi/linux#5154 kernel: hwmon: (lm75) Add Atmel AT30TS74 support See: raspberrypi/linux#5158 kernel: vc4-kms-v3d COB and interrupt fixes See: raspberrypi/linux#5121 kernel: Unicam dummy buffer overrun fix See: raspberrypi/linux#5157 kernel: ASoC:ma120x0p: Extend the volume range to -144dB (mute) See: raspberrypi/linux#5160
kernel: configs: Add LAN7430 driver on BCM2711 See: raspberrypi/linux#4117 kernel: Add a pullup/down parameter to PPS DTBO See: raspberrypi/linux#5154 kernel: hwmon: (lm75) Add Atmel AT30TS74 support See: raspberrypi/linux#5158 kernel: vc4-kms-v3d COB and interrupt fixes See: raspberrypi/linux#5121 kernel: Unicam dummy buffer overrun fix See: raspberrypi/linux#5157 kernel: ASoC:ma120x0p: Extend the volume range to -144dB (mute) See: raspberrypi/linux#5160
This fix has been running very nicely on my systems with self-compiled kernel and those updated with rpi-update for a while now. Is there a cadence or projected date when this will make it into the "raspberrypi-kernel".deb archive ? |
The patch just missed the last stable bump. Although there's no official cadence, changes to the stable branch seem to happen roughly every month. Image releases are less frequent. There's another camera-related fix likely in the near future, and perhaps a fix to the NVME booting, but once we've decided about those an update to stable seems reasonable. |
No description provided.