On 5/12/24 17:32, Jason Gunthorpe wrote:
On Fri, May 10, 2024 at 02:54:49PM +0200, Przemek Kitszel wrote:
+ refcount_set(new_ref, 1);
+ ref = __xa_cmpxchg(&irqs, irq, NULL, new_ref, GFP_KERNEL);
+ if (ref) {
+ kfree(new_ref);
+ if (xa_is_err(ref)) {
+ ret = xa_err(ref);
+ goto out;
+ }
+
+ /* Another thread beat us to creating the enrtry. */
+ refcount_inc(ref);
How can that happen? Why not just use a normal simple lock for all of
this so you don't have to mess with refcounts at all? This is not
performance-relevent code at all, but yet with a refcount you cause
almost the same issues that a normal lock would have, plus the increased
complexity of all of the surrounding code (like this, and the crazy
__xa_cmpxchg() call)
Make this simple please.
I find current API of xarray not ideal for this use case, and would like
to fix it, but let me write a proper RFC to don't derail (or slow down)
this series.
I think xarray can do this just fine already??
xa_lock(&irqs);
used = xa_to_value(xa_load(&irqs, irq));
used++;
ret = xa_store(&irqs, irq, xa_mk_value(used));
xa_unlock(&irqs);
And you can safely read the value using the typical xa_load RCU locking.
Jason
What if I want to store some struct, potentially with need of some init
call (say, there will be a spinlock there)?
I believe the solution is to extend xarray so it will alloc the struct
(think flex array or user/priv data for "entry") and even init it
(so two new functions).