diff options
-rw-r--r-- | kernel/bpf/hashtab.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 3ea87fb19a94..63c86a7be2a1 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
@@ -45,8 +45,13 @@ enum extra_elem_state { | |||
45 | struct htab_elem { | 45 | struct htab_elem { |
46 | union { | 46 | union { |
47 | struct hlist_node hash_node; | 47 | struct hlist_node hash_node; |
48 | struct bpf_htab *htab; | 48 | struct { |
49 | struct pcpu_freelist_node fnode; | 49 | void *padding; |
50 | union { | ||
51 | struct bpf_htab *htab; | ||
52 | struct pcpu_freelist_node fnode; | ||
53 | }; | ||
54 | }; | ||
50 | }; | 55 | }; |
51 | union { | 56 | union { |
52 | struct rcu_head rcu; | 57 | struct rcu_head rcu; |
@@ -162,7 +167,8 @@ skip_percpu_elems: | |||
162 | offsetof(struct htab_elem, lru_node), | 167 | offsetof(struct htab_elem, lru_node), |
163 | htab->elem_size, htab->map.max_entries); | 168 | htab->elem_size, htab->map.max_entries); |
164 | else | 169 | else |
165 | pcpu_freelist_populate(&htab->freelist, htab->elems, | 170 | pcpu_freelist_populate(&htab->freelist, |
171 | htab->elems + offsetof(struct htab_elem, fnode), | ||
166 | htab->elem_size, htab->map.max_entries); | 172 | htab->elem_size, htab->map.max_entries); |
167 | 173 | ||
168 | return 0; | 174 | return 0; |
@@ -217,6 +223,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) | |||
217 | int err, i; | 223 | int err, i; |
218 | u64 cost; | 224 | u64 cost; |
219 | 225 | ||
226 | BUILD_BUG_ON(offsetof(struct htab_elem, htab) != | ||
227 | offsetof(struct htab_elem, hash_node.pprev)); | ||
228 | BUILD_BUG_ON(offsetof(struct htab_elem, fnode.next) != | ||
229 | offsetof(struct htab_elem, hash_node.pprev)); | ||
230 | |||
220 | if (lru && !capable(CAP_SYS_ADMIN)) | 231 | if (lru && !capable(CAP_SYS_ADMIN)) |
221 | /* LRU implementation is much complicated than other | 232 | /* LRU implementation is much complicated than other |
222 | * maps. Hence, limit to CAP_SYS_ADMIN for now. | 233 | * maps. Hence, limit to CAP_SYS_ADMIN for now. |
@@ -582,9 +593,13 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
582 | int err = 0; | 593 | int err = 0; |
583 | 594 | ||
584 | if (prealloc) { | 595 | if (prealloc) { |
585 | l_new = (struct htab_elem *)pcpu_freelist_pop(&htab->freelist); | 596 | struct pcpu_freelist_node *l; |
586 | if (!l_new) | 597 | |
598 | l = pcpu_freelist_pop(&htab->freelist); | ||
599 | if (!l) | ||
587 | err = -E2BIG; | 600 | err = -E2BIG; |
601 | else | ||
602 | l_new = container_of(l, struct htab_elem, fnode); | ||
588 | } else { | 603 | } else { |
589 | if (atomic_inc_return(&htab->count) > htab->map.max_entries) { | 604 | if (atomic_inc_return(&htab->count) > htab->map.max_entries) { |
590 | atomic_dec(&htab->count); | 605 | atomic_dec(&htab->count); |