* [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