Use BPF_F_CURRENT_CPU in perf_submit / perf_read when possible
authorTeng Qin <qinteng@fb.com>
Tue, 23 May 2017 18:57:44 +0000 (11:57 -0700)
committerTeng Qin <qinteng@fb.com>
Wed, 24 May 2017 20:25:32 +0000 (13:25 -0700)
src/cc/export/helpers.h
src/cc/frontends/clang/CMakeLists.txt
src/cc/frontends/clang/b_frontend_action.cc
src/cc/frontends/clang/loader.cc
tests/python/test_perf_event.py

index 2229503bb6f70ec19b826066d4a4e3f303f85b41..b8a00b7c1991b18ed4eb5cbf138891d635a7974e 100644 (file)
@@ -65,6 +65,17 @@ BPF_TABLE(_table_type, _key_type, _leaf_type, _name, _max_entries); \
 __attribute__((section("maps/export"))) \
 struct _name##_table_t __##_name
 
+// Identifier for current CPU used in perf_submit and perf_read
+// Prefer BPF_F_CURRENT_CPU flag, falls back to call helper for older kernel
+// Can be overridden from BCC
+#ifndef CUR_CPU_IDENTIFIER
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
+#define CUR_CPU_IDENTIFIER BPF_F_CURRENT_CPU
+#else
+#define CUR_CPU_IDENTIFIER bpf_get_smp_processor_id()
+#endif
+#endif
+
 // Table for pushing custom events to userspace via ring buffer
 #define BPF_PERF_OUTPUT(_name) \
 struct _name##_table_t { \
index 7cd9178fc85216b2f0be4e8e3ad5ffa7c92cf199..9fc7f694e5cd83383288662a835c74dc2b27edf3 100644 (file)
@@ -2,4 +2,8 @@
 # Licensed under the Apache License, Version 2.0 (the "License")
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKERNEL_MODULES_DIR='\"${BCC_KERNEL_MODULES_DIR}\"'")
+if(DEFINED BCC_CUR_CPU_IDENTIFIER)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCUR_CPU_IDENTIFIER='\"${BCC_CUR_CPU_IDENTIFIER}\"'")
+endif()
+
 add_library(clang_frontend STATIC loader.cc b_frontend_action.cc tp_frontend_action.cc kbuild_helper.cc ../../common.cc)
index 293f374827c46451062fada6d38700987f802f61..39047e1f63a62d4d540d0ef3ebe1627837c6b3e5 100644 (file)
@@ -341,7 +341,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
           string args_other = rewriter_.getRewrittenText(expansionRange(SourceRange(Call->getArg(1)->getLocStart(),
                                                            Call->getArg(2)->getLocEnd())));
           txt = "bpf_perf_event_output(" + arg0 + ", bpf_pseudo_fd(1, " + fd + ")";
-          txt += ", bpf_get_smp_processor_id(), " + args_other + ")";
+          txt += ", CUR_CPU_IDENTIFIER, " + args_other + ")";
         } else if (memb_name == "perf_submit_skb") {
           string skb = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
           string skb_len = rewriter_.getRewrittenText(expansionRange(Call->getArg(1)->getSourceRange()));
index a1ccb834380cd25094995129834c542f30b24c71..0558a6d46e61b6a29bab109af2cc50afb2509176 100644 (file)
@@ -160,6 +160,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts, const st
     for (auto i = 0; i < ncflags; ++i)
       flags_cstr.push_back(cflags[i]);
   }
+#ifdef CUR_CPU_IDENTIFIER
+  string cur_cpu_flag = string("-DCUR_CPU_IDENTIFIER=") + CUR_CPU_IDENTIFIER;
+  flags_cstr.push_back(cur_cpu_flag.c_str());
+#endif
 
   // set up the error reporting class
   IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions());
index cefdc482f68ecc9d82035b8511c457a9b3294c1f..a7c8721eb55ae06128c7fd3274f49e003325a213 100755 (executable)
@@ -17,7 +17,7 @@ BPF_ARRAY(prev, u64, NUM_CPUS);
 BPF_HISTOGRAM(dist);
 int kprobe__sys_getuid(void *ctx) {
     u32 cpu = bpf_get_smp_processor_id();
-    u64 val = cnt1.perf_read(cpu);
+    u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER);
 
     if (((s64)val < 0) && ((s64)val > -256))
         return 0;
@@ -27,7 +27,7 @@ int kprobe__sys_getuid(void *ctx) {
 }
 int kretprobe__sys_getuid(void *ctx) {
     u32 cpu = bpf_get_smp_processor_id();
-    u64 val = cnt1.perf_read(cpu);
+    u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER);
 
     if (((s64)val < 0) && ((s64)val > -256))
         return 0;