summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavidlohr Bueso <dave@stgolabs.net>2017-09-08 19:15:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-08 21:26:49 -0400
commitf808c13fd3738948e10196496959871130612b61 (patch)
tree0f9b1bf3ccc9c4d051bf4fed87b493dced56d032
parent09663c86e24953556ff8696efa023557901f2b66 (diff)
lib/interval_tree: fast overlap detection
Allow interval trees to quickly check for overlaps to avoid unnecesary tree lookups in interval_tree_iter_first(). As of this patch, all interval tree flavors will require using a 'rb_root_cached' such that we can have the leftmost node easily available. While most users will make use of this feature, those with special functions (in addition to the generic insert, delete, search calls) will avoid using the cached option as they can do funky things with insertions -- for example, vma_interval_tree_insert_after(). [jglisse@redhat.com: fix deadlock from typo vm_lock_anon_vma()] Link: http://lkml.kernel.org/r/20170808225719.20723-1-jglisse@redhat.com Link: http://lkml.kernel.org/r/20170719014603.19029-12-dave@stgolabs.net Signed-off-by: Davidlohr Bueso <dbueso@suse.de> Signed-off-by: Jérôme Glisse <jglisse@redhat.com> Acked-by: Christian König <christian.koenig@amd.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Doug Ledford <dledford@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Cc: David Airlie <airlied@linux.ie> Cc: Jason Wang <jasowang@redhat.com> Cc: Christian Benvenuti <benve@cisco.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h2
-rw-r--r--drivers/gpu/drm/drm_mm.c19
-rw-r--r--drivers/gpu/drm/drm_vma_manager.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mn.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c7
-rw-r--r--drivers/infiniband/core/umem_rbtree.c4
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c2
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.c10
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom.c6
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom.h2
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c15
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h12
-rw-r--r--drivers/vhost/vhost.c2
-rw-r--r--drivers/vhost/vhost.h2
-rw-r--r--fs/hugetlbfs/inode.c6
-rw-r--r--fs/inode.c2
-rw-r--r--include/drm/drm_mm.h2
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/interval_tree.h8
-rw-r--r--include/linux/interval_tree_generic.h46
-rw-r--r--include/linux/mm.h17
-rw-r--r--include/linux/rmap.h4
-rw-r--r--include/rdma/ib_umem_odp.h11
-rw-r--r--include/rdma/ib_verbs.h2
-rw-r--r--lib/interval_tree_test.c4
-rw-r--r--mm/interval_tree.c10
-rw-r--r--mm/memory.c4
-rw-r--r--mm/mmap.c10
-rw-r--r--mm/rmap.c4
33 files changed, 145 insertions, 105 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index e1cde6b80027..3b0f2ec6eec7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -51,7 +51,7 @@ struct amdgpu_mn {
51 51
52 /* objects protected by lock */ 52 /* objects protected by lock */
53 struct mutex lock; 53 struct mutex lock;
54 struct rb_root objects; 54 struct rb_root_cached objects;
55}; 55};
56 56
57struct amdgpu_mn_node { 57struct amdgpu_mn_node {
@@ -76,8 +76,8 @@ static void amdgpu_mn_destroy(struct work_struct *work)
76 mutex_lock(&adev->mn_lock); 76 mutex_lock(&adev->mn_lock);
77 mutex_lock(&rmn->lock); 77 mutex_lock(&rmn->lock);
78 hash_del(&rmn->node); 78 hash_del(&rmn->node);
79 rbtree_postorder_for_each_entry_safe(node, next_node, &rmn->objects, 79 rbtree_postorder_for_each_entry_safe(node, next_node,
80 it.rb) { 80 &rmn->objects.rb_root, it.rb) {
81 list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) { 81 list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) {
82 bo->mn = NULL; 82 bo->mn = NULL;
83 list_del_init(&bo->mn_list); 83 list_del_init(&bo->mn_list);
@@ -221,7 +221,7 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev)
221 rmn->mm = mm; 221 rmn->mm = mm;
222 rmn->mn.ops = &amdgpu_mn_ops; 222 rmn->mn.ops = &amdgpu_mn_ops;
223 mutex_init(&rmn->lock); 223 mutex_init(&rmn->lock);
224 rmn->objects = RB_ROOT; 224 rmn->objects = RB_ROOT_CACHED;
225 225
226 r = __mmu_notifier_register(&rmn->mn, mm); 226 r = __mmu_notifier_register(&rmn->mn, mm);
227 if (r) 227 if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6b1343e5541d..b9a5a77eedaf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2475,7 +2475,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2475 u64 flags; 2475 u64 flags;
2476 uint64_t init_pde_value = 0; 2476 uint64_t init_pde_value = 0;
2477 2477
2478 vm->va = RB_ROOT; 2478 vm->va = RB_ROOT_CACHED;
2479 vm->client_id = atomic64_inc_return(&adev->vm_manager.client_counter); 2479 vm->client_id = atomic64_inc_return(&adev->vm_manager.client_counter);
2480 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) 2480 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
2481 vm->reserved_vmid[i] = NULL; 2481 vm->reserved_vmid[i] = NULL;
@@ -2596,10 +2596,11 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
2596 2596
2597 amd_sched_entity_fini(vm->entity.sched, &vm->entity); 2597 amd_sched_entity_fini(vm->entity.sched, &vm->entity);
2598 2598
2599 if (!RB_EMPTY_ROOT(&vm->va)) { 2599 if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
2600 dev_err(adev->dev, "still active bo inside vm\n"); 2600 dev_err(adev->dev, "still active bo inside vm\n");
2601 } 2601 }
2602 rbtree_postorder_for_each_entry_safe(mapping, tmp, &vm->va, rb) { 2602 rbtree_postorder_for_each_entry_safe(mapping, tmp,
2603 &vm->va.rb_root, rb) {
2603 list_del(&mapping->list); 2604 list_del(&mapping->list);
2604 amdgpu_vm_it_remove(mapping, &vm->va); 2605 amdgpu_vm_it_remove(mapping, &vm->va);
2605 kfree(mapping); 2606 kfree(mapping);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index ba6691b58ee7..6716355403ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -118,7 +118,7 @@ struct amdgpu_vm_pt {
118 118
119struct amdgpu_vm { 119struct amdgpu_vm {
120 /* tree of virtual addresses mapped */ 120 /* tree of virtual addresses mapped */
121 struct rb_root va; 121 struct rb_root_cached va;
122 122
123 /* protecting invalidated */ 123 /* protecting invalidated */
124 spinlock_t status_lock; 124 spinlock_t status_lock;
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index f794089d30ac..61a1c8ea74bc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -169,7 +169,7 @@ INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
169struct drm_mm_node * 169struct drm_mm_node *
170__drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last) 170__drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
171{ 171{
172 return drm_mm_interval_tree_iter_first((struct rb_root *)&mm->interval_tree, 172 return drm_mm_interval_tree_iter_first((struct rb_root_cached *)&mm->interval_tree,
173 start, last) ?: (struct drm_mm_node *)&mm->head_node; 173 start, last) ?: (struct drm_mm_node *)&mm->head_node;
174} 174}
175EXPORT_SYMBOL(__drm_mm_interval_first); 175EXPORT_SYMBOL(__drm_mm_interval_first);
@@ -180,6 +180,7 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
180 struct drm_mm *mm = hole_node->mm; 180 struct drm_mm *mm = hole_node->mm;
181 struct rb_node **link, *rb; 181 struct rb_node **link, *rb;
182 struct drm_mm_node *parent; 182 struct drm_mm_node *parent;
183 bool leftmost = true;
183 184
184 node->__subtree_last = LAST(node); 185 node->__subtree_last = LAST(node);
185 186
@@ -196,9 +197,10 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
196 197
197 rb = &hole_node->rb; 198 rb = &hole_node->rb;
198 link = &hole_node->rb.rb_right; 199 link = &hole_node->rb.rb_right;
200 leftmost = false;
199 } else { 201 } else {
200 rb = NULL; 202 rb = NULL;
201 link = &mm->interval_tree.rb_node; 203 link = &mm->interval_tree.rb_root.rb_node;
202 } 204 }
203 205
204 while (*link) { 206 while (*link) {
@@ -208,14 +210,15 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
208 parent->__subtree_last = node->__subtree_last; 210 parent->__subtree_last = node->__subtree_last;
209 if (node->start < parent->start) 211 if (node->start < parent->start)
210 link = &parent->rb.rb_left; 212 link = &parent->rb.rb_left;
211 else 213 else {
212 link = &parent->rb.rb_right; 214 link = &parent->rb.rb_right;
215 leftmost = true;
216 }
213 } 217 }
214 218
215 rb_link_node(&node->rb, rb, link); 219 rb_link_node(&node->rb, rb, link);
216 rb_insert_augmented(&node->rb, 220 rb_insert_augmented_cached(&node->rb, &mm->interval_tree, leftmost,
217 &mm->interval_tree, 221 &drm_mm_interval_tree_augment);
218 &drm_mm_interval_tree_augment);
219} 222}
220 223
221#define RB_INSERT(root, member, expr) do { \ 224#define RB_INSERT(root, member, expr) do { \
@@ -577,7 +580,7 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
577 *new = *old; 580 *new = *old;
578 581
579 list_replace(&old->node_list, &new->node_list); 582 list_replace(&old->node_list, &new->node_list);
580 rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree); 583 rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree.rb_root);
581 584
582 if (drm_mm_hole_follows(old)) { 585 if (drm_mm_hole_follows(old)) {
583 list_replace(&old->hole_stack, &new->hole_stack); 586 list_replace(&old->hole_stack, &new->hole_stack);
@@ -863,7 +866,7 @@ void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
863 mm->color_adjust = NULL; 866 mm->color_adjust = NULL;
864 867
865 INIT_LIST_HEAD(&mm->hole_stack); 868 INIT_LIST_HEAD(&mm->hole_stack);
866 mm->interval_tree = RB_ROOT; 869 mm->interval_tree = RB_ROOT_CACHED;
867 mm->holes_size = RB_ROOT; 870 mm->holes_size = RB_ROOT;
868 mm->holes_addr = RB_ROOT; 871 mm->holes_addr = RB_ROOT;
869 872
diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c
index d9100b565198..28f1226576f8 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -147,7 +147,7 @@ struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_m
147 struct rb_node *iter; 147 struct rb_node *iter;
148 unsigned long offset; 148 unsigned long offset;
149 149
150 iter = mgr->vm_addr_space_mm.interval_tree.rb_node; 150 iter = mgr->vm_addr_space_mm.interval_tree.rb_root.rb_node;
151 best = NULL; 151 best = NULL;
152 152
153 while (likely(iter)) { 153 while (likely(iter)) {
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index f152a38d7079..23fd18bd1b56 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -49,7 +49,7 @@ struct i915_mmu_notifier {
49 spinlock_t lock; 49 spinlock_t lock;
50 struct hlist_node node; 50 struct hlist_node node;
51 struct mmu_notifier mn; 51 struct mmu_notifier mn;
52 struct rb_root objects; 52 struct rb_root_cached objects;
53 struct workqueue_struct *wq; 53 struct workqueue_struct *wq;
54}; 54};
55 55
@@ -123,7 +123,7 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
123 struct interval_tree_node *it; 123 struct interval_tree_node *it;
124 LIST_HEAD(cancelled); 124 LIST_HEAD(cancelled);
125 125
126 if (RB_EMPTY_ROOT(&mn->objects)) 126 if (RB_EMPTY_ROOT(&mn->objects.rb_root))
127 return; 127 return;
128 128
129 /* interval ranges are inclusive, but invalidate range is exclusive */ 129 /* interval ranges are inclusive, but invalidate range is exclusive */
@@ -172,7 +172,7 @@ i915_mmu_notifier_create(struct mm_struct *mm)
172 172
173 spin_lock_init(&mn->lock); 173 spin_lock_init(&mn->lock);
174 mn->mn.ops = &i915_gem_userptr_notifier; 174 mn->mn.ops = &i915_gem_userptr_notifier;
175 mn->objects = RB_ROOT; 175 mn->objects = RB_ROOT_CACHED;
176 mn->wq = alloc_workqueue("i915-userptr-release", WQ_UNBOUND, 0); 176 mn->wq = alloc_workqueue("i915-userptr-release", WQ_UNBOUND, 0);
177 if (mn->wq == NULL) { 177 if (mn->wq == NULL) {
178 kfree(mn); 178 kfree(mn);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ec63bc5e9de7..8cbaeec090c9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -924,7 +924,7 @@ struct radeon_vm_id {
924struct radeon_vm { 924struct radeon_vm {
925 struct mutex mutex; 925 struct mutex mutex;
926 926
927 struct rb_root va; 927 struct rb_root_cached va;
928 928
929 /* protecting invalidated and freed */ 929 /* protecting invalidated and freed */
930 spinlock_t status_lock; 930 spinlock_t status_lock;
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c
index 896f2cf51e4e..1d62288b7ee3 100644
--- a/drivers/gpu/drm/radeon/radeon_mn.c
+++ b/drivers/gpu/drm/radeon/radeon_mn.c
@@ -50,7 +50,7 @@ struct radeon_mn {
50 50
51 /* objects protected by lock */ 51 /* objects protected by lock */
52 struct mutex lock; 52 struct mutex lock;
53 struct rb_root objects; 53 struct rb_root_cached objects;
54}; 54};
55 55
56struct radeon_mn_node { 56struct radeon_mn_node {
@@ -75,8 +75,8 @@ static void radeon_mn_destroy(struct work_struct *work)
75 mutex_lock(&rdev->mn_lock); 75 mutex_lock(&rdev->mn_lock);
76 mutex_lock(&rmn->lock); 76 mutex_lock(&rmn->lock);
77 hash_del(&rmn->node); 77 hash_del(&rmn->node);
78 rbtree_postorder_for_each_entry_safe(node, next_node, &rmn->objects, 78 rbtree_postorder_for_each_entry_safe(node, next_node,
79 it.rb) { 79 &rmn->objects.rb_root, it.rb) {
80 80
81 interval_tree_remove(&node->it, &rmn->objects); 81 interval_tree_remove(&node->it, &rmn->objects);
82 list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) { 82 list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) {
@@ -205,7 +205,7 @@ static struct radeon_mn *radeon_mn_get(struct radeon_device *rdev)
205 rmn->mm = mm; 205 rmn->mm = mm;
206 rmn->mn.ops = &radeon_mn_ops; 206 rmn->mn.ops = &radeon_mn_ops;
207 mutex_init(&rmn->lock); 207 mutex_init(&rmn->lock);
208 rmn->objects = RB_ROOT; 208 rmn->objects = RB_ROOT_CACHED;
209 209
210 r = __mmu_notifier_register(&rmn->mn, mm); 210 r = __mmu_notifier_register(&rmn->mn, mm);
211 if (r) 211 if (r)
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 5e82b408d522..e5c0e635e371 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -1185,7 +1185,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1185 vm->ids[i].last_id_use = NULL; 1185 vm->ids[i].last_id_use = NULL;
1186 } 1186 }
1187 mutex_init(&vm->mutex); 1187 mutex_init(&vm->mutex);
1188 vm->va = RB_ROOT; 1188 vm->va = RB_ROOT_CACHED;
1189 spin_lock_init(&vm->status_lock); 1189 spin_lock_init(&vm->status_lock);
1190 INIT_LIST_HEAD(&vm->invalidated); 1190 INIT_LIST_HEAD(&vm->invalidated);
1191 INIT_LIST_HEAD(&vm->freed); 1191 INIT_LIST_HEAD(&vm->freed);
@@ -1232,10 +1232,11 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
1232 struct radeon_bo_va *bo_va, *tmp; 1232 struct radeon_bo_va *bo_va, *tmp;
1233 int i, r; 1233 int i, r;
1234 1234
1235 if (!RB_EMPTY_ROOT(&vm->va)) { 1235 if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
1236 dev_err(rdev->dev, "still active bo inside vm\n"); 1236 dev_err(rdev->dev, "still active bo inside vm\n");
1237 } 1237 }
1238 rbtree_postorder_for_each_entry_safe(bo_va, tmp, &vm->va, it.rb) { 1238 rbtree_postorder_for_each_entry_safe(bo_va, tmp,
1239 &vm->va.rb_root, it.rb) {
1239 interval_tree_remove(&bo_va->it, &vm->va); 1240 interval_tree_remove(&bo_va->it, &vm->va);
1240 r = radeon_bo_reserve(bo_va->bo, false); 1241 r = radeon_bo_reserve(bo_va->bo, false);
1241 if (!r) { 1242 if (!r) {
diff --git a/drivers/infiniband/core/umem_rbtree.c b/drivers/infiniband/core/umem_rbtree.c
index d176597b4d78..fc801920e341 100644
--- a/drivers/infiniband/core/umem_rbtree.c
+++ b/drivers/infiniband/core/umem_rbtree.c
@@ -72,7 +72,7 @@ INTERVAL_TREE_DEFINE(struct umem_odp_node, rb, u64, __subtree_last,
72/* @last is not a part of the interval. See comment for function 72/* @last is not a part of the interval. See comment for function
73 * node_last. 73 * node_last.
74 */ 74 */
75int rbt_ib_umem_for_each_in_range(struct rb_root *root, 75int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
76 u64 start, u64 last, 76 u64 start, u64 last,
77 umem_call_back cb, 77 umem_call_back cb,
78 void *cookie) 78 void *cookie)
@@ -95,7 +95,7 @@ int rbt_ib_umem_for_each_in_range(struct rb_root *root,
95} 95}
96EXPORT_SYMBOL(rbt_ib_umem_for_each_in_range); 96EXPORT_SYMBOL(rbt_ib_umem_for_each_in_range);
97 97
98struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root, 98struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root_cached *root,
99 u64 addr, u64 length) 99 u64 addr, u64 length)
100{ 100{
101 struct umem_odp_node *node; 101 struct umem_odp_node *node;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index e0cb99860934..4ab30d832ac5 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -118,7 +118,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
118 ucontext->closing = 0; 118 ucontext->closing = 0;
119 119
120#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING 120#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
121 ucontext->umem_tree = RB_ROOT; 121 ucontext->umem_tree = RB_ROOT_CACHED;
122 init_rwsem(&ucontext->umem_rwsem); 122 init_rwsem(&ucontext->umem_rwsem);
123 ucontext->odp_mrs_count = 0; 123 ucontext->odp_mrs_count = 0;
124 INIT_LIST_HEAD(&ucontext->no_private_counters); 124 INIT_LIST_HEAD(&ucontext->no_private_counters);
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index 2f0d285dc278..175002c046ed 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -54,7 +54,7 @@
54 54
55struct mmu_rb_handler { 55struct mmu_rb_handler {
56 struct mmu_notifier mn; 56 struct mmu_notifier mn;
57 struct rb_root root; 57 struct rb_root_cached root;
58 void *ops_arg; 58 void *ops_arg;
59 spinlock_t lock; /* protect the RB tree */ 59 spinlock_t lock; /* protect the RB tree */
60 struct mmu_rb_ops *ops; 60 struct mmu_rb_ops *ops;
@@ -108,7 +108,7 @@ int hfi1_mmu_rb_register(void *ops_arg, struct mm_struct *mm,
108 if (!handlr) 108 if (!handlr)
109 return -ENOMEM; 109 return -ENOMEM;
110 110
111 handlr->root = RB_ROOT; 111 handlr->root = RB_ROOT_CACHED;
112 handlr->ops = ops; 112 handlr->ops = ops;
113 handlr->ops_arg = ops_arg; 113 handlr->ops_arg = ops_arg;
114 INIT_HLIST_NODE(&handlr->mn.hlist); 114 INIT_HLIST_NODE(&handlr->mn.hlist);
@@ -149,9 +149,9 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler)
149 INIT_LIST_HEAD(&del_list); 149 INIT_LIST_HEAD(&del_list);
150 150
151 spin_lock_irqsave(&handler->lock, flags); 151 spin_lock_irqsave(&handler->lock, flags);
152 while ((node = rb_first(&handler->root))) { 152 while ((node = rb_first_cached(&handler->root))) {
153 rbnode = rb_entry(node, struct mmu_rb_node, node); 153 rbnode = rb_entry(node, struct mmu_rb_node, node);
154 rb_erase(node, &handler->root); 154 rb_erase_cached(node, &handler->root);
155 /* move from LRU list to delete list */ 155 /* move from LRU list to delete list */
156 list_move(&rbnode->list, &del_list); 156 list_move(&rbnode->list, &del_list);
157 } 157 }
@@ -300,7 +300,7 @@ static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn,
300{ 300{
301 struct mmu_rb_handler *handler = 301 struct mmu_rb_handler *handler =
302 container_of(mn, struct mmu_rb_handler, mn); 302 container_of(mn, struct mmu_rb_handler, mn);
303 struct rb_root *root = &handler->root; 303 struct rb_root_cached *root = &handler->root;
304 struct mmu_rb_node *node, *ptr = NULL; 304 struct mmu_rb_node *node, *ptr = NULL;
305 unsigned long flags; 305 unsigned long flags;
306 bool added = false; 306 bool added = false;
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index c49db7c33979..4381c0a9a873 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -227,7 +227,7 @@ static void __usnic_uiom_reg_release(struct usnic_uiom_pd *pd,
227 vpn_last = vpn_start + npages - 1; 227 vpn_last = vpn_start + npages - 1;
228 228
229 spin_lock(&pd->lock); 229 spin_lock(&pd->lock);
230 usnic_uiom_remove_interval(&pd->rb_root, vpn_start, 230 usnic_uiom_remove_interval(&pd->root, vpn_start,
231 vpn_last, &rm_intervals); 231 vpn_last, &rm_intervals);
232 usnic_uiom_unmap_sorted_intervals(&rm_intervals, pd); 232 usnic_uiom_unmap_sorted_intervals(&rm_intervals, pd);
233 233
@@ -379,7 +379,7 @@ struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd,
379 err = usnic_uiom_get_intervals_diff(vpn_start, vpn_last, 379 err = usnic_uiom_get_intervals_diff(vpn_start, vpn_last,
380 (writable) ? IOMMU_WRITE : 0, 380 (writable) ? IOMMU_WRITE : 0,
381 IOMMU_WRITE, 381 IOMMU_WRITE,
382 &pd->rb_root, 382 &pd->root,
383 &sorted_diff_intervals); 383 &sorted_diff_intervals);
384 if (err) { 384 if (err) {
385 usnic_err("Failed disjoint interval vpn [0x%lx,0x%lx] err %d\n", 385 usnic_err("Failed disjoint interval vpn [0x%lx,0x%lx] err %d\n",
@@ -395,7 +395,7 @@ struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd,
395 395
396 } 396 }
397 397
398 err = usnic_uiom_insert_interval(&pd->rb_root, vpn_start, vpn_last, 398 err = usnic_uiom_insert_interval(&pd->root, vpn_start, vpn_last,
399 (writable) ? IOMMU_WRITE : 0); 399 (writable) ? IOMMU_WRITE : 0);
400 if (err) { 400 if (err) {
401 usnic_err("Failed insert interval vpn [0x%lx,0x%lx] err %d\n", 401 usnic_err("Failed insert interval vpn [0x%lx,0x%lx] err %d\n",
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.h b/drivers/infiniband/hw/usnic/usnic_uiom.h
index 45ca7c1613a7..431efe4143f4 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.h
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.h
@@ -55,7 +55,7 @@ struct usnic_uiom_dev {
55struct usnic_uiom_pd { 55struct usnic_uiom_pd {
56 struct iommu_domain *domain; 56 struct iommu_domain *domain;
57 spinlock_t lock; 57 spinlock_t lock;
58 struct rb_root rb_root; 58 struct rb_root_cached root;
59 struct list_head devs; 59 struct list_head devs;
60 int dev_cnt; 60 int dev_cnt;
61}; 61};
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
index 42b4b4c4e452..d399523206c7 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
@@ -100,9 +100,9 @@ static int interval_cmp(void *priv, struct list_head *a, struct list_head *b)
100} 100}
101 101
102static void 102static void
103find_intervals_intersection_sorted(struct rb_root *root, unsigned long start, 103find_intervals_intersection_sorted(struct rb_root_cached *root,
104 unsigned long last, 104 unsigned long start, unsigned long last,
105 struct list_head *list) 105 struct list_head *list)
106{ 106{
107 struct usnic_uiom_interval_node *node; 107 struct usnic_uiom_interval_node *node;
108 108
@@ -118,7 +118,7 @@ find_intervals_intersection_sorted(struct rb_root *root, unsigned long start,
118 118
119int usnic_uiom_get_intervals_diff(unsigned long start, unsigned long last, 119int usnic_uiom_get_intervals_diff(unsigned long start, unsigned long last,
120 int flags, int flag_mask, 120 int flags, int flag_mask,
121 struct rb_root *root, 121 struct rb_root_cached *root,
122 struct list_head *diff_set) 122 struct list_head *diff_set)
123{ 123{
124 struct usnic_uiom_interval_node *interval, *tmp; 124 struct usnic_uiom_interval_node *interval, *tmp;
@@ -175,7 +175,7 @@ void usnic_uiom_put_interval_set(struct list_head *intervals)
175 kfree(interval); 175 kfree(interval);
176} 176}
177 177
178int usnic_uiom_insert_interval(struct rb_root *root, unsigned long start, 178int usnic_uiom_insert_interval(struct rb_root_cached *root, unsigned long start,
179 unsigned long last, int flags) 179 unsigned long last, int flags)
180{ 180{
181 struct usnic_uiom_interval_node *interval, *tmp; 181 struct usnic_uiom_interval_node *interval, *tmp;
@@ -246,8 +246,9 @@ err_out:
246 return err; 246 return err;
247} 247}
248 248
249void usnic_uiom_remove_interval(struct rb_root *root, unsigned long start, 249void usnic_uiom_remove_interval(struct rb_root_cached *root,
250 unsigned long last, struct list_head *removed) 250 unsigned long start, unsigned long last,
251 struct list_head *removed)
251{ 252{
252 struct usnic_uiom_interval_node *interval; 253 struct usnic_uiom_interval_node *interval;
253 254
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
index c0b0b876ab90..1d7fc3226bca 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
+++ b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
@@ -48,12 +48,12 @@ struct usnic_uiom_interval_node {
48 48
49extern void 49extern void
50usnic_uiom_interval_tree_insert(struct usnic_uiom_interval_node *node, 50usnic_uiom_interval_tree_insert(struct usnic_uiom_interval_node *node,
51 struct rb_root *root); 51 struct rb_root_cached *root);
52extern void 52extern void
53usnic_uiom_interval_tree_remove(struct usnic_uiom_interval_node *node, 53usnic_uiom_interval_tree_remove(struct usnic_uiom_interval_node *node,
54 struct rb_root *root); 54 struct rb_root_cached *root);
55extern struct usnic_uiom_interval_node * 55extern struct usnic_uiom_interval_node *
56usnic_uiom_interval_tree_iter_first(struct rb_root *root, 56usnic_uiom_interval_tree_iter_first(struct rb_root_cached *root,
57 unsigned long start, 57 unsigned long start,
58 unsigned long last); 58 unsigned long last);
59extern struct usnic_uiom_interval_node * 59extern struct usnic_uiom_interval_node *
@@ -63,7 +63,7 @@ usnic_uiom_interval_tree_iter_next(struct usnic_uiom_interval_node *node,
63 * Inserts {start...last} into {root}. If there are overlaps, 63 * Inserts {start...last} into {root}. If there are overlaps,
64 * nodes will be broken up and merged 64 * nodes will be broken up and merged
65 */ 65 */
66int usnic_uiom_insert_interval(struct rb_root *root, 66int usnic_uiom_insert_interval(struct rb_root_cached *root,
67 unsigned long start, unsigned long last, 67 unsigned long start, unsigned long last,
68 int flags); 68 int flags);
69/* 69/*
@@ -71,7 +71,7 @@ int usnic_uiom_insert_interval(struct rb_root *root,
71 * 'removed.' The caller is responsibile for freeing memory of nodes in 71 * 'removed.' The caller is responsibile for freeing memory of nodes in
72 * 'removed.' 72 * 'removed.'
73 */ 73 */
74void usnic_uiom_remove_interval(struct rb_root *root, 74void usnic_uiom_remove_interval(struct rb_root_cached *root,
75 unsigned long start, unsigned long last, 75 unsigned long start, unsigned long last,
76 struct list_head *removed); 76 struct list_head *removed);
77/* 77/*
@@ -81,7 +81,7 @@ void usnic_uiom_remove_interval(struct rb_root *root,
81int usnic_uiom_get_intervals_diff(unsigned long start, 81int usnic_uiom_get_intervals_diff(unsigned long start,
82 unsigned long last, int flags, 82 unsigned long last, int flags,
83 int flag_mask, 83 int flag_mask,
84 struct rb_root *root, 84 struct rb_root_cached *root,
85 struct list_head *diff_set); 85 struct list_head *diff_set);
86/* Call this to free diff_set returned by usnic_uiom_get_intervals_diff */ 86/* Call this to free diff_set returned by usnic_uiom_get_intervals_diff */
87void usnic_uiom_put_interval_set(struct list_head *intervals); 87void usnic_uiom_put_interval_set(struct list_head *intervals);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 9cb3f722dce1..d6dbb28245e6 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1271,7 +1271,7 @@ static struct vhost_umem *vhost_umem_alloc(void)
1271 if (!umem) 1271 if (!umem)
1272 return NULL; 1272 return NULL;
1273 1273
1274 umem->umem_tree = RB_ROOT; 1274 umem->umem_tree = RB_ROOT_CACHED;
1275 umem->numem = 0; 1275 umem->numem = 0;
1276 INIT_LIST_HEAD(&umem->umem_list); 1276 INIT_LIST_HEAD(&umem->umem_list);
1277 1277
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index bb7c29b8b9fc..d59a9cc65f9d 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -71,7 +71,7 @@ struct vhost_umem_node {
71}; 71};
72 72
73struct vhost_umem { 73struct vhost_umem {
74 struct rb_root umem_tree; 74 struct rb_root_cached umem_tree;
75 struct list_head umem_list; 75 struct list_head umem_list;
76 int numem; 76 int numem;
77}; 77};
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8c6f4b8f910f..59073e9f01a4 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -334,7 +334,7 @@ static void remove_huge_page(struct page *page)
334} 334}
335 335
336static void 336static void
337hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end) 337hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end)
338{ 338{
339 struct vm_area_struct *vma; 339 struct vm_area_struct *vma;
340 340
@@ -498,7 +498,7 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
498 498
499 i_size_write(inode, offset); 499 i_size_write(inode, offset);
500 i_mmap_lock_write(mapping); 500 i_mmap_lock_write(mapping);
501 if (!RB_EMPTY_ROOT(&mapping->i_mmap)) 501 if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))
502 hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0); 502 hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0);
503 i_mmap_unlock_write(mapping); 503 i_mmap_unlock_write(mapping);
504 remove_inode_hugepages(inode, offset, LLONG_MAX); 504 remove_inode_hugepages(inode, offset, LLONG_MAX);
@@ -523,7 +523,7 @@ static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
523 523
524 inode_lock(inode); 524 inode_lock(inode);
525 i_mmap_lock_write(mapping); 525 i_mmap_lock_write(mapping);
526 if (!RB_EMPTY_ROOT(&mapping->i_mmap)) 526 if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))
527 hugetlb_vmdelete_list(&mapping->i_mmap, 527 hugetlb_vmdelete_list(&mapping->i_mmap,
528 hole_start >> PAGE_SHIFT, 528 hole_start >> PAGE_SHIFT,
529 hole_end >> PAGE_SHIFT); 529 hole_end >> PAGE_SHIFT);
diff --git a/fs/inode.c b/fs/inode.c
index 6a1626e0edaf..210054157a49 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -353,7 +353,7 @@ void address_space_init_once(struct address_space *mapping)
353 init_rwsem(&mapping->i_mmap_rwsem); 353 init_rwsem(&mapping->i_mmap_rwsem);
354 INIT_LIST_HEAD(&mapping->private_list); 354 INIT_LIST_HEAD(&mapping->private_list);
355 spin_lock_init(&mapping->private_lock); 355 spin_lock_init(&mapping->private_lock);
356 mapping->i_mmap = RB_ROOT; 356 mapping->i_mmap = RB_ROOT_CACHED;
357} 357}
358EXPORT_SYMBOL(address_space_init_once); 358EXPORT_SYMBOL(address_space_init_once);
359 359
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 49b292e98fec..8d10fc97801c 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -172,7 +172,7 @@ struct drm_mm {
172 * according to the (increasing) start address of the memory node. */ 172 * according to the (increasing) start address of the memory node. */
173 struct drm_mm_node head_node; 173 struct drm_mm_node head_node;
174 /* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */ 174 /* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */
175 struct rb_root interval_tree; 175 struct rb_root_cached interval_tree;
176 struct rb_root holes_size; 176 struct rb_root holes_size;
177 struct rb_root holes_addr; 177 struct rb_root holes_addr;
178 178
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 509434aaf5a4..6111976848ff 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -392,7 +392,7 @@ struct address_space {
392 struct radix_tree_root page_tree; /* radix tree of all pages */ 392 struct radix_tree_root page_tree; /* radix tree of all pages */
393 spinlock_t tree_lock; /* and lock protecting it */ 393 spinlock_t tree_lock; /* and lock protecting it */
394 atomic_t i_mmap_writable;/* count VM_SHARED mappings */ 394 atomic_t i_mmap_writable;/* count VM_SHARED mappings */
395 struct rb_root i_mmap; /* tree of private and shared mappings */ 395 struct rb_root_cached i_mmap; /* tree of private and shared mappings */
396 struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */ 396 struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */
397 /* Protected by tree_lock together with the radix tree */ 397 /* Protected by tree_lock together with the radix tree */
398 unsigned long nrpages; /* number of total pages */ 398 unsigned long nrpages; /* number of total pages */
@@ -487,7 +487,7 @@ static inline void i_mmap_unlock_read(struct address_space *mapping)
487 */ 487 */
488static inline int mapping_mapped(struct address_space *mapping) 488static inline int mapping_mapped(struct address_space *mapping)
489{ 489{
490 return !RB_EMPTY_ROOT(&mapping->i_mmap); 490 return !RB_EMPTY_ROOT(&mapping->i_mmap.rb_root);
491} 491}
492 492
493/* 493/*
diff --git a/include/linux/interval_tree.h b/include/linux/interval_tree.h
index 724556aa3c95..202ee1283f4b 100644
--- a/include/linux/interval_tree.h
+++ b/include/linux/interval_tree.h
@@ -11,13 +11,15 @@ struct interval_tree_node {
11}; 11};
12 12
13extern void 13extern void
14interval_tree_insert(struct interval_tree_node *node, struct rb_root *root); 14interval_tree_insert(struct interval_tree_node *node,
15 struct rb_root_cached *root);
15 16
16extern void 17extern void
17interval_tree_remove(struct interval_tree_node *node, struct rb_root *root); 18interval_tree_remove(struct interval_tree_node *node,
19 struct rb_root_cached *root);
18 20
19extern struct interval_tree_node * 21extern struct interval_tree_node *
20interval_tree_iter_first(struct rb_root *root, 22interval_tree_iter_first(struct rb_root_cached *root,
21 unsigned long start, unsigned long last); 23 unsigned long start, unsigned long last);
22 24
23extern struct interval_tree_node * 25extern struct interval_tree_node *
diff --git a/include/linux/interval_tree_generic.h b/include/linux/interval_tree_generic.h
index 58370e1862ad..f096423c8cbd 100644
--- a/include/linux/interval_tree_generic.h
+++ b/include/linux/interval_tree_generic.h
@@ -65,11 +65,13 @@ RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB, \
65 \ 65 \
66/* Insert / remove interval nodes from the tree */ \ 66/* Insert / remove interval nodes from the tree */ \
67 \ 67 \
68ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root) \ 68ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, \
69 struct rb_root_cached *root) \
69{ \ 70{ \
70 struct rb_node **link = &root->rb_node, *rb_parent = NULL; \ 71 struct rb_node **link = &root->rb_root.rb_node, *rb_parent = NULL; \
71 ITTYPE start = ITSTART(node), last = ITLAST(node); \ 72 ITTYPE start = ITSTART(node), last = ITLAST(node); \
72 ITSTRUCT *parent; \ 73 ITSTRUCT *parent; \
74 bool leftmost = true; \
73 \ 75 \
74 while (*link) { \ 76 while (*link) { \
75 rb_parent = *link; \ 77 rb_parent = *link; \
@@ -78,18 +80,22 @@ ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root) \
78 parent->ITSUBTREE = last; \ 80 parent->ITSUBTREE = last; \
79 if (start < ITSTART(parent)) \ 81 if (start < ITSTART(parent)) \
80 link = &parent->ITRB.rb_left; \ 82 link = &parent->ITRB.rb_left; \
81 else \ 83 else { \
82 link = &parent->ITRB.rb_right; \ 84 link = &parent->ITRB.rb_right; \
85 leftmost = false; \
86 } \
83 } \ 87 } \
84 \ 88 \
85 node->ITSUBTREE = last; \ 89 node->ITSUBTREE = last; \
86 rb_link_node(&node->ITRB, rb_parent, link); \ 90 rb_link_node(&node->ITRB, rb_parent, link); \
87 rb_insert_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \ 91 rb_insert_augmented_cached(&node->ITRB, root, \
92 leftmost, &ITPREFIX ## _augment); \
88} \ 93} \
89 \ 94 \
90ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, struct rb_root *root) \ 95ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, \
96 struct rb_root_cached *root) \
91{ \ 97{ \
92 rb_erase_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \ 98 rb_erase_augmented_cached(&node->ITRB, root, &ITPREFIX ## _augment); \
93} \ 99} \
94 \ 100 \
95/* \ 101/* \
@@ -140,15 +146,35 @@ ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
140} \ 146} \
141 \ 147 \
142ITSTATIC ITSTRUCT * \ 148ITSTATIC ITSTRUCT * \
143ITPREFIX ## _iter_first(struct rb_root *root, ITTYPE start, ITTYPE last) \ 149ITPREFIX ## _iter_first(struct rb_root_cached *root, \
150 ITTYPE start, ITTYPE last) \
144{ \ 151{ \
145 ITSTRUCT *node; \ 152 ITSTRUCT *node, *leftmost; \
146 \ 153 \
147 if (!root->rb_node) \ 154 if (!root->rb_root.rb_node) \
148 return NULL; \ 155 return NULL; \
149 node = rb_entry(root->rb_node, ITSTRUCT, ITRB); \ 156 \
157 /* \
158 * Fastpath range intersection/overlap between A: [a0, a1] and \
159 * B: [b0, b1] is given by: \
160 * \
161 * a0 <= b1 && b0 <= a1 \
162 * \
163 * ... where A holds the lock range and B holds the smallest \
164 * 'start' and largest 'last' in the tree. For the later, we \
165 * rely on the root node, which by augmented interval tree \
166 * property, holds the largest value in its last-in-subtree. \
167 * This allows mitigating some of the tree walk overhead for \
168 * for non-intersecting ranges, maintained and consulted in O(1). \
169 */ \
170 node = rb_entry(root->rb_root.rb_node, ITSTRUCT, ITRB); \
150 if (node->ITSUBTREE < start) \ 171 if (node->ITSUBTREE < start) \
151 return NULL; \ 172 return NULL; \
173 \
174 leftmost = rb_entry(root->rb_leftmost, ITSTRUCT, ITRB); \
175 if (ITSTART(leftmost) > last) \
176 return NULL; \
177 \
152 return ITPREFIX ## _subtree_search(node, start, last); \ 178 return ITPREFIX ## _subtree_search(node, start, last); \
153} \ 179} \
154 \ 180 \
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5195e272fc4a..f8c10d336e42 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2034,13 +2034,13 @@ extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t);
2034 2034
2035/* interval_tree.c */ 2035/* interval_tree.c */
2036void vma_interval_tree_insert(struct vm_area_struct *node, 2036void vma_interval_tree_insert(struct vm_area_struct *node,
2037 struct rb_root *root); 2037 struct rb_root_cached *root);
2038void vma_interval_tree_insert_after(struct vm_area_struct *node, 2038void vma_interval_tree_insert_after(struct vm_area_struct *node,
2039 struct vm_area_struct *prev, 2039 struct vm_area_struct *prev,
2040 struct rb_root *root); 2040 struct rb_root_cached *root);
2041void vma_interval_tree_remove(struct vm_area_struct *node, 2041void vma_interval_tree_remove(struct vm_area_struct *node,
2042 struct rb_root *root); 2042 struct rb_root_cached *root);
2043struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root *root, 2043struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root_cached *root,
2044 unsigned long start, unsigned long last); 2044 unsigned long start, unsigned long last);
2045struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node, 2045struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node,
2046 unsigned long start, unsigned long last); 2046 unsigned long start, unsigned long last);
@@ -2050,11 +2050,12 @@ struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node,
2050 vma; vma = vma_interval_tree_iter_next(vma, start, last)) 2050 vma; vma = vma_interval_tree_iter_next(vma, start, last))
2051 2051
2052void anon_vma_interval_tree_insert(struct anon_vma_chain *node, 2052void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
2053 struct rb_root *root); 2053 struct rb_root_cached *root);
2054void anon_vma_interval_tree_remove(struct anon_vma_chain *node, 2054void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
2055 struct rb_root *root); 2055 struct rb_root_cached *root);
2056struct anon_vma_chain *anon_vma_interval_tree_iter_first( 2056struct anon_vma_chain *
2057 struct rb_root *root, unsigned long start, unsigned long last); 2057anon_vma_interval_tree_iter_first(struct rb_root_cached *root,
2058 unsigned long start, unsigned long last);
2058struct anon_vma_chain *anon_vma_interval_tree_iter_next( 2059struct anon_vma_chain *anon_vma_interval_tree_iter_next(
2059 struct anon_vma_chain *node, unsigned long start, unsigned long last); 2060 struct anon_vma_chain *node, unsigned long start, unsigned long last);
2060#ifdef CONFIG_DEBUG_VM_RB 2061#ifdef CONFIG_DEBUG_VM_RB
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index f8ca2e74b819..733d3d8181e2 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -55,7 +55,9 @@ struct anon_vma {
55 * is serialized by a system wide lock only visible to 55 * is serialized by a system wide lock only visible to
56 * mm_take_all_locks() (mm_all_locks_mutex). 56 * mm_take_all_locks() (mm_all_locks_mutex).
57 */ 57 */
58 struct rb_root rb_root; /* Interval tree of private "related" vmas */ 58
59 /* Interval tree of private "related" vmas */
60 struct rb_root_cached rb_root;
59}; 61};
60 62
61/* 63/*
diff --git a/include/rdma/ib_umem_odp.h b/include/rdma/ib_umem_odp.h
index fb67554aabd6..5eb7f5bc8248 100644
--- a/include/rdma/ib_umem_odp.h
+++ b/include/rdma/ib_umem_odp.h
@@ -111,22 +111,25 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 start_offset, u64 bcnt,
111void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 start_offset, 111void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 start_offset,
112 u64 bound); 112 u64 bound);
113 113
114void rbt_ib_umem_insert(struct umem_odp_node *node, struct rb_root *root); 114void rbt_ib_umem_insert(struct umem_odp_node *node,
115void rbt_ib_umem_remove(struct umem_odp_node *node, struct rb_root *root); 115 struct rb_root_cached *root);
116void rbt_ib_umem_remove(struct umem_odp_node *node,
117 struct rb_root_cached *root);
116typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end, 118typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end,
117 void *cookie); 119 void *cookie);
118/* 120/*
119 * Call the callback on each ib_umem in the range. Returns the logical or of 121 * Call the callback on each ib_umem in the range. Returns the logical or of
120 * the return values of the functions called. 122 * the return values of the functions called.
121 */ 123 */
122int rbt_ib_umem_for_each_in_range(struct rb_root *root, u64 start, u64 end, 124int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
125 u64 start, u64 end,
123 umem_call_back cb, void *cookie); 126 umem_call_back cb, void *cookie);
124 127
125/* 128/*
126 * Find first region intersecting with address range. 129 * Find first region intersecting with address range.
127 * Return NULL if not found 130 * Return NULL if not found
128 */ 131 */
129struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root, 132struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root_cached *root,
130 u64 addr, u64 length); 133 u64 addr, u64 length);
131 134
132static inline int ib_umem_mmu_notifier_retry(struct ib_umem *item, 135static inline int ib_umem_mmu_notifier_retry(struct ib_umem *item,
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index e6df68048517..bdb1279a415b 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1457,7 +1457,7 @@ struct ib_ucontext {
1457 1457
1458 struct pid *tgid; 1458 struct pid *tgid;
1459#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING 1459#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
1460 struct rb_root umem_tree; 1460 struct rb_root_cached umem_tree;
1461 /* 1461 /*
1462 * Protects .umem_rbroot and tree, as well as odp_mrs_count and 1462 * Protects .umem_rbroot and tree, as well as odp_mrs_count and
1463 * mmu notifiers registration. 1463 * mmu notifiers registration.
diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c
index df495fe81421..0e343fd29570 100644
--- a/lib/interval_tree_test.c
+++ b/lib/interval_tree_test.c
@@ -19,14 +19,14 @@ __param(bool, search_all, false, "Searches will iterate all nodes in the tree");
19 19
20__param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint"); 20__param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint");
21 21
22static struct rb_root root = RB_ROOT; 22static struct rb_root_cached root = RB_ROOT_CACHED;
23static struct interval_tree_node *nodes = NULL; 23static struct interval_tree_node *nodes = NULL;
24static u32 *queries = NULL; 24static u32 *queries = NULL;
25 25
26static struct rnd_state rnd; 26static struct rnd_state rnd;
27 27
28static inline unsigned long 28static inline unsigned long
29search(struct rb_root *root, unsigned long start, unsigned long last) 29search(struct rb_root_cached *root, unsigned long start, unsigned long last)
30{ 30{
31 struct interval_tree_node *node; 31 struct interval_tree_node *node;
32 unsigned long results = 0; 32 unsigned long results = 0;
diff --git a/mm/interval_tree.c b/mm/interval_tree.c
index f2c2492681bf..b47664358796 100644
--- a/mm/interval_tree.c
+++ b/mm/interval_tree.c
@@ -28,7 +28,7 @@ INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.rb,
28/* Insert node immediately after prev in the interval tree */ 28/* Insert node immediately after prev in the interval tree */
29void vma_interval_tree_insert_after(struct vm_area_struct *node, 29void vma_interval_tree_insert_after(struct vm_area_struct *node,
30 struct vm_area_struct *prev, 30 struct vm_area_struct *prev,
31 struct rb_root *root) 31 struct rb_root_cached *root)
32{ 32{
33 struct rb_node **link; 33 struct rb_node **link;
34 struct vm_area_struct *parent; 34 struct vm_area_struct *parent;
@@ -55,7 +55,7 @@ void vma_interval_tree_insert_after(struct vm_area_struct *node,
55 55
56 node->shared.rb_subtree_last = last; 56 node->shared.rb_subtree_last = last;
57 rb_link_node(&node->shared.rb, &parent->shared.rb, link); 57 rb_link_node(&node->shared.rb, &parent->shared.rb, link);
58 rb_insert_augmented(&node->shared.rb, root, 58 rb_insert_augmented(&node->shared.rb, &root->rb_root,
59 &vma_interval_tree_augment); 59 &vma_interval_tree_augment);
60} 60}
61 61
@@ -74,7 +74,7 @@ INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, unsigned long, rb_subtree_last,
74 static inline, __anon_vma_interval_tree) 74 static inline, __anon_vma_interval_tree)
75 75
76void anon_vma_interval_tree_insert(struct anon_vma_chain *node, 76void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
77 struct rb_root *root) 77 struct rb_root_cached *root)
78{ 78{
79#ifdef CONFIG_DEBUG_VM_RB 79#ifdef CONFIG_DEBUG_VM_RB
80 node->cached_vma_start = avc_start_pgoff(node); 80 node->cached_vma_start = avc_start_pgoff(node);
@@ -84,13 +84,13 @@ void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
84} 84}
85 85
86void anon_vma_interval_tree_remove(struct anon_vma_chain *node, 86void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
87 struct rb_root *root) 87 struct rb_root_cached *root)
88{ 88{
89 __anon_vma_interval_tree_remove(node, root); 89 __anon_vma_interval_tree_remove(node, root);
90} 90}
91 91
92struct anon_vma_chain * 92struct anon_vma_chain *
93anon_vma_interval_tree_iter_first(struct rb_root *root, 93anon_vma_interval_tree_iter_first(struct rb_root_cached *root,
94 unsigned long first, unsigned long last) 94 unsigned long first, unsigned long last)
95{ 95{
96 return __anon_vma_interval_tree_iter_first(root, first, last); 96 return __anon_vma_interval_tree_iter_first(root, first, last);
diff --git a/mm/memory.c b/mm/memory.c
index 0bbc1d612a63..ec4e15494901 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2761,7 +2761,7 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma,
2761 zap_page_range_single(vma, start_addr, end_addr - start_addr, details); 2761 zap_page_range_single(vma, start_addr, end_addr - start_addr, details);
2762} 2762}
2763 2763
2764static inline void unmap_mapping_range_tree(struct rb_root *root, 2764static inline void unmap_mapping_range_tree(struct rb_root_cached *root,
2765 struct zap_details *details) 2765 struct zap_details *details)
2766{ 2766{
2767 struct vm_area_struct *vma; 2767 struct vm_area_struct *vma;
@@ -2825,7 +2825,7 @@ void unmap_mapping_range(struct address_space *mapping,
2825 details.last_index = ULONG_MAX; 2825 details.last_index = ULONG_MAX;
2826 2826
2827 i_mmap_lock_write(mapping); 2827 i_mmap_lock_write(mapping);
2828 if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap))) 2828 if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root)))
2829 unmap_mapping_range_tree(&mapping->i_mmap, &details); 2829 unmap_mapping_range_tree(&mapping->i_mmap, &details);
2830 i_mmap_unlock_write(mapping); 2830 i_mmap_unlock_write(mapping);
2831} 2831}
diff --git a/mm/mmap.c b/mm/mmap.c
index 4c5981651407..680506faceae 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -685,7 +685,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
685 struct mm_struct *mm = vma->vm_mm; 685 struct mm_struct *mm = vma->vm_mm;
686 struct vm_area_struct *next = vma->vm_next, *orig_vma = vma; 686 struct vm_area_struct *next = vma->vm_next, *orig_vma = vma;
687 struct address_space *mapping = NULL; 687 struct address_space *mapping = NULL;
688 struct rb_root *root = NULL; 688 struct rb_root_cached *root = NULL;
689 struct anon_vma *anon_vma = NULL; 689 struct anon_vma *anon_vma = NULL;
690 struct file *file = vma->vm_file; 690 struct file *file = vma->vm_file;
691 bool start_changed = false, end_changed = false; 691 bool start_changed = false, end_changed = false;
@@ -3340,7 +3340,7 @@ static DEFINE_MUTEX(mm_all_locks_mutex);
3340 3340
3341static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) 3341static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
3342{ 3342{
3343 if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) { 3343 if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_root.rb_node)) {
3344 /* 3344 /*
3345 * The LSB of head.next can't change from under us 3345 * The LSB of head.next can't change from under us
3346 * because we hold the mm_all_locks_mutex. 3346 * because we hold the mm_all_locks_mutex.
@@ -3356,7 +3356,7 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
3356 * anon_vma->root->rwsem. 3356 * anon_vma->root->rwsem.
3357 */ 3357 */
3358 if (__test_and_set_bit(0, (unsigned long *) 3358 if (__test_and_set_bit(0, (unsigned long *)
3359 &anon_vma->root->rb_root.rb_node)) 3359 &anon_vma->root->rb_root.rb_root.rb_node))
3360 BUG(); 3360 BUG();
3361 } 3361 }
3362} 3362}
@@ -3458,7 +3458,7 @@ out_unlock:
3458 3458
3459static void vm_unlock_anon_vma(struct anon_vma *anon_vma) 3459static void vm_unlock_anon_vma(struct anon_vma *anon_vma)
3460{ 3460{
3461 if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) { 3461 if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_root.rb_node)) {
3462 /* 3462 /*
3463 * The LSB of head.next can't change to 0 from under 3463 * The LSB of head.next can't change to 0 from under
3464 * us because we hold the mm_all_locks_mutex. 3464 * us because we hold the mm_all_locks_mutex.
@@ -3472,7 +3472,7 @@ static void vm_unlock_anon_vma(struct anon_vma *anon_vma)
3472 * anon_vma->root->rwsem. 3472 * anon_vma->root->rwsem.
3473 */ 3473 */
3474 if (!__test_and_clear_bit(0, (unsigned long *) 3474 if (!__test_and_clear_bit(0, (unsigned long *)
3475 &anon_vma->root->rb_root.rb_node)) 3475 &anon_vma->root->rb_root.rb_root.rb_node))
3476 BUG(); 3476 BUG();
3477 anon_vma_unlock_write(anon_vma); 3477 anon_vma_unlock_write(anon_vma);
3478 } 3478 }
diff --git a/mm/rmap.c b/mm/rmap.c
index 0618cd85b862..b874c4761e84 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -391,7 +391,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
391 * Leave empty anon_vmas on the list - we'll need 391 * Leave empty anon_vmas on the list - we'll need
392 * to free them outside the lock. 392 * to free them outside the lock.
393 */ 393 */
394 if (RB_EMPTY_ROOT(&anon_vma->rb_root)) { 394 if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) {
395 anon_vma->parent->degree--; 395 anon_vma->parent->degree--;
396 continue; 396 continue;
397 } 397 }
@@ -425,7 +425,7 @@ static void anon_vma_ctor(void *data)
425 425
426 init_rwsem(&anon_vma->rwsem); 426 init_rwsem(&anon_vma->rwsem);
427 atomic_set(&anon_vma->refcount, 0); 427 atomic_set(&anon_vma->refcount, 0);
428 anon_vma->rb_root = RB_ROOT; 428 anon_vma->rb_root = RB_ROOT_CACHED;
429} 429}
430 430
431void __init anon_vma_init(void) 431void __init anon_vma_init(void)