aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/stackmap.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2017-01-18 09:14:17 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-18 17:12:26 -0500
commitd407bd25a204bd66b7346dde24bd3d37ef0e0b05 (patch)
tree01e49e08ca4f4eb258a2e2d9c67d03d503498696 /kernel/bpf/stackmap.c
parent9ed59592e3e379b2e9557dc1d9e9ec8fcbb33f16 (diff)
bpf: don't trigger OOM killer under pressure with map alloc
This patch adds two helpers, bpf_map_area_alloc() and bpf_map_area_free(), that are to be used for map allocations. Using kmalloc() for very large allocations can cause excessive work within the page allocator, so i) fall back earlier to vmalloc() when the attempt is considered costly anyway, and even more importantly ii) don't trigger OOM killer with any of the allocators. Since this is based on a user space request, for example, when creating maps with element pre-allocation, we really want such requests to fail instead of killing other user space processes. Also, don't spam the kernel log with warnings should any of the allocations fail under pressure. Given that, we can make backend selection in bpf_map_area_alloc() generic, and convert all maps over to use this API for spots with potentially large allocation requests. Note, replacing the one kmalloc_array() is fine as overflow checks happen earlier in htab_map_alloc(), since it must also protect the multiplication for vmalloc() should kmalloc_array() fail. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/stackmap.c')
-rw-r--r--kernel/bpf/stackmap.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index 732ae16d12b7..be8519148c25 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -7,7 +7,6 @@
7#include <linux/bpf.h> 7#include <linux/bpf.h>
8#include <linux/jhash.h> 8#include <linux/jhash.h>
9#include <linux/filter.h> 9#include <linux/filter.h>
10#include <linux/vmalloc.h>
11#include <linux/stacktrace.h> 10#include <linux/stacktrace.h>
12#include <linux/perf_event.h> 11#include <linux/perf_event.h>
13#include "percpu_freelist.h" 12#include "percpu_freelist.h"
@@ -32,7 +31,7 @@ static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
32 u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; 31 u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
33 int err; 32 int err;
34 33
35 smap->elems = vzalloc(elem_size * smap->map.max_entries); 34 smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries);
36 if (!smap->elems) 35 if (!smap->elems)
37 return -ENOMEM; 36 return -ENOMEM;
38 37
@@ -45,7 +44,7 @@ static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
45 return 0; 44 return 0;
46 45
47free_elems: 46free_elems:
48 vfree(smap->elems); 47 bpf_map_area_free(smap->elems);
49 return err; 48 return err;
50} 49}
51 50
@@ -76,12 +75,9 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
76 if (cost >= U32_MAX - PAGE_SIZE) 75 if (cost >= U32_MAX - PAGE_SIZE)
77 return ERR_PTR(-E2BIG); 76 return ERR_PTR(-E2BIG);
78 77
79 smap = kzalloc(cost, GFP_USER | __GFP_NOWARN); 78 smap = bpf_map_area_alloc(cost);
80 if (!smap) { 79 if (!smap)
81 smap = vzalloc(cost); 80 return ERR_PTR(-ENOMEM);
82 if (!smap)
83 return ERR_PTR(-ENOMEM);
84 }
85 81
86 err = -E2BIG; 82 err = -E2BIG;
87 cost += n_buckets * (value_size + sizeof(struct stack_map_bucket)); 83 cost += n_buckets * (value_size + sizeof(struct stack_map_bucket));
@@ -112,7 +108,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
112put_buffers: 108put_buffers:
113 put_callchain_buffers(); 109 put_callchain_buffers();
114free_smap: 110free_smap:
115 kvfree(smap); 111 bpf_map_area_free(smap);
116 return ERR_PTR(err); 112 return ERR_PTR(err);
117} 113}
118 114
@@ -262,9 +258,9 @@ static void stack_map_free(struct bpf_map *map)
262 /* wait for bpf programs to complete before freeing stack map */ 258 /* wait for bpf programs to complete before freeing stack map */
263 synchronize_rcu(); 259 synchronize_rcu();
264 260
265 vfree(smap->elems); 261 bpf_map_area_free(smap->elems);
266 pcpu_freelist_destroy(&smap->freelist); 262 pcpu_freelist_destroy(&smap->freelist);
267 kvfree(smap); 263 bpf_map_area_free(smap);
268 put_callchain_buffers(); 264 put_callchain_buffers();
269} 265}
270 266