uprobes: Change build_map_info() to try kmalloc(GFP_NOWAIT) first
authorOleg Nesterov <oleg@redhat.com>
Fri, 15 Jun 2012 15:43:36 +0000 (17:43 +0200)
committerIngo Molnar <mingo@kernel.org>
Sat, 16 Jun 2012 07:10:44 +0000 (09:10 +0200)
build_map_info() doesn't allocate the memory under i_mmap_mutex
to avoid the deadlock with page reclaim. But it can try
GFP_NOWAIT first, it should work in the likely case and thus we
almost never need the pre-alloc-and-retry path.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Anton Arapov <anton@redhat.com>
Link: http://lkml.kernel.org/r/20120615154336.GA9588@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
kernel/events/uprobes.c

index 4e0db3496d706ebcd0f2cfc1186835a22a7126fe..897417dbca8e991fb3834cfee13705d4a10f0304 100644 (file)
@@ -761,6 +761,16 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
                if (!valid_vma(vma, is_register))
                        continue;
 
+               if (!prev && !more) {
+                       /*
+                        * Needs GFP_NOWAIT to avoid i_mmap_mutex recursion through
+                        * reclaim. This is optimistic, no harm done if it fails.
+                        */
+                       prev = kmalloc(sizeof(struct map_info),
+                                       GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN);
+                       if (prev)
+                               prev->next = NULL;
+               }
                if (!prev) {
                        more++;
                        continue;