On Mon, Jan 26, 2026 at 02:20:24PM +0100, Johan Hovold wrote:
> On Sat, Jan 24, 2026 at 06:46:11PM +0100, Danilo Krummrich wrote:
> > On Sat Jan 24, 2026 at 6:05 PM CET, Johan Hovold wrote:
> > > The revocable implementation uses two separate abstractions, struct
> > > revocable_provider and struct revocable, in order to store the SRCU read
> > > lock index which must be passed unaltered to srcu_read_unlock() in the
> > > same context when a resource is no longer needed:
> > >
> > >   struct revocable {
> > >           struct revocable_provider *rp;
> > >           int idx;
> > >   };
> > >
> > >   void *revocable_try_access(struct revocable *rev)
> > >   {
> > >           struct revocable_provider *rp = rev->rp;
> > >
> > >           rev->idx = srcu_read_lock(&rp->srcu);
> > >           return srcu_dereference(rp->res, &rp->srcu);
> > >   }
> > >
> > >   void revocable_withdraw_access(struct revocable *rev)
> > >   {
> > >           struct revocable_provider *rp = rev->rp;
> > >
> > >           srcu_read_unlock(&rp->srcu, rev->idx);
> > >   }
> > >
> > > Multiple threads may however share the same struct revocable and
> > > therefore potentially overwrite the SRCU index of another thread which
> > > can cause the SRCU synchronisation in revocable_provider_revoke() to
> > > never complete.
> > 
> > I think the easiest fix would be to just return the index to the caller and 
> > let
> > the corresponding revocable macro accessors handle it, such that it is still
> > transparent to the user.
> 
> It can certainly be made to work, but it will be a very different API
> since there would no longer be any need for the non-intuitive
> revocable_provider and revocable split.

Thank you both for the suggestions.  I'll try it out.

Reply via email to