Re: [PATCH 09/11] lib/interval-tree: convert interval_tree to half closed intervals

From: Koenig, Christian
Date: Fri Oct 04 2019 - 03:21:54 EST


Am 04.10.19 um 08:57 schrieb Christian KÃnig:
> Am 03.10.19 um 22:18 schrieb Davidlohr Bueso:
>> The generic tree tree really wants [a, b) intervals, not fully closed.
>> As such convert it to use the new interval_tree_gen.h. Most of the
>> conversions are straightforward, with the exception of perhaps
>> radeon_vm_bo_set_addr(), but semantics have been tried to be left
>> untouched.
>
> NAK, the whole thing won't work.
>
> See we need to handle the full device address space which means we
> have values in the range of 0x0-0xffffffff.
>
> If you make this a closed interval then the end would wrap around to
> 0x0 if long is only 32bit.

Well I've just now re-read the subject line. From that it sounds like
you are actually trying to fix the interval tree to use a half closed
interval, e.g. something like [a, b[

But your code changes sometimes doesn't seem to reflect that.

Regards,
Christian.

>
> Regards,
> Christian.
>
>>
>> Cc: "Christian KÃnig" <christian.koenig@xxxxxxx>
>> Cc: Alex Deucher <alexander.deucher@xxxxxxx>
>> Cc: David Airlie <airlied@xxxxxxxx>
>> Cc: Daniel Vetter <daniel@xxxxxxxx>
>> Cc: Doug Ledford <dledford@xxxxxxxxxx>
>> Cc: Joerg Roedel <joro@xxxxxxxxxx>
>> Cc: "JÃrÃme Glisse" <jglisse@xxxxxxxxxx>
>> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx
>> Cc: linux-rdma@xxxxxxxxxxxxxxx
>> Signed-off-by: Davidlohr Bueso <dbueso@xxxxxxx>
>> ---
>> Â drivers/gpu/drm/amd/amdgpu/amdgpu_mn.cÂÂÂÂÂ | 12 +++---------
>> Â drivers/gpu/drm/i915/gem/i915_gem_userptr.c |Â 5 +----
>> Â drivers/gpu/drm/radeon/radeon_mn.cÂÂÂÂÂÂÂÂÂ | 11 ++++-------
>> Â drivers/gpu/drm/radeon/radeon_trace.hÂÂÂÂÂÂ |Â 2 +-
>> Â drivers/gpu/drm/radeon/radeon_vm.cÂÂÂÂÂÂÂÂÂ | 26
>> +++++++++++++-------------
>> Â drivers/infiniband/core/umem_odp.cÂÂÂÂÂÂÂÂÂ | 21 +++++++--------------
>> Â drivers/iommu/virtio-iommu.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 6 +++---
>> Â include/linux/interval_tree.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 2 +-
>> Â include/rdma/ib_umem_odp.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 4 ++--
>> Â lib/interval_tree.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 6 +++---
>> Â 10 files changed, 38 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> index 31d4deb5d294..4bbaa9ffa570 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> @@ -205,9 +205,6 @@ amdgpu_mn_sync_pagetables_gfx(struct hmm_mirror
>> *mirror,
>> ÂÂÂÂÂ bool blockable = mmu_notifier_range_blockable(update);
>> ÂÂÂÂÂ struct interval_tree_node *it;
>> Â -ÂÂÂ /* notification is exclusive, but interval is inclusive */
>> -ÂÂÂ end -= 1;
>> -
>> ÂÂÂÂÂ /* TODO we should be able to split locking for interval tree and
>> ÂÂÂÂÂÂ * amdgpu_mn_invalidate_node
>> ÂÂÂÂÂÂ */
>> @@ -254,9 +251,6 @@ amdgpu_mn_sync_pagetables_hsa(struct hmm_mirror
>> *mirror,
>> ÂÂÂÂÂ bool blockable = mmu_notifier_range_blockable(update);
>> ÂÂÂÂÂ struct interval_tree_node *it;
>> Â -ÂÂÂ /* notification is exclusive, but interval is inclusive */
>> -ÂÂÂ end -= 1;
>> -
>> ÂÂÂÂÂ if (amdgpu_mn_read_lock(amn, blockable))
>> ÂÂÂÂÂÂÂÂÂ return -EAGAIN;
>> Â @@ -374,7 +368,7 @@ struct amdgpu_mn *amdgpu_mn_get(struct
>> amdgpu_device *adev,
>> ÂÂ */
>> Â int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
>> Â {
>> -ÂÂÂ unsigned long end = addr + amdgpu_bo_size(bo) - 1;
>> +ÂÂÂ unsigned long end = addr + amdgpu_bo_size(bo);
>> ÂÂÂÂÂ struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>> ÂÂÂÂÂ enum amdgpu_mn_type type =
>> ÂÂÂÂÂÂÂÂÂ bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX;
>> @@ -400,7 +394,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo,
>> unsigned long addr)
>> ÂÂÂÂÂÂÂÂÂ node = container_of(it, struct amdgpu_mn_node, it);
>> ÂÂÂÂÂÂÂÂÂ interval_tree_remove(&node->it, &amn->objects);
>> ÂÂÂÂÂÂÂÂÂ addr = min(it->start, addr);
>> -ÂÂÂÂÂÂÂ end = max(it->last, end);
>> +ÂÂÂÂÂÂÂ end = max(it->end, end);
>> ÂÂÂÂÂÂÂÂÂ list_splice(&node->bos, &bos);
>> ÂÂÂÂÂ }
>> Â @@ -412,7 +406,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo,
>> unsigned long addr)
>> ÂÂÂÂÂ bo->mn = amn;
>> Â ÂÂÂÂÂ node->it.start = addr;
>> -ÂÂÂ node->it.last = end;
>> +ÂÂÂ node->it.end = end;
>> ÂÂÂÂÂ INIT_LIST_HEAD(&node->bos);
>> ÂÂÂÂÂ list_splice(&bos, &node->bos);
>> ÂÂÂÂÂ list_add(&bo->mn_list, &node->bos);
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
>> b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
>> index 11b231c187c5..818ff6b33102 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
>> @@ -99,9 +99,6 @@ userptr_mn_invalidate_range_start(struct
>> mmu_notifier *_mn,
>> ÂÂÂÂÂ if (RB_EMPTY_ROOT(&mn->objects.rb_root))
>> ÂÂÂÂÂÂÂÂÂ return 0;
>> Â -ÂÂÂ /* interval ranges are inclusive, but invalidate range is
>> exclusive */
>> -ÂÂÂ end = range->end - 1;
>> -
>> ÂÂÂÂÂ spin_lock(&mn->lock);
>> ÂÂÂÂÂ it = interval_tree_iter_first(&mn->objects, range->start, end);
>> ÂÂÂÂÂ while (it) {
>> @@ -275,7 +272,7 @@ i915_gem_userptr_init__mmu_notifier(struct
>> drm_i915_gem_object *obj,
>> ÂÂÂÂÂ mo->mn = mn;
>> ÂÂÂÂÂ mo->obj = obj;
>> ÂÂÂÂÂ mo->it.start = obj->userptr.ptr;
>> -ÂÂÂ mo->it.last = obj->userptr.ptr + obj->base.size - 1;
>> +ÂÂÂ mo->it.end = obj->userptr.ptr + obj->base.size;
>> ÂÂÂÂÂ RB_CLEAR_NODE(&mo->it.rb);
>> Â ÂÂÂÂÂ obj->userptr.mmu_object = mo;
>> diff --git a/drivers/gpu/drm/radeon/radeon_mn.c
>> b/drivers/gpu/drm/radeon/radeon_mn.c
>> index dbab9a3a969b..4810421dacc2 100644
>> --- a/drivers/gpu/drm/radeon/radeon_mn.c
>> +++ b/drivers/gpu/drm/radeon/radeon_mn.c
>> @@ -66,12 +66,9 @@ static int radeon_mn_invalidate_range_start(struct
>> mmu_notifier *mn,
>> ÂÂÂÂÂ struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn);
>> ÂÂÂÂÂ struct ttm_operation_ctx ctx = { false, false };
>> ÂÂÂÂÂ struct interval_tree_node *it;
>> -ÂÂÂ unsigned long end;
>> +ÂÂÂ unsigned long end = range->end;
>> ÂÂÂÂÂ int ret = 0;
>> Â -ÂÂÂ /* notification is exclusive, but interval is inclusive */
>> -ÂÂÂ end = range->end - 1;
>> -
>> ÂÂÂÂÂ /* TODO we should be able to split locking for interval tree and
>> ÂÂÂÂÂÂ * the tear down.
>> ÂÂÂÂÂÂ */
>> @@ -174,7 +171,7 @@ static const struct mmu_notifier_ops
>> radeon_mn_ops = {
>> ÂÂ */
>> Â int radeon_mn_register(struct radeon_bo *bo, unsigned long addr)
>> Â {
>> -ÂÂÂ unsigned long end = addr + radeon_bo_size(bo) - 1;
>> +ÂÂÂ unsigned long end = addr + radeon_bo_size(bo);
>> ÂÂÂÂÂ struct mmu_notifier *mn;
>> ÂÂÂÂÂ struct radeon_mn *rmn;
>> ÂÂÂÂÂ struct radeon_mn_node *node = NULL;
>> @@ -195,7 +192,7 @@ int radeon_mn_register(struct radeon_bo *bo,
>> unsigned long addr)
>> ÂÂÂÂÂÂÂÂÂ node = container_of(it, struct radeon_mn_node, it);
>> ÂÂÂÂÂÂÂÂÂ interval_tree_remove(&node->it, &rmn->objects);
>> ÂÂÂÂÂÂÂÂÂ addr = min(it->start, addr);
>> -ÂÂÂÂÂÂÂ end = max(it->last, end);
>> +ÂÂÂÂÂÂÂ end = max(it->end, end);
>> ÂÂÂÂÂÂÂÂÂ list_splice(&node->bos, &bos);
>> ÂÂÂÂÂ }
>> Â @@ -210,7 +207,7 @@ int radeon_mn_register(struct radeon_bo *bo,
>> unsigned long addr)
>> ÂÂÂÂÂ bo->mn = rmn;
>> Â ÂÂÂÂÂ node->it.start = addr;
>> -ÂÂÂ node->it.last = end;
>> +ÂÂÂ node->it.end = end;
>> ÂÂÂÂÂ INIT_LIST_HEAD(&node->bos);
>> ÂÂÂÂÂ list_splice(&bos, &node->bos);
>> ÂÂÂÂÂ list_add(&bo->mn_list, &node->bos);
>> diff --git a/drivers/gpu/drm/radeon/radeon_trace.h
>> b/drivers/gpu/drm/radeon/radeon_trace.h
>> index c93f3ab3c4e3..4324f3fc5d82 100644
>> --- a/drivers/gpu/drm/radeon/radeon_trace.h
>> +++ b/drivers/gpu/drm/radeon/radeon_trace.h
>> @@ -73,7 +73,7 @@ TRACE_EVENT(radeon_vm_bo_update,
>> Â ÂÂÂÂÂÂÂÂÂ TP_fast_assign(
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ __entry->soffset = bo_va->it.start;
>> -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ __entry->eoffset = bo_va->it.last + 1;
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ __entry->eoffset = bo_va->it.end;
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ __entry->flags = bo_va->flags;
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ ),
>> ÂÂÂÂÂÂÂÂÂ TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x",
>> diff --git a/drivers/gpu/drm/radeon/radeon_vm.c
>> b/drivers/gpu/drm/radeon/radeon_vm.c
>> index e0ad547786e8..b2a54aff21f4 100644
>> --- a/drivers/gpu/drm/radeon/radeon_vm.c
>> +++ b/drivers/gpu/drm/radeon/radeon_vm.c
>> @@ -329,7 +329,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct
>> radeon_device *rdev,
>> ÂÂÂÂÂ bo_va->vm = vm;
>> ÂÂÂÂÂ bo_va->bo = bo;
>> ÂÂÂÂÂ bo_va->it.start = 0;
>> -ÂÂÂ bo_va->it.last = 0;
>> +ÂÂÂ bo_va->it.end = 0;
>> ÂÂÂÂÂ bo_va->flags = 0;
>> ÂÂÂÂÂ bo_va->ref_count = 1;
>> ÂÂÂÂÂ INIT_LIST_HEAD(&bo_va->bo_list);
>> @@ -456,7 +456,7 @@ int radeon_vm_bo_set_addr(struct radeon_device
>> *rdev,
>> Â ÂÂÂÂÂ if (soffset) {
>> ÂÂÂÂÂÂÂÂÂ /* make sure object fit at this offset */
>> -ÂÂÂÂÂÂÂ eoffset = soffset + size - 1;
>> +ÂÂÂÂÂÂÂ eoffset = soffset + size;
>> ÂÂÂÂÂÂÂÂÂ if (soffset >= eoffset) {
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ r = -EINVAL;
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ goto error_unreserve;
>> @@ -486,14 +486,14 @@ int radeon_vm_bo_set_addr(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ /* bo and tmp overlap, invalid offset */
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with "
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo,
>> -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ soffset, tmp->bo, tmp->it.start, tmp->it.last);
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ soffset, tmp->bo, tmp->it.start, tmp->it.end);
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ mutex_unlock(&vm->mutex);
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ r = -EINVAL;
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ goto error_unreserve;
>> ÂÂÂÂÂÂÂÂÂ }
>> ÂÂÂÂÂ }
>> Â -ÂÂÂ if (bo_va->it.start || bo_va->it.last) {
>> +ÂÂÂ if (bo_va->it.start || bo_va->it.end) {
>> ÂÂÂÂÂÂÂÂÂ /* add a clone of the bo_va to clear the old address */
>> ÂÂÂÂÂÂÂÂÂ struct radeon_bo_va *tmp;
>> ÂÂÂÂÂÂÂÂÂ tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
>> @@ -503,14 +503,14 @@ int radeon_vm_bo_set_addr(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ goto error_unreserve;
>> ÂÂÂÂÂÂÂÂÂ }
>> ÂÂÂÂÂÂÂÂÂ tmp->it.start = bo_va->it.start;
>> -ÂÂÂÂÂÂÂ tmp->it.last = bo_va->it.last;
>> +ÂÂÂÂÂÂÂ tmp->it.end = bo_va->it.end;
>> ÂÂÂÂÂÂÂÂÂ tmp->vm = vm;
>> ÂÂÂÂÂÂÂÂÂ tmp->bo = radeon_bo_ref(bo_va->bo);
>> Â ÂÂÂÂÂÂÂÂÂ interval_tree_remove(&bo_va->it, &vm->va);
>> ÂÂÂÂÂÂÂÂÂ spin_lock(&vm->status_lock);
>> ÂÂÂÂÂÂÂÂÂ bo_va->it.start = 0;
>> -ÂÂÂÂÂÂÂ bo_va->it.last = 0;
>> +ÂÂÂÂÂÂÂ bo_va->it.end = 0;
>> ÂÂÂÂÂÂÂÂÂ list_del_init(&bo_va->vm_status);
>> ÂÂÂÂÂÂÂÂÂ list_add(&tmp->vm_status, &vm->freed);
>> ÂÂÂÂÂÂÂÂÂ spin_unlock(&vm->status_lock);
>> @@ -519,7 +519,7 @@ int radeon_vm_bo_set_addr(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂ if (soffset || eoffset) {
>> ÂÂÂÂÂÂÂÂÂ spin_lock(&vm->status_lock);
>> ÂÂÂÂÂÂÂÂÂ bo_va->it.start = soffset;
>> -ÂÂÂÂÂÂÂ bo_va->it.last = eoffset;
>> +ÂÂÂÂÂÂÂ bo_va->it.end = eoffset;
>> ÂÂÂÂÂÂÂÂÂ list_add(&bo_va->vm_status, &vm->cleared);
>> ÂÂÂÂÂÂÂÂÂ spin_unlock(&vm->status_lock);
>> ÂÂÂÂÂÂÂÂÂ interval_tree_insert(&bo_va->it, &vm->va);
>> @@ -964,7 +964,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
>> Â ÂÂÂÂÂ trace_radeon_vm_bo_update(bo_va);
>> Â -ÂÂÂ nptes = bo_va->it.last - bo_va->it.start + 1;
>> +ÂÂÂ nptes = bo_va->it.end - bo_va->it.start;
>> Â ÂÂÂÂÂ /* reserve space for one command every (1 << BLOCK_SIZE) entries
>> ÂÂÂÂÂÂÂÂ or 2k dwords (whatever is smaller) */
>> @@ -1010,7 +1010,7 @@ int radeon_vm_bo_update(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂ }
>> Â ÂÂÂÂÂ r = radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start,
>> -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ bo_va->it.last + 1, addr,
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ bo_va->it.end, addr,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ radeon_vm_page_flags(bo_va->flags));
>> ÂÂÂÂÂ if (r) {
>> ÂÂÂÂÂÂÂÂÂ radeon_ib_free(rdev, &ib);
>> @@ -1026,7 +1026,7 @@ int radeon_vm_bo_update(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂÂÂÂÂ return r;
>> ÂÂÂÂÂ }
>> ÂÂÂÂÂ ib.fence->is_vm_update = true;
>> -ÂÂÂ radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1,
>> ib.fence);
>> +ÂÂÂ radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.end, ib.fence);
>> ÂÂÂÂÂ radeon_fence_unref(&bo_va->last_pt_update);
>> ÂÂÂÂÂ bo_va->last_pt_update = radeon_fence_ref(ib.fence);
>> ÂÂÂÂÂ radeon_ib_free(rdev, &ib);
>> @@ -1124,12 +1124,12 @@ void radeon_vm_bo_rmv(struct radeon_device
>> *rdev,
>> ÂÂÂÂÂ list_del(&bo_va->bo_list);
>> Â ÂÂÂÂÂ mutex_lock(&vm->mutex);
>> -ÂÂÂ if (bo_va->it.start || bo_va->it.last)
>> +ÂÂÂ if (bo_va->it.start || bo_va->it.end)
>> ÂÂÂÂÂÂÂÂÂ interval_tree_remove(&bo_va->it, &vm->va);
>> Â ÂÂÂÂÂ spin_lock(&vm->status_lock);
>> ÂÂÂÂÂ list_del(&bo_va->vm_status);
>> -ÂÂÂ if (bo_va->it.start || bo_va->it.last) {
>> +ÂÂÂ if (bo_va->it.start || bo_va->it.end) {
>> ÂÂÂÂÂÂÂÂÂ bo_va->bo = radeon_bo_ref(bo_va->bo);
>> ÂÂÂÂÂÂÂÂÂ list_add(&bo_va->vm_status, &vm->freed);
>> ÂÂÂÂÂ } else {
>> @@ -1158,7 +1158,7 @@ void radeon_vm_bo_invalidate(struct
>> radeon_device *rdev,
>> ÂÂÂÂÂ list_for_each_entry(bo_va, &bo->va, bo_list) {
>> ÂÂÂÂÂÂÂÂÂ spin_lock(&bo_va->vm->status_lock);
>> ÂÂÂÂÂÂÂÂÂ if (list_empty(&bo_va->vm_status) &&
>> -ÂÂÂÂÂÂÂÂÂÂÂ (bo_va->it.start || bo_va->it.last))
>> +ÂÂÂÂÂÂÂÂÂÂÂ (bo_va->it.start || bo_va->it.end))
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
>> ÂÂÂÂÂÂÂÂÂ spin_unlock(&bo_va->vm->status_lock);
>> ÂÂÂÂÂ }
>> diff --git a/drivers/infiniband/core/umem_odp.c
>> b/drivers/infiniband/core/umem_odp.c
>> index f67a30fda1ed..9b7ac93223d6 100644
>> --- a/drivers/infiniband/core/umem_odp.c
>> +++ b/drivers/infiniband/core/umem_odp.c
>> @@ -219,26 +219,19 @@ static inline int ib_init_umem_odp(struct
>> ib_umem_odp *umem_odp)
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ ALIGN_DOWN(umem_odp->umem.address, page_size);
>> ÂÂÂÂÂÂÂÂÂ if (check_add_overflow(umem_odp->umem.address,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ (unsigned long)umem_odp->umem.length,
>> -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ &umem_odp->interval_tree.last))
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ &umem_odp->interval_tree.end))
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ return -EOVERFLOW;
>> -ÂÂÂÂÂÂÂ umem_odp->interval_tree.last =
>> -ÂÂÂÂÂÂÂÂÂÂÂ ALIGN(umem_odp->interval_tree.last, page_size);
>> -ÂÂÂÂÂÂÂ if (unlikely(umem_odp->interval_tree.last < page_size))
>> +ÂÂÂÂÂÂÂ umem_odp->interval_tree.end =
>> +ÂÂÂÂÂÂÂÂÂÂÂ ALIGN(umem_odp->interval_tree.end, page_size);
>> +ÂÂÂÂÂÂÂ if (unlikely(umem_odp->interval_tree.end < page_size))
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ return -EOVERFLOW;
>> Â -ÂÂÂÂÂÂÂ pages = (umem_odp->interval_tree.last -
>> +ÂÂÂÂÂÂÂ pages = (umem_odp->interval_tree.end -
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ umem_odp->interval_tree.start) >>
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ umem_odp->page_shift;
>> ÂÂÂÂÂÂÂÂÂ if (!pages)
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ return -EINVAL;
>> Â -ÂÂÂÂÂÂÂ /*
>> -ÂÂÂÂÂÂÂÂ * Note that the representation of the intervals in the
>> -ÂÂÂÂÂÂÂÂ * interval tree considers the ending point as contained in
>> -ÂÂÂÂÂÂÂÂ * the interval.
>> -ÂÂÂÂÂÂÂÂ */
>> -ÂÂÂÂÂÂÂ umem_odp->interval_tree.last--;
>> -
>> ÂÂÂÂÂÂÂÂÂ umem_odp->page_list = kvcalloc(
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ pages, sizeof(*umem_odp->page_list), GFP_KERNEL);
>> ÂÂÂÂÂÂÂÂÂ if (!umem_odp->page_list)
>> @@ -777,12 +770,12 @@ int rbt_ib_umem_for_each_in_range(struct
>> rb_root_cached *root,
>> ÂÂÂÂÂ if (unlikely(start == last))
>> ÂÂÂÂÂÂÂÂÂ return ret_val;
>> Â -ÂÂÂ for (node = interval_tree_iter_first(root, start, last - 1);
>> +ÂÂÂ for (node = interval_tree_iter_first(root, start, last);
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ node; node = next) {
>> ÂÂÂÂÂÂÂÂÂ /* TODO move the blockable decision up to the callback */
>> ÂÂÂÂÂÂÂÂÂ if (!blockable)
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ return -EAGAIN;
>> -ÂÂÂÂÂÂÂ next = interval_tree_iter_next(node, start, last - 1);
>> +ÂÂÂÂÂÂÂ next = interval_tree_iter_next(node, start, last);
>> ÂÂÂÂÂÂÂÂÂ umem = container_of(node, struct ib_umem_odp, interval_tree);
>> ÂÂÂÂÂÂÂÂÂ ret_val = cb(umem, start, last, cookie) || ret_val;
>> ÂÂÂÂÂ }
>> diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
>> index 3ea9d7682999..771740981f43 100644
>> --- a/drivers/iommu/virtio-iommu.c
>> +++ b/drivers/iommu/virtio-iommu.c
>> @@ -323,7 +323,7 @@ static int viommu_add_mapping(struct
>> viommu_domain *vdomain, unsigned long iova,
>> Â ÂÂÂÂÂ mapping->paddrÂÂÂÂÂÂÂ = paddr;
>> ÂÂÂÂÂ mapping->iova.startÂÂÂ = iova;
>> -ÂÂÂ mapping->iova.lastÂÂÂ = iova + size - 1;
>> +ÂÂÂ mapping->iova.endÂÂÂ = iova + size;
>> ÂÂÂÂÂ mapping->flagsÂÂÂÂÂÂÂ = flags;
>> Â ÂÂÂÂÂ spin_lock_irqsave(&vdomain->mappings_lock, irqflags);
>> @@ -348,7 +348,7 @@ static size_t viommu_del_mappings(struct
>> viommu_domain *vdomain,
>> Â {
>> ÂÂÂÂÂ size_t unmapped = 0;
>> ÂÂÂÂÂ unsigned long flags;
>> -ÂÂÂ unsigned long last = iova + size - 1;
>> +ÂÂÂ unsigned long last = iova + size;
>> ÂÂÂÂÂ struct viommu_mapping *mapping = NULL;
>> ÂÂÂÂÂ struct interval_tree_node *node, *next;
>> Â @@ -367,7 +367,7 @@ static size_t viommu_del_mappings(struct
>> viommu_domain *vdomain,
>> ÂÂÂÂÂÂÂÂÂÂ * Virtio-iommu doesn't allow UNMAP to split a mapping created
>> ÂÂÂÂÂÂÂÂÂÂ * with a single MAP request, so remove the full mapping.
>> ÂÂÂÂÂÂÂÂÂÂ */
>> -ÂÂÂÂÂÂÂ unmapped += mapping->iova.last - mapping->iova.start + 1;
>> +ÂÂÂÂÂÂÂ unmapped += mapping->iova.end - mapping->iova.start;
>> Â ÂÂÂÂÂÂÂÂÂ interval_tree_remove(node, &vdomain->mappings);
>> ÂÂÂÂÂÂÂÂÂ kfree(mapping);
>> diff --git a/include/linux/interval_tree.h
>> b/include/linux/interval_tree.h
>> index 288c26f50732..f3d1ea9e4003 100644
>> --- a/include/linux/interval_tree.h
>> +++ b/include/linux/interval_tree.h
>> @@ -7,7 +7,7 @@
>> Â struct interval_tree_node {
>> ÂÂÂÂÂ struct rb_node rb;
>> ÂÂÂÂÂ unsigned long start;ÂÂÂ /* Start of interval */
>> -ÂÂÂ unsigned long last;ÂÂÂ /* Last location _in_ interval */
>> +ÂÂÂ unsigned long end;ÂÂÂ /* Last location _outside_ interval */
>> ÂÂÂÂÂ unsigned long __subtree_last;
>> Â };
>> Â diff --git a/include/rdma/ib_umem_odp.h b/include/rdma/ib_umem_odp.h
>> index 253df1a1fa54..d0ae7aa2139b 100644
>> --- a/include/rdma/ib_umem_odp.h
>> +++ b/include/rdma/ib_umem_odp.h
>> @@ -97,7 +97,7 @@ static inline unsigned long ib_umem_start(struct
>> ib_umem_odp *umem_odp)
>> Â /* Returns the address of the page after the last one of an ODP
>> umem. */
>> Â static inline unsigned long ib_umem_end(struct ib_umem_odp *umem_odp)
>> Â {
>> -ÂÂÂ return umem_odp->interval_tree.last + 1;
>> +ÂÂÂ return umem_odp->interval_tree.end;
>> Â }
>> Â Â static inline size_t ib_umem_odp_num_pages(struct ib_umem_odp
>> *umem_odp)
>> @@ -165,7 +165,7 @@ rbt_ib_umem_lookup(struct rb_root_cached *root,
>> u64 addr, u64 length)
>> Â {
>> ÂÂÂÂÂ struct interval_tree_node *node;
>> Â -ÂÂÂ node = interval_tree_iter_first(root, addr, addr + length - 1);
>> +ÂÂÂ node = interval_tree_iter_first(root, addr, addr + length);
>> ÂÂÂÂÂ if (!node)
>> ÂÂÂÂÂÂÂÂÂ return NULL;
>> ÂÂÂÂÂ return container_of(node, struct ib_umem_odp, interval_tree);
>> diff --git a/lib/interval_tree.c b/lib/interval_tree.c
>> index 593ce56ece50..336ec5113a28 100644
>> --- a/lib/interval_tree.c
>> +++ b/lib/interval_tree.c
>> @@ -1,15 +1,15 @@
>> Â // SPDX-License-Identifier: GPL-2.0-only
>> Â #include <linux/interval_tree.h>
>> -#include <linux/interval_tree_generic.h>
>> +#include <linux/interval_tree_gen.h>
>> Â #include <linux/compiler.h>
>> Â #include <linux/export.h>
>> Â Â #define START(node) ((node)->start)
>> -#define LAST(node)Â ((node)->last)
>> +#define END(node)Â ((node)->end)
>> Â Â INTERVAL_TREE_DEFINE(struct interval_tree_node, rb,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ unsigned long, __subtree_last,
>> -ÂÂÂÂÂÂÂÂÂÂÂÂ START, LAST,, interval_tree)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂ START, END,, interval_tree)
>> Â Â EXPORT_SYMBOL_GPL(interval_tree_insert);
>> Â EXPORT_SYMBOL_GPL(interval_tree_remove);
>