aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/bpf/hashtab.c30
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
665static 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
671static 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
665static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, 680static 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
1221static struct bpf_map *fd_htab_map_alloc(union bpf_attr *attr) 1233static 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
1236static void fd_htab_map_free(struct bpf_map *map) 1240static void fd_htab_map_free(struct bpf_map *map)