libbpf: Hashmap interface update to allow both long and void* keys/values
An update for libbpf's hashmap interface from void* -> void* to a
polymorphic one, allowing both long and void* keys and values.
This simplifies many use cases in libbpf as hashmaps there are mostly
integer to integer.
Perf copies hashmap implementation from libbpf and has to be
updated as well.
Changes to libbpf, selftests/bpf and perf are packed as a single
commit to avoid compilation issues with any future bisect.
Polymorphic interface is acheived by hiding hashmap interface
functions behind auxiliary macros that take care of necessary
type casts, for example:
    #define hashmap_cast_ptr(p)						\
	({								\
		_Static_assert((p) == NULL || sizeof(*(p)) == sizeof(long),\
			       #p " pointee should be a long-sized integer or a pointer"); \
		(long *)(p);						\
	})
    bool hashmap_find(const struct hashmap *map, long key, long *value);
    #define hashmap__find(map, key, value) \
		hashmap_find((map), (long)(key), hashmap_cast_ptr(value))
- hashmap__find macro casts key and value parameters to long
  and long* respectively
- hashmap_cast_ptr ensures that value pointer points to a memory
  of appropriate size.
This hack was suggested by Andrii Nakryiko in [1].
This is a follow up for [2].
[1] https://lore.kernel.org/bpf/CAEf4BzZ8KFneEJxFAaNCCFPGqp20hSpS2aCj76uRk3-qZUH5xg@mail.gmail.com/
[2] https://lore.kernel.org/bpf/af1facf9-7bc8-8a3d-0db4-7b3f333589a2@meta.com/T/#m65b28f1d6d969fcd318b556db6a3ad499a42607d
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20221109142611.879983-2-eddyz87@gmail.com
			
			
This commit is contained in:
		
				
					committed by
					
						 Andrii Nakryiko
						Andrii Nakryiko
					
				
			
			
				
	
			
			
			
						parent
						
							e5659e4e19
						
					
				
				
					commit
					c302378bc1
				
			| @@ -518,9 +518,8 @@ static int show_map_close_json(int fd, struct bpf_map_info *info) | ||||
| 
 | ||||
| 		jsonw_name(json_wtr, "pinned"); | ||||
| 		jsonw_start_array(json_wtr); | ||||
| 		hashmap__for_each_key_entry(map_table, entry, | ||||
| 					    u32_as_hash_field(info->id)) | ||||
| 			jsonw_string(json_wtr, entry->value); | ||||
| 		hashmap__for_each_key_entry(map_table, entry, info->id) | ||||
| 			jsonw_string(json_wtr, entry->pvalue); | ||||
| 		jsonw_end_array(json_wtr); | ||||
| 	} | ||||
| 
 | ||||
| @@ -595,9 +594,8 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info) | ||||
| 	if (!hashmap__empty(map_table)) { | ||||
| 		struct hashmap_entry *entry; | ||||
| 
 | ||||
| 		hashmap__for_each_key_entry(map_table, entry, | ||||
| 					    u32_as_hash_field(info->id)) | ||||
| 			printf("\n\tpinned %s", (char *)entry->value); | ||||
| 		hashmap__for_each_key_entry(map_table, entry, info->id) | ||||
| 			printf("\n\tpinned %s", (char *)entry->pvalue); | ||||
| 	} | ||||
| 
 | ||||
| 	if (frozen_str) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user