Added helpers for BPF_PERCPU_ARRAY (#1230)
authorRomain <romain-intel@users.noreply.github.com>
Thu, 29 Jun 2017 19:00:31 +0000 (12:00 -0700)
committerSasha Goldshtein <goldshtn@gmail.com>
Thu, 29 Jun 2017 19:00:31 +0000 (22:00 +0300)
docs/reference_guide.md
src/cc/export/helpers.h
tests/python/test_percpu.py

index b5846fc..f727fdc 100644 (file)
@@ -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)```
 
index b8a00b7..bbc393a 100644 (file)
@@ -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) \
index daedbcc..5ab3691 100755 (executable)
@@ -15,6 +15,14 @@ class TestPercpu(unittest.TestCase):
         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);