aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xarray.c')
-rw-r--r--lib/xarray.c139
1 files changed, 60 insertions, 79 deletions
diff --git a/lib/xarray.c b/lib/xarray.c
index 8b176f009c08..bbacca576593 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -610,8 +610,8 @@ static int xas_expand(struct xa_state *xas, void *head)
610 * (see the xa_cmpxchg() implementation for an example). 610 * (see the xa_cmpxchg() implementation for an example).
611 * 611 *
612 * Return: If the slot already existed, returns the contents of this slot. 612 * Return: If the slot already existed, returns the contents of this slot.
613 * If the slot was newly created, returns NULL. If it failed to create the 613 * If the slot was newly created, returns %NULL. If it failed to create the
614 * slot, returns NULL and indicates the error in @xas. 614 * slot, returns %NULL and indicates the error in @xas.
615 */ 615 */
616static void *xas_create(struct xa_state *xas) 616static void *xas_create(struct xa_state *xas)
617{ 617{
@@ -1334,44 +1334,31 @@ void *__xa_erase(struct xarray *xa, unsigned long index)
1334 XA_STATE(xas, xa, index); 1334 XA_STATE(xas, xa, index);
1335 return xas_result(&xas, xas_store(&xas, NULL)); 1335 return xas_result(&xas, xas_store(&xas, NULL));
1336} 1336}
1337EXPORT_SYMBOL_GPL(__xa_erase); 1337EXPORT_SYMBOL(__xa_erase);
1338 1338
1339/** 1339/**
1340 * xa_store() - Store this entry in the XArray. 1340 * xa_erase() - Erase this entry from the XArray.
1341 * @xa: XArray. 1341 * @xa: XArray.
1342 * @index: Index into array. 1342 * @index: Index of entry.
1343 * @entry: New entry.
1344 * @gfp: Memory allocation flags.
1345 * 1343 *
1346 * After this function returns, loads from this index will return @entry. 1344 * This function is the equivalent of calling xa_store() with %NULL as
1347 * Storing into an existing multislot entry updates the entry of every index. 1345 * the third argument. The XArray does not need to allocate memory, so
1348 * The marks associated with @index are unaffected unless @entry is %NULL. 1346 * the user does not need to provide GFP flags.
1349 * 1347 *
1350 * Context: Process context. Takes and releases the xa_lock. May sleep 1348 * Context: Any context. Takes and releases the xa_lock.
1351 * if the @gfp flags permit. 1349 * Return: The entry which used to be at this index.
1352 * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry
1353 * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation
1354 * failed.
1355 */ 1350 */
1356void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) 1351void *xa_erase(struct xarray *xa, unsigned long index)
1357{ 1352{
1358 XA_STATE(xas, xa, index); 1353 void *entry;
1359 void *curr;
1360
1361 if (WARN_ON_ONCE(xa_is_internal(entry)))
1362 return XA_ERROR(-EINVAL);
1363 1354
1364 do { 1355 xa_lock(xa);
1365 xas_lock(&xas); 1356 entry = __xa_erase(xa, index);
1366 curr = xas_store(&xas, entry); 1357 xa_unlock(xa);
1367 if (xa_track_free(xa) && entry)
1368 xas_clear_mark(&xas, XA_FREE_MARK);
1369 xas_unlock(&xas);
1370 } while (xas_nomem(&xas, gfp));
1371 1358
1372 return xas_result(&xas, curr); 1359 return entry;
1373} 1360}
1374EXPORT_SYMBOL(xa_store); 1361EXPORT_SYMBOL(xa_erase);
1375 1362
1376/** 1363/**
1377 * __xa_store() - Store this entry in the XArray. 1364 * __xa_store() - Store this entry in the XArray.
@@ -1395,10 +1382,12 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
1395 1382
1396 if (WARN_ON_ONCE(xa_is_internal(entry))) 1383 if (WARN_ON_ONCE(xa_is_internal(entry)))
1397 return XA_ERROR(-EINVAL); 1384 return XA_ERROR(-EINVAL);
1385 if (xa_track_free(xa) && !entry)
1386 entry = XA_ZERO_ENTRY;
1398 1387
1399 do { 1388 do {
1400 curr = xas_store(&xas, entry); 1389 curr = xas_store(&xas, entry);
1401 if (xa_track_free(xa) && entry) 1390 if (xa_track_free(xa))
1402 xas_clear_mark(&xas, XA_FREE_MARK); 1391 xas_clear_mark(&xas, XA_FREE_MARK);
1403 } while (__xas_nomem(&xas, gfp)); 1392 } while (__xas_nomem(&xas, gfp));
1404 1393
@@ -1407,45 +1396,33 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
1407EXPORT_SYMBOL(__xa_store); 1396EXPORT_SYMBOL(__xa_store);
1408 1397
1409/** 1398/**
1410 * xa_cmpxchg() - Conditionally replace an entry in the XArray. 1399 * xa_store() - Store this entry in the XArray.
1411 * @xa: XArray. 1400 * @xa: XArray.
1412 * @index: Index into array. 1401 * @index: Index into array.
1413 * @old: Old value to test against. 1402 * @entry: New entry.
1414 * @entry: New value to place in array.
1415 * @gfp: Memory allocation flags. 1403 * @gfp: Memory allocation flags.
1416 * 1404 *
1417 * If the entry at @index is the same as @old, replace it with @entry. 1405 * After this function returns, loads from this index will return @entry.
1418 * If the return value is equal to @old, then the exchange was successful. 1406 * Storing into an existing multislot entry updates the entry of every index.
1407 * The marks associated with @index are unaffected unless @entry is %NULL.
1419 * 1408 *
1420 * Context: Process context. Takes and releases the xa_lock. May sleep 1409 * Context: Any context. Takes and releases the xa_lock.
1421 * if the @gfp flags permit. 1410 * May sleep if the @gfp flags permit.
1422 * Return: The old value at this index or xa_err() if an error happened. 1411 * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry
1412 * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation
1413 * failed.
1423 */ 1414 */
1424void *xa_cmpxchg(struct xarray *xa, unsigned long index, 1415void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
1425 void *old, void *entry, gfp_t gfp)
1426{ 1416{
1427 XA_STATE(xas, xa, index);
1428 void *curr; 1417 void *curr;
1429 1418
1430 if (WARN_ON_ONCE(xa_is_internal(entry))) 1419 xa_lock(xa);
1431 return XA_ERROR(-EINVAL); 1420 curr = __xa_store(xa, index, entry, gfp);
1432 1421 xa_unlock(xa);
1433 do {
1434 xas_lock(&xas);
1435 curr = xas_load(&xas);
1436 if (curr == XA_ZERO_ENTRY)
1437 curr = NULL;
1438 if (curr == old) {
1439 xas_store(&xas, entry);
1440 if (xa_track_free(xa) && entry)
1441 xas_clear_mark(&xas, XA_FREE_MARK);
1442 }
1443 xas_unlock(&xas);
1444 } while (xas_nomem(&xas, gfp));
1445 1422
1446 return xas_result(&xas, curr); 1423 return curr;
1447} 1424}
1448EXPORT_SYMBOL(xa_cmpxchg); 1425EXPORT_SYMBOL(xa_store);
1449 1426
1450/** 1427/**
1451 * __xa_cmpxchg() - Store this entry in the XArray. 1428 * __xa_cmpxchg() - Store this entry in the XArray.
@@ -1471,6 +1448,8 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
1471 1448
1472 if (WARN_ON_ONCE(xa_is_internal(entry))) 1449 if (WARN_ON_ONCE(xa_is_internal(entry)))
1473 return XA_ERROR(-EINVAL); 1450 return XA_ERROR(-EINVAL);
1451 if (xa_track_free(xa) && !entry)
1452 entry = XA_ZERO_ENTRY;
1474 1453
1475 do { 1454 do {
1476 curr = xas_load(&xas); 1455 curr = xas_load(&xas);
@@ -1478,7 +1457,7 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
1478 curr = NULL; 1457 curr = NULL;
1479 if (curr == old) { 1458 if (curr == old) {
1480 xas_store(&xas, entry); 1459 xas_store(&xas, entry);
1481 if (xa_track_free(xa) && entry) 1460 if (xa_track_free(xa))
1482 xas_clear_mark(&xas, XA_FREE_MARK); 1461 xas_clear_mark(&xas, XA_FREE_MARK);
1483 } 1462 }
1484 } while (__xas_nomem(&xas, gfp)); 1463 } while (__xas_nomem(&xas, gfp));
@@ -1488,7 +1467,7 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
1488EXPORT_SYMBOL(__xa_cmpxchg); 1467EXPORT_SYMBOL(__xa_cmpxchg);
1489 1468
1490/** 1469/**
1491 * xa_reserve() - Reserve this index in the XArray. 1470 * __xa_reserve() - Reserve this index in the XArray.
1492 * @xa: XArray. 1471 * @xa: XArray.
1493 * @index: Index into array. 1472 * @index: Index into array.
1494 * @gfp: Memory allocation flags. 1473 * @gfp: Memory allocation flags.
@@ -1496,33 +1475,32 @@ EXPORT_SYMBOL(__xa_cmpxchg);
1496 * Ensures there is somewhere to store an entry at @index in the array. 1475 * Ensures there is somewhere to store an entry at @index in the array.
1497 * If there is already something stored at @index, this function does 1476 * If there is already something stored at @index, this function does
1498 * nothing. If there was nothing there, the entry is marked as reserved. 1477 * nothing. If there was nothing there, the entry is marked as reserved.
1499 * Loads from @index will continue to see a %NULL pointer until a 1478 * Loading from a reserved entry returns a %NULL pointer.
1500 * subsequent store to @index.
1501 * 1479 *
1502 * If you do not use the entry that you have reserved, call xa_release() 1480 * If you do not use the entry that you have reserved, call xa_release()
1503 * or xa_erase() to free any unnecessary memory. 1481 * or xa_erase() to free any unnecessary memory.
1504 * 1482 *
1505 * Context: Process context. Takes and releases the xa_lock, IRQ or BH safe 1483 * Context: Any context. Expects the xa_lock to be held on entry. May
1506 * if specified in XArray flags. May sleep if the @gfp flags permit. 1484 * release the lock, sleep and reacquire the lock if the @gfp flags permit.
1507 * Return: 0 if the reservation succeeded or -ENOMEM if it failed. 1485 * Return: 0 if the reservation succeeded or -ENOMEM if it failed.
1508 */ 1486 */
1509int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) 1487int __xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp)
1510{ 1488{
1511 XA_STATE(xas, xa, index); 1489 XA_STATE(xas, xa, index);
1512 unsigned int lock_type = xa_lock_type(xa);
1513 void *curr; 1490 void *curr;
1514 1491
1515 do { 1492 do {
1516 xas_lock_type(&xas, lock_type);
1517 curr = xas_load(&xas); 1493 curr = xas_load(&xas);
1518 if (!curr) 1494 if (!curr) {
1519 xas_store(&xas, XA_ZERO_ENTRY); 1495 xas_store(&xas, XA_ZERO_ENTRY);
1520 xas_unlock_type(&xas, lock_type); 1496 if (xa_track_free(xa))
1521 } while (xas_nomem(&xas, gfp)); 1497 xas_clear_mark(&xas, XA_FREE_MARK);
1498 }
1499 } while (__xas_nomem(&xas, gfp));
1522 1500
1523 return xas_error(&xas); 1501 return xas_error(&xas);
1524} 1502}
1525EXPORT_SYMBOL(xa_reserve); 1503EXPORT_SYMBOL(__xa_reserve);
1526 1504
1527#ifdef CONFIG_XARRAY_MULTI 1505#ifdef CONFIG_XARRAY_MULTI
1528static void xas_set_range(struct xa_state *xas, unsigned long first, 1506static void xas_set_range(struct xa_state *xas, unsigned long first,
@@ -1587,8 +1565,9 @@ void *xa_store_range(struct xarray *xa, unsigned long first,
1587 do { 1565 do {
1588 xas_lock(&xas); 1566 xas_lock(&xas);
1589 if (entry) { 1567 if (entry) {
1590 unsigned int order = (last == ~0UL) ? 64 : 1568 unsigned int order = BITS_PER_LONG;
1591 ilog2(last + 1); 1569 if (last + 1)
1570 order = __ffs(last + 1);
1592 xas_set_order(&xas, last, order); 1571 xas_set_order(&xas, last, order);
1593 xas_create(&xas); 1572 xas_create(&xas);
1594 if (xas_error(&xas)) 1573 if (xas_error(&xas))
@@ -1662,7 +1641,7 @@ EXPORT_SYMBOL(__xa_alloc);
1662 * @index: Index of entry. 1641 * @index: Index of entry.
1663 * @mark: Mark number. 1642 * @mark: Mark number.
1664 * 1643 *
1665 * Attempting to set a mark on a NULL entry does not succeed. 1644 * Attempting to set a mark on a %NULL entry does not succeed.
1666 * 1645 *
1667 * Context: Any context. Expects xa_lock to be held on entry. 1646 * Context: Any context. Expects xa_lock to be held on entry.
1668 */ 1647 */
@@ -1674,7 +1653,7 @@ void __xa_set_mark(struct xarray *xa, unsigned long index, xa_mark_t mark)
1674 if (entry) 1653 if (entry)
1675 xas_set_mark(&xas, mark); 1654 xas_set_mark(&xas, mark);
1676} 1655}
1677EXPORT_SYMBOL_GPL(__xa_set_mark); 1656EXPORT_SYMBOL(__xa_set_mark);
1678 1657
1679/** 1658/**
1680 * __xa_clear_mark() - Clear this mark on this entry while locked. 1659 * __xa_clear_mark() - Clear this mark on this entry while locked.
@@ -1692,7 +1671,7 @@ void __xa_clear_mark(struct xarray *xa, unsigned long index, xa_mark_t mark)
1692 if (entry) 1671 if (entry)
1693 xas_clear_mark(&xas, mark); 1672 xas_clear_mark(&xas, mark);
1694} 1673}
1695EXPORT_SYMBOL_GPL(__xa_clear_mark); 1674EXPORT_SYMBOL(__xa_clear_mark);
1696 1675
1697/** 1676/**
1698 * xa_get_mark() - Inquire whether this mark is set on this entry. 1677 * xa_get_mark() - Inquire whether this mark is set on this entry.
@@ -1732,7 +1711,7 @@ EXPORT_SYMBOL(xa_get_mark);
1732 * @index: Index of entry. 1711 * @index: Index of entry.
1733 * @mark: Mark number. 1712 * @mark: Mark number.
1734 * 1713 *
1735 * Attempting to set a mark on a NULL entry does not succeed. 1714 * Attempting to set a mark on a %NULL entry does not succeed.
1736 * 1715 *
1737 * Context: Process context. Takes and releases the xa_lock. 1716 * Context: Process context. Takes and releases the xa_lock.
1738 */ 1717 */
@@ -1829,6 +1808,8 @@ void *xa_find_after(struct xarray *xa, unsigned long *indexp,
1829 entry = xas_find_marked(&xas, max, filter); 1808 entry = xas_find_marked(&xas, max, filter);
1830 else 1809 else
1831 entry = xas_find(&xas, max); 1810 entry = xas_find(&xas, max);
1811 if (xas.xa_node == XAS_BOUNDS)
1812 break;
1832 if (xas.xa_shift) { 1813 if (xas.xa_shift) {
1833 if (xas.xa_index & ((1UL << xas.xa_shift) - 1)) 1814 if (xas.xa_index & ((1UL << xas.xa_shift) - 1))
1834 continue; 1815 continue;
@@ -1899,7 +1880,7 @@ static unsigned int xas_extract_marked(struct xa_state *xas, void **dst,
1899 * 1880 *
1900 * The @filter may be an XArray mark value, in which case entries which are 1881 * The @filter may be an XArray mark value, in which case entries which are
1901 * marked with that mark will be copied. It may also be %XA_PRESENT, in 1882 * marked with that mark will be copied. It may also be %XA_PRESENT, in
1902 * which case all entries which are not NULL will be copied. 1883 * which case all entries which are not %NULL will be copied.
1903 * 1884 *
1904 * The entries returned may not represent a snapshot of the XArray at a 1885 * The entries returned may not represent a snapshot of the XArray at a
1905 * moment in time. For example, if another thread stores to index 5, then 1886 * moment in time. For example, if another thread stores to index 5, then