Page MenuHomeFreeBSD

D38543.diff
No OneTemporary

D38543.diff

diff --git a/sys/compat/linuxkpi/common/src/linux_xarray.c b/sys/compat/linuxkpi/common/src/linux_xarray.c
--- a/sys/compat/linuxkpi/common/src/linux_xarray.c
+++ b/sys/compat/linuxkpi/common/src/linux_xarray.c
@@ -31,6 +31,18 @@
#include <vm/vm_pageout.h>
+/*
+ * Linux' XArray allows to store a NULL pointer as a value. xa_load() would
+ * return NULL for both an unused index and an index set to NULL. But it
+ * impacts xa_alloc() which needs to find the next available index.
+ *
+ * However, our implementation relies on a radix tree (see `linux_radix.c`)
+ * which does not accept NULL pointers as values. I'm not sure this is a
+ * limitation or a feature, so to work around this, a NULL value is replaced by
+ * `NULL_VALUE`, an unlikely address, when we pass it to linux_radix.
+ */
+#define NULL_VALUE (void *)0x1
+
/*
* This function removes the element at the given index and returns
* the pointer to the removed element, if any.
@@ -38,9 +50,15 @@
void *
__xa_erase(struct xarray *xa, uint32_t index)
{
+ void *retval;
+
XA_ASSERT_LOCKED(xa);
- return (radix_tree_delete(&xa->root, index));
+ retval = radix_tree_delete(&xa->root, index);
+ if (retval == NULL_VALUE)
+ retval = NULL;
+
+ return (retval);
}
void *
@@ -68,6 +86,9 @@
retval = radix_tree_lookup(&xa->root, index);
xa_unlock(xa);
+ if (retval == NULL_VALUE)
+ retval = NULL;
+
return (retval);
}
@@ -109,6 +130,8 @@
MPASS((mask & (mask + 1)) == 0);
*pindex = (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0;
+ if (ptr == NULL)
+ ptr = NULL_VALUE;
retry:
retval = radix_tree_insert(&xa->root, *pindex, ptr);
@@ -137,6 +160,9 @@
{
int retval;
+ if (ptr == NULL)
+ ptr = NULL_VALUE;
+
xa_lock(xa);
retval = __xa_alloc(xa, pindex, ptr, mask, gfp);
xa_unlock(xa);
@@ -166,6 +192,8 @@
MPASS((mask & (mask + 1)) == 0);
*pnext_index = (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0;
+ if (ptr == NULL)
+ ptr = NULL_VALUE;
retry:
retval = radix_tree_insert(&xa->root, *pnext_index, ptr);
@@ -220,6 +248,8 @@
int retval;
XA_ASSERT_LOCKED(xa);
+ if (ptr == NULL)
+ ptr = NULL_VALUE;
retry:
retval = radix_tree_insert(&xa->root, index, ptr);
@@ -262,11 +292,15 @@
int retval;
XA_ASSERT_LOCKED(xa);
+ if (ptr == NULL)
+ ptr = NULL_VALUE;
retry:
retval = radix_tree_store(&xa->root, index, &ptr);
switch (retval) {
case 0:
+ if (ptr == NULL_VALUE)
+ ptr = NULL;
break;
case -ENOMEM:
if (likely(gfp & M_WAITOK)) {
@@ -374,6 +408,8 @@
found = radix_tree_iter_find(&xa->root, &iter, &ppslot);
if (likely(found)) {
retval = *ppslot;
+ if (retval == NULL_VALUE)
+ retval = NULL;
*pindex = iter.index;
} else {
retval = NULL;

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 17, 9:55 PM (15 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15843620
Default Alt Text
D38543.diff (2 KB)

Event Timeline