[libcamera-devel] [PATCH 3/6] libcamera: control_serializer: Keep handles in sync
paul.elder at ideasonboard.com
paul.elder at ideasonboard.com
Mon Sep 6 10:43:41 CEST 2021
Hi Laurent and Jacopo,
On Mon, Sep 06, 2021 at 02:01:30AM +0300, Laurent Pinchart wrote:
> Hi Jacopo,
>
> On Fri, Sep 03, 2021 at 03:28:41PM +0200, Jacopo Mondi wrote:
> > On Fri, Sep 03, 2021 at 02:46:35PM +0300, Laurent Pinchart wrote:
> > > On Wed, Sep 01, 2021 at 04:37:57PM +0200, Jacopo Mondi wrote:
> > > > When running the IPA in isolated mode, each side of the IPC boundary
> > > > has an instance of the ControlSerializer class.
> > > >
> > > > Each serializer instance tags with a numerical id (handle) each
> > > > ControlInfoMap instance it serializes, to be capable of associating
> > > > ControlList with it at serialization and deserialization time, and
> > > > increments the numerical counter for each newly serialized control info
> > > > map.
> > > >
> > > > Having two instances of the ControlSerializer class running in two
> > > > different process spaces, each instance increments its own counter,
> > > > preventing from maintaining a globally shared state where each
> > > > ControlInfoMap instance is reference by a unique identifier.
> > > >
> > > > Fix this by advancing the serial_ counter at ControlInfoMap
> > > > de-serialization time, so that each newly serialized map will have a
> > > > globally unique identifier.
> > >
> > > That's an interesting one. The control serializer was developed with the
> > > assumption that a ControlInfoMap would only be sent from the pipeline
> > > handler to the IPA, not the other way around.
> > >
> > > > Fixes: 2c5f0ad23aa4 ("libcamera: Add controls serializer")
> > >
> > > Technically, the breakage was introduced by the first change in the IPA
> > > protocol that sent a ControlInfoMap in the IPA to pipeline handler
> > > direction, but I don't mind keeping the Fixes tag as-is.
> > >
> > > > Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> > > > ---
> > > > src/libcamera/control_serializer.cpp | 3 +++
> > > > 1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp
> > > > index 27360526f9eb..08cfecca3078 100644
> > > > --- a/src/libcamera/control_serializer.cpp
> > > > +++ b/src/libcamera/control_serializer.cpp
> > > > @@ -380,6 +380,9 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
> > > > return {};
> > > > }
> > > >
> > > > + /* Keep the info map handles in sync between the two sides of IPC. */
> > > > + serial_ = std::max(serial_, hdr->handle);
> > >
> > > Can it be this simple ? What if the pipeline handler sends a
> > > ControlInfoMap to the IPA at the same time as the IPA sends a
> > > ControlInfoMap to the pipeline handler ? Each side will increment their
> > > serial number, but the same number will refer to two different maps.
> >
> > Yes, this might happen during a capture session, where the PH/IPA
> > interactions are aysnchronous. It can't happen before, as there won't
> > be concurrect calls between the two sides of the IPC
> >
> > A regular run looks like
> >
> > -----------------------------------------------------------------------------
> > PH handle# IPC IPA handl#
> > -----------------------------------------------------------------------------
> > ser(map) 1 --->
> > deser(map)
> > max(0,1)=1
> >
> > <--- ser(map) 2
> > max(1,2)=2
> > deser(map)
> >
> > ser(map) 3
> > ...
> > -----------------------------------------------------------------------------
> >
> > This could break only if a ser/deser sequence is interleaved with
> > another serialization event
> >
> > -----------------------------------------------------------------------------
> > PH handle# IPC IPA handl#
> > -----------------------------------------------------------------------------
> > ser(map) 1 ---->
> >
> > <---- ser(map) 1
> >
> > deser(map)
> > max(1,1)=1
> > max(1,1)=1
> > deser(map)
> >
> > ser(map) 2
> > ...
> > -----------------------------------------------------------------------------
> >
> > Which is very unfortunate but possible.
> >
> > We have no centralized state between the two processes and we have no
> > way to assign handles in the proxies, as they have the same
> > information as the control serializer has.
> >
> > This might seem rather stupid, but we have two sides of the IPC, can't
> > we use even handles on one side and odd ones on the other ? The
> > proxies initialize the controls serializer with a seed (0 or 1) and we
> > simply serial_ += 2 ?
>
> That's very much a hack. A pretty clever one actually :-) With a comment
> to tell that this should likely be revisited (and a very brief
> explanation of why it's done that way), I think I'm fine with it. Paul,
> any comment ?
Ah, I see, you separate the serial number spaces, that way it'll never
conflict. I think that's a good idea.
Paul
>
> > > > +
> > > > /*
> > > > * Use the ControlIdMap corresponding to the id map type. If the type
> > > > * references a globally defined id map (such as controls::controls
>
> --
> Regards,
>
> Laurent Pinchart
More information about the libcamera-devel
mailing list