diff options
author | Artemy Kovalyov <artemyko@mellanox.com> | 2017-01-18 16:58:07 +0200 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-02-14 11:41:17 -0500 |
commit | d07d1d70ce1ad1c525f51f459ce36ca49ec2bf48 (patch) | |
tree | 09873cb0c3319aa49d59d1f44e2007e9bbd96356 /drivers/infiniband/core/umem_rbtree.c | |
parent | 25bf14d6f5898a59325f3ecabda7695565776594 (diff) | |
download | linux-d07d1d70ce1ad1c525f51f459ce36ca49ec2bf48.tar.gz linux-d07d1d70ce1ad1c525f51f459ce36ca49ec2bf48.tar.bz2 linux-d07d1d70ce1ad1c525f51f459ce36ca49ec2bf48.zip |
IB/umem: Update on demand page (ODP) support
Currently ODP MR may explicitly register virtual address space area
of limited length.
This change allows MR to cover entire process virtual address space
dynamicaly adding/removing translation entries to device MTT.
Add following changes to support implicit MR:
* Allow umem to be zero size to back-up implicit MR.
* Add new function ib_alloc_odp_umem() to add virtual memory regions
to implicit MR dynamically on demand.
* Add new function rbt_ib_umem_lookup() to find dynamically added
virtual memory regions.
* Expose function rbt_ib_umem_for_each_in_range() to other modules and
make it safe
Signed-off-by: Artemy Kovalyov <artemyko@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/core/umem_rbtree.c')
-rw-r--r-- | drivers/infiniband/core/umem_rbtree.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/infiniband/core/umem_rbtree.c b/drivers/infiniband/core/umem_rbtree.c index 727d788448f5..d176597b4d78 100644 --- a/drivers/infiniband/core/umem_rbtree.c +++ b/drivers/infiniband/core/umem_rbtree.c @@ -78,17 +78,32 @@ int rbt_ib_umem_for_each_in_range(struct rb_root *root, void *cookie) { int ret_val = 0; - struct umem_odp_node *node; + struct umem_odp_node *node, *next; struct ib_umem_odp *umem; if (unlikely(start == last)) return ret_val; - for (node = rbt_ib_umem_iter_first(root, start, last - 1); node; - node = rbt_ib_umem_iter_next(node, start, last - 1)) { + for (node = rbt_ib_umem_iter_first(root, start, last - 1); + node; node = next) { + next = rbt_ib_umem_iter_next(node, start, last - 1); umem = container_of(node, struct ib_umem_odp, interval_tree); ret_val = cb(umem->umem, start, last, cookie) || ret_val; } return ret_val; } +EXPORT_SYMBOL(rbt_ib_umem_for_each_in_range); + +struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root, + u64 addr, u64 length) +{ + struct umem_odp_node *node; + + node = rbt_ib_umem_iter_first(root, addr, addr + length - 1); + if (node) + return container_of(node, struct ib_umem_odp, interval_tree); + return NULL; + +} +EXPORT_SYMBOL(rbt_ib_umem_lookup); |