public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] xarray: extract __xa_cmpxchg_raw
@ 2024-11-12 19:25 Tamir Duberstein
  2024-11-12 19:25 ` [PATCH 1/2] xarray: extract xa_zero_to_null Tamir Duberstein
  2024-11-12 19:25 ` [PATCH 2/2] xarray: extract helper from __xa_{insert,cmpxchg} Tamir Duberstein
  0 siblings, 2 replies; 3+ messages in thread
From: Tamir Duberstein @ 2024-11-12 19:25 UTC (permalink / raw)
  To: Andrew Morton, Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, Alice Ryhl, Andreas Hindborg,
	Tamir Duberstein

This series reduces duplication between __xa_cmpxchg and __xa_insert by
extracting a new function that does not coerce zero entries to null on
the return path.

The new function may be used by the upcoming Rust xarray abstraction in
its reservation API where it is useful to tell the difference between
zero entries and null slots.

Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
Tamir Duberstein (2):
      xarray: extract xa_zero_to_null
      xarray: extract helper from __xa_{insert,cmpxchg}

 lib/xarray.c | 50 +++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 25 deletions(-)
---
base-commit: 2d5404caa8c7bb5c4e0435f94b28834ae5456623
change-id: 20241023-xarray-insert-cmpxchg-507661adac1c

Best regards,
-- 
Tamir Duberstein <tamird@gmail.com>


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

* [PATCH 1/2] xarray: extract xa_zero_to_null
  2024-11-12 19:25 [PATCH 0/2] xarray: extract __xa_cmpxchg_raw Tamir Duberstein
@ 2024-11-12 19:25 ` Tamir Duberstein
  2024-11-12 19:25 ` [PATCH 2/2] xarray: extract helper from __xa_{insert,cmpxchg} Tamir Duberstein
  1 sibling, 0 replies; 3+ messages in thread
From: Tamir Duberstein @ 2024-11-12 19:25 UTC (permalink / raw)
  To: Andrew Morton, Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, Alice Ryhl, Andreas Hindborg,
	Tamir Duberstein

Reduce code duplication by extracting a static inline function that
returns its argument if it is non-zero and NULL otherwise.

This changes xas_result to check for errors before checking for zero but
this cannot change the behavior of existing callers:
- __xa_erase: passes the result of xas_store(_, NULL) which cannot fail.
- __xa_store: passes the result of xas_store(_, entry) which may fail.
  xas_store calls xas_create when entry is not NULL which returns NULL
  on error, which is immediately checked. This should not change
  observable behavior.
- __xa_cmpxchg: passes the result of xas_load(_) which might be zero.
  This would previously return NULL regardless of the outcome of
  xas_store but xas_store cannot fail if xas_load returns zero
  because there is no need to allocate memory.
- xa_store_range: same as __xa_erase.

Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 lib/xarray.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/lib/xarray.c b/lib/xarray.c
index 32d4bac8c94ca13e11f350c6bcfcacc2040d0359..1b8305bffbff07adb80334fc83b5dc8e40ba2f50 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -435,6 +435,11 @@ static unsigned long max_index(void *entry)
 	return (XA_CHUNK_SIZE << xa_to_node(entry)->shift) - 1;
 }
 
+static inline void *xa_zero_to_null(void *entry)
+{
+	return xa_is_zero(entry) ? NULL : entry;
+}
+
 static void xas_shrink(struct xa_state *xas)
 {
 	struct xarray *xa = xas->xa;
@@ -451,8 +456,8 @@ static void xas_shrink(struct xa_state *xas)
 			break;
 		if (!xa_is_node(entry) && node->shift)
 			break;
-		if (xa_is_zero(entry) && xa_zero_busy(xa))
-			entry = NULL;
+		if (xa_zero_busy(xa))
+			entry = xa_zero_to_null(entry);
 		xas->xa_node = XAS_BOUNDS;
 
 		RCU_INIT_POINTER(xa->xa_head, entry);
@@ -1474,9 +1479,7 @@ void *xa_load(struct xarray *xa, unsigned long index)
 
 	rcu_read_lock();
 	do {
-		entry = xas_load(&xas);
-		if (xa_is_zero(entry))
-			entry = NULL;
+		entry = xa_zero_to_null(xas_load(&xas));
 	} while (xas_retry(&xas, entry));
 	rcu_read_unlock();
 
@@ -1486,11 +1489,9 @@ EXPORT_SYMBOL(xa_load);
 
 static void *xas_result(struct xa_state *xas, void *curr)
 {
-	if (xa_is_zero(curr))
-		return NULL;
 	if (xas_error(xas))
 		curr = xas->xa_node;
-	return curr;
+	return xa_zero_to_null(curr);
 }
 
 /**

-- 
2.47.0


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

* [PATCH 2/2] xarray: extract helper from __xa_{insert,cmpxchg}
  2024-11-12 19:25 [PATCH 0/2] xarray: extract __xa_cmpxchg_raw Tamir Duberstein
  2024-11-12 19:25 ` [PATCH 1/2] xarray: extract xa_zero_to_null Tamir Duberstein
@ 2024-11-12 19:25 ` Tamir Duberstein
  1 sibling, 0 replies; 3+ messages in thread
From: Tamir Duberstein @ 2024-11-12 19:25 UTC (permalink / raw)
  To: Andrew Morton, Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, Alice Ryhl, Andreas Hindborg,
	Tamir Duberstein

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.

Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 lib/xarray.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/lib/xarray.c b/lib/xarray.c
index 1b8305bffbff07adb80334fc83b5dc8e40ba2f50..2af86bede3c119060650ee8b891751531c6732e7 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -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;
 }
 
 /**
@@ -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);
 

-- 
2.47.0


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

end of thread, other threads:[~2024-11-12 19:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-12 19:25 [PATCH 0/2] xarray: extract __xa_cmpxchg_raw Tamir Duberstein
2024-11-12 19:25 ` [PATCH 1/2] xarray: extract xa_zero_to_null Tamir Duberstein
2024-11-12 19:25 ` [PATCH 2/2] xarray: extract helper from __xa_{insert,cmpxchg} Tamir Duberstein

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