diff options
-rw-r--r-- | kernel/bpf/hashtab.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index ae822de4a90a..d246905f2bb1 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
@@ -662,12 +662,27 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, | |||
662 | } | 662 | } |
663 | } | 663 | } |
664 | 664 | ||
665 | static bool fd_htab_map_needs_adjust(const struct bpf_htab *htab) | ||
666 | { | ||
667 | return htab->map.map_type == BPF_MAP_TYPE_HASH_OF_MAPS && | ||
668 | BITS_PER_LONG == 64; | ||
669 | } | ||
670 | |||
671 | static u32 htab_size_value(const struct bpf_htab *htab, bool percpu) | ||
672 | { | ||
673 | u32 size = htab->map.value_size; | ||
674 | |||
675 | if (percpu || fd_htab_map_needs_adjust(htab)) | ||
676 | size = round_up(size, 8); | ||
677 | return size; | ||
678 | } | ||
679 | |||
665 | static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | 680 | static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, |
666 | void *value, u32 key_size, u32 hash, | 681 | void *value, u32 key_size, u32 hash, |
667 | bool percpu, bool onallcpus, | 682 | bool percpu, bool onallcpus, |
668 | struct htab_elem *old_elem) | 683 | struct htab_elem *old_elem) |
669 | { | 684 | { |
670 | u32 size = htab->map.value_size; | 685 | u32 size = htab_size_value(htab, percpu); |
671 | bool prealloc = htab_is_prealloc(htab); | 686 | bool prealloc = htab_is_prealloc(htab); |
672 | struct htab_elem *l_new, **pl_new; | 687 | struct htab_elem *l_new, **pl_new; |
673 | void __percpu *pptr; | 688 | void __percpu *pptr; |
@@ -707,9 +722,6 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
707 | 722 | ||
708 | memcpy(l_new->key, key, key_size); | 723 | memcpy(l_new->key, key, key_size); |
709 | if (percpu) { | 724 | if (percpu) { |
710 | /* round up value_size to 8 bytes */ | ||
711 | size = round_up(size, 8); | ||
712 | |||
713 | if (prealloc) { | 725 | if (prealloc) { |
714 | pptr = htab_elem_get_ptr(l_new, key_size); | 726 | pptr = htab_elem_get_ptr(l_new, key_size); |
715 | } else { | 727 | } else { |
@@ -1220,17 +1232,9 @@ const struct bpf_map_ops htab_lru_percpu_map_ops = { | |||
1220 | 1232 | ||
1221 | static struct bpf_map *fd_htab_map_alloc(union bpf_attr *attr) | 1233 | static struct bpf_map *fd_htab_map_alloc(union bpf_attr *attr) |
1222 | { | 1234 | { |
1223 | struct bpf_map *map; | ||
1224 | |||
1225 | if (attr->value_size != sizeof(u32)) | 1235 | if (attr->value_size != sizeof(u32)) |
1226 | return ERR_PTR(-EINVAL); | 1236 | return ERR_PTR(-EINVAL); |
1227 | 1237 | return htab_map_alloc(attr); | |
1228 | /* pointer is stored internally */ | ||
1229 | attr->value_size = sizeof(void *); | ||
1230 | map = htab_map_alloc(attr); | ||
1231 | attr->value_size = sizeof(u32); | ||
1232 | |||
1233 | return map; | ||
1234 | } | 1238 | } |
1235 | 1239 | ||
1236 | static void fd_htab_map_free(struct bpf_map *map) | 1240 | static void fd_htab_map_free(struct bpf_map *map) |