- [4. BPF_HISTOGRAM](#4-bpf_histogram)
- [5. BPF_STACK_TRACE](#5-bpf_stack_trace)
- [6. BPF_PERF_ARRAY](#6-bpf_perf_array)
- - [7. BPF_PERCPU_ARRAY](#7-bpf_percpu_array)
- - [8. BPF_LPM_TRIE](#8-bpf_lpm_trie)
- - [9. BPF_PROG_ARRAY](#9-bpf_prog_array)
- - [10. BPF_DEVMAP](#10-bpf_devmap)
- - [11. BPF_CPUMAP](#11-bpf_cpumap)
- - [12. BPF_XSKMAP](#12-bpf_xskmap)
- - [13. BPF_ARRAY_OF_MAPS](#13-bpf_array_of_maps)
- - [14. BPF_HASH_OF_MAPS](#14-bpf_hash_of_maps)
- - [15. BPF_STACK](#15-bpf_stack)
- - [16. BPF_QUEUE](#16-bpf_queue)
- - [17. map.lookup()](#17-maplookup)
- - [18. map.lookup_or_try_init()](#18-maplookup_or_try_init)
- - [19. map.delete()](#19-mapdelete)
- - [20. map.update()](#20-mapupdate)
- - [21. map.insert()](#21-mapinsert)
- - [22. map.increment()](#22-mapincrement)
- - [23. map.get_stackid()](#23-mapget_stackid)
- - [24. map.perf_read()](#24-mapperf_read)
- - [25. map.call()](#25-mapcall)
- - [26. map.redirect_map()](#26-mapredirect_map)
- - [27. map.push()](#27-mappush)
- - [28. map.pop()](#28-mappop)
- - [29. map.peek()](#29-mappeek)
+ - [7. BPF_PERCPU_HASH](#7-bpf_percpu_hash)
+ - [8. BPF_PERCPU_ARRAY](#8-bpf_percpu_array)
+ - [9. BPF_LPM_TRIE](#9-bpf_lpm_trie)
+ - [10. BPF_PROG_ARRAY](#10-bpf_prog_array)
+ - [11. BPF_DEVMAP](#11-bpf_devmap)
+ - [12. BPF_CPUMAP](#12-bpf_cpumap)
+ - [13. BPF_XSKMAP](#13-bpf_xskmap)
+ - [14. BPF_ARRAY_OF_MAPS](#14-bpf_array_of_maps)
+ - [15. BPF_HASH_OF_MAPS](#15-bpf_hash_of_maps)
+ - [16. BPF_STACK](#16-bpf_stack)
+ - [17. BPF_QUEUE](#17-bpf_queue)
+ - [18. map.lookup()](#18-maplookup)
+ - [19. map.lookup_or_try_init()](#19-maplookup_or_try_init)
+ - [20. map.delete()](#20-mapdelete)
+ - [21. map.update()](#21-mapupdate)
+ - [22. map.insert()](#22-mapinsert)
+ - [23. map.increment()](#23-mapincrement)
+ - [24. map.get_stackid()](#24-mapget_stackid)
+ - [25. map.perf_read()](#25-mapperf_read)
+ - [26. map.call()](#26-mapcall)
+ - [27. map.redirect_map()](#27-mapredirect_map)
+ - [28. map.push()](#28-mappush)
+ - [29. map.pop()](#29-mappop)
+ - [30. map.peek()](#30-mappeek)
- [Licensing](#licensing)
- [Rewriter](#rewriter)
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_PERF_ARRAY+path%3Atests&type=Code)
-### 7. BPF_PERCPU_ARRAY
+### 7. BPF_PERCPU_HASH
+
+Syntax: ```BPF_PERCPU_HASH(name [, key_type [, leaf_type [, size]]])```
+
+Creates NUM_CPU int-indexed hash maps (associative arrays) named ```name```, with optional parameters. Each CPU will have a separate copy of this array. The copies are not kept synchronized in any way.
+
+Note that due to limits defined in the kernel (in linux/mm/percpu.c), the ```leaf_type``` cannot have a size of more than 32KB.
+In other words, ```BPF_PERCPU_HASH``` elements cannot be larger than 32KB in size.
+
+
+Defaults: ```BPF_PERCPU_HASH(name, key_type=u64, leaf_type=u64, size=10240)```
+
+For example:
+
+```C
+BPF_PERCPU_HASH(start, struct request *);
+```
+
+This creates NUM_CPU hashes named ```start``` where the key is a ```struct request *```, and the value defaults to u64.
+
+This is a wrapper macro for `BPF_TABLE("percpu_hash", ...)`.
+
+Methods (covered later): map.lookup(), map.lookup_or_try_init(), map.delete(), map.update(), map.insert(), map.increment().
+
+Examples in situ:
+[search /examples](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_HASH+path%3Aexamples&type=Code),
+[search /tools](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_HASH+path%3Atools&type=Code)
+
+
+### 8. BPF_PERCPU_ARRAY
Syntax: ```BPF_PERCPU_ARRAY(name [, leaf_type [, size]])```
[search /examples](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_ARRAY+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_ARRAY+path%3Atools&type=Code)
-### 8. BPF_LPM_TRIE
+### 9. BPF_LPM_TRIE
Syntax: `BPF_LPM_TRIE(name [, key_type [, leaf_type [, size]]])`
[search /examples](https://github.com/iovisor/bcc/search?q=BPF_LPM_TRIE+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=BPF_LPM_TRIE+path%3Atools&type=Code)
-### 9. BPF_PROG_ARRAY
+### 10. BPF_PROG_ARRAY
Syntax: ```BPF_PROG_ARRAY(name, size)```
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_PROG_ARRAY+path%3Atests&type=Code),
[assign fd](https://github.com/iovisor/bcc/blob/master/examples/networking/tunnel_monitor/monitor.py#L24-L26)
-### 10. BPF_DEVMAP
+### 11. BPF_DEVMAP
Syntax: ```BPF_DEVMAP(name, size)```
Examples in situ:
[search /examples](https://github.com/iovisor/bcc/search?q=BPF_DEVMAP+path%3Aexamples&type=Code),
-### 11. BPF_CPUMAP
+### 12. BPF_CPUMAP
Syntax: ```BPF_CPUMAP(name, size)```
Examples in situ:
[search /examples](https://github.com/iovisor/bcc/search?q=BPF_CPUMAP+path%3Aexamples&type=Code),
-### 12. BPF_XSKMAP
+### 13. BPF_XSKMAP
Syntax: ```BPF_XSKMAP(name, size)```
Examples in situ:
[search /examples](https://github.com/iovisor/bcc/search?q=BPF_XSKMAP+path%3Aexamples&type=Code),
-### 13. BPF_ARRAY_OF_MAPS
+### 14. BPF_ARRAY_OF_MAPS
Syntax: ```BPF_ARRAY_OF_MAPS(name, inner_map_name, size)```
BPF_ARRAY_OF_MAPS(maps_array, "ex1", 10);
```
-### 14. BPF_HASH_OF_MAPS
+### 15. BPF_HASH_OF_MAPS
Syntax: ```BPF_HASH_OF_MAPS(name, inner_map_name, size)```
BPF_HASH_OF_MAPS(maps_hash, "ex1", 10);
```
-### 15. BPF_STACK
+### 16. BPF_STACK
Syntax: ```BPF_STACK(name, leaf_type, max_entries[, flags])```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_STACK+path%3Atests&type=Code),
-### 16. BPF_QUEUE
+### 17. BPF_QUEUE
Syntax: ```BPF_QUEUE(name, leaf_type, max_entries[, flags])```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_QUEUE+path%3Atests&type=Code),
-### 17. map.lookup()
+### 18. map.lookup()
Syntax: ```*val map.lookup(&key)```
[search /examples](https://github.com/iovisor/bcc/search?q=lookup+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=lookup+path%3Atools&type=Code)
-### 18. map.lookup_or_try_init()
+### 19. map.lookup_or_try_init()
Syntax: ```*val map.lookup_or_try_init(&key, &zero)```
Note: The old map.lookup_or_init() may cause return from the function, so lookup_or_try_init() is recommended as it
does not have this side effect.
-### 19. map.delete()
+### 20. map.delete()
Syntax: ```map.delete(&key)```
[search /examples](https://github.com/iovisor/bcc/search?q=delete+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=delete+path%3Atools&type=Code)
-### 20. map.update()
+### 21. map.update()
Syntax: ```map.update(&key, &val)```
[search /examples](https://github.com/iovisor/bcc/search?q=update+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=update+path%3Atools&type=Code)
-### 21. map.insert()
+### 22. map.insert()
Syntax: ```map.insert(&key, &val)```
[search /examples](https://github.com/iovisor/bcc/search?q=insert+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=insert+path%3Atools&type=Code)
-### 22. map.increment()
+### 23. map.increment()
Syntax: ```map.increment(key[, increment_amount])```
[search /examples](https://github.com/iovisor/bcc/search?q=increment+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=increment+path%3Atools&type=Code)
-### 23. map.get_stackid()
+### 24. map.get_stackid()
Syntax: ```int map.get_stackid(void *ctx, u64 flags)```
[search /examples](https://github.com/iovisor/bcc/search?q=get_stackid+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=get_stackid+path%3Atools&type=Code)
-### 24. map.perf_read()
+### 25. map.perf_read()
Syntax: ```u64 map.perf_read(u32 cpu)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=perf_read+path%3Atests&type=Code)
-### 25. map.call()
+### 26. map.call()
Syntax: ```void map.call(void *ctx, int index)```
[search /examples](https://github.com/iovisor/bcc/search?l=C&q=call+path%3Aexamples&type=Code),
[search /tests](https://github.com/iovisor/bcc/search?l=C&q=call+path%3Atests&type=Code)
-### 26. map.redirect_map()
+### 27. map.redirect_map()
Syntax: ```int map.redirect_map(int index, int flags)```
Examples in situ:
[search /examples](https://github.com/iovisor/bcc/search?l=C&q=redirect_map+path%3Aexamples&type=Code),
-### 27. map.push()
+### 28. map.push()
Syntax: ```int map.push(&val, int flags)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=push+path%3Atests&type=Code),
-### 28. map.pop()
+### 29. map.pop()
Syntax: ```int map.pop(&val)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=pop+path%3Atests&type=Code),
-### 29. map.peek()
+### 30. map.peek()
Syntax: ```int map.peek(&val)```
#define BPF_HASH(...) \
BPF_HASHX(__VA_ARGS__, BPF_HASH4, BPF_HASH3, BPF_HASH2, BPF_HASH1)(__VA_ARGS__)
+#define BPF_PERCPU_HASH1(_name) \
+ BPF_TABLE("percpu_hash", u64, u64, _name, 10240)
+#define BPF_PERCPU_HASH2(_name, _key_type) \
+ BPF_TABLE("percpu_hash", _key_type, u64, _name, 10240)
+#define BPF_PERCPU_HASH3(_name, _key_type, _leaf_type) \
+ BPF_TABLE("percpu_hash", _key_type, _leaf_type, _name, 10240)
+#define BPF_PERCPU_HASH4(_name, _key_type, _leaf_type, _size) \
+ BPF_TABLE("percpu_hash", _key_type, _leaf_type, _name, _size)
+
+// helper for default-variable macro function
+#define BPF_PERCPU_HASHX(_1, _2, _3, _4, NAME, ...) NAME
+
+// Define a hash function, some arguments optional
+// BPF_PERCPU_HASH(name, key_type=u64, leaf_type=u64, size=10240)
+#define BPF_PERCPU_HASH(...) \
+ BPF_PERCPU_HASHX( \
+ __VA_ARGS__, BPF_PERCPU_HASH4, BPF_PERCPU_HASH3, BPF_PERCPU_HASH2, BPF_PERCPU_HASH1) \
+ (__VA_ARGS__)
+
#define BPF_ARRAY1(_name) \
BPF_TABLE("array", int, u64, _name, 10240)
#define BPF_ARRAY2(_name, _leaf_type) \