Merge "Revert "bpf: change how we detect device bpf support level""
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index d02ed87..3e8a1f7 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -37,6 +37,7 @@
 #include <vector>
 
 #include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 
 #define BPF_FS_PATH "/sys/fs/bpf/"
 
@@ -44,6 +45,7 @@
 #define BPF_LOAD_LOG_SZ 0x1ffff
 
 using android::base::StartsWith;
+using android::base::unique_fd;
 using std::ifstream;
 using std::ios;
 using std::string;
@@ -82,7 +84,7 @@
     vector<char> data;
     vector<char> rel_data;
 
-    int prog_fd; /* fd after loading */
+    unique_fd prog_fd; /* fd after loading */
 } codeSection;
 
 /* Common with the eBPF C program */
@@ -319,7 +321,7 @@
         }
 
         if (cs_temp.data.size() > 0) {
-            cs.push_back(cs_temp);
+            cs.push_back(std::move(cs_temp));
             ALOGD("Adding section %d to cs list\n", i);
         }
     }
@@ -380,8 +382,8 @@
     return 0;
 }
 
-static int createMaps(const char* elfPath, ifstream& elfFile, vector<int>& mapFds) {
-    int ret, fd;
+static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>& mapFds) {
+    int ret;
     vector<char> mdData;
     vector<struct bpf_map_def> md;
     vector<string> mapNames;
@@ -395,22 +397,21 @@
     ret = getMapNames(elfFile, mapNames);
     if (ret) return ret;
 
-    mapFds.resize(mapNames.size());
-
     for (int i = 0; i < (int)mapNames.size(); i++) {
+        unique_fd fd;
         // Format of pin location is /sys/fs/bpf/map_<filename>_<mapname>
         string mapPinLoc;
         bool reuse = false;
 
         mapPinLoc = string(BPF_FS_PATH) + "map_" + fname + "_" + string(mapNames[i]);
         if (access(mapPinLoc.c_str(), F_OK) == 0) {
-            fd = bpf_obj_get(mapPinLoc.c_str());
-            ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd);
+            fd.reset(bpf_obj_get(mapPinLoc.c_str()));
+            ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd.get());
             reuse = true;
         } else {
-            fd = bpf_create_map(md[i].type, mapNames[i].c_str(), md[i].key_size, md[i].value_size,
-                                md[i].max_entries, md[i].map_flags);
-            ALOGD("bpf_create_map name %s, ret: %d\n", mapNames[i].c_str(), fd);
+            fd.reset(bpf_create_map(md[i].type, mapNames[i].c_str(), md[i].key_size, md[i].value_size,
+                                    md[i].max_entries, md[i].map_flags));
+            ALOGD("bpf_create_map name %s, ret: %d\n", mapNames[i].c_str(), fd.get());
         }
 
         if (fd < 0) return fd;
@@ -421,7 +422,7 @@
             if (ret < 0) return ret;
         }
 
-        mapFds[i] = fd;
+        mapFds.push_back(std::move(fd));
     }
 
     return ret;
@@ -472,7 +473,7 @@
     insn->src_reg = BPF_PSEUDO_MAP_FD;
 }
 
-static void applyMapRelo(ifstream& elfFile, vector<int> mapFds, vector<codeSection>& cs) {
+static void applyMapRelo(ifstream& elfFile, vector<unique_fd> &mapFds, vector<codeSection>& cs) {
     vector<string> mapNames;
 
     int ret = getMapNames(elfFile, mapNames);
@@ -524,8 +525,8 @@
             fd = bpf_prog_load(cs[i].type, cs[i].name.c_str(), (struct bpf_insn*)cs[i].data.data(),
                                cs[i].data.size(), license.c_str(), kvers, 0,
                                log_buf.data(), log_buf.size());
-            ALOGD("New bpf core prog_load for %s (%s) returned: %d\n", elfPath, cs[i].name.c_str(),
-                  fd);
+            ALOGD("bpf_prog_load lib call for %s (%s) returned: %d (%s)\n", elfPath,
+                  cs[i].name.c_str(), fd, std::strerror(errno));
 
             if (fd <= 0)
                 ALOGE("bpf_prog_load: log_buf contents: %s\n", (char *)log_buf.data());
@@ -539,7 +540,7 @@
             if (ret < 0) return ret;
         }
 
-        cs[i].prog_fd = fd;
+        cs[i].prog_fd.reset(fd);
     }
 
     return 0;
@@ -548,7 +549,7 @@
 int loadProg(const char* elfPath) {
     vector<char> license;
     vector<codeSection> cs;
-    vector<int> mapFds;
+    vector<unique_fd> mapFds;
     int ret;
 
     ifstream elfFile(elfPath, ios::in | ios::binary);
@@ -578,7 +579,7 @@
     }
 
     for (int i = 0; i < (int)mapFds.size(); i++)
-        ALOGD("map_fd found at %d is %d in %s\n", i, mapFds[i], elfPath);
+        ALOGD("map_fd found at %d is %d in %s\n", i, mapFds[i].get(), elfPath);
 
     applyMapRelo(elfFile, mapFds, cs);
 
diff --git a/progs/Android.bp b/progs/Android.bp
new file mode 100644
index 0000000..37feafd
--- /dev/null
+++ b/progs/Android.bp
@@ -0,0 +1,20 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_headers {
+    name: "bpf_prog_headers",
+    export_include_dirs: ["include"],
+}
diff --git a/progs/include/bpf_helpers.h b/progs/include/bpf_helpers.h
index 3ab68af..e933021 100644
--- a/progs/include/bpf_helpers.h
+++ b/progs/include/bpf_helpers.h
@@ -75,19 +75,6 @@
 static unsigned long long (*bpf_get_current_pid_tgid)(void) = (void*) BPF_FUNC_get_current_pid_tgid;
 static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
 static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
-/* networking  */
-static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie;
-static uint32_t (*bpf_get_socket_uid)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_uid;
-static int (*bpf_skb_load_bytes)(struct __sk_buff* skb, int off, void* to,
-                                 int len) = (void*)BPF_FUNC_skb_load_bytes;
-
-static int (*bpf_skb_change_proto)(struct __sk_buff* skb, __be16 proto,
-                                   __u64 flags) = (void*)BPF_FUNC_skb_change_proto;
-static int (*bpf_l3_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
-                                  __u64 flags) = (void*)BPF_FUNC_l3_csum_replace;
-static int (*bpf_l4_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
-                                  __u64 flags) = (void*)BPF_FUNC_l4_csum_replace;
-static int (*bpf_redirect)(__u32 ifindex, __u64 flags) = (void*)BPF_FUNC_redirect;
 
 /*
  * Map structure to be used by Android eBPF C programs. The Android eBPF loader
diff --git a/progs/include/bpf_timeinstate.h b/progs/include/bpf_timeinstate.h
new file mode 100644
index 0000000..6cbc4e1
--- /dev/null
+++ b/progs/include/bpf_timeinstate.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+
+#define BPF_FS_PATH "/sys/fs/bpf/"
+
+// Number of frequencies for which a UID's times can be tracked in a single map entry. If some CPUs
+// have more than 32 freqs available, a single UID is tracked using 2 or more entries.
+#define FREQS_PER_ENTRY 32
+// Number of distinct CPU counts for which a UID's concurrent time stats can be tracked in a single
+// map entry. On systems with more than 8 CPUs, a single UID is tracked using 2 or more entries.
+#define CPUS_PER_ENTRY 8
+
+typedef struct {
+    uint32_t uid;
+    uint32_t bucket;
+} time_key_t;
+
+typedef struct {
+    uint64_t ar[FREQS_PER_ENTRY];
+} tis_val_t;
+
+typedef struct {
+    uint64_t active[CPUS_PER_ENTRY];
+    uint64_t policy[CPUS_PER_ENTRY];
+} concurrent_val_t;
+
+typedef struct {
+    uint32_t policy;
+    uint32_t freq;
+} freq_idx_key_t;