Message ID | CAEmqJPqRYY8T6u1vBFv1aXjkaH60fK3WhkMZSEGQEhoiruk0Zw@mail.gmail.com |
---|---|
State | Not Applicable |
Headers | show |
Series |
|
Related | show |
Quoting Naushir Patuck via libcamera-devel (2022-10-28 10:42:55) > Hi all, > > I wonder if I could get some thoughts regarding a problem we are seeing > with running multiple cameras in separate libcamera processes on Raspberry > Pi (this probably affects any/all platforms though). > > In my scenario, I have libcamera process 1 running "cam -c 1 -C" and > streaming from imx477 using the Raspberry Pi pipeline handler. In process > 2, I have "cam -c 2 -C" running streaming from a USB camera using the > uvcvideo pipeline handler. If I exit process 2, I get the following error > messages: > > [0:01:33.155169911] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video2[16:cap]: Unable to request 0 buffers: Device or resource busy > [0:01:33.155359910] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video3[17:cap]: Unable to request 0 buffers: Device or resource busy > [0:01:33.155460595] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video13[18:out]: Unable to request 0 buffers: Device or resource busy > [0:01:33.155564354] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video14[19:cap]: Unable to request 0 buffers: Device or resource busy > [0:01:33.155664150] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video15[20:cap]: Unable to request 0 buffers: Device or resource busy > [0:01:33.155763483] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > /dev/video16[21:cap]: Unable to request 0 buffers: Device or resource busy > > These errors come up because the V4L2VideoDevice destructor in process 2 is > indirectly calling ioctl(REQBUFS, 0) on all the Unicam and ISP device nodes > while the device driver buffer queues are actively owned and used by > process 1. This does not actively interfere with process 1 running, it > continues happily enough. > > The error here stems from the fact that the RPi pipeline handler > PipelineHandler::match() opens all the device nodes for every Camera object > registered through PipelineHandler::registerCamera(). So even if the > Camera was never used by a process, when terminating the V4L2VideoDevice > destructor will call ioctl(REQBUFS, 0) for every single device. This > behavior is exactly the same for the ipu3 and rkisp1 pipeline handlers. > > So the question is how to fix this and avoid the error messages? > > 1) The V4L2VideoDevice destructor should not call ioctl(REQBUFS, 0) if it > has not allocated buffers for the device: > > diff --git a/src/libcamera/v4l2_videodevice.cpp > b/src/libcamera/v4l2_videodevice.cpp > index e30858c9fa02..108e60f035ab 100644 > --- a/src/libcamera/v4l2_videodevice.cpp > +++ b/src/libcamera/v4l2_videodevice.cpp > @@ -758,7 +758,8 @@ void V4L2VideoDevice::close() > if (!isOpen()) > return; > > - releaseBuffers(); > + if (cache_) > + releaseBuffers(); > delete fdBufferNotifier_; > > 2) All pipeline handlers need to change and avoid calling device open() in > PipelineHandler::match(), and defer this call to when configure() gets > called. > > Option 2 is not trivial, as (at least in the RPi pipeline handler) a bunch > of validation occurs in PipelineHandler::match() that needs the device > nodes to be open. In my opinion, option 1 seems to be the correct thing to > do. > > Any other suggestions or thoughts? As a quick reply, without looking through code - then yes, opeion 1 seems most reasonable. We should not be trying to release things that we haven't claimed in that process. At least the kernel is preventing it from actually releasing any memory - (I believe) - but indeed - it's not a good position to be in, trying to free someone elses buffers. I'd check that releaseBuffers() isn't called anywhere else explicitly (I expect this is just the destructor code path?) which might make the cache_ check better suited in releaseBuffers() itself ... but otherwise it seems sane to make sure we only release resources we acquire. -- Kieran > > Regards, > Naush
On Fri, 28 Oct 2022 at 11:24, Kieran Bingham < kieran.bingham@ideasonboard.com> wrote: > Quoting Naushir Patuck via libcamera-devel (2022-10-28 10:42:55) > > Hi all, > > > > I wonder if I could get some thoughts regarding a problem we are seeing > > with running multiple cameras in separate libcamera processes on > Raspberry > > Pi (this probably affects any/all platforms though). > > > > In my scenario, I have libcamera process 1 running "cam -c 1 -C" and > > streaming from imx477 using the Raspberry Pi pipeline handler. In > process > > 2, I have "cam -c 2 -C" running streaming from a USB camera using the > > uvcvideo pipeline handler. If I exit process 2, I get the following > error > > messages: > > > > [0:01:33.155169911] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video2[16:cap]: Unable to request 0 buffers: Device or resource busy > > [0:01:33.155359910] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video3[17:cap]: Unable to request 0 buffers: Device or resource busy > > [0:01:33.155460595] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video13[18:out]: Unable to request 0 buffers: Device or resource > busy > > [0:01:33.155564354] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video14[19:cap]: Unable to request 0 buffers: Device or resource > busy > > [0:01:33.155664150] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video15[20:cap]: Unable to request 0 buffers: Device or resource > busy > > [0:01:33.155763483] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241 > > /dev/video16[21:cap]: Unable to request 0 buffers: Device or resource > busy > > > > These errors come up because the V4L2VideoDevice destructor in process 2 > is > > indirectly calling ioctl(REQBUFS, 0) on all the Unicam and ISP device > nodes > > while the device driver buffer queues are actively owned and used by > > process 1. This does not actively interfere with process 1 running, it > > continues happily enough. > > > > The error here stems from the fact that the RPi pipeline handler > > PipelineHandler::match() opens all the device nodes for every Camera > object > > registered through PipelineHandler::registerCamera(). So even if the > > Camera was never used by a process, when terminating the V4L2VideoDevice > > destructor will call ioctl(REQBUFS, 0) for every single device. This > > behavior is exactly the same for the ipu3 and rkisp1 pipeline handlers. > > > > So the question is how to fix this and avoid the error messages? > > > > 1) The V4L2VideoDevice destructor should not call ioctl(REQBUFS, 0) if it > > has not allocated buffers for the device: > > > > diff --git a/src/libcamera/v4l2_videodevice.cpp > > b/src/libcamera/v4l2_videodevice.cpp > > index e30858c9fa02..108e60f035ab 100644 > > --- a/src/libcamera/v4l2_videodevice.cpp > > +++ b/src/libcamera/v4l2_videodevice.cpp > > @@ -758,7 +758,8 @@ void V4L2VideoDevice::close() > > if (!isOpen()) > > return; > > > > - releaseBuffers(); > > + if (cache_) > > + releaseBuffers(); > > delete fdBufferNotifier_; > > > > 2) All pipeline handlers need to change and avoid calling device open() > in > > PipelineHandler::match(), and defer this call to when configure() gets > > called. > > > > Option 2 is not trivial, as (at least in the RPi pipeline handler) a > bunch > > of validation occurs in PipelineHandler::match() that needs the device > > nodes to be open. In my opinion, option 1 seems to be the correct thing > to > > do. > > > > Any other suggestions or thoughts? > > As a quick reply, without looking through code - then yes, opeion 1 > seems most reasonable. We should not be trying to release things that we > haven't claimed in that process. > > At least the kernel is preventing it from actually releasing any memory > - (I believe) - but indeed - it's not a good position to be in, trying > to free someone elses buffers. > The kernel handles this correctly, so nothing stops working thankfully! > > I'd check that releaseBuffers() isn't called anywhere else explicitly (I > expect this is just the destructor code path?) which might make the > cache_ check better suited in releaseBuffers() itself ... but otherwise > it seems sane to make sure we only release resources we acquire. > releaseBuffers() only ever gets called from close(), but I'll put the cache_ check in releaseBuffers() to be safe from possible future changes. Naush > -- > Kieran > > > > > > > Regards, > > Naush >
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index e30858c9fa02..108e60f035ab 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -758,7 +758,8 @@ void V4L2VideoDevice::close() if (!isOpen()) return; - releaseBuffers(); + if (cache_) + releaseBuffers(); delete fdBufferNotifier_; 2) All pipeline handlers need to change and avoid calling device open() in