diff options
Diffstat (limited to 'include/linux/xarray.h')
-rw-r--r-- | include/linux/xarray.h | 267 |
1 files changed, 203 insertions, 64 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h index d9514928ddac..564892e19f8c 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h | |||
@@ -289,9 +289,7 @@ struct xarray { | |||
289 | void xa_init_flags(struct xarray *, gfp_t flags); | 289 | void xa_init_flags(struct xarray *, gfp_t flags); |
290 | void *xa_load(struct xarray *, unsigned long index); | 290 | void *xa_load(struct xarray *, unsigned long index); |
291 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | 291 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); |
292 | void *xa_cmpxchg(struct xarray *, unsigned long index, | 292 | void *xa_erase(struct xarray *, unsigned long index); |
293 | void *old, void *entry, gfp_t); | ||
294 | int xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
295 | void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, | 293 | void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, |
296 | void *entry, gfp_t); | 294 | void *entry, gfp_t); |
297 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); | 295 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); |
@@ -344,65 +342,6 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) | |||
344 | } | 342 | } |
345 | 343 | ||
346 | /** | 344 | /** |
347 | * xa_erase() - Erase this entry from the XArray. | ||
348 | * @xa: XArray. | ||
349 | * @index: Index of entry. | ||
350 | * | ||
351 | * This function is the equivalent of calling xa_store() with %NULL as | ||
352 | * the third argument. The XArray does not need to allocate memory, so | ||
353 | * the user does not need to provide GFP flags. | ||
354 | * | ||
355 | * Context: Process context. Takes and releases the xa_lock. | ||
356 | * Return: The entry which used to be at this index. | ||
357 | */ | ||
358 | static inline void *xa_erase(struct xarray *xa, unsigned long index) | ||
359 | { | ||
360 | return xa_store(xa, index, NULL, 0); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * xa_insert() - Store this entry in the XArray unless another entry is | ||
365 | * already present. | ||
366 | * @xa: XArray. | ||
367 | * @index: Index into array. | ||
368 | * @entry: New entry. | ||
369 | * @gfp: Memory allocation flags. | ||
370 | * | ||
371 | * If you would rather see the existing entry in the array, use xa_cmpxchg(). | ||
372 | * This function is for users who don't care what the entry is, only that | ||
373 | * one is present. | ||
374 | * | ||
375 | * Context: Process context. Takes and releases the xa_lock. | ||
376 | * May sleep if the @gfp flags permit. | ||
377 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
378 | * -ENOMEM if memory could not be allocated. | ||
379 | */ | ||
380 | static inline int xa_insert(struct xarray *xa, unsigned long index, | ||
381 | void *entry, gfp_t gfp) | ||
382 | { | ||
383 | void *curr = xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
384 | if (!curr) | ||
385 | return 0; | ||
386 | if (xa_is_err(curr)) | ||
387 | return xa_err(curr); | ||
388 | return -EEXIST; | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * xa_release() - Release a reserved entry. | ||
393 | * @xa: XArray. | ||
394 | * @index: Index of entry. | ||
395 | * | ||
396 | * After calling xa_reserve(), you can call this function to release the | ||
397 | * reservation. If the entry at @index has been stored to, this function | ||
398 | * will do nothing. | ||
399 | */ | ||
400 | static inline void xa_release(struct xarray *xa, unsigned long index) | ||
401 | { | ||
402 | xa_cmpxchg(xa, index, NULL, NULL, 0); | ||
403 | } | ||
404 | |||
405 | /** | ||
406 | * xa_for_each() - Iterate over a portion of an XArray. | 345 | * xa_for_each() - Iterate over a portion of an XArray. |
407 | * @xa: XArray. | 346 | * @xa: XArray. |
408 | * @entry: Entry retrieved from array. | 347 | * @entry: Entry retrieved from array. |
@@ -455,6 +394,7 @@ void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | |||
455 | void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, | 394 | void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, |
456 | void *entry, gfp_t); | 395 | void *entry, gfp_t); |
457 | int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); | 396 | int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); |
397 | int __xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
458 | void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); | 398 | void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); |
459 | void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); | 399 | void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); |
460 | 400 | ||
@@ -487,6 +427,58 @@ static inline int __xa_insert(struct xarray *xa, unsigned long index, | |||
487 | } | 427 | } |
488 | 428 | ||
489 | /** | 429 | /** |
430 | * xa_store_bh() - Store this entry in the XArray. | ||
431 | * @xa: XArray. | ||
432 | * @index: Index into array. | ||
433 | * @entry: New entry. | ||
434 | * @gfp: Memory allocation flags. | ||
435 | * | ||
436 | * This function is like calling xa_store() except it disables softirqs | ||
437 | * while holding the array lock. | ||
438 | * | ||
439 | * Context: Any context. Takes and releases the xa_lock while | ||
440 | * disabling softirqs. | ||
441 | * Return: The entry which used to be at this index. | ||
442 | */ | ||
443 | static inline void *xa_store_bh(struct xarray *xa, unsigned long index, | ||
444 | void *entry, gfp_t gfp) | ||
445 | { | ||
446 | void *curr; | ||
447 | |||
448 | xa_lock_bh(xa); | ||
449 | curr = __xa_store(xa, index, entry, gfp); | ||
450 | xa_unlock_bh(xa); | ||
451 | |||
452 | return curr; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * xa_store_irq() - Erase this entry from the XArray. | ||
457 | * @xa: XArray. | ||
458 | * @index: Index into array. | ||
459 | * @entry: New entry. | ||
460 | * @gfp: Memory allocation flags. | ||
461 | * | ||
462 | * This function is like calling xa_store() except it disables interrupts | ||
463 | * while holding the array lock. | ||
464 | * | ||
465 | * Context: Process context. Takes and releases the xa_lock while | ||
466 | * disabling interrupts. | ||
467 | * Return: The entry which used to be at this index. | ||
468 | */ | ||
469 | static inline void *xa_store_irq(struct xarray *xa, unsigned long index, | ||
470 | void *entry, gfp_t gfp) | ||
471 | { | ||
472 | void *curr; | ||
473 | |||
474 | xa_lock_irq(xa); | ||
475 | curr = __xa_store(xa, index, entry, gfp); | ||
476 | xa_unlock_irq(xa); | ||
477 | |||
478 | return curr; | ||
479 | } | ||
480 | |||
481 | /** | ||
490 | * xa_erase_bh() - Erase this entry from the XArray. | 482 | * xa_erase_bh() - Erase this entry from the XArray. |
491 | * @xa: XArray. | 483 | * @xa: XArray. |
492 | * @index: Index of entry. | 484 | * @index: Index of entry. |
@@ -495,7 +487,7 @@ static inline int __xa_insert(struct xarray *xa, unsigned long index, | |||
495 | * the third argument. The XArray does not need to allocate memory, so | 487 | * the third argument. The XArray does not need to allocate memory, so |
496 | * the user does not need to provide GFP flags. | 488 | * the user does not need to provide GFP flags. |
497 | * | 489 | * |
498 | * Context: Process context. Takes and releases the xa_lock while | 490 | * Context: Any context. Takes and releases the xa_lock while |
499 | * disabling softirqs. | 491 | * disabling softirqs. |
500 | * Return: The entry which used to be at this index. | 492 | * Return: The entry which used to be at this index. |
501 | */ | 493 | */ |
@@ -535,6 +527,61 @@ static inline void *xa_erase_irq(struct xarray *xa, unsigned long index) | |||
535 | } | 527 | } |
536 | 528 | ||
537 | /** | 529 | /** |
530 | * xa_cmpxchg() - Conditionally replace an entry in the XArray. | ||
531 | * @xa: XArray. | ||
532 | * @index: Index into array. | ||
533 | * @old: Old value to test against. | ||
534 | * @entry: New value to place in array. | ||
535 | * @gfp: Memory allocation flags. | ||
536 | * | ||
537 | * If the entry at @index is the same as @old, replace it with @entry. | ||
538 | * If the return value is equal to @old, then the exchange was successful. | ||
539 | * | ||
540 | * Context: Any context. Takes and releases the xa_lock. May sleep | ||
541 | * if the @gfp flags permit. | ||
542 | * Return: The old value at this index or xa_err() if an error happened. | ||
543 | */ | ||
544 | static inline void *xa_cmpxchg(struct xarray *xa, unsigned long index, | ||
545 | void *old, void *entry, gfp_t gfp) | ||
546 | { | ||
547 | void *curr; | ||
548 | |||
549 | xa_lock(xa); | ||
550 | curr = __xa_cmpxchg(xa, index, old, entry, gfp); | ||
551 | xa_unlock(xa); | ||
552 | |||
553 | return curr; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * xa_insert() - Store this entry in the XArray unless another entry is | ||
558 | * already present. | ||
559 | * @xa: XArray. | ||
560 | * @index: Index into array. | ||
561 | * @entry: New entry. | ||
562 | * @gfp: Memory allocation flags. | ||
563 | * | ||
564 | * If you would rather see the existing entry in the array, use xa_cmpxchg(). | ||
565 | * This function is for users who don't care what the entry is, only that | ||
566 | * one is present. | ||
567 | * | ||
568 | * Context: Process context. Takes and releases the xa_lock. | ||
569 | * May sleep if the @gfp flags permit. | ||
570 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
571 | * -ENOMEM if memory could not be allocated. | ||
572 | */ | ||
573 | static inline int xa_insert(struct xarray *xa, unsigned long index, | ||
574 | void *entry, gfp_t gfp) | ||
575 | { | ||
576 | void *curr = xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
577 | if (!curr) | ||
578 | return 0; | ||
579 | if (xa_is_err(curr)) | ||
580 | return xa_err(curr); | ||
581 | return -EEXIST; | ||
582 | } | ||
583 | |||
584 | /** | ||
538 | * xa_alloc() - Find somewhere to store this entry in the XArray. | 585 | * xa_alloc() - Find somewhere to store this entry in the XArray. |
539 | * @xa: XArray. | 586 | * @xa: XArray. |
540 | * @id: Pointer to ID. | 587 | * @id: Pointer to ID. |
@@ -575,7 +622,7 @@ static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, | |||
575 | * Updates the @id pointer with the index, then stores the entry at that | 622 | * Updates the @id pointer with the index, then stores the entry at that |
576 | * index. A concurrent lookup will not see an uninitialised @id. | 623 | * index. A concurrent lookup will not see an uninitialised @id. |
577 | * | 624 | * |
578 | * Context: Process context. Takes and releases the xa_lock while | 625 | * Context: Any context. Takes and releases the xa_lock while |
579 | * disabling softirqs. May sleep if the @gfp flags permit. | 626 | * disabling softirqs. May sleep if the @gfp flags permit. |
580 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if | 627 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if |
581 | * there is no more space in the XArray. | 628 | * there is no more space in the XArray. |
@@ -621,6 +668,98 @@ static inline int xa_alloc_irq(struct xarray *xa, u32 *id, u32 max, void *entry, | |||
621 | return err; | 668 | return err; |
622 | } | 669 | } |
623 | 670 | ||
671 | /** | ||
672 | * xa_reserve() - Reserve this index in the XArray. | ||
673 | * @xa: XArray. | ||
674 | * @index: Index into array. | ||
675 | * @gfp: Memory allocation flags. | ||
676 | * | ||
677 | * Ensures there is somewhere to store an entry at @index in the array. | ||
678 | * If there is already something stored at @index, this function does | ||
679 | * nothing. If there was nothing there, the entry is marked as reserved. | ||
680 | * Loading from a reserved entry returns a %NULL pointer. | ||
681 | * | ||
682 | * If you do not use the entry that you have reserved, call xa_release() | ||
683 | * or xa_erase() to free any unnecessary memory. | ||
684 | * | ||
685 | * Context: Any context. Takes and releases the xa_lock. | ||
686 | * May sleep if the @gfp flags permit. | ||
687 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
688 | */ | ||
689 | static inline | ||
690 | int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
691 | { | ||
692 | int ret; | ||
693 | |||
694 | xa_lock(xa); | ||
695 | ret = __xa_reserve(xa, index, gfp); | ||
696 | xa_unlock(xa); | ||
697 | |||
698 | return ret; | ||
699 | } | ||
700 | |||
701 | /** | ||
702 | * xa_reserve_bh() - Reserve this index in the XArray. | ||
703 | * @xa: XArray. | ||
704 | * @index: Index into array. | ||
705 | * @gfp: Memory allocation flags. | ||
706 | * | ||
707 | * A softirq-disabling version of xa_reserve(). | ||
708 | * | ||
709 | * Context: Any context. Takes and releases the xa_lock while | ||
710 | * disabling softirqs. | ||
711 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
712 | */ | ||
713 | static inline | ||
714 | int xa_reserve_bh(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
715 | { | ||
716 | int ret; | ||
717 | |||
718 | xa_lock_bh(xa); | ||
719 | ret = __xa_reserve(xa, index, gfp); | ||
720 | xa_unlock_bh(xa); | ||
721 | |||
722 | return ret; | ||
723 | } | ||
724 | |||
725 | /** | ||
726 | * xa_reserve_irq() - Reserve this index in the XArray. | ||
727 | * @xa: XArray. | ||
728 | * @index: Index into array. | ||
729 | * @gfp: Memory allocation flags. | ||
730 | * | ||
731 | * An interrupt-disabling version of xa_reserve(). | ||
732 | * | ||
733 | * Context: Process context. Takes and releases the xa_lock while | ||
734 | * disabling interrupts. | ||
735 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
736 | */ | ||
737 | static inline | ||
738 | int xa_reserve_irq(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
739 | { | ||
740 | int ret; | ||
741 | |||
742 | xa_lock_irq(xa); | ||
743 | ret = __xa_reserve(xa, index, gfp); | ||
744 | xa_unlock_irq(xa); | ||
745 | |||
746 | return ret; | ||
747 | } | ||
748 | |||
749 | /** | ||
750 | * xa_release() - Release a reserved entry. | ||
751 | * @xa: XArray. | ||
752 | * @index: Index of entry. | ||
753 | * | ||
754 | * After calling xa_reserve(), you can call this function to release the | ||
755 | * reservation. If the entry at @index has been stored to, this function | ||
756 | * will do nothing. | ||
757 | */ | ||
758 | static inline void xa_release(struct xarray *xa, unsigned long index) | ||
759 | { | ||
760 | xa_cmpxchg(xa, index, NULL, NULL, 0); | ||
761 | } | ||
762 | |||
624 | /* Everything below here is the Advanced API. Proceed with caution. */ | 763 | /* Everything below here is the Advanced API. Proceed with caution. */ |
625 | 764 | ||
626 | /* | 765 | /* |