diff --git a/docs/reference_guide.md b/docs/reference_guide.md index b5846fc6044a..f727fdcbfbe7 100644 --- a/docs/reference_guide.md +++ b/docs/reference_guide.md @@ -33,13 +33,15 @@ 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. map.lookup()](#7-maplookup) - - [8. map.lookup_or_init()](#8-maplookup_or_init) - - [9. map.delete()](#9-mapdelete) - - [10. map.update()](#10-mapupdate) - - [11. map.increment()](#11-mapincrement) - - [12. map.get_stackid()](#12-mapget_stackid) - - [13. map.perf_read()](#13-mapperf_read) + - [7. BPF_PERCPU_ARRAY](#7-bpf_percpu_array) + - [8. map.lookup()](#8-maplookup) + - [9. map.lookup_or_init()](#9-maplookup_or_init) + - [10. map.delete()](#10-mapdelete) + - [11. map.update()](#11-mapupdate) + - [12. map.insert()](#12-mapinsert) + - [13. map.increment()](#13-mapincrement) + - [14. map.get_stackid()](#14-mapget_stackid) + - [15. map.perf_read()](#15-mapperf_read) - [bcc Python](#bcc-python) - [Initialization](#initialization) @@ -505,7 +507,30 @@ 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. map.lookup() +### 7. BPF_PERCPU_ARRAY + +Syntax: ```BPF_PERCPU_ARRAY(name [, leaf_type [, size]])``` + +Creates NUM_CPU int-indexed arrays which are optimized for fastest lookup and update, named ```name```, with optional parameters. Each CPU will have a separate copy of this array. The copies are not kept synchronized in any way. + + +Defaults: ```BPF_PERCPU_ARRAY(name, leaf_type=u64, size=10240)``` + +For example: + +```C +BPF_PERCPU_ARRAY(counts, u64, 32); +``` + +This creates NUM_CPU arrays named ```counts``` where with 32 buckets and 64-bit integer values. + +Methods (covered later): map.lookup(), map.update(), map.increment(). Note that all array elements are pre-allocated with zero values and can not be deleted. + +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. map.lookup() Syntax: ```*val map.lookup(&key)``` @@ -515,7 +540,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) -### 8. map.lookup_or_init() +### 9. map.lookup_or_init() Syntax: ```*val map.lookup_or_init(&key, &zero)``` @@ -525,7 +550,7 @@ Examples in situ: [search /examples](https://github.com/iovisor/bcc/search?q=lookup_or_init+path%3Aexamples&type=Code), [search /tools](https://github.com/iovisor/bcc/search?q=lookup_or_init+path%3Atools&type=Code) -### 9. map.delete() +### 10. map.delete() Syntax: ```map.delete(&key)``` @@ -535,7 +560,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) -### 10. map.update() +### 11. map.update() Syntax: ```map.update(&key, &val)``` @@ -545,7 +570,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) -### 11. map.insert() +### 12. map.insert() Syntax: ```map.insert(&key, &val)``` @@ -554,7 +579,7 @@ Associate the value in the second argument to the key, only if there was no prev Examples in situ: [search /examples](https://github.com/iovisor/bcc/search?q=insert+path%3Aexamples&type=Code) -### 12. map.increment() +### 13. map.increment() Syntax: ```map.increment(key)``` @@ -564,7 +589,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) -### 13. map.get_stackid() +### 14. map.get_stackid() Syntax: ```int map.get_stackid(void *ctx, u64 flags)``` @@ -574,7 +599,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) -### 14. map.perf_read() +### 15. map.perf_read() Syntax: ```u64 map.perf_read(u32 cpu)``` diff --git a/src/cc/export/helpers.h b/src/cc/export/helpers.h index b8a00b7c1991..bbc393ab63e1 100644 --- a/src/cc/export/helpers.h +++ b/src/cc/export/helpers.h @@ -133,6 +133,23 @@ struct _name##_table_t _name #define BPF_ARRAY(...) \ BPF_ARRAYX(__VA_ARGS__, BPF_ARRAY3, BPF_ARRAY2, BPF_ARRAY1)(__VA_ARGS__) +#define BPF_PERCPU_ARRAY1(_name) \ + BPF_TABLE("percpu_array", int, u64, _name, 10240) +#define BPF_PERCPU_ARRAY2(_name, _leaf_type) \ + BPF_TABLE("percpu_array", int, _leaf_type, _name, 10240) +#define BPF_PERCPU_ARRAY3(_name, _leaf_type, _size) \ + BPF_TABLE("percpu_array", int, _leaf_type, _name, _size) + +// helper for default-variable macro function +#define BPF_PERCPU_ARRAYX(_1, _2, _3, NAME, ...) NAME + +// Define an array function (per CPU), some arguments optional +// BPF_PERCPU_ARRAY(name, leaf_type=u64, size=10240) +#define BPF_PERCPU_ARRAY(...) \ + BPF_PERCPU_ARRAYX( \ + __VA_ARGS__, BPF_PERCPU_ARRAY3, BPF_PERCPU_ARRAY2, BPF_PERCPU_ARRAY1) \ + (__VA_ARGS__) + #define BPF_HIST1(_name) \ BPF_TABLE("histogram", int, u64, _name, 64) #define BPF_HIST2(_name, _key_type) \ diff --git a/tests/python/test_percpu.py b/tests/python/test_percpu.py index daedbccff566..5ab36918f2f1 100755 --- a/tests/python/test_percpu.py +++ b/tests/python/test_percpu.py @@ -15,6 +15,14 @@ def setUp(self): except: raise unittest.SkipTest("PerCpu unsupported on this kernel") + def test_helper(self): + test_prog1 = """ + BPF_PERCPU_ARRAY(stub_default); + BPF_PERCPU_ARRAY(stub_type, u64); + BPF_PERCPU_ARRAY(stub_full, u64, 1024); + """ + BPF(text=test_prog1) + def test_u64(self): test_prog1 = """ BPF_TABLE("percpu_hash", u32, u64, stats, 1);