Skip to content

Commit

Permalink
Added helpers for BPF_PERCPU_HASH
Browse files Browse the repository at this point in the history
  • Loading branch information
L3n41c authored and yonghong-song committed Feb 25, 2021
1 parent 8e6f333 commit c8de00e
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 56 deletions.
122 changes: 76 additions & 46 deletions docs/reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,30 @@ This guide is incomplete. If something feels missing, check the bcc and kernel s
- [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)

Expand Down Expand Up @@ -980,7 +981,36 @@ Methods (covered later): map.perf_read().
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]])```

Expand Down Expand Up @@ -1008,7 +1038,7 @@ Examples in situ:
[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]]])`
Expand All @@ -1032,7 +1062,7 @@ Examples in situ:
[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)```

Expand All @@ -1047,7 +1077,7 @@ Examples in situ:
[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)```

Expand All @@ -1063,7 +1093,7 @@ Methods (covered later): map.redirect_map().
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)```

Expand All @@ -1079,7 +1109,7 @@ Methods (covered later): map.redirect_map().
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)```

Expand All @@ -1095,7 +1125,7 @@ Methods (covered later): map.redirect_map(). map.lookup()
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)```

Expand All @@ -1108,7 +1138,7 @@ BPF_TABLE("hash", int, int, ex2, 1024);
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)```

Expand All @@ -1121,7 +1151,7 @@ BPF_ARRAY(ex2, int, 1024);
BPF_HASH_OF_MAPS(maps_hash, "ex1", 10);
```
### 15. BPF_STACK
### 16. BPF_STACK
Syntax: ```BPF_STACK(name, leaf_type, max_entries[, flags])```

Expand All @@ -1141,7 +1171,7 @@ Methods (covered later): map.push(), map.pop(), map.peek().
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])```

Expand All @@ -1161,7 +1191,7 @@ Methods (covered later): map.push(), map.pop(), map.peek().
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)```

Expand All @@ -1171,7 +1201,7 @@ Examples in situ:
[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)```

Expand All @@ -1184,7 +1214,7 @@ Examples in situ:
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)```

Expand All @@ -1194,7 +1224,7 @@ Examples in situ:
[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)```

Expand All @@ -1204,7 +1234,7 @@ Examples in situ:
[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)```

Expand All @@ -1214,7 +1244,7 @@ Examples in situ:
[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])```

Expand All @@ -1224,7 +1254,7 @@ Examples in situ:
[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)```

Expand All @@ -1234,7 +1264,7 @@ Examples in situ:
[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)```

Expand All @@ -1243,7 +1273,7 @@ This returns the hardware performance counter as configured in [5. BPF_PERF_ARRA
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)```

Expand Down Expand Up @@ -1282,7 +1312,7 @@ Examples in situ:
[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)```

Expand Down Expand Up @@ -1320,7 +1350,7 @@ b.attach_xdp("eth1", out_fn, 0)
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)```

Expand All @@ -1331,7 +1361,7 @@ Returns 0 on success, negative error on failure.
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)```

Expand All @@ -1342,7 +1372,7 @@ Returns 0 on success, negative error on failure.
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)```

Expand Down
2 changes: 1 addition & 1 deletion examples/networking/xdp/xdp_macswap_count.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def usage():
#include <linux/ipv6.h>
BPF_TABLE("percpu_array", uint32_t, long, dropcnt, 256);
BPF_PERCPU_ARRAY(dropcnt, long, 256);
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
struct iphdr *iph = data + nh_off;
Expand Down
19 changes: 19 additions & 0 deletions src/cc/export/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,25 @@ struct _name##_table_t _name = { .max_entries = (_max_entries) }
#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) \
Expand Down
4 changes: 2 additions & 2 deletions tests/cc/test_array_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ TEST_CASE("test array table", "[array_table]") {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
TEST_CASE("percpu array table", "[percpu_array_table]") {
const std::string BPF_PROGRAM = R"(
BPF_TABLE("percpu_hash", int, u64, myhash, 128);
BPF_TABLE("percpu_array", int, u64, myarray, 64);
BPF_PERCPU_HASH(myhash, int, u64, 128);
BPF_PERCPU_ARRAY(myarray, u64, 64);
)";

ebpf::BPF bpf;
Expand Down
2 changes: 1 addition & 1 deletion tests/cc/test_bpf_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ TEST_CASE("test bpf table", "[bpf_table]") {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
TEST_CASE("test bpf percpu tables", "[bpf_percpu_table]") {
const std::string BPF_PROGRAM = R"(
BPF_TABLE("percpu_hash", int, u64, myhash, 128);
BPF_PERCPU_HASH(myhash, int, u64, 128);
)";

ebpf::BPF bpf;
Expand Down
4 changes: 2 additions & 2 deletions tests/cc/test_hash_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ TEST_CASE("test hash table", "[hash_table]") {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
TEST_CASE("percpu hash table", "[percpu_hash_table]") {
const std::string BPF_PROGRAM = R"(
BPF_TABLE("percpu_hash", int, u64, myhash, 128);
BPF_TABLE("percpu_array", int, u64, myarray, 64);
BPF_PERCPU_HASH(myhash, int, u64, 128);
BPF_PERCPU_ARRAY(myarray, u64, 64);
)";

ebpf::BPF bpf;
Expand Down
8 changes: 4 additions & 4 deletions tests/python/test_percpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class TestPercpu(unittest.TestCase):

def setUp(self):
try:
b = BPF(text='BPF_TABLE("percpu_array", u32, u32, stub, 1);')
b = BPF(text='BPF_PERCPU_ARRAY(stub, u32, 1);')
except:
raise unittest.SkipTest("PerCpu unsupported on this kernel")

Expand All @@ -25,7 +25,7 @@ def test_helper(self):

def test_u64(self):
test_prog1 = """
BPF_TABLE("percpu_hash", u32, u64, stats, 1);
BPF_PERCPU_HASH(stats, u32, u64, 1);
int hello_world(void *ctx) {
u32 key=0;
u64 value = 0, *val;
Expand Down Expand Up @@ -57,7 +57,7 @@ def test_u64(self):

def test_u32(self):
test_prog1 = """
BPF_TABLE("percpu_array", u32, u32, stats, 1);
BPF_PERCPU_ARRAY(stats, u32, 1);
int hello_world(void *ctx) {
u32 key=0;
u32 value = 0, *val;
Expand Down Expand Up @@ -93,7 +93,7 @@ def test_struct_custom_func(self):
u32 c1;
u32 c2;
} counter;
BPF_TABLE("percpu_hash", u32, counter, stats, 1);
BPF_PERCPU_HASH(stats, u32, counter, 1);
int hello_world(void *ctx) {
u32 key=0;
counter value = {0,0}, *val;
Expand Down

0 comments on commit c8de00e

Please sign in to comment.