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

maple_tree: move debug check to __mas_set_range()

__mas_set_range() was created to shortcut resetting the maple state and a
debug check was added to the caller (the vma iterator) to ensure the
internal maple state remains safe to use. Move the debug check from the
vma iterator into the maple tree itself so other users do not incorrectly
use the advanced maple state modification.

Fallout from this change include a large amount of debug setup needed to
be moved to earlier in the header, and the maple_tree.h radix-tree test
code needed to move the inclusion of the header to after the atomic
define. None of those changes have functional changes.

Link: https://lkml.kernel.org/r/20231101171629.3612299-4-Liam.Howlett@oracle.com
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Peng Zhang <zhangpeng.00@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Liam R. Howlett and committed by
Andrew Morton
bf857ddd f7a59018

+160 -159
+159 -156
include/linux/maple_tree.h
··· 557 557 */ 558 558 #define mas_for_each(__mas, __entry, __max) \ 559 559 while (((__entry) = mas_find((__mas), (__max))) != NULL) 560 - /** 561 - * __mas_set_range() - Set up Maple Tree operation state to a sub-range of the 562 - * current location. 563 - * @mas: Maple Tree operation state. 564 - * @start: New start of range in the Maple Tree. 565 - * @last: New end of range in the Maple Tree. 566 - * 567 - * set the internal maple state values to a sub-range. 568 - * Please use mas_set_range() if you do not know where you are in the tree. 569 - */ 570 - static inline void __mas_set_range(struct ma_state *mas, unsigned long start, 571 - unsigned long last) 572 - { 573 - mas->index = start; 574 - mas->last = last; 575 - } 576 - 577 - /** 578 - * mas_set_range() - Set up Maple Tree operation state for a different index. 579 - * @mas: Maple Tree operation state. 580 - * @start: New start of range in the Maple Tree. 581 - * @last: New end of range in the Maple Tree. 582 - * 583 - * Move the operation state to refer to a different range. This will 584 - * have the effect of starting a walk from the top; see mas_next() 585 - * to move to an adjacent index. 586 - */ 587 - static inline 588 - void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last) 589 - { 590 - __mas_set_range(mas, start, last); 591 - mas->node = MAS_START; 592 - } 593 - 594 - /** 595 - * mas_set() - Set up Maple Tree operation state for a different index. 596 - * @mas: Maple Tree operation state. 597 - * @index: New index into the Maple Tree. 598 - * 599 - * Move the operation state to refer to a different index. This will 600 - * have the effect of starting a walk from the top; see mas_next() 601 - * to move to an adjacent index. 602 - */ 603 - static inline void mas_set(struct ma_state *mas, unsigned long index) 604 - { 605 - 606 - mas_set_range(mas, index, index); 607 - } 608 - 609 - static inline bool mt_external_lock(const struct maple_tree *mt) 610 - { 611 - return (mt->ma_flags & MT_FLAGS_LOCK_MASK) == MT_FLAGS_LOCK_EXTERN; 612 - } 613 - 614 - /** 615 - * mt_init_flags() - Initialise an empty maple tree with flags. 616 - * @mt: Maple Tree 617 - * @flags: maple tree flags. 618 - * 619 - * If you need to initialise a Maple Tree with special flags (eg, an 620 - * allocation tree), use this function. 621 - * 622 - * Context: Any context. 623 - */ 624 - static inline void mt_init_flags(struct maple_tree *mt, unsigned int flags) 625 - { 626 - mt->ma_flags = flags; 627 - if (!mt_external_lock(mt)) 628 - spin_lock_init(&mt->ma_lock); 629 - rcu_assign_pointer(mt->ma_root, NULL); 630 - } 631 - 632 - /** 633 - * mt_init() - Initialise an empty maple tree. 634 - * @mt: Maple Tree 635 - * 636 - * An empty Maple Tree. 637 - * 638 - * Context: Any context. 639 - */ 640 - static inline void mt_init(struct maple_tree *mt) 641 - { 642 - mt_init_flags(mt, 0); 643 - } 644 - 645 - static inline bool mt_in_rcu(struct maple_tree *mt) 646 - { 647 - #ifdef CONFIG_MAPLE_RCU_DISABLED 648 - return false; 649 - #endif 650 - return mt->ma_flags & MT_FLAGS_USE_RCU; 651 - } 652 - 653 - /** 654 - * mt_clear_in_rcu() - Switch the tree to non-RCU mode. 655 - * @mt: The Maple Tree 656 - */ 657 - static inline void mt_clear_in_rcu(struct maple_tree *mt) 658 - { 659 - if (!mt_in_rcu(mt)) 660 - return; 661 - 662 - if (mt_external_lock(mt)) { 663 - WARN_ON(!mt_lock_is_held(mt)); 664 - mt->ma_flags &= ~MT_FLAGS_USE_RCU; 665 - } else { 666 - mtree_lock(mt); 667 - mt->ma_flags &= ~MT_FLAGS_USE_RCU; 668 - mtree_unlock(mt); 669 - } 670 - } 671 - 672 - /** 673 - * mt_set_in_rcu() - Switch the tree to RCU safe mode. 674 - * @mt: The Maple Tree 675 - */ 676 - static inline void mt_set_in_rcu(struct maple_tree *mt) 677 - { 678 - if (mt_in_rcu(mt)) 679 - return; 680 - 681 - if (mt_external_lock(mt)) { 682 - WARN_ON(!mt_lock_is_held(mt)); 683 - mt->ma_flags |= MT_FLAGS_USE_RCU; 684 - } else { 685 - mtree_lock(mt); 686 - mt->ma_flags |= MT_FLAGS_USE_RCU; 687 - mtree_unlock(mt); 688 - } 689 - } 690 - 691 - static inline unsigned int mt_height(const struct maple_tree *mt) 692 - { 693 - return (mt->ma_flags & MT_FLAGS_HEIGHT_MASK) >> MT_FLAGS_HEIGHT_OFFSET; 694 - } 695 - 696 - void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max); 697 - void *mt_find_after(struct maple_tree *mt, unsigned long *index, 698 - unsigned long max); 699 - void *mt_prev(struct maple_tree *mt, unsigned long index, unsigned long min); 700 - void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max); 701 - 702 - /** 703 - * mt_for_each - Iterate over each entry starting at index until max. 704 - * @__tree: The Maple Tree 705 - * @__entry: The current entry 706 - * @__index: The index to start the search from. Subsequently used as iterator. 707 - * @__max: The maximum limit for @index 708 - * 709 - * This iterator skips all entries, which resolve to a NULL pointer, 710 - * e.g. entries which has been reserved with XA_ZERO_ENTRY. 711 - */ 712 - #define mt_for_each(__tree, __entry, __index, __max) \ 713 - for (__entry = mt_find(__tree, &(__index), __max); \ 714 - __entry; __entry = mt_find_after(__tree, &(__index), __max)) 715 - 716 560 717 561 #ifdef CONFIG_DEBUG_MAPLE_TREE 718 562 enum mt_dump_format { ··· 681 837 #define MAS_WARN_ON(__mas, __x) WARN_ON(__x) 682 838 #define MAS_WR_WARN_ON(__mas, __x) WARN_ON(__x) 683 839 #endif /* CONFIG_DEBUG_MAPLE_TREE */ 840 + 841 + /** 842 + * __mas_set_range() - Set up Maple Tree operation state to a sub-range of the 843 + * current location. 844 + * @mas: Maple Tree operation state. 845 + * @start: New start of range in the Maple Tree. 846 + * @last: New end of range in the Maple Tree. 847 + * 848 + * set the internal maple state values to a sub-range. 849 + * Please use mas_set_range() if you do not know where you are in the tree. 850 + */ 851 + static inline void __mas_set_range(struct ma_state *mas, unsigned long start, 852 + unsigned long last) 853 + { 854 + /* Ensure the range starts within the current slot */ 855 + MAS_WARN_ON(mas, mas_is_active(mas) && 856 + (mas->index > start || mas->last < start)); 857 + mas->index = start; 858 + mas->last = last; 859 + } 860 + 861 + /** 862 + * mas_set_range() - Set up Maple Tree operation state for a different index. 863 + * @mas: Maple Tree operation state. 864 + * @start: New start of range in the Maple Tree. 865 + * @last: New end of range in the Maple Tree. 866 + * 867 + * Move the operation state to refer to a different range. This will 868 + * have the effect of starting a walk from the top; see mas_next() 869 + * to move to an adjacent index. 870 + */ 871 + static inline 872 + void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last) 873 + { 874 + mas->node = MAS_START; 875 + __mas_set_range(mas, start, last); 876 + } 877 + 878 + /** 879 + * mas_set() - Set up Maple Tree operation state for a different index. 880 + * @mas: Maple Tree operation state. 881 + * @index: New index into the Maple Tree. 882 + * 883 + * Move the operation state to refer to a different index. This will 884 + * have the effect of starting a walk from the top; see mas_next() 885 + * to move to an adjacent index. 886 + */ 887 + static inline void mas_set(struct ma_state *mas, unsigned long index) 888 + { 889 + 890 + mas_set_range(mas, index, index); 891 + } 892 + 893 + static inline bool mt_external_lock(const struct maple_tree *mt) 894 + { 895 + return (mt->ma_flags & MT_FLAGS_LOCK_MASK) == MT_FLAGS_LOCK_EXTERN; 896 + } 897 + 898 + /** 899 + * mt_init_flags() - Initialise an empty maple tree with flags. 900 + * @mt: Maple Tree 901 + * @flags: maple tree flags. 902 + * 903 + * If you need to initialise a Maple Tree with special flags (eg, an 904 + * allocation tree), use this function. 905 + * 906 + * Context: Any context. 907 + */ 908 + static inline void mt_init_flags(struct maple_tree *mt, unsigned int flags) 909 + { 910 + mt->ma_flags = flags; 911 + if (!mt_external_lock(mt)) 912 + spin_lock_init(&mt->ma_lock); 913 + rcu_assign_pointer(mt->ma_root, NULL); 914 + } 915 + 916 + /** 917 + * mt_init() - Initialise an empty maple tree. 918 + * @mt: Maple Tree 919 + * 920 + * An empty Maple Tree. 921 + * 922 + * Context: Any context. 923 + */ 924 + static inline void mt_init(struct maple_tree *mt) 925 + { 926 + mt_init_flags(mt, 0); 927 + } 928 + 929 + static inline bool mt_in_rcu(struct maple_tree *mt) 930 + { 931 + #ifdef CONFIG_MAPLE_RCU_DISABLED 932 + return false; 933 + #endif 934 + return mt->ma_flags & MT_FLAGS_USE_RCU; 935 + } 936 + 937 + /** 938 + * mt_clear_in_rcu() - Switch the tree to non-RCU mode. 939 + * @mt: The Maple Tree 940 + */ 941 + static inline void mt_clear_in_rcu(struct maple_tree *mt) 942 + { 943 + if (!mt_in_rcu(mt)) 944 + return; 945 + 946 + if (mt_external_lock(mt)) { 947 + WARN_ON(!mt_lock_is_held(mt)); 948 + mt->ma_flags &= ~MT_FLAGS_USE_RCU; 949 + } else { 950 + mtree_lock(mt); 951 + mt->ma_flags &= ~MT_FLAGS_USE_RCU; 952 + mtree_unlock(mt); 953 + } 954 + } 955 + 956 + /** 957 + * mt_set_in_rcu() - Switch the tree to RCU safe mode. 958 + * @mt: The Maple Tree 959 + */ 960 + static inline void mt_set_in_rcu(struct maple_tree *mt) 961 + { 962 + if (mt_in_rcu(mt)) 963 + return; 964 + 965 + if (mt_external_lock(mt)) { 966 + WARN_ON(!mt_lock_is_held(mt)); 967 + mt->ma_flags |= MT_FLAGS_USE_RCU; 968 + } else { 969 + mtree_lock(mt); 970 + mt->ma_flags |= MT_FLAGS_USE_RCU; 971 + mtree_unlock(mt); 972 + } 973 + } 974 + 975 + static inline unsigned int mt_height(const struct maple_tree *mt) 976 + { 977 + return (mt->ma_flags & MT_FLAGS_HEIGHT_MASK) >> MT_FLAGS_HEIGHT_OFFSET; 978 + } 979 + 980 + void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max); 981 + void *mt_find_after(struct maple_tree *mt, unsigned long *index, 982 + unsigned long max); 983 + void *mt_prev(struct maple_tree *mt, unsigned long index, unsigned long min); 984 + void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max); 985 + 986 + /** 987 + * mt_for_each - Iterate over each entry starting at index until max. 988 + * @__tree: The Maple Tree 989 + * @__entry: The current entry 990 + * @__index: The index to start the search from. Subsequently used as iterator. 991 + * @__max: The maximum limit for @index 992 + * 993 + * This iterator skips all entries, which resolve to a NULL pointer, 994 + * e.g. entries which has been reserved with XA_ZERO_ENTRY. 995 + */ 996 + #define mt_for_each(__tree, __entry, __index, __max) \ 997 + for (__entry = mt_find(__tree, &(__index), __max); \ 998 + __entry; __entry = mt_find_after(__tree, &(__index), __max)) 684 999 685 1000 #endif /*_LINUX_MAPLE_TREE_H */
-2
mm/internal.h
··· 1135 1135 static inline void vma_iter_config(struct vma_iterator *vmi, 1136 1136 unsigned long index, unsigned long last) 1137 1137 { 1138 - MAS_BUG_ON(&vmi->mas, vmi->mas.node != MAS_START && 1139 - (vmi->mas.index > index || vmi->mas.last < index)); 1140 1138 __mas_set_range(&vmi->mas, index, last - 1); 1141 1139 } 1142 1140
+1 -1
tools/testing/radix-tree/linux/maple_tree.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 #define atomic_t int32_t 3 - #include "../../../../include/linux/maple_tree.h" 4 3 #define atomic_inc(x) uatomic_inc(x) 5 4 #define atomic_read(x) uatomic_read(x) 6 5 #define atomic_set(x, y) do {} while (0) 7 6 #define U8_MAX UCHAR_MAX 7 + #include "../../../../include/linux/maple_tree.h"