public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] Potential refcounting
@ 2026-04-27  2:07 Ginger
  2026-04-29  8:36 ` Tariq Toukan
  0 siblings, 1 reply; 4+ messages in thread
From: Ginger @ 2026-04-27  2:07 UTC (permalink / raw)
  To: tariqt; +Cc: netdev, linux-rdma, linux-kernel

Dear Linux kernel maintainers,

My research-based static analyzer found a potential
refcounting/atomicity bug within the
'drivers/net/ethernet/mellanox/mlx4' subsystem, more specifically, in
'drivers/net/ethernet/mellanox/mlx4/cq.c'.

Kernel version: long-term kernel v6.18.9

Potential concurrent triggering executions:
T0:
mlx4_cq_tasklet_cb
     --> if (refcount_dec_and_test(&mcq->refcount))
     --> complete(&mcq->free)

T1:
mlx4_cq_completion
    --> cq->comp(cq);
        --> mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
            --> spin_lock_irqsave(&tasklet_ctx->lock, flags);
            --> refcount_inc(&cq->refcount);
            --> spin_unlock_irqrestore(&tasklet_ctx->lock, flags);

In T1, the refcounting increment on 'cq->refcount)', although within
the protection range of the 'tasklet_ctx->locl', is not synchronized
against T0 because 'refcount_inc()' does not check whether the
refcount has reached zero in T0. This case is potentially problematic
because T0 decrements he 'mcq->refcount' and can enable the
'mlx4_cq_free()' to proceed.

Thank you for your time and consideration.

Best regards,
Ginger

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] Potential refcounting
  2026-04-27  2:07 [bug report] Potential refcounting Ginger
@ 2026-04-29  8:36 ` Tariq Toukan
  2026-04-29 10:13   ` Ginger
  0 siblings, 1 reply; 4+ messages in thread
From: Tariq Toukan @ 2026-04-29  8:36 UTC (permalink / raw)
  To: Ginger; +Cc: netdev, linux-rdma, linux-kernel, ttoukan.linux



On 27/04/2026 5:07, Ginger wrote:
> Dear Linux kernel maintainers,
> 
> My research-based static analyzer found a potential
> refcounting/atomicity bug within the
> 'drivers/net/ethernet/mellanox/mlx4' subsystem, more specifically, in
> 'drivers/net/ethernet/mellanox/mlx4/cq.c'.
> 
> Kernel version: long-term kernel v6.18.9
> 
> Potential concurrent triggering executions:
> T0:
> mlx4_cq_tasklet_cb
>       --> if (refcount_dec_and_test(&mcq->refcount))
>       --> complete(&mcq->free)
> 
> T1:
> mlx4_cq_completion
>      --> cq->comp(cq);
>          --> mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
>              --> spin_lock_irqsave(&tasklet_ctx->lock, flags);
>              --> refcount_inc(&cq->refcount);
>              --> spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
> 
> In T1, the refcounting increment on 'cq->refcount)', although within
> the protection range of the 'tasklet_ctx->locl', is not synchronized
> against T0 because 'refcount_inc()' does not check whether the
> refcount has reached zero in T0. This case is potentially problematic
> because T0 decrements he 'mcq->refcount' and can enable the
> 'mlx4_cq_free()' to proceed.
> 
> Thank you for your time and consideration.
> 
> Best regards,
> Ginger
> 

Hi,

Thanks for your report.

IMO the described race is impossible.

CQs that work with mlx4_add_cq_to_tasklet as their comp() callback (i.e. 
T1) are added to the relevant list only after refcount is incremented.

Hence, if a CQ exists in the list in T0, it necessarily means that 
refcount is already elevated, and calling refcount_dec_and_test is safe.

Regards,
Tariq

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] Potential refcounting
  2026-04-29  8:36 ` Tariq Toukan
@ 2026-04-29 10:13   ` Ginger
  2026-04-29 12:44     ` Jason Gunthorpe
  0 siblings, 1 reply; 4+ messages in thread
From: Ginger @ 2026-04-29 10:13 UTC (permalink / raw)
  To: Tariq Toukan; +Cc: netdev, linux-rdma, ttoukan.linux

Hi Tariq,

Thank you for your prompt and detailed response. I agree with your
point that calling refcount_dec_and_test() is safe.
However, the major concern of the original report is that whether
simply calling 'refcount_inc()' is safe in 'mlx4_add_cq_to_tasklet()':

T0:
if during a tasklet callback calling 'mlx4_cq_tasklet_cb', a destroy
verb arrives, which eventually leads to 'mlx4_cq_free()'. Both
functions can decrement the 'cq->refcount' and potentially enable
cq->free.

T1:
irq fires --> mlx4_cq_completion --> mlx4_add_cq_to_tasklet -->
refcount_inc(). Here, the refcount increment does not check whether it
has been zeroed in T0.

Side note: to see if T1 (i.e., IRQ) can fire, I checked the calling
path to 'mlx4_cq_free' and only 'synchronize_irq()' is seen, but not
'disable_irq()'. It means that T1 may still happen after T0 calls
'mlx4_cq_free()'.

Is the above race possible? IMHO, perhaps it would better to change
'refcount_inc()' to something like 'refcount_inc_not_zero()' if the
race may happen.


Best regards,
Ginger

On Wed, Apr 29, 2026 at 4:36 PM Tariq Toukan <tariqt@nvidia.com> wrote:
>
>
>
> On 27/04/2026 5:07, Ginger wrote:
> > Dear Linux kernel maintainers,
> >
> > My research-based static analyzer found a potential
> > refcounting/atomicity bug within the
> > 'drivers/net/ethernet/mellanox/mlx4' subsystem, more specifically, in
> > 'drivers/net/ethernet/mellanox/mlx4/cq.c'.
> >
> > Kernel version: long-term kernel v6.18.9
> >
> > Potential concurrent triggering executions:
> > T0:
> > mlx4_cq_tasklet_cb
> >       --> if (refcount_dec_and_test(&mcq->refcount))
> >       --> complete(&mcq->free)
> >
> > T1:
> > mlx4_cq_completion
> >      --> cq->comp(cq);
> >          --> mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
> >              --> spin_lock_irqsave(&tasklet_ctx->lock, flags);
> >              --> refcount_inc(&cq->refcount);
> >              --> spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
> >
> > In T1, the refcounting increment on 'cq->refcount)', although within
> > the protection range of the 'tasklet_ctx->locl', is not synchronized
> > against T0 because 'refcount_inc()' does not check whether the
> > refcount has reached zero in T0. This case is potentially problematic
> > because T0 decrements he 'mcq->refcount' and can enable the
> > 'mlx4_cq_free()' to proceed.
> >
> > Thank you for your time and consideration.
> >
> > Best regards,
> > Ginger
> >
>
> Hi,
>
> Thanks for your report.
>
> IMO the described race is impossible.
>
> CQs that work with mlx4_add_cq_to_tasklet as their comp() callback (i.e.
> T1) are added to the relevant list only after refcount is incremented.
>
> Hence, if a CQ exists in the list in T0, it necessarily means that
> refcount is already elevated, and calling refcount_dec_and_test is safe.
>
> Regards,
> Tariq

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] Potential refcounting
  2026-04-29 10:13   ` Ginger
@ 2026-04-29 12:44     ` Jason Gunthorpe
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Gunthorpe @ 2026-04-29 12:44 UTC (permalink / raw)
  To: Ginger; +Cc: Tariq Toukan, netdev, linux-rdma, ttoukan.linux

On Wed, Apr 29, 2026 at 06:13:40PM +0800, Ginger wrote:
> Side note: to see if T1 (i.e., IRQ) can fire, I checked the calling
> path to 'mlx4_cq_free' and only 'synchronize_irq()' is seen, but not
> 'disable_irq()'. It means that T1 may still happen after T0 calls
> 'mlx4_cq_free()'.

synchronize_irq() is supposed to wait for any concurrently running IRQ
threads to finish. New IRQ threads will then be guarenteed to see the
radix_tree_delete() and can't see the CQ being removed here.

Since the refcount is != 0 until after synchronize_irq(), and the irq
can't see the cq after synchronize_irq() there should be no issue.

Jason

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-29 12:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27  2:07 [bug report] Potential refcounting Ginger
2026-04-29  8:36 ` Tariq Toukan
2026-04-29 10:13   ` Ginger
2026-04-29 12:44     ` Jason Gunthorpe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox