]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xarray: extract helper from __xa_{insert,cmpxchg}
authorTamir Duberstein <tamird@gmail.com>
Tue, 12 Nov 2024 19:25:37 +0000 (14:25 -0500)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 13 Jan 2025 04:20:58 +0000 (20:20 -0800)
Reduce code duplication by extracting a static inline function.  This
function is identical to __xa_cmpxchg with the exception that it does not
coerce zero entries to null on the return path.

[tamird@gmail.com: fix __xa_erase()]
Link: https://lkml.kernel.org/r/CAJ-ks9kN_qddZ3Ne5d=cADu5POC1rHd4rQcbVSD_spnZOrLLZg@mail.gmail.com
Link: https://lkml.kernel.org/r/20241112-xarray-insert-cmpxchg-v1-2-dc2bdd8c4136@gmail.com
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Andreas Hindborg <a.hindborg@kernel.org>
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
lib/xarray.c

index 1b8305bffbff07adb80334fc83b5dc8e40ba2f50..5da8d18899a1e49628ca084f26a7717c4a826187 100644 (file)
@@ -1491,7 +1491,7 @@ static void *xas_result(struct xa_state *xas, void *curr)
 {
        if (xas_error(xas))
                curr = xas->xa_node;
-       return xa_zero_to_null(curr);
+       return curr;
 }
 
 /**
@@ -1509,7 +1509,7 @@ static void *xas_result(struct xa_state *xas, void *curr)
 void *__xa_erase(struct xarray *xa, unsigned long index)
 {
        XA_STATE(xas, xa, index);
-       return xas_result(&xas, xas_store(&xas, NULL));
+       return xas_result(&xas, xa_zero_to_null(xas_store(&xas, NULL)));
 }
 EXPORT_SYMBOL(__xa_erase);
 
@@ -1568,7 +1568,7 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
                        xas_clear_mark(&xas, XA_FREE_MARK);
        } while (__xas_nomem(&xas, gfp));
 
-       return xas_result(&xas, curr);
+       return xas_result(&xas, xa_zero_to_null(curr));
 }
 EXPORT_SYMBOL(__xa_store);
 
@@ -1601,6 +1601,9 @@ void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
 }
 EXPORT_SYMBOL(xa_store);
 
+static inline void *__xa_cmpxchg_raw(struct xarray *xa, unsigned long index,
+                       void *old, void *entry, gfp_t gfp);
+
 /**
  * __xa_cmpxchg() - Store this entry in the XArray.
  * @xa: XArray.
@@ -1619,6 +1622,13 @@ EXPORT_SYMBOL(xa_store);
  */
 void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
                        void *old, void *entry, gfp_t gfp)
+{
+       return xa_zero_to_null(__xa_cmpxchg_raw(xa, index, old, entry, gfp));
+}
+EXPORT_SYMBOL(__xa_cmpxchg);
+
+static inline void *__xa_cmpxchg_raw(struct xarray *xa, unsigned long index,
+                       void *old, void *entry, gfp_t gfp)
 {
        XA_STATE(xas, xa, index);
        void *curr;
@@ -1637,7 +1647,6 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
 
        return xas_result(&xas, curr);
 }
-EXPORT_SYMBOL(__xa_cmpxchg);
 
 /**
  * __xa_insert() - Store this entry in the XArray if no entry is present.
@@ -1657,26 +1666,16 @@ EXPORT_SYMBOL(__xa_cmpxchg);
  */
 int __xa_insert(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
 {
-       XA_STATE(xas, xa, index);
        void *curr;
+       int errno;
 
-       if (WARN_ON_ONCE(xa_is_advanced(entry)))
-               return -EINVAL;
        if (!entry)
                entry = XA_ZERO_ENTRY;
-
-       do {
-               curr = xas_load(&xas);
-               if (!curr) {
-                       xas_store(&xas, entry);
-                       if (xa_track_free(xa))
-                               xas_clear_mark(&xas, XA_FREE_MARK);
-               } else {
-                       xas_set_err(&xas, -EBUSY);
-               }
-       } while (__xas_nomem(&xas, gfp));
-
-       return xas_error(&xas);
+       curr = __xa_cmpxchg_raw(xa, index, NULL, entry, gfp);
+       errno = xa_err(curr);
+       if (errno)
+               return errno;
+       return (curr != NULL) ? -EBUSY : 0;
 }
 EXPORT_SYMBOL(__xa_insert);