aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2007-04-18 23:20:28 -0400
committerRoland Dreier <rolandd@cisco.com>2007-05-08 21:00:37 -0400
commit1bf66a30421ca772820f489d88c16d0c430d6a67 (patch)
treeb1ab223e6908d772bcad7f9bc3382c33ad5a4490 /include
parentf7c6a7b5d59980b076abbf2ceeb8735591290285 (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')
-rw-r--r--include/rdma/ib_umem.h3
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
50struct ib_umem_chunk { 53struct ib_umem_chunk {