diff options
author | Roland Dreier <rolandd@cisco.com> | 2007-03-04 19:15:11 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-05-08 21:00:37 -0400 |
commit | f7c6a7b5d59980b076abbf2ceeb8735591290285 (patch) | |
tree | 29c35b47052bba87f031a4744d8ad12ff5187149 /drivers/infiniband/core/uverbs_main.c | |
parent | 36f021b579d195cdc5fa6f3e2bab198b4bf70643 (diff) |
IB/uverbs: Export ib_umem_get()/ib_umem_release() to modules
Export ib_umem_get()/ib_umem_release() and put low-level drivers in
control of when to call ib_umem_get() to pin and DMA map userspace,
rather than always calling it in ib_uverbs_reg_mr() before calling the
low-level driver's reg_user_mr method.
Also move these functions to be in the ib_core module instead of
ib_uverbs, so that driver modules using them do not depend on
ib_uverbs.
This has a number of advantages:
- It is better design from the standpoint of making generic code a
library that can be used or overridden by device-specific code as
the details of specific devices dictate.
- Drivers that do not need to pin userspace memory regions do not
need to take the performance hit of calling ib_mem_get(). For
example, although I have not tried to implement it in this patch,
the ipath driver should be able to avoid pinning memory and just
use copy_{to,from}_user() to access userspace memory regions.
- Buffers that need special mapping treatment can be identified by
the low-level driver. For example, it may be possible to solve
some Altix-specific memory ordering issues with mthca CQs in
userspace by mapping CQ buffers with extra flags.
- Drivers that need to pin and DMA map userspace memory for things
other than memory regions can use ib_umem_get() directly, instead
of hacks using extra parameters to their reg_phys_mr method. For
example, the mlx4 driver that is pending being merged needs to pin
and DMA map QP and CQ buffers, but it does not need to create a
memory key for these buffers. So the cleanest solution is for mlx4
to call ib_umem_get() in the create_qp and create_cq methods.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/uverbs_main.c')
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index d44e54799651..14d7ccd89195 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -183,6 +183,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, | |||
183 | if (!context) | 183 | if (!context) |
184 | return 0; | 184 | return 0; |
185 | 185 | ||
186 | context->closing = 1; | ||
187 | |||
186 | list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { | 188 | list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { |
187 | struct ib_ah *ah = uobj->object; | 189 | struct ib_ah *ah = uobj->object; |
188 | 190 | ||
@@ -230,16 +232,10 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, | |||
230 | 232 | ||
231 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { | 233 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { |
232 | struct ib_mr *mr = uobj->object; | 234 | struct ib_mr *mr = uobj->object; |
233 | struct ib_device *mrdev = mr->device; | ||
234 | struct ib_umem_object *memobj; | ||
235 | 235 | ||
236 | idr_remove_uobj(&ib_uverbs_mr_idr, uobj); | 236 | idr_remove_uobj(&ib_uverbs_mr_idr, uobj); |
237 | ib_dereg_mr(mr); | 237 | ib_dereg_mr(mr); |
238 | 238 | kfree(uobj); | |
239 | memobj = container_of(uobj, struct ib_umem_object, uobject); | ||
240 | ib_umem_release_on_close(mrdev, &memobj->umem); | ||
241 | |||
242 | kfree(memobj); | ||
243 | } | 239 | } |
244 | 240 | ||
245 | list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { | 241 | list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { |
@@ -906,7 +902,6 @@ static void __exit ib_uverbs_cleanup(void) | |||
906 | unregister_filesystem(&uverbs_event_fs); | 902 | unregister_filesystem(&uverbs_event_fs); |
907 | class_destroy(uverbs_class); | 903 | class_destroy(uverbs_class); |
908 | unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); | 904 | unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); |
909 | flush_scheduled_work(); | ||
910 | idr_destroy(&ib_uverbs_pd_idr); | 905 | idr_destroy(&ib_uverbs_pd_idr); |
911 | idr_destroy(&ib_uverbs_mr_idr); | 906 | idr_destroy(&ib_uverbs_mr_idr); |
912 | idr_destroy(&ib_uverbs_mw_idr); | 907 | idr_destroy(&ib_uverbs_mw_idr); |