event_type.cpp revision 04d08a35c5e1cabdf6eb7397536a790b0ff44459
167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui/* 267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Copyright (C) 2015 The Android Open Source Project 367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * you may not use this file except in compliance with the License. 667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * You may obtain a copy of the License at 767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * http://www.apache.org/licenses/LICENSE-2.0 967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 1067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Unless required by applicable law or agreed to in writing, software 1167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * distributed under the License is distributed on an "AS IS" BASIS, 1267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * See the License for the specific language governing permissions and 1467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * limitations under the License. 1567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui */ 1667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_type.h" 1867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <unistd.h> 20f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui#include <algorithm> 2167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <string> 2267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <vector> 239759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui 24f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui#include <base/file.h> 259759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui#include <base/logging.h> 269759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui 2767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_attr.h" 2867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_fd.h" 29f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui#include "utils.h" 3067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 3167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#define EVENT_TYPE_TABLE_ENTRY(name, type, config) \ 3267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui { name, type, config } \ 3367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui , 3467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 35f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cuistatic const std::vector<EventType> static_event_type_array = { 3667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_type_table.h" 3767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui}; 3867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 39f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cuistatic const std::vector<EventType> GetTracepointEventTypes() { 40f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<EventType> result; 41f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui const std::string tracepoint_dirname = "/sys/kernel/debug/tracing/events"; 42f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<std::string> system_dirs; 43f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui GetEntriesInDir(tracepoint_dirname, nullptr, &system_dirs); 44f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& system_name : system_dirs) { 45f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string system_path = tracepoint_dirname + "/" + system_name; 46f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<std::string> event_dirs; 47f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui GetEntriesInDir(system_path, nullptr, &event_dirs); 48f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& event_name : event_dirs) { 49f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string id_path = system_path + "/" + event_name + "/id"; 50f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string id_content; 51f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (!android::base::ReadFileToString(id_path, &id_content)) { 52f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui continue; 53f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 54f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui char* endptr; 55f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui uint64_t id = strtoull(id_content.c_str(), &endptr, 10); 56f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (endptr == id_content.c_str()) { 57f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui LOG(DEBUG) << "unexpected id '" << id_content << "' in " << id_path; 58f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui continue; 59f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 60f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui result.push_back(EventType(system_name + ":" + event_name, PERF_TYPE_TRACEPOINT, id)); 61f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 62f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 63f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::sort(result.begin(), result.end(), 64f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui [](const EventType& type1, const EventType& type2) { return type1.name < type2.name; }); 65f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui return result; 66f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui} 67f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui 68d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cuiconst std::vector<EventType>& GetAllEventTypes() { 69f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui static std::vector<EventType> event_type_array; 70f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (event_type_array.empty()) { 71f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui event_type_array.insert(event_type_array.end(), static_event_type_array.begin(), 72f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui static_event_type_array.end()); 73f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui const std::vector<EventType> tracepoint_array = GetTracepointEventTypes(); 74f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui event_type_array.insert(event_type_array.end(), tracepoint_array.begin(), 75f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui tracepoint_array.end()); 76f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 7767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui return event_type_array; 7867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 7967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 80d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cuiconst EventType* FindEventTypeByConfig(uint32_t type, uint64_t config) { 81d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (auto& event_type : GetAllEventTypes()) { 82d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type.type == type && event_type.config == config) { 83d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return &event_type; 84d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 85d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 86d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return nullptr; 87d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui} 88d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui 899fd3cc1048a3d0338df4a48760dfd655560992a1Yabin Cuiconst EventType* FindEventTypeByName(const std::string& name) { 909759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui const EventType* result = nullptr; 91f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& event_type : GetAllEventTypes()) { 9267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui if (event_type.name == name) { 939759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui result = &event_type; 949759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui break; 9567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 9667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 979759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui if (result == nullptr) { 989759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui LOG(ERROR) << "Unknown event_type '" << name 999759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui << "', try `simpleperf list` to list all possible event type names"; 1009759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui return nullptr; 1019759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui } 1029759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui return result; 10367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 10467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1059fd3cc1048a3d0338df4a48760dfd655560992a1Yabin Cuistd::unique_ptr<EventTypeAndModifier> ParseEventType(const std::string& event_type_str) { 106d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui static std::string modifier_characters = "ukhGHp"; 107d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui std::unique_ptr<EventTypeAndModifier> event_type_modifier(new EventTypeAndModifier); 1085872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_modifier->name = event_type_str; 1095872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui std::string event_type_name = event_type_str; 110d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui std::string modifier; 111d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui size_t comm_pos = event_type_str.rfind(':'); 112d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (comm_pos != std::string::npos) { 113d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui bool match_modifier = true; 114d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (size_t i = comm_pos + 1; i < event_type_str.size(); ++i) { 115d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui char c = event_type_str[i]; 116d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (c != ' ' && modifier_characters.find(c) == std::string::npos) { 117d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui match_modifier = false; 118d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 119d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 120d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 121d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (match_modifier) { 1225872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_name = event_type_str.substr(0, comm_pos); 123d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui modifier = event_type_str.substr(comm_pos + 1); 12467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 12567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 1265872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui const EventType* event_type = FindEventTypeByName(event_type_name); 127d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type == nullptr) { 128d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui // Try if the modifier belongs to the event type name, like some tracepoint events. 129d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (!modifier.empty()) { 1305872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_name = event_type_str; 131d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui modifier.clear(); 1325872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type = FindEventTypeByName(event_type_name); 133d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 134d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type == nullptr) { 135d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return nullptr; 136d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 137d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 138d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->event_type = *event_type; 139d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (modifier.find_first_of("ukh") != std::string::npos) { 140d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_user = true; 141d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_kernel = true; 142d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_hv = true; 143d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 144d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (modifier.find_first_of("GH") != std::string::npos) { 145d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_guest = true; 146d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_host = true; 147d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 148d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui 149d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (auto& c : modifier) { 150d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui switch (c) { 151d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'u': 152d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_user = false; 153d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 154d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'k': 155d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_kernel = false; 156d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 157d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'h': 158d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_hv = false; 159d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 160d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'G': 161d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_guest = false; 162d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 163d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'H': 164d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_host = false; 165d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 166d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'p': 167d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->precise_ip++; 168d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 169d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case ' ': 170d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 171d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui default: 172d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui LOG(ERROR) << "Unknown event type modifier '" << c << "'"; 173d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 174d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 17504d08a35c5e1cabdf6eb7397536a790b0ff44459Yabin Cui event_type_modifier->modifier = modifier; 176d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return event_type_modifier; 17767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 178