diff options
author | Roland Dreier <rolandd@cisco.com> | 2007-04-18 23:20:28 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-05-08 21:00:37 -0400 |
commit | 1bf66a30421ca772820f489d88c16d0c430d6a67 (patch) | |
tree | b1ab223e6908d772bcad7f9bc3382c33ad5a4490 /include/rdma | |
parent | f7c6a7b5d59980b076abbf2ceeb8735591290285 (diff) |
IB: Put rlimit accounting struct in struct ib_umem
When memory pinned with ib_umem_get() is released, ib_umem_release()
needs to subtract the amount of memory being unpinned from
mm->locked_vm. However, ib_umem_release() may be called with
mm->mmap_sem already held for writing if the memory is being released
as part of an munmap() call, so it is sometimes necessary to defer
this accounting into a workqueue.
However, the work struct used to defer this accounting is dynamically
allocated before it is queued, so there is the possibility of failing
that allocation. If the allocation fails, then ib_umem_release has no
choice except to bail out and leave the process with a permanently
elevated locked_vm.
Fix this by allocating the structure to defer accounting as part of
the original struct ib_umem, so there's no possibility of failing a
later allocation if creating the struct ib_umem and pinning memory
succeeds.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'include/rdma')
-rw-r--r-- | include/rdma/ib_umem.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h index 06307f7e43e0..b3a36f7d79e5 100644 --- a/include/rdma/ib_umem.h +++ b/include/rdma/ib_umem.h | |||
@@ -45,6 +45,9 @@ struct ib_umem { | |||
45 | int page_size; | 45 | int page_size; |
46 | int writable; | 46 | int writable; |
47 | struct list_head chunk_list; | 47 | struct list_head chunk_list; |
48 | struct work_struct work; | ||
49 | struct mm_struct *mm; | ||
50 | unsigned long diff; | ||
48 | }; | 51 | }; |
49 | 52 | ||
50 | struct ib_umem_chunk { | 53 | struct ib_umem_chunk { |