Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xarray: extract xa_zero_to_null

Patch series "xarray: extract __xa_cmpxchg_raw".

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.


This patch (of 2):

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.

Link: https://lkml.kernel.org/r/20241112-xarray-insert-cmpxchg-v1-0-dc2bdd8c4136@gmail.com
Link: https://lkml.kernel.org/r/20241112-xarray-insert-cmpxchg-v1-1-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>

authored by

Tamir Duberstein and committed by
Andrew Morton
74e2712b 4093676f

+9 -8
+9 -8
lib/xarray.c
··· 435 435 return (XA_CHUNK_SIZE << xa_to_node(entry)->shift) - 1; 436 436 } 437 437 438 + static inline void *xa_zero_to_null(void *entry) 439 + { 440 + return xa_is_zero(entry) ? NULL : entry; 441 + } 442 + 438 443 static void xas_shrink(struct xa_state *xas) 439 444 { 440 445 struct xarray *xa = xas->xa; ··· 456 451 break; 457 452 if (!xa_is_node(entry) && node->shift) 458 453 break; 459 - if (xa_is_zero(entry) && xa_zero_busy(xa)) 460 - entry = NULL; 454 + if (xa_zero_busy(xa)) 455 + entry = xa_zero_to_null(entry); 461 456 xas->xa_node = XAS_BOUNDS; 462 457 463 458 RCU_INIT_POINTER(xa->xa_head, entry); ··· 1479 1474 1480 1475 rcu_read_lock(); 1481 1476 do { 1482 - entry = xas_load(&xas); 1483 - if (xa_is_zero(entry)) 1484 - entry = NULL; 1477 + entry = xa_zero_to_null(xas_load(&xas)); 1485 1478 } while (xas_retry(&xas, entry)); 1486 1479 rcu_read_unlock(); 1487 1480 ··· 1489 1486 1490 1487 static void *xas_result(struct xa_state *xas, void *curr) 1491 1488 { 1492 - if (xa_is_zero(curr)) 1493 - return NULL; 1494 1489 if (xas_error(xas)) 1495 1490 curr = xas->xa_node; 1496 - return curr; 1491 + return xa_zero_to_null(curr); 1497 1492 } 1498 1493 1499 1494 /**