diff options
Diffstat (limited to 'kernel/bpf/stackmap.c')
-rw-r--r-- | kernel/bpf/stackmap.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index 950ab2f28922..3d86072d8e32 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c | |||
@@ -89,6 +89,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) | |||
89 | { | 89 | { |
90 | u32 value_size = attr->value_size; | 90 | u32 value_size = attr->value_size; |
91 | struct bpf_stack_map *smap; | 91 | struct bpf_stack_map *smap; |
92 | struct bpf_map_memory mem; | ||
92 | u64 cost, n_buckets; | 93 | u64 cost, n_buckets; |
93 | int err; | 94 | int err; |
94 | 95 | ||
@@ -116,40 +117,37 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) | |||
116 | n_buckets = roundup_pow_of_two(attr->max_entries); | 117 | n_buckets = roundup_pow_of_two(attr->max_entries); |
117 | 118 | ||
118 | cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap); | 119 | cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap); |
119 | if (cost >= U32_MAX - PAGE_SIZE) | 120 | cost += n_buckets * (value_size + sizeof(struct stack_map_bucket)); |
120 | return ERR_PTR(-E2BIG); | 121 | err = bpf_map_charge_init(&mem, cost); |
122 | if (err) | ||
123 | return ERR_PTR(err); | ||
121 | 124 | ||
122 | smap = bpf_map_area_alloc(cost, bpf_map_attr_numa_node(attr)); | 125 | smap = bpf_map_area_alloc(cost, bpf_map_attr_numa_node(attr)); |
123 | if (!smap) | 126 | if (!smap) { |
127 | bpf_map_charge_finish(&mem); | ||
124 | return ERR_PTR(-ENOMEM); | 128 | return ERR_PTR(-ENOMEM); |
125 | 129 | } | |
126 | err = -E2BIG; | ||
127 | cost += n_buckets * (value_size + sizeof(struct stack_map_bucket)); | ||
128 | if (cost >= U32_MAX - PAGE_SIZE) | ||
129 | goto free_smap; | ||
130 | 130 | ||
131 | bpf_map_init_from_attr(&smap->map, attr); | 131 | bpf_map_init_from_attr(&smap->map, attr); |
132 | smap->map.value_size = value_size; | 132 | smap->map.value_size = value_size; |
133 | smap->n_buckets = n_buckets; | 133 | smap->n_buckets = n_buckets; |
134 | smap->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; | ||
135 | |||
136 | err = bpf_map_precharge_memlock(smap->map.pages); | ||
137 | if (err) | ||
138 | goto free_smap; | ||
139 | 134 | ||
140 | err = get_callchain_buffers(sysctl_perf_event_max_stack); | 135 | err = get_callchain_buffers(sysctl_perf_event_max_stack); |
141 | if (err) | 136 | if (err) |
142 | goto free_smap; | 137 | goto free_charge; |
143 | 138 | ||
144 | err = prealloc_elems_and_freelist(smap); | 139 | err = prealloc_elems_and_freelist(smap); |
145 | if (err) | 140 | if (err) |
146 | goto put_buffers; | 141 | goto put_buffers; |
147 | 142 | ||
143 | bpf_map_charge_move(&smap->map.memory, &mem); | ||
144 | |||
148 | return &smap->map; | 145 | return &smap->map; |
149 | 146 | ||
150 | put_buffers: | 147 | put_buffers: |
151 | put_callchain_buffers(); | 148 | put_callchain_buffers(); |
152 | free_smap: | 149 | free_charge: |
150 | bpf_map_charge_finish(&mem); | ||
153 | bpf_map_area_free(smap); | 151 | bpf_map_area_free(smap); |
154 | return ERR_PTR(err); | 152 | return ERR_PTR(err); |
155 | } | 153 | } |