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

xarray: Replace exceptional entries

Introduce xarray value entries and tagged pointers to replace radix
tree exceptional entries. This is a slight change in encoding to allow
the use of an extra bit (we can now store BITS_PER_LONG - 1 bits in a
value entry). It is also a change in emphasis; exceptional entries are
intimidating and different. As the comment explains, you can choose
to store values or pointers in the xarray and they are both first-class
citizens.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
Reviewed-by: Josef Bacik <jbacik@fb.com>

+278 -232
+1 -3
arch/powerpc/include/asm/book3s/64/pgtable.h
··· 723 723 BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \ 724 724 BUILD_BUG_ON(_PAGE_HPTEFLAGS & _PAGE_SWP_SOFT_DIRTY); \ 725 725 } while (0) 726 - /* 727 - * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT; 728 - */ 726 + 729 727 #define SWP_TYPE_BITS 5 730 728 #define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ 731 729 & ((1UL << SWP_TYPE_BITS) - 1))
+1 -3
arch/powerpc/include/asm/nohash/64/pgtable.h
··· 313 313 #define MAX_SWAPFILES_CHECK() do { \ 314 314 BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \ 315 315 } while (0) 316 - /* 317 - * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT; 318 - */ 316 + 319 317 #define SWP_TYPE_BITS 5 320 318 #define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ 321 319 & ((1UL << SWP_TYPE_BITS) - 1))
+7 -10
drivers/gpu/drm/i915/i915_gem.c
··· 5996 5996 count = __sg_page_count(sg); 5997 5997 5998 5998 while (idx + count <= n) { 5999 - unsigned long exception, i; 5999 + void *entry; 6000 + unsigned long i; 6000 6001 int ret; 6001 6002 6002 6003 /* If we cannot allocate and insert this entry, or the ··· 6012 6011 if (ret && ret != -EEXIST) 6013 6012 goto scan; 6014 6013 6015 - exception = 6016 - RADIX_TREE_EXCEPTIONAL_ENTRY | 6017 - idx << RADIX_TREE_EXCEPTIONAL_SHIFT; 6014 + entry = xa_mk_value(idx); 6018 6015 for (i = 1; i < count; i++) { 6019 - ret = radix_tree_insert(&iter->radix, idx + i, 6020 - (void *)exception); 6016 + ret = radix_tree_insert(&iter->radix, idx + i, entry); 6021 6017 if (ret && ret != -EEXIST) 6022 6018 goto scan; 6023 6019 } ··· 6052 6054 GEM_BUG_ON(!sg); 6053 6055 6054 6056 /* If this index is in the middle of multi-page sg entry, 6055 - * the radixtree will contain an exceptional entry that points 6057 + * the radix tree will contain a value entry that points 6056 6058 * to the start of that range. We will return the pointer to 6057 6059 * the base page and the offset of this page within the 6058 6060 * sg entry's range. 6059 6061 */ 6060 6062 *offset = 0; 6061 - if (unlikely(radix_tree_exception(sg))) { 6062 - unsigned long base = 6063 - (unsigned long)sg >> RADIX_TREE_EXCEPTIONAL_SHIFT; 6063 + if (unlikely(xa_is_value(sg))) { 6064 + unsigned long base = xa_to_value(sg); 6064 6065 6065 6066 sg = radix_tree_lookup(&iter->radix, base); 6066 6067 GEM_BUG_ON(!sg);
+6 -12
drivers/staging/erofs/utils.c
··· 35 35 36 36 #ifdef CONFIG_EROFS_FS_ZIP 37 37 38 - /* radix_tree and the future XArray both don't use tagptr_t yet */ 39 38 struct erofs_workgroup *erofs_find_workgroup( 40 39 struct super_block *sb, pgoff_t index, bool *tag) 41 40 { ··· 46 47 rcu_read_lock(); 47 48 grp = radix_tree_lookup(&sbi->workstn_tree, index); 48 49 if (grp != NULL) { 49 - *tag = radix_tree_exceptional_entry(grp); 50 - grp = (void *)((unsigned long)grp & 51 - ~RADIX_TREE_EXCEPTIONAL_ENTRY); 50 + *tag = xa_pointer_tag(grp); 51 + grp = xa_untag_pointer(grp); 52 52 53 53 if (erofs_workgroup_get(grp, &oldcount)) { 54 54 /* prefer to relax rcu read side */ ··· 81 83 sbi = EROFS_SB(sb); 82 84 erofs_workstn_lock(sbi); 83 85 84 - if (tag) 85 - grp = (void *)((unsigned long)grp | 86 - 1UL << RADIX_TREE_EXCEPTIONAL_SHIFT); 86 + grp = xa_tag_pointer(grp, tag); 87 87 88 88 err = radix_tree_insert(&sbi->workstn_tree, 89 89 grp->index, grp); ··· 127 131 128 132 for (i = 0; i < found; ++i) { 129 133 int cnt; 130 - struct erofs_workgroup *grp = (void *) 131 - ((unsigned long)batch[i] & 132 - ~RADIX_TREE_EXCEPTIONAL_ENTRY); 134 + struct erofs_workgroup *grp = xa_untag_pointer(batch[i]); 133 135 134 136 first_index = grp->index + 1; 135 137 ··· 144 150 #endif 145 151 continue; 146 152 147 - if (radix_tree_delete(&sbi->workstn_tree, 148 - grp->index) != grp) { 153 + if (xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree, 154 + grp->index)) != grp) { 149 155 #ifdef EROFS_FS_HAS_MANAGED_CACHE 150 156 skip: 151 157 erofs_workgroup_unfreeze(grp, 1);
+1 -1
fs/btrfs/compression.c
··· 440 440 rcu_read_lock(); 441 441 page = radix_tree_lookup(&mapping->i_pages, pg_index); 442 442 rcu_read_unlock(); 443 - if (page && !radix_tree_exceptional_entry(page)) { 443 + if (page && !xa_is_value(page)) { 444 444 misses++; 445 445 if (misses > 4) 446 446 break;
+55 -57
fs/dax.c
··· 59 59 fs_initcall(init_dax_wait_table); 60 60 61 61 /* 62 - * We use lowest available bit in exceptional entry for locking, one bit for 63 - * the entry size (PMD) and two more to tell us if the entry is a zero page or 64 - * an empty entry that is just used for locking. In total four special bits. 62 + * DAX pagecache entries use XArray value entries so they can't be mistaken 63 + * for pages. We use one bit for locking, one bit for the entry size (PMD) 64 + * and two more to tell us if the entry is a zero page or an empty entry that 65 + * is just used for locking. In total four special bits. 65 66 * 66 67 * If the PMD bit isn't set the entry has size PAGE_SIZE, and if the ZERO_PAGE 67 68 * and EMPTY bits aren't set the entry is a normal DAX entry with a filesystem 68 69 * block allocation. 69 70 */ 70 - #define RADIX_DAX_SHIFT (RADIX_TREE_EXCEPTIONAL_SHIFT + 4) 71 - #define RADIX_DAX_ENTRY_LOCK (1 << RADIX_TREE_EXCEPTIONAL_SHIFT) 72 - #define RADIX_DAX_PMD (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 1)) 73 - #define RADIX_DAX_ZERO_PAGE (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 2)) 74 - #define RADIX_DAX_EMPTY (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 3)) 71 + #define DAX_SHIFT (4) 72 + #define DAX_LOCKED (1UL << 0) 73 + #define DAX_PMD (1UL << 1) 74 + #define DAX_ZERO_PAGE (1UL << 2) 75 + #define DAX_EMPTY (1UL << 3) 75 76 76 77 static unsigned long dax_radix_pfn(void *entry) 77 78 { 78 - return (unsigned long)entry >> RADIX_DAX_SHIFT; 79 + return xa_to_value(entry) >> DAX_SHIFT; 79 80 } 80 81 81 82 static void *dax_radix_locked_entry(unsigned long pfn, unsigned long flags) 82 83 { 83 - return (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY | flags | 84 - (pfn << RADIX_DAX_SHIFT) | RADIX_DAX_ENTRY_LOCK); 84 + return xa_mk_value(flags | ((unsigned long)pfn << DAX_SHIFT) | 85 + DAX_LOCKED); 85 86 } 86 87 87 88 static unsigned int dax_radix_order(void *entry) 88 89 { 89 - if ((unsigned long)entry & RADIX_DAX_PMD) 90 + if (xa_to_value(entry) & DAX_PMD) 90 91 return PMD_SHIFT - PAGE_SHIFT; 91 92 return 0; 92 93 } 93 94 94 95 static int dax_is_pmd_entry(void *entry) 95 96 { 96 - return (unsigned long)entry & RADIX_DAX_PMD; 97 + return xa_to_value(entry) & DAX_PMD; 97 98 } 98 99 99 100 static int dax_is_pte_entry(void *entry) 100 101 { 101 - return !((unsigned long)entry & RADIX_DAX_PMD); 102 + return !(xa_to_value(entry) & DAX_PMD); 102 103 } 103 104 104 105 static int dax_is_zero_entry(void *entry) 105 106 { 106 - return (unsigned long)entry & RADIX_DAX_ZERO_PAGE; 107 + return xa_to_value(entry) & DAX_ZERO_PAGE; 107 108 } 108 109 109 110 static int dax_is_empty_entry(void *entry) 110 111 { 111 - return (unsigned long)entry & RADIX_DAX_EMPTY; 112 + return xa_to_value(entry) & DAX_EMPTY; 112 113 } 113 114 114 115 /* ··· 187 186 */ 188 187 static inline int slot_locked(struct address_space *mapping, void **slot) 189 188 { 190 - unsigned long entry = (unsigned long) 191 - radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock); 192 - return entry & RADIX_DAX_ENTRY_LOCK; 189 + unsigned long entry = xa_to_value( 190 + radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock)); 191 + return entry & DAX_LOCKED; 193 192 } 194 193 195 194 /* ··· 197 196 */ 198 197 static inline void *lock_slot(struct address_space *mapping, void **slot) 199 198 { 200 - unsigned long entry = (unsigned long) 201 - radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock); 202 - 203 - entry |= RADIX_DAX_ENTRY_LOCK; 204 - radix_tree_replace_slot(&mapping->i_pages, slot, (void *)entry); 205 - return (void *)entry; 199 + unsigned long v = xa_to_value( 200 + radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock)); 201 + void *entry = xa_mk_value(v | DAX_LOCKED); 202 + radix_tree_replace_slot(&mapping->i_pages, slot, entry); 203 + return entry; 206 204 } 207 205 208 206 /* ··· 209 209 */ 210 210 static inline void *unlock_slot(struct address_space *mapping, void **slot) 211 211 { 212 - unsigned long entry = (unsigned long) 213 - radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock); 214 - 215 - entry &= ~(unsigned long)RADIX_DAX_ENTRY_LOCK; 216 - radix_tree_replace_slot(&mapping->i_pages, slot, (void *)entry); 217 - return (void *)entry; 212 + unsigned long v = xa_to_value( 213 + radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock)); 214 + void *entry = xa_mk_value(v & ~DAX_LOCKED); 215 + radix_tree_replace_slot(&mapping->i_pages, slot, entry); 216 + return entry; 218 217 } 219 218 220 219 /* 221 220 * Lookup entry in radix tree, wait for it to become unlocked if it is 222 - * exceptional entry and return it. The caller must call 221 + * a DAX entry and return it. The caller must call 223 222 * put_unlocked_mapping_entry() when he decided not to lock the entry or 224 223 * put_locked_mapping_entry() when he locked the entry and now wants to 225 224 * unlock it. ··· 241 242 entry = __radix_tree_lookup(&mapping->i_pages, index, NULL, 242 243 &slot); 243 244 if (!entry || 244 - WARN_ON_ONCE(!radix_tree_exceptional_entry(entry)) || 245 + WARN_ON_ONCE(!xa_is_value(entry)) || 245 246 !slot_locked(mapping, slot)) { 246 247 if (slotp) 247 248 *slotp = slot; ··· 282 283 283 284 xa_lock_irq(&mapping->i_pages); 284 285 entry = __radix_tree_lookup(&mapping->i_pages, index, NULL, &slot); 285 - if (WARN_ON_ONCE(!entry || !radix_tree_exceptional_entry(entry) || 286 + if (WARN_ON_ONCE(!entry || !xa_is_value(entry) || 286 287 !slot_locked(mapping, slot))) { 287 288 xa_unlock_irq(&mapping->i_pages); 288 289 return; ··· 471 472 } 472 473 473 474 /* 474 - * Find radix tree entry at given index. If it points to an exceptional entry, 475 - * return it with the radix tree entry locked. If the radix tree doesn't 476 - * contain given index, create an empty exceptional entry for the index and 477 - * return with it locked. 475 + * Find radix tree entry at given index. If it is a DAX entry, return it 476 + * with the radix tree entry locked. If the radix tree doesn't contain the 477 + * given index, create an empty entry for the index and return with it locked. 478 478 * 479 - * When requesting an entry with size RADIX_DAX_PMD, grab_mapping_entry() will 479 + * When requesting an entry with size DAX_PMD, grab_mapping_entry() will 480 480 * either return that locked entry or will return an error. This error will 481 481 * happen if there are any 4k entries within the 2MiB range that we are 482 482 * requesting. ··· 505 507 xa_lock_irq(&mapping->i_pages); 506 508 entry = get_unlocked_mapping_entry(mapping, index, &slot); 507 509 508 - if (WARN_ON_ONCE(entry && !radix_tree_exceptional_entry(entry))) { 510 + if (WARN_ON_ONCE(entry && !xa_is_value(entry))) { 509 511 entry = ERR_PTR(-EIO); 510 512 goto out_unlock; 511 513 } 512 514 513 515 if (entry) { 514 - if (size_flag & RADIX_DAX_PMD) { 516 + if (size_flag & DAX_PMD) { 515 517 if (dax_is_pte_entry(entry)) { 516 518 put_unlocked_mapping_entry(mapping, index, 517 519 entry); ··· 582 584 true); 583 585 } 584 586 585 - entry = dax_radix_locked_entry(0, size_flag | RADIX_DAX_EMPTY); 587 + entry = dax_radix_locked_entry(0, size_flag | DAX_EMPTY); 586 588 587 589 err = __radix_tree_insert(&mapping->i_pages, index, 588 590 dax_radix_order(entry), entry); ··· 671 673 if (index >= end) 672 674 break; 673 675 674 - if (WARN_ON_ONCE( 675 - !radix_tree_exceptional_entry(pvec_ent))) 676 + if (WARN_ON_ONCE(!xa_is_value(pvec_ent))) 676 677 continue; 677 678 678 679 xa_lock_irq(&mapping->i_pages); ··· 710 713 711 714 xa_lock_irq(pages); 712 715 entry = get_unlocked_mapping_entry(mapping, index, NULL); 713 - if (!entry || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry))) 716 + if (!entry || WARN_ON_ONCE(!xa_is_value(entry))) 714 717 goto out; 715 718 if (!trunc && 716 719 (radix_tree_tag_get(pages, index, PAGECACHE_TAG_DIRTY) || ··· 726 729 return ret; 727 730 } 728 731 /* 729 - * Delete exceptional DAX entry at @index from @mapping. Wait for radix tree 730 - * entry to get unlocked before deleting it. 732 + * Delete DAX entry at @index from @mapping. Wait for it 733 + * to be unlocked before deleting it. 731 734 */ 732 735 int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index) 733 736 { ··· 737 740 * This gets called from truncate / punch_hole path. As such, the caller 738 741 * must hold locks protecting against concurrent modifications of the 739 742 * radix tree (usually fs-private i_mmap_sem for writing). Since the 740 - * caller has seen exceptional entry for this index, we better find it 743 + * caller has seen a DAX entry for this index, we better find it 741 744 * at that index as well... 742 745 */ 743 746 WARN_ON_ONCE(!ret); ··· 745 748 } 746 749 747 750 /* 748 - * Invalidate exceptional DAX entry if it is clean. 751 + * Invalidate DAX entry if it is clean. 749 752 */ 750 753 int dax_invalidate_mapping_entry_sync(struct address_space *mapping, 751 754 pgoff_t index) ··· 799 802 if (dirty) 800 803 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); 801 804 802 - if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) { 805 + if (dax_is_zero_entry(entry) && !(flags & DAX_ZERO_PAGE)) { 803 806 /* we are replacing a zero page with block mapping */ 804 807 if (dax_is_pmd_entry(entry)) 805 808 unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR, ··· 937 940 * A page got tagged dirty in DAX mapping? Something is seriously 938 941 * wrong. 939 942 */ 940 - if (WARN_ON(!radix_tree_exceptional_entry(entry))) 943 + if (WARN_ON(!xa_is_value(entry))) 941 944 return -EIO; 942 945 943 946 xa_lock_irq(pages); 944 947 entry2 = get_unlocked_mapping_entry(mapping, index, &slot); 945 948 /* Entry got punched out / reallocated? */ 946 - if (!entry2 || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry2))) 949 + if (!entry2 || WARN_ON_ONCE(!xa_is_value(entry2))) 947 950 goto put_unlocked; 948 951 /* 949 952 * Entry got reallocated elsewhere? No need to writeback. We have to ··· 1120 1123 pfn_t pfn = pfn_to_pfn_t(my_zero_pfn(vaddr)); 1121 1124 vm_fault_t ret; 1122 1125 1123 - dax_insert_mapping_entry(mapping, vmf, entry, pfn, RADIX_DAX_ZERO_PAGE, 1124 - false); 1126 + dax_insert_mapping_entry(mapping, vmf, entry, pfn, 1127 + DAX_ZERO_PAGE, false); 1128 + 1125 1129 ret = vmf_insert_mixed(vmf->vma, vaddr, pfn); 1126 1130 trace_dax_load_hole(inode, vmf, ret); 1127 1131 return ret; ··· 1512 1514 1513 1515 pfn = page_to_pfn_t(zero_page); 1514 1516 ret = dax_insert_mapping_entry(mapping, vmf, entry, pfn, 1515 - RADIX_DAX_PMD | RADIX_DAX_ZERO_PAGE, false); 1517 + DAX_PMD | DAX_ZERO_PAGE, false); 1516 1518 1517 1519 ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd); 1518 1520 if (!pmd_none(*(vmf->pmd))) { ··· 1595 1597 * is already in the tree, for instance), it will return -EEXIST and 1596 1598 * we just fall back to 4k entries. 1597 1599 */ 1598 - entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD); 1600 + entry = grab_mapping_entry(mapping, pgoff, DAX_PMD); 1599 1601 if (IS_ERR(entry)) 1600 1602 goto fallback; 1601 1603 ··· 1633 1635 goto finish_iomap; 1634 1636 1635 1637 entry = dax_insert_mapping_entry(mapping, vmf, entry, pfn, 1636 - RADIX_DAX_PMD, write && !sync); 1638 + DAX_PMD, write && !sync); 1637 1639 1638 1640 /* 1639 1641 * If we are doing synchronous page fault and inode needs fsync,
+1 -1
fs/proc/task_mmu.c
··· 521 521 if (!page) 522 522 return; 523 523 524 - if (radix_tree_exceptional_entry(page)) 524 + if (xa_is_value(page)) 525 525 mss->swap += PAGE_SIZE; 526 526 else 527 527 put_page(page);
+8 -28
include/linux/radix-tree.h
··· 28 28 #include <linux/rcupdate.h> 29 29 #include <linux/spinlock.h> 30 30 #include <linux/types.h> 31 + #include <linux/xarray.h> 31 32 32 33 /* 33 34 * The bottom two bits of the slot determine how the remaining bits in the 34 35 * slot are interpreted: 35 36 * 36 37 * 00 - data pointer 37 - * 01 - internal entry 38 - * 10 - exceptional entry 39 - * 11 - this bit combination is currently unused/reserved 38 + * 10 - internal entry 39 + * x1 - value entry 40 40 * 41 41 * The internal entry may be a pointer to the next level in the tree, a 42 42 * sibling entry, or an indicator that the entry in this slot has been moved 43 43 * to another location in the tree and the lookup should be restarted. While 44 44 * NULL fits the 'data pointer' pattern, it means that there is no entry in 45 45 * the tree for this index (no matter what level of the tree it is found at). 46 - * This means that you cannot store NULL in the tree as a value for the index. 46 + * This means that storing a NULL entry in the tree is the same as deleting 47 + * the entry from the tree. 47 48 */ 48 49 #define RADIX_TREE_ENTRY_MASK 3UL 49 - #define RADIX_TREE_INTERNAL_NODE 1UL 50 - 51 - /* 52 - * Most users of the radix tree store pointers but shmem/tmpfs stores swap 53 - * entries in the same tree. They are marked as exceptional entries to 54 - * distinguish them from pointers to struct page. 55 - * EXCEPTIONAL_ENTRY tests the bit, EXCEPTIONAL_SHIFT shifts content past it. 56 - */ 57 - #define RADIX_TREE_EXCEPTIONAL_ENTRY 2 58 - #define RADIX_TREE_EXCEPTIONAL_SHIFT 2 50 + #define RADIX_TREE_INTERNAL_NODE 2UL 59 51 60 52 static inline bool radix_tree_is_internal_node(void *ptr) 61 53 { ··· 75 83 76 84 /* 77 85 * @count is the count of every non-NULL element in the ->slots array 78 - * whether that is an exceptional entry, a retry entry, a user pointer, 86 + * whether that is a value entry, a retry entry, a user pointer, 79 87 * a sibling entry or a pointer to the next level of the tree. 80 88 * @exceptional is the count of every element in ->slots which is 81 - * either radix_tree_exceptional_entry() or is a sibling entry for an 82 - * exceptional entry. 89 + * either a value entry or a sibling of a value entry. 83 90 */ 84 91 struct radix_tree_node { 85 92 unsigned char shift; /* Bits remaining in each slot */ ··· 257 266 static inline int radix_tree_deref_retry(void *arg) 258 267 { 259 268 return unlikely(radix_tree_is_internal_node(arg)); 260 - } 261 - 262 - /** 263 - * radix_tree_exceptional_entry - radix_tree_deref_slot gave exceptional entry? 264 - * @arg: value returned by radix_tree_deref_slot 265 - * Returns: 0 if well-aligned pointer, non-0 if exceptional entry. 266 - */ 267 - static inline int radix_tree_exceptional_entry(void *arg) 268 - { 269 - /* Not unlikely because radix_tree_exception often tested first */ 270 - return (unsigned long)arg & RADIX_TREE_EXCEPTIONAL_ENTRY; 271 269 } 272 270 273 271 /**
+7 -12
include/linux/swapops.h
··· 18 18 * 19 19 * swp_entry_t's are *never* stored anywhere in their arch-dependent format. 20 20 */ 21 - #define SWP_TYPE_SHIFT(e) ((sizeof(e.val) * 8) - \ 22 - (MAX_SWAPFILES_SHIFT + RADIX_TREE_EXCEPTIONAL_SHIFT)) 23 - #define SWP_OFFSET_MASK(e) ((1UL << SWP_TYPE_SHIFT(e)) - 1) 21 + #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) 22 + #define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1) 24 23 25 24 /* 26 25 * Store a type+offset into a swp_entry_t in an arch-independent format ··· 28 29 { 29 30 swp_entry_t ret; 30 31 31 - ret.val = (type << SWP_TYPE_SHIFT(ret)) | 32 - (offset & SWP_OFFSET_MASK(ret)); 32 + ret.val = (type << SWP_TYPE_SHIFT) | (offset & SWP_OFFSET_MASK); 33 33 return ret; 34 34 } 35 35 ··· 38 40 */ 39 41 static inline unsigned swp_type(swp_entry_t entry) 40 42 { 41 - return (entry.val >> SWP_TYPE_SHIFT(entry)); 43 + return (entry.val >> SWP_TYPE_SHIFT); 42 44 } 43 45 44 46 /* ··· 47 49 */ 48 50 static inline pgoff_t swp_offset(swp_entry_t entry) 49 51 { 50 - return entry.val & SWP_OFFSET_MASK(entry); 52 + return entry.val & SWP_OFFSET_MASK; 51 53 } 52 54 53 55 #ifdef CONFIG_MMU ··· 88 90 { 89 91 swp_entry_t entry; 90 92 91 - entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT; 93 + entry.val = xa_to_value(arg); 92 94 return entry; 93 95 } 94 96 95 97 static inline void *swp_to_radix_entry(swp_entry_t entry) 96 98 { 97 - unsigned long value; 98 - 99 - value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT; 100 - return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY); 99 + return xa_mk_value(entry.val); 101 100 } 102 101 103 102 #if IS_ENABLED(CONFIG_DEVICE_PRIVATE)
+102
include/linux/xarray.h
··· 5 5 * eXtensible Arrays 6 6 * Copyright (c) 2017 Microsoft Corporation 7 7 * Author: Matthew Wilcox <willy@infradead.org> 8 + * 9 + * See Documentation/core-api/xarray.rst for how to use the XArray. 8 10 */ 9 11 12 + #include <linux/bug.h> 10 13 #include <linux/spinlock.h> 14 + #include <linux/types.h> 15 + 16 + /* 17 + * The bottom two bits of the entry determine how the XArray interprets 18 + * the contents: 19 + * 20 + * 00: Pointer entry 21 + * 10: Internal entry 22 + * x1: Value entry or tagged pointer 23 + * 24 + * Attempting to store internal entries in the XArray is a bug. 25 + */ 26 + 27 + #define BITS_PER_XA_VALUE (BITS_PER_LONG - 1) 28 + 29 + /** 30 + * xa_mk_value() - Create an XArray entry from an integer. 31 + * @v: Value to store in XArray. 32 + * 33 + * Context: Any context. 34 + * Return: An entry suitable for storing in the XArray. 35 + */ 36 + static inline void *xa_mk_value(unsigned long v) 37 + { 38 + WARN_ON((long)v < 0); 39 + return (void *)((v << 1) | 1); 40 + } 41 + 42 + /** 43 + * xa_to_value() - Get value stored in an XArray entry. 44 + * @entry: XArray entry. 45 + * 46 + * Context: Any context. 47 + * Return: The value stored in the XArray entry. 48 + */ 49 + static inline unsigned long xa_to_value(const void *entry) 50 + { 51 + return (unsigned long)entry >> 1; 52 + } 53 + 54 + /** 55 + * xa_is_value() - Determine if an entry is a value. 56 + * @entry: XArray entry. 57 + * 58 + * Context: Any context. 59 + * Return: True if the entry is a value, false if it is a pointer. 60 + */ 61 + static inline bool xa_is_value(const void *entry) 62 + { 63 + return (unsigned long)entry & 1; 64 + } 65 + 66 + /** 67 + * xa_tag_pointer() - Create an XArray entry for a tagged pointer. 68 + * @p: Plain pointer. 69 + * @tag: Tag value (0, 1 or 3). 70 + * 71 + * If the user of the XArray prefers, they can tag their pointers instead 72 + * of storing value entries. Three tags are available (0, 1 and 3). 73 + * These are distinct from the xa_mark_t as they are not replicated up 74 + * through the array and cannot be searched for. 75 + * 76 + * Context: Any context. 77 + * Return: An XArray entry. 78 + */ 79 + static inline void *xa_tag_pointer(void *p, unsigned long tag) 80 + { 81 + return (void *)((unsigned long)p | tag); 82 + } 83 + 84 + /** 85 + * xa_untag_pointer() - Turn an XArray entry into a plain pointer. 86 + * @entry: XArray entry. 87 + * 88 + * If you have stored a tagged pointer in the XArray, call this function 89 + * to get the untagged version of the pointer. 90 + * 91 + * Context: Any context. 92 + * Return: A pointer. 93 + */ 94 + static inline void *xa_untag_pointer(void *entry) 95 + { 96 + return (void *)((unsigned long)entry & ~3UL); 97 + } 98 + 99 + /** 100 + * xa_pointer_tag() - Get the tag stored in an XArray entry. 101 + * @entry: XArray entry. 102 + * 103 + * If you have stored a tagged pointer in the XArray, call this function 104 + * to get the tag of that pointer. 105 + * 106 + * Context: Any context. 107 + * Return: A tag. 108 + */ 109 + static inline unsigned int xa_pointer_tag(void *entry) 110 + { 111 + return (unsigned long)entry & 3UL; 112 + } 11 113 12 114 #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) 13 115 #define xa_lock(xa) spin_lock(&(xa)->xa_lock)
+25 -35
lib/idr.c
··· 338 338 * by the number of bits in the leaf bitmap before doing a radix tree lookup. 339 339 * 340 340 * As an optimisation, if there are only a few low bits set in any given 341 - * leaf, instead of allocating a 128-byte bitmap, we use the 'exceptional 342 - * entry' functionality of the radix tree to store BITS_PER_LONG - 2 bits 343 - * directly in the entry. By being really tricksy, we could store 344 - * BITS_PER_LONG - 1 bits, but there're diminishing returns after optimising 345 - * for 0-3 allocated IDs. 341 + * leaf, instead of allocating a 128-byte bitmap, we store the bits 342 + * directly in the entry. 346 343 * 347 344 * We allow the radix tree 'exceptional' count to get out of date. Nothing 348 345 * in the IDA nor the radix tree code checks it. If it becomes important ··· 363 366 struct radix_tree_iter iter; 364 367 struct ida_bitmap *bitmap; 365 368 unsigned long index; 366 - unsigned bit, ebit; 369 + unsigned bit; 367 370 int new; 368 371 369 372 index = start / IDA_BITMAP_BITS; 370 373 bit = start % IDA_BITMAP_BITS; 371 - ebit = bit + RADIX_TREE_EXCEPTIONAL_SHIFT; 372 374 373 375 slot = radix_tree_iter_init(&iter, index); 374 376 for (;;) { ··· 382 386 return PTR_ERR(slot); 383 387 } 384 388 } 385 - if (iter.index > index) { 389 + if (iter.index > index) 386 390 bit = 0; 387 - ebit = RADIX_TREE_EXCEPTIONAL_SHIFT; 388 - } 389 391 new = iter.index * IDA_BITMAP_BITS; 390 392 bitmap = rcu_dereference_raw(*slot); 391 - if (radix_tree_exception(bitmap)) { 392 - unsigned long tmp = (unsigned long)bitmap; 393 - ebit = find_next_zero_bit(&tmp, BITS_PER_LONG, ebit); 394 - if (ebit < BITS_PER_LONG) { 395 - tmp |= 1UL << ebit; 396 - rcu_assign_pointer(*slot, (void *)tmp); 397 - return new + ebit - 398 - RADIX_TREE_EXCEPTIONAL_SHIFT; 393 + if (xa_is_value(bitmap)) { 394 + unsigned long tmp = xa_to_value(bitmap); 395 + int vbit = find_next_zero_bit(&tmp, BITS_PER_XA_VALUE, 396 + bit); 397 + if (vbit < BITS_PER_XA_VALUE) { 398 + tmp |= 1UL << vbit; 399 + rcu_assign_pointer(*slot, xa_mk_value(tmp)); 400 + return new + vbit; 399 401 } 400 402 bitmap = this_cpu_xchg(ida_bitmap, NULL); 401 403 if (!bitmap) 402 404 return -EAGAIN; 403 - bitmap->bitmap[0] = tmp >> RADIX_TREE_EXCEPTIONAL_SHIFT; 405 + bitmap->bitmap[0] = tmp; 404 406 rcu_assign_pointer(*slot, bitmap); 405 407 } 406 408 ··· 419 425 new += bit; 420 426 if (new < 0) 421 427 return -ENOSPC; 422 - if (ebit < BITS_PER_LONG) { 423 - bitmap = (void *)((1UL << ebit) | 424 - RADIX_TREE_EXCEPTIONAL_ENTRY); 425 - radix_tree_iter_replace(root, &iter, slot, 426 - bitmap); 427 - return new; 428 + if (bit < BITS_PER_XA_VALUE) { 429 + bitmap = xa_mk_value(1UL << bit); 430 + } else { 431 + bitmap = this_cpu_xchg(ida_bitmap, NULL); 432 + if (!bitmap) 433 + return -EAGAIN; 434 + __set_bit(bit, bitmap->bitmap); 428 435 } 429 - bitmap = this_cpu_xchg(ida_bitmap, NULL); 430 - if (!bitmap) 431 - return -EAGAIN; 432 - __set_bit(bit, bitmap->bitmap); 433 436 radix_tree_iter_replace(root, &iter, slot, bitmap); 434 437 } 435 438 ··· 448 457 goto err; 449 458 450 459 bitmap = rcu_dereference_raw(*slot); 451 - if (radix_tree_exception(bitmap)) { 460 + if (xa_is_value(bitmap)) { 452 461 btmp = (unsigned long *)slot; 453 - offset += RADIX_TREE_EXCEPTIONAL_SHIFT; 462 + offset += 1; /* Intimate knowledge of the value encoding */ 454 463 if (offset >= BITS_PER_LONG) 455 464 goto err; 456 465 } else { ··· 461 470 462 471 __clear_bit(offset, btmp); 463 472 radix_tree_iter_tag_set(&ida->ida_rt, &iter, IDR_FREE); 464 - if (radix_tree_exception(bitmap)) { 465 - if (rcu_dereference_raw(*slot) == 466 - (void *)RADIX_TREE_EXCEPTIONAL_ENTRY) 473 + if (xa_is_value(bitmap)) { 474 + if (xa_to_value(rcu_dereference_raw(*slot)) == 0) 467 475 radix_tree_iter_delete(&ida->ida_rt, &iter, slot); 468 476 } else if (bitmap_empty(btmp, IDA_BITMAP_BITS)) { 469 477 kfree(bitmap); ··· 493 503 xa_lock_irqsave(&ida->ida_rt, flags); 494 504 radix_tree_for_each_slot(slot, &ida->ida_rt, &iter, 0) { 495 505 struct ida_bitmap *bitmap = rcu_dereference_raw(*slot); 496 - if (!radix_tree_exception(bitmap)) 506 + if (!xa_is_value(bitmap)) 497 507 kfree(bitmap); 498 508 radix_tree_iter_delete(&ida->ida_rt, &iter, slot); 499 509 }
+9 -12
lib/radix-tree.c
··· 340 340 for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) 341 341 dump_ida_node(node->slots[i], 342 342 index | (i << node->shift)); 343 - } else if (radix_tree_exceptional_entry(entry)) { 343 + } else if (xa_is_value(entry)) { 344 344 pr_debug("ida excp: %p offset %d indices %lu-%lu data %lx\n", 345 345 entry, (int)(index & RADIX_TREE_MAP_MASK), 346 346 index * IDA_BITMAP_BITS, 347 - index * IDA_BITMAP_BITS + BITS_PER_LONG - 348 - RADIX_TREE_EXCEPTIONAL_SHIFT, 349 - (unsigned long)entry >> 350 - RADIX_TREE_EXCEPTIONAL_SHIFT); 347 + index * IDA_BITMAP_BITS + BITS_PER_XA_VALUE, 348 + xa_to_value(entry)); 351 349 } else { 352 350 struct ida_bitmap *bitmap = entry; 353 351 ··· 654 656 BUG_ON(shift > BITS_PER_LONG); 655 657 if (radix_tree_is_internal_node(entry)) { 656 658 entry_to_node(entry)->parent = node; 657 - } else if (radix_tree_exceptional_entry(entry)) { 659 + } else if (xa_is_value(entry)) { 658 660 /* Moving an exceptional root->rnode to a node */ 659 661 node->exceptional = 1; 660 662 } ··· 953 955 !is_sibling_entry(node, old) && 954 956 (old != RADIX_TREE_RETRY)) 955 957 radix_tree_free_nodes(old); 956 - if (radix_tree_exceptional_entry(old)) 958 + if (xa_is_value(old)) 957 959 node->exceptional--; 958 960 } 959 961 if (node) { 960 962 node->count += n; 961 - if (radix_tree_exceptional_entry(item)) 963 + if (xa_is_value(item)) 962 964 node->exceptional += n; 963 965 } 964 966 return n; ··· 972 974 rcu_assign_pointer(*slot, item); 973 975 if (node) { 974 976 node->count++; 975 - if (radix_tree_exceptional_entry(item)) 977 + if (xa_is_value(item)) 976 978 node->exceptional++; 977 979 } 978 980 return 1; ··· 1188 1190 radix_tree_update_node_t update_node) 1189 1191 { 1190 1192 void *old = rcu_dereference_raw(*slot); 1191 - int exceptional = !!radix_tree_exceptional_entry(item) - 1192 - !!radix_tree_exceptional_entry(old); 1193 + int exceptional = !!xa_is_value(item) - !!xa_is_value(old); 1193 1194 int count = calculate_count(root, node, slot, item, old); 1194 1195 1195 1196 /* ··· 1989 1992 struct radix_tree_node *node, void __rcu **slot) 1990 1993 { 1991 1994 void *old = rcu_dereference_raw(*slot); 1992 - int exceptional = radix_tree_exceptional_entry(old) ? -1 : 0; 1995 + int exceptional = xa_is_value(old) ? -1 : 0; 1993 1996 unsigned offset = get_slot_offset(node, slot); 1994 1997 int tag; 1995 1998
+5 -5
mm/filemap.c
··· 127 127 128 128 p = radix_tree_deref_slot_protected(slot, 129 129 &mapping->i_pages.xa_lock); 130 - if (!radix_tree_exceptional_entry(p)) 130 + if (!xa_is_value(p)) 131 131 return -EEXIST; 132 132 133 133 mapping->nrexceptional--; ··· 336 336 break; 337 337 page = radix_tree_deref_slot_protected(slot, 338 338 &mapping->i_pages.xa_lock); 339 - if (radix_tree_exceptional_entry(page)) 339 + if (xa_is_value(page)) 340 340 continue; 341 341 if (!tail_pages) { 342 342 /* ··· 1355 1355 struct page *page; 1356 1356 1357 1357 page = radix_tree_lookup(&mapping->i_pages, index); 1358 - if (!page || radix_tree_exceptional_entry(page)) 1358 + if (!page || xa_is_value(page)) 1359 1359 break; 1360 1360 index++; 1361 1361 if (index == 0) ··· 1396 1396 struct page *page; 1397 1397 1398 1398 page = radix_tree_lookup(&mapping->i_pages, index); 1399 - if (!page || radix_tree_exceptional_entry(page)) 1399 + if (!page || xa_is_value(page)) 1400 1400 break; 1401 1401 index--; 1402 1402 if (index == ULONG_MAX) ··· 1539 1539 1540 1540 repeat: 1541 1541 page = find_get_entry(mapping, offset); 1542 - if (radix_tree_exceptional_entry(page)) 1542 + if (xa_is_value(page)) 1543 1543 page = NULL; 1544 1544 if (!page) 1545 1545 goto no_page;
+1 -1
mm/khugepaged.c
··· 1369 1369 1370 1370 page = radix_tree_deref_slot_protected(slot, 1371 1371 &mapping->i_pages.xa_lock); 1372 - if (radix_tree_exceptional_entry(page) || !PageUptodate(page)) { 1372 + if (xa_is_value(page) || !PageUptodate(page)) { 1373 1373 xa_unlock_irq(&mapping->i_pages); 1374 1374 /* swap in or instantiate fallocated page */ 1375 1375 if (shmem_getpage(mapping->host, index, &page,
+1 -1
mm/madvise.c
··· 251 251 index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; 252 252 253 253 page = find_get_entry(mapping, index); 254 - if (!radix_tree_exceptional_entry(page)) { 254 + if (!xa_is_value(page)) { 255 255 if (page) 256 256 put_page(page); 257 257 continue;
+1 -1
mm/memcontrol.c
··· 4750 4750 /* shmem/tmpfs may report page out on swap: account for that too. */ 4751 4751 if (shmem_mapping(mapping)) { 4752 4752 page = find_get_entry(mapping, pgoff); 4753 - if (radix_tree_exceptional_entry(page)) { 4753 + if (xa_is_value(page)) { 4754 4754 swp_entry_t swp = radix_to_swp_entry(page); 4755 4755 if (do_memsw_account()) 4756 4756 *entry = swp;
+1 -1
mm/mincore.c
··· 66 66 * shmem/tmpfs may return swap: account for swapcache 67 67 * page too. 68 68 */ 69 - if (radix_tree_exceptional_entry(page)) { 69 + if (xa_is_value(page)) { 70 70 swp_entry_t swp = radix_to_swp_entry(page); 71 71 page = find_get_page(swap_address_space(swp), 72 72 swp_offset(swp));
+1 -1
mm/readahead.c
··· 179 179 rcu_read_lock(); 180 180 page = radix_tree_lookup(&mapping->i_pages, page_offset); 181 181 rcu_read_unlock(); 182 - if (page && !radix_tree_exceptional_entry(page)) { 182 + if (page && !xa_is_value(page)) { 183 183 /* 184 184 * Page already present? Kick off the current batch of 185 185 * contiguous pages before continuing with the next
+5 -5
mm/shmem.c
··· 709 709 continue; 710 710 } 711 711 712 - if (radix_tree_exceptional_entry(page)) 712 + if (xa_is_value(page)) 713 713 swapped++; 714 714 715 715 if (need_resched()) { ··· 824 824 if (index >= end) 825 825 break; 826 826 827 - if (radix_tree_exceptional_entry(page)) { 827 + if (xa_is_value(page)) { 828 828 if (unfalloc) 829 829 continue; 830 830 nr_swaps_freed += !shmem_free_swap(mapping, ··· 921 921 if (index >= end) 922 922 break; 923 923 924 - if (radix_tree_exceptional_entry(page)) { 924 + if (xa_is_value(page)) { 925 925 if (unfalloc) 926 926 continue; 927 927 if (shmem_free_swap(mapping, index, page)) { ··· 1643 1643 repeat: 1644 1644 swap.val = 0; 1645 1645 page = find_lock_entry(mapping, index); 1646 - if (radix_tree_exceptional_entry(page)) { 1646 + if (xa_is_value(page)) { 1647 1647 swap = radix_to_swp_entry(page); 1648 1648 page = NULL; 1649 1649 } ··· 2578 2578 index = indices[i]; 2579 2579 } 2580 2580 page = pvec.pages[i]; 2581 - if (page && !radix_tree_exceptional_entry(page)) { 2581 + if (page && !xa_is_value(page)) { 2582 2582 if (!PageUptodate(page)) 2583 2583 page = NULL; 2584 2584 }
+1 -1
mm/swap.c
··· 965 965 966 966 for (i = 0, j = 0; i < pagevec_count(pvec); i++) { 967 967 struct page *page = pvec->pages[i]; 968 - if (!radix_tree_exceptional_entry(page)) 968 + if (!xa_is_value(page)) 969 969 pvec->pages[j++] = page; 970 970 } 971 971 pvec->nr = j;
+6 -6
mm/truncate.c
··· 70 70 return; 71 71 72 72 for (j = 0; j < pagevec_count(pvec); j++) 73 - if (radix_tree_exceptional_entry(pvec->pages[j])) 73 + if (xa_is_value(pvec->pages[j])) 74 74 break; 75 75 76 76 if (j == pagevec_count(pvec)) ··· 85 85 struct page *page = pvec->pages[i]; 86 86 pgoff_t index = indices[i]; 87 87 88 - if (!radix_tree_exceptional_entry(page)) { 88 + if (!xa_is_value(page)) { 89 89 pvec->pages[j++] = page; 90 90 continue; 91 91 } ··· 347 347 if (index >= end) 348 348 break; 349 349 350 - if (radix_tree_exceptional_entry(page)) 350 + if (xa_is_value(page)) 351 351 continue; 352 352 353 353 if (!trylock_page(page)) ··· 442 442 break; 443 443 } 444 444 445 - if (radix_tree_exceptional_entry(page)) 445 + if (xa_is_value(page)) 446 446 continue; 447 447 448 448 lock_page(page); ··· 561 561 if (index > end) 562 562 break; 563 563 564 - if (radix_tree_exceptional_entry(page)) { 564 + if (xa_is_value(page)) { 565 565 invalidate_exceptional_entry(mapping, index, 566 566 page); 567 567 continue; ··· 692 692 if (index > end) 693 693 break; 694 694 695 - if (radix_tree_exceptional_entry(page)) { 695 + if (xa_is_value(page)) { 696 696 if (!invalidate_exceptional_entry2(mapping, 697 697 index, page)) 698 698 ret = -EBUSY;
+6 -7
mm/workingset.c
··· 155 155 * refault distance will immediately activate the refaulting page. 156 156 */ 157 157 158 - #define EVICTION_SHIFT (RADIX_TREE_EXCEPTIONAL_ENTRY + \ 159 - NODES_SHIFT + \ 158 + #define EVICTION_SHIFT ((BITS_PER_LONG - BITS_PER_XA_VALUE) + \ 159 + NODES_SHIFT + \ 160 160 MEM_CGROUP_ID_SHIFT) 161 161 #define EVICTION_MASK (~0UL >> EVICTION_SHIFT) 162 162 ··· 173 173 static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction) 174 174 { 175 175 eviction >>= bucket_order; 176 + eviction &= EVICTION_MASK; 176 177 eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; 177 178 eviction = (eviction << NODES_SHIFT) | pgdat->node_id; 178 - eviction = (eviction << RADIX_TREE_EXCEPTIONAL_SHIFT); 179 179 180 - return (void *)(eviction | RADIX_TREE_EXCEPTIONAL_ENTRY); 180 + return xa_mk_value(eviction); 181 181 } 182 182 183 183 static void unpack_shadow(void *shadow, int *memcgidp, pg_data_t **pgdat, 184 184 unsigned long *evictionp) 185 185 { 186 - unsigned long entry = (unsigned long)shadow; 186 + unsigned long entry = xa_to_value(shadow); 187 187 int memcgid, nid; 188 188 189 - entry >>= RADIX_TREE_EXCEPTIONAL_SHIFT; 190 189 nid = entry & ((1UL << NODES_SHIFT) - 1); 191 190 entry >>= NODES_SHIFT; 192 191 memcgid = entry & ((1UL << MEM_CGROUP_ID_SHIFT) - 1); ··· 452 453 goto out_invalid; 453 454 for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { 454 455 if (node->slots[i]) { 455 - if (WARN_ON_ONCE(!radix_tree_exceptional_entry(node->slots[i]))) 456 + if (WARN_ON_ONCE(!xa_is_value(node->slots[i]))) 456 457 goto out_invalid; 457 458 if (WARN_ON_ONCE(!node->exceptional)) 458 459 goto out_invalid;
+3 -3
tools/testing/radix-tree/idr-test.c
··· 19 19 20 20 #include "test.h" 21 21 22 - #define DUMMY_PTR ((void *)0x12) 22 + #define DUMMY_PTR ((void *)0x10) 23 23 24 24 int item_idr_free(int id, void *p, void *data) 25 25 { ··· 411 411 int id = ida_alloc(&ida, GFP_NOWAIT); 412 412 if (id == -ENOMEM) { 413 413 IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) != 414 - BITS_PER_LONG - 2); 414 + BITS_PER_XA_VALUE); 415 415 id = ida_alloc(&ida, GFP_KERNEL); 416 416 } else { 417 417 IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) == 418 - BITS_PER_LONG - 2); 418 + BITS_PER_XA_VALUE); 419 419 } 420 420 IDA_BUG_ON(&ida, id != i); 421 421 }
-1
tools/testing/radix-tree/linux/radix-tree.h
··· 2 2 #ifndef _TEST_RADIX_TREE_H 3 3 #define _TEST_RADIX_TREE_H 4 4 5 - #include "generated/map-shift.h" 6 5 #include "../../../../include/linux/radix-tree.h" 7 6 8 7 extern int kmalloc_verbose;
+23 -24
tools/testing/radix-tree/multiorder.c
··· 39 39 40 40 /* 41 41 * Verify we get collisions for covered indices. We try and fail to 42 - * insert an exceptional entry so we don't leak memory via 42 + * insert a value entry so we don't leak memory via 43 43 * item_insert_order(). 44 44 */ 45 45 for_each_index(i, base, order) { 46 - err = __radix_tree_insert(&tree, i, order, 47 - (void *)(0xA0 | RADIX_TREE_EXCEPTIONAL_ENTRY)); 46 + err = __radix_tree_insert(&tree, i, order, xa_mk_value(0xA0)); 48 47 assert(err == -EEXIST); 49 48 } 50 49 ··· 379 380 } 380 381 381 382 /* 382 - * Check that the accounting of exceptional entries is handled correctly 383 - * by joining an exceptional entry to a normal pointer. 383 + * Check that the accounting of value entries is handled correctly 384 + * by joining a value entry to a normal pointer. 384 385 */ 385 386 static void multiorder_join2(unsigned order1, unsigned order2) 386 387 { ··· 390 391 void *item2; 391 392 392 393 item_insert_order(&tree, 0, order2); 393 - radix_tree_insert(&tree, 1 << order2, (void *)0x12UL); 394 + radix_tree_insert(&tree, 1 << order2, xa_mk_value(5)); 394 395 item2 = __radix_tree_lookup(&tree, 1 << order2, &node, NULL); 395 - assert(item2 == (void *)0x12UL); 396 + assert(item2 == xa_mk_value(5)); 396 397 assert(node->exceptional == 1); 397 398 398 399 item2 = radix_tree_lookup(&tree, 0); ··· 406 407 } 407 408 408 409 /* 409 - * This test revealed an accounting bug for exceptional entries at one point. 410 + * This test revealed an accounting bug for value entries at one point. 410 411 * Nodes were being freed back into the pool with an elevated exception count 411 412 * by radix_tree_join() and then radix_tree_split() was failing to zero the 412 413 * count of exceptional entries. ··· 420 421 unsigned long i; 421 422 422 423 for (i = 0; i < (1 << order); i++) { 423 - radix_tree_insert(&tree, i, (void *)0x12UL); 424 + radix_tree_insert(&tree, i, xa_mk_value(5)); 424 425 } 425 426 426 - radix_tree_join(&tree, 0, order, (void *)0x16UL); 427 + radix_tree_join(&tree, 0, order, xa_mk_value(7)); 427 428 rcu_barrier(); 428 429 429 430 radix_tree_split(&tree, 0, 0); 430 431 431 432 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 432 - radix_tree_iter_replace(&tree, &iter, slot, (void *)0x12UL); 433 + radix_tree_iter_replace(&tree, &iter, slot, xa_mk_value(5)); 433 434 } 434 435 435 436 __radix_tree_lookup(&tree, 0, &node, NULL); ··· 516 517 struct radix_tree_node *node; 517 518 void *item; 518 519 519 - __radix_tree_insert(&tree, 0, old_order, (void *)0x12); 520 + __radix_tree_insert(&tree, 0, old_order, xa_mk_value(5)); 520 521 521 522 item = __radix_tree_lookup(&tree, 0, &node, NULL); 522 - assert(item == (void *)0x12); 523 + assert(item == xa_mk_value(5)); 523 524 assert(node->exceptional > 0); 524 525 525 526 radix_tree_split(&tree, 0, new_order); ··· 529 530 } 530 531 531 532 item = __radix_tree_lookup(&tree, 0, &node, NULL); 532 - assert(item != (void *)0x12); 533 + assert(item != xa_mk_value(5)); 533 534 assert(node->exceptional == 0); 534 535 535 536 item_kill_tree(&tree); ··· 543 544 struct radix_tree_node *node; 544 545 void *item; 545 546 546 - __radix_tree_insert(&tree, 0, old_order, (void *)0x12); 547 + __radix_tree_insert(&tree, 0, old_order, xa_mk_value(5)); 547 548 548 549 item = __radix_tree_lookup(&tree, 0, &node, NULL); 549 - assert(item == (void *)0x12); 550 + assert(item == xa_mk_value(5)); 550 551 assert(node->exceptional > 0); 551 552 552 553 radix_tree_split(&tree, 0, new_order); 553 554 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 554 - radix_tree_iter_replace(&tree, &iter, slot, (void *)0x16); 555 + radix_tree_iter_replace(&tree, &iter, slot, xa_mk_value(7)); 555 556 } 556 557 557 558 item = __radix_tree_lookup(&tree, 0, &node, NULL); 558 - assert(item == (void *)0x16); 559 + assert(item == xa_mk_value(7)); 559 560 assert(node->exceptional > 0); 560 561 561 562 item_kill_tree(&tree); 562 563 563 - __radix_tree_insert(&tree, 0, old_order, (void *)0x12); 564 + __radix_tree_insert(&tree, 0, old_order, xa_mk_value(5)); 564 565 565 566 item = __radix_tree_lookup(&tree, 0, &node, NULL); 566 - assert(item == (void *)0x12); 567 + assert(item == xa_mk_value(5)); 567 568 assert(node->exceptional > 0); 568 569 569 570 radix_tree_split(&tree, 0, new_order); 570 571 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 571 572 if (iter.index == (1 << new_order)) 572 573 radix_tree_iter_replace(&tree, &iter, slot, 573 - (void *)0x16); 574 + xa_mk_value(7)); 574 575 else 575 576 radix_tree_iter_replace(&tree, &iter, slot, NULL); 576 577 } 577 578 578 579 item = __radix_tree_lookup(&tree, 1 << new_order, &node, NULL); 579 - assert(item == (void *)0x16); 580 + assert(item == xa_mk_value(7)); 580 581 assert(node->count == node->exceptional); 581 582 do { 582 583 node = node->parent; ··· 609 610 610 611 item_insert_order(&tree, 0, 5); 611 612 612 - __radix_tree_insert(&tree, 1 << 5, 5, (void *)0x12); 613 + __radix_tree_insert(&tree, 1 << 5, 5, xa_mk_value(5)); 613 614 __radix_tree_lookup(&tree, 0, &node, NULL); 614 615 assert(node->count == node->exceptional * 2); 615 616 radix_tree_delete(&tree, 1 << 5); 616 617 assert(node->exceptional == 0); 617 618 618 - __radix_tree_insert(&tree, 1 << 5, 5, (void *)0x12); 619 + __radix_tree_insert(&tree, 1 << 5, 5, xa_mk_value(5)); 619 620 __radix_tree_lookup(&tree, 1 << 5, &node, &slot); 620 621 assert(node->count == node->exceptional * 2); 621 622 __radix_tree_replace(&tree, node, slot, NULL, NULL);
+1 -1
tools/testing/radix-tree/test.c
··· 295 295 int nfound; 296 296 297 297 radix_tree_for_each_slot(slot, root, &iter, 0) { 298 - if (radix_tree_exceptional_entry(*slot)) 298 + if (xa_is_value(*slot)) 299 299 radix_tree_delete(root, iter.index); 300 300 } 301 301