diff options
Diffstat (limited to 'kernel/bpf/hashtab.c')
-rw-r--r-- | kernel/bpf/hashtab.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 04b8eda94e7d..03cc59ee9c95 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/jhash.h> | 15 | #include <linux/jhash.h> |
16 | #include <linux/filter.h> | 16 | #include <linux/filter.h> |
17 | #include <linux/rculist_nulls.h> | 17 | #include <linux/rculist_nulls.h> |
18 | #include <linux/random.h> | ||
18 | #include <uapi/linux/btf.h> | 19 | #include <uapi/linux/btf.h> |
19 | #include "percpu_freelist.h" | 20 | #include "percpu_freelist.h" |
20 | #include "bpf_lru_list.h" | 21 | #include "bpf_lru_list.h" |
@@ -41,6 +42,7 @@ struct bpf_htab { | |||
41 | atomic_t count; /* number of elements in this hashtable */ | 42 | atomic_t count; /* number of elements in this hashtable */ |
42 | u32 n_buckets; /* number of hash buckets */ | 43 | u32 n_buckets; /* number of hash buckets */ |
43 | u32 elem_size; /* size of each element in bytes */ | 44 | u32 elem_size; /* size of each element in bytes */ |
45 | u32 hashrnd; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | /* each htab element is struct htab_elem + key + value */ | 48 | /* each htab element is struct htab_elem + key + value */ |
@@ -371,6 +373,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) | |||
371 | if (!htab->buckets) | 373 | if (!htab->buckets) |
372 | goto free_htab; | 374 | goto free_htab; |
373 | 375 | ||
376 | htab->hashrnd = get_random_int(); | ||
374 | for (i = 0; i < htab->n_buckets; i++) { | 377 | for (i = 0; i < htab->n_buckets; i++) { |
375 | INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i); | 378 | INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i); |
376 | raw_spin_lock_init(&htab->buckets[i].lock); | 379 | raw_spin_lock_init(&htab->buckets[i].lock); |
@@ -402,9 +405,9 @@ free_htab: | |||
402 | return ERR_PTR(err); | 405 | return ERR_PTR(err); |
403 | } | 406 | } |
404 | 407 | ||
405 | static inline u32 htab_map_hash(const void *key, u32 key_len) | 408 | static inline u32 htab_map_hash(const void *key, u32 key_len, u32 hashrnd) |
406 | { | 409 | { |
407 | return jhash(key, key_len, 0); | 410 | return jhash(key, key_len, hashrnd); |
408 | } | 411 | } |
409 | 412 | ||
410 | static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash) | 413 | static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash) |
@@ -470,7 +473,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key) | |||
470 | 473 | ||
471 | key_size = map->key_size; | 474 | key_size = map->key_size; |
472 | 475 | ||
473 | hash = htab_map_hash(key, key_size); | 476 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
474 | 477 | ||
475 | head = select_bucket(htab, hash); | 478 | head = select_bucket(htab, hash); |
476 | 479 | ||
@@ -597,7 +600,7 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) | |||
597 | if (!key) | 600 | if (!key) |
598 | goto find_first_elem; | 601 | goto find_first_elem; |
599 | 602 | ||
600 | hash = htab_map_hash(key, key_size); | 603 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
601 | 604 | ||
602 | head = select_bucket(htab, hash); | 605 | head = select_bucket(htab, hash); |
603 | 606 | ||
@@ -824,7 +827,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
824 | 827 | ||
825 | key_size = map->key_size; | 828 | key_size = map->key_size; |
826 | 829 | ||
827 | hash = htab_map_hash(key, key_size); | 830 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
828 | 831 | ||
829 | b = __select_bucket(htab, hash); | 832 | b = __select_bucket(htab, hash); |
830 | head = &b->head; | 833 | head = &b->head; |
@@ -880,7 +883,7 @@ static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
880 | 883 | ||
881 | key_size = map->key_size; | 884 | key_size = map->key_size; |
882 | 885 | ||
883 | hash = htab_map_hash(key, key_size); | 886 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
884 | 887 | ||
885 | b = __select_bucket(htab, hash); | 888 | b = __select_bucket(htab, hash); |
886 | head = &b->head; | 889 | head = &b->head; |
@@ -945,7 +948,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
945 | 948 | ||
946 | key_size = map->key_size; | 949 | key_size = map->key_size; |
947 | 950 | ||
948 | hash = htab_map_hash(key, key_size); | 951 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
949 | 952 | ||
950 | b = __select_bucket(htab, hash); | 953 | b = __select_bucket(htab, hash); |
951 | head = &b->head; | 954 | head = &b->head; |
@@ -998,7 +1001,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
998 | 1001 | ||
999 | key_size = map->key_size; | 1002 | key_size = map->key_size; |
1000 | 1003 | ||
1001 | hash = htab_map_hash(key, key_size); | 1004 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
1002 | 1005 | ||
1003 | b = __select_bucket(htab, hash); | 1006 | b = __select_bucket(htab, hash); |
1004 | head = &b->head; | 1007 | head = &b->head; |
@@ -1071,7 +1074,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key) | |||
1071 | 1074 | ||
1072 | key_size = map->key_size; | 1075 | key_size = map->key_size; |
1073 | 1076 | ||
1074 | hash = htab_map_hash(key, key_size); | 1077 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
1075 | b = __select_bucket(htab, hash); | 1078 | b = __select_bucket(htab, hash); |
1076 | head = &b->head; | 1079 | head = &b->head; |
1077 | 1080 | ||
@@ -1103,7 +1106,7 @@ static int htab_lru_map_delete_elem(struct bpf_map *map, void *key) | |||
1103 | 1106 | ||
1104 | key_size = map->key_size; | 1107 | key_size = map->key_size; |
1105 | 1108 | ||
1106 | hash = htab_map_hash(key, key_size); | 1109 | hash = htab_map_hash(key, key_size, htab->hashrnd); |
1107 | b = __select_bucket(htab, hash); | 1110 | b = __select_bucket(htab, hash); |
1108 | head = &b->head; | 1111 | head = &b->head; |
1109 | 1112 | ||