On Mon, Jan 12, 2026 at 4:49 PM Boris Brezillon
<[email protected]> wrote:
>
> On Mon, 12 Jan 2026 16:19:52 +0100
> Alice Ryhl <[email protected]> wrote:
>
> > On Mon, Jan 12, 2026 at 3:40 PM Boris Brezillon
> > <[email protected]> wrote:
> > >
> > > On Mon, 12 Jan 2026 12:33:33 +0000
> > > Steven Price <[email protected]> wrote:
> > >
> > > > On 09/01/2026 13:08, Boris Brezillon wrote:
> > > > > +static void panthor_gem_vm_close(struct vm_area_struct *vma)
> > > > > +{
> > > > > +   struct panthor_gem_object *bo = 
> > > > > to_panthor_bo(vma->vm_private_data);
> > > > > +
> > > > > +   if (drm_gem_is_imported(&bo->base))
> > > > > +           goto out;
> > > > > +
> > > > > +   if (refcount_dec_not_one(&bo->cmap.mmap_count))
> > > > > +           goto out;
> > > > > +
> > > > > +   dma_resv_lock(bo->base.resv, NULL);
> > > > > +   if (!refcount_dec_not_one(&bo->cmap.mmap_count))
> > > > > +           refcount_set(&bo->cmap.mmap_count, 0);
> > > > > +   dma_resv_unlock(bo->base.resv);
> > > >
> > > > I don't think this logic is safe. Holding the resv_lock doesn't protect
> > > > against another thread doing a refcount_inc_not_zero() without holding
> > > > the lock.
> > > >
> > > > I think you can just replace the if() part with a refcount_dec() call,
> > > > the lock AFAICT is needed because the following patch wants to be sure
> > > > that !!mmap_count is stable when resv_lock is held.
> > >
> > > I wish I could, but refcount_dec() doesn't let me do the 1 -> 0 without
> > > complaining :P.
> >
> > I'm pretty sure that refcount_dec() is fine with 1->0.
>
> That's not what [1] says. refcount_dec_and_test() is okay though, but
> it'd force us to do a
>
>         (void)refcount_dec_and_test()
>
> and detail why it's okay to ignore the returned value. Not too sure
> which one is better.

You're right, I mixed it up with refcount_dec_and_test().

> > > > I also feel you should invert the conditino for refcount_dec_not_one,
> > > > leading to the following which I feel is easier to read:
> > > >
> > > > static void panthor_gem_vm_close(struct vm_area_struct *vma)
> > > > {
> > > >       [...]
> > > >
> > > >       if (!refcount_dec_not_one(&bo->cmap.mmap_count)) {
> > > >               dma_resv_lock(bo->base.resv, NULL);
> > > >               refcount_dec(&bo->cmap.mmap_count);
> > > >               dma_resv_unlock(bo->base.resv);
> > > >       }
> > >
> > > The best I can do is:
> > >
> > >         if (!refcount_dec_not_one(&bo->cmap.mmap_count)) {
> > >                 dma_resv_lock(bo->base.resv, NULL);
> > >                 if (!refcount_dec_not_one(&bo->cmap.mmap_count))
> > >                         refcount_set(&bo->cmap.mmap_count, 0);
> > >                 dma_resv_unlock(bo->base.resv);
> > >         }
> > >
> > > so we only take the lock when absolutely needed, but the 1 -> 0
> > > transition still has to be done with "if (dec_not_one) set(0)".
> >
> > Why not just use atomic_t and use the atomic inc/dec operations? They
> > don't have saturation, but also do not require treating zero
> > specially.
>
> I had suggested using atomics back when I was reviewing the
> shmem-shrinker stuff to avoid this exact same issue. I can't find the
> thread anymore and I can't remember the rationale either (probably that
> saturation detection was useful, still), but the decision was to use a
> refcount_t. I don't mind using atomics here, but I'd rather not be
> blocked on that when/if I try to move that code into a common lib.
>
> [1]https://elixir.bootlin.com/linux/v6.19-rc4/source/include/linux/refcount.h#L460

It's just a suggestion - no need to block on it.

It sounds like refcount_t should have an refcount_inc_maybe_first()
where 0->1 is ok.

Alice

Alice

Reply via email to