Loading cmds/atrace/README.md 0 → 100644 +48 −0 Original line number Diff line number Diff line # Atrace categories The atrace command (and the perfetto configuration) allow listing **categories** to select subsets of events to be traced. Each category can include some userspace events and some ftrace events. ## Vendor categories It's possible to extend exiting categories (or to define new categories) from the /vendor partition in order to add hardware specific ftrace events. Since android 14, if the file `/vendor/etc/atrace/atrace_categories.txt`, atrace and perfetto will consider the categories and ftrace events listed there. The file contains a list of categories, and for each category (on the following lines, indented with one or more spaces of time), a list of ftrace events that should be enabled when the category is enabled. Each ftrace event should be a subdirectory in `/sys/kernel/tracing/events/` and should be of the form `group/event`. Listing a whole group is not supported, each event needs to be listed explicitly. It is not an error if an ftrace event is listed in the file, but not present on the tracing file system. Example: ``` gfx mali/gpu_power_state mali/mali_pm_status thermal_tj thermal_exynos/thermal_cpu_pressure thermal_exynos/thermal_exynos_arm_update ``` The file lists two categories (`gfx` and `thermal_tj`). When the `gfx` category is enabled, atrace (or perfetto) will enable `/sys/kernel/tracing/events/mali/gpu_power_state` and `/sys/kernel/tracing/events/mali/mali_pm_status`. When the `thermal_tj` category is enabled, atrace (or perfetto) will enable `/sys/kernel/tracing/events/thermal_exynos/thermal_cpu_pressure` and `/sys/kernel/tracing/events/thermal_exynos/thermal_exynos_arm_update`. Since android 14, if the file `/vendor/etc/atrace/atrace_categories.txt` exists on the file system, perfetto and atrace do not query the android.hardware.atrace HAL (which is deprecated). cmds/atrace/atrace.cpp +104 −28 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <android-base/file.h> #include <android-base/macros.h> #include <android-base/properties.h> #include <android-base/strings.h> #include <android-base/stringprintf.h> using namespace android; Loading @@ -73,6 +74,8 @@ const char* k_coreServiceCategory = "core_services"; const char* k_pdxServiceCategory = "pdx"; const char* k_coreServicesProp = "ro.atrace.core.services"; const char* kVendorCategoriesPath = "/vendor/etc/atrace/atrace_categories.txt"; typedef enum { OPT, REQ } requiredness; struct TracingCategory { Loading Loading @@ -255,7 +258,20 @@ static const TracingCategory k_categories[] = { } }, }; struct TracingVendorCategory { // A category in the vendor categories file. struct TracingVendorFileCategory { // The name identifying the category. std::string name; // If the category is enabled through command. bool enabled = false; // Paths to the ftrace enable files (relative to g_traceFolder). std::vector<std::string> ftrace_enable_paths; }; // A category in the vendor HIDL HAL. struct TracingVendorHalCategory { // The name identifying the category. std::string name; Loading @@ -265,11 +281,8 @@ struct TracingVendorCategory { // If the category is enabled through command. bool enabled; TracingVendorCategory(string &&name, string &&description, bool enabled) : name(std::move(name)) , description(std::move(description)) , enabled(enabled) {} TracingVendorHalCategory(string&& name, string&& description, bool enabled) : name(std::move(name)), description(std::move(description)), enabled(enabled) {} }; /* Command line options */ Loading @@ -289,8 +302,9 @@ static bool g_tracePdx = false; static bool g_traceAborted = false; static bool g_categoryEnables[arraysize(k_categories)] = {}; static std::string g_traceFolder; static std::vector<TracingVendorFileCategory> g_vendorFileCategories; static sp<IAtraceDevice> g_atraceHal; static std::vector<TracingVendorCategory> g_vendorCategories; static std::vector<TracingVendorHalCategory> g_vendorHalCategories; /* Sys file paths */ static const char* k_traceClockPath = Loading Loading @@ -647,6 +661,13 @@ static bool disableKernelTraceEvents() { } } } for (const TracingVendorFileCategory& c : g_vendorFileCategories) { for (const std::string& path : c.ftrace_enable_paths) { if (fileIsWritable(path.c_str())) { ok &= setKernelOptionEnable(path.c_str(), false); } } } return ok; } Loading Loading @@ -726,7 +747,13 @@ static bool setKernelTraceFuncs(const char* funcs) static bool setCategoryEnable(const char* name) { bool vendor_found = false; for (auto &c : g_vendorCategories) { for (auto& c : g_vendorFileCategories) { if (strcmp(name, c.name.c_str()) == 0) { c.enabled = true; vendor_found = true; } } for (auto& c : g_vendorHalCategories) { if (strcmp(name, c.name.c_str()) == 0) { c.enabled = true; vendor_found = true; Loading Loading @@ -872,6 +899,16 @@ static bool setUpKernelTracing() } } for (const TracingVendorFileCategory& c : g_vendorFileCategories) { if (c.enabled) { for (const std::string& path : c.ftrace_enable_paths) { if (fileIsWritable(path.c_str())) { ok &= setKernelOptionEnable(path.c_str(), true); } } } } return ok; } Loading Loading @@ -1057,7 +1094,10 @@ static void listSupportedCategories() printf(" %10s - %s\n", c.name, c.longname); } } for (const auto &c : g_vendorCategories) { for (const auto& c : g_vendorFileCategories) { printf(" %10s - (VENDOR)\n", c.name.c_str()); } for (const auto& c : g_vendorHalCategories) { printf(" %10s - %s (HAL)\n", c.name.c_str(), c.description.c_str()); } } Loading Loading @@ -1116,8 +1156,38 @@ bool findTraceFiles() return true; } void initVendorCategories() { void initVendorCategoriesFromFile() { std::ifstream is(kVendorCategoriesPath); for (std::string line; std::getline(is, line);) { if (line.empty()) { continue; } if (android::base::StartsWith(line, ' ') || android::base::StartsWith(line, '\t')) { if (g_vendorFileCategories.empty()) { fprintf(stderr, "Malformed vendor categories file\n"); exit(1); return; } std::string_view path = std::string_view(line).substr(1); while (android::base::StartsWith(path, ' ') || android::base::StartsWith(path, '\t')) { path.remove_prefix(1); } if (path.empty()) { continue; } std::string enable_path = "events/"; enable_path += path; enable_path += "/enable"; g_vendorFileCategories.back().ftrace_enable_paths.push_back(std::move(enable_path)); } else { TracingVendorFileCategory cat; cat.name = line; g_vendorFileCategories.push_back(std::move(cat)); } } } void initVendorCategoriesFromHal() { g_atraceHal = IAtraceDevice::getService(); if (g_atraceHal == nullptr) { Loading @@ -1125,11 +1195,10 @@ void initVendorCategories() return; } Return<void> ret = g_atraceHal->listCategories( [](const auto& list) { g_vendorCategories.reserve(list.size()); Return<void> ret = g_atraceHal->listCategories([](const auto& list) { g_vendorHalCategories.reserve(list.size()); for (const auto& category : list) { g_vendorCategories.emplace_back(category.name, category.description, false); g_vendorHalCategories.emplace_back(category.name, category.description, false); } }); if (!ret.isOk()) { Loading @@ -1137,15 +1206,23 @@ void initVendorCategories() } } static bool setUpVendorTracing() { void initVendorCategories() { // If kVendorCategoriesPath exists on the filesystem, do not use the HAL. if (access(kVendorCategoriesPath, F_OK) != -1) { initVendorCategoriesFromFile(); } else { initVendorCategoriesFromHal(); } } static bool setUpVendorTracingWithHal() { if (g_atraceHal == nullptr) { // No atrace HAL return true; } std::vector<hidl_string> categories; for (const auto &c : g_vendorCategories) { for (const auto& c : g_vendorHalCategories) { if (c.enabled) { categories.emplace_back(c.name); } Loading @@ -1166,15 +1243,14 @@ static bool setUpVendorTracing() return true; } static bool cleanUpVendorTracing() { static bool cleanUpVendorTracingWithHal() { if (g_atraceHal == nullptr) { // No atrace HAL return true; } if (!g_vendorCategories.size()) { // No vendor categories if (!g_vendorHalCategories.size()) { // No vendor HAL categories return true; } Loading Loading @@ -1328,7 +1404,7 @@ int main(int argc, char **argv) if (ok && traceStart && !onlyUserspace) { ok &= setUpKernelTracing(); ok &= setUpVendorTracing(); ok &= setUpVendorTracingWithHal(); ok &= startTrace(); } Loading Loading @@ -1399,7 +1475,7 @@ int main(int argc, char **argv) if (traceStop) { cleanUpUserspaceTracing(); if (!onlyUserspace) { cleanUpVendorTracing(); cleanUpVendorTracingWithHal(); cleanUpKernelTracing(); } } Loading include/android/performance_hint.h +17 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,23 @@ int APerformanceHint_reportActualWorkDuration( void APerformanceHint_closeSession( APerformanceHintSession* session) __INTRODUCED_IN(__ANDROID_API_T__); /** * Set a list of threads to the performance hint session. This operation will replace * the current list of threads with the given list of threads. * * @param session The performance hint session instance for the threads. * @param threadIds The list of threads to be associated with this session. They must be part of * this app's thread group. * @param size the size of the list of threadIds. * @return 0 on success. * EINVAL if the list of thread ids is empty or if any of the thread ids is not part of the thread group. * EPIPE if communication with the system service has failed. */ int APerformanceHint_setThreads( APerformanceHintSession* session, const int32_t* threadIds, size_t size) __INTRODUCED_IN(__ANDROID_API_U__); __END_DECLS #endif // ANDROID_NATIVE_PERFORMANCE_HINT_H include/private/performance_hint_private.h +6 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,12 @@ enum SessionHint { */ int APerformanceHint_sendHint(void* session, int hint); /** * Return the list of thread ids, this API should only be used for testing only. */ int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds, size_t* const size); __END_DECLS #endif // ANDROID_PRIVATE_NATIVE_PERFORMANCE_HINT_PRIVATE_H libs/binder/Parcel.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1475,7 +1475,7 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { #ifdef BINDER_WITH_KERNEL_IPC flat_binder_object obj; obj.hdr.type = BINDER_TYPE_FD; obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj.flags = 0; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.handle = fd; obj.cookie = takeOwnership ? 1 : 0; Loading Loading
cmds/atrace/README.md 0 → 100644 +48 −0 Original line number Diff line number Diff line # Atrace categories The atrace command (and the perfetto configuration) allow listing **categories** to select subsets of events to be traced. Each category can include some userspace events and some ftrace events. ## Vendor categories It's possible to extend exiting categories (or to define new categories) from the /vendor partition in order to add hardware specific ftrace events. Since android 14, if the file `/vendor/etc/atrace/atrace_categories.txt`, atrace and perfetto will consider the categories and ftrace events listed there. The file contains a list of categories, and for each category (on the following lines, indented with one or more spaces of time), a list of ftrace events that should be enabled when the category is enabled. Each ftrace event should be a subdirectory in `/sys/kernel/tracing/events/` and should be of the form `group/event`. Listing a whole group is not supported, each event needs to be listed explicitly. It is not an error if an ftrace event is listed in the file, but not present on the tracing file system. Example: ``` gfx mali/gpu_power_state mali/mali_pm_status thermal_tj thermal_exynos/thermal_cpu_pressure thermal_exynos/thermal_exynos_arm_update ``` The file lists two categories (`gfx` and `thermal_tj`). When the `gfx` category is enabled, atrace (or perfetto) will enable `/sys/kernel/tracing/events/mali/gpu_power_state` and `/sys/kernel/tracing/events/mali/mali_pm_status`. When the `thermal_tj` category is enabled, atrace (or perfetto) will enable `/sys/kernel/tracing/events/thermal_exynos/thermal_cpu_pressure` and `/sys/kernel/tracing/events/thermal_exynos/thermal_exynos_arm_update`. Since android 14, if the file `/vendor/etc/atrace/atrace_categories.txt` exists on the file system, perfetto and atrace do not query the android.hardware.atrace HAL (which is deprecated).
cmds/atrace/atrace.cpp +104 −28 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <android-base/file.h> #include <android-base/macros.h> #include <android-base/properties.h> #include <android-base/strings.h> #include <android-base/stringprintf.h> using namespace android; Loading @@ -73,6 +74,8 @@ const char* k_coreServiceCategory = "core_services"; const char* k_pdxServiceCategory = "pdx"; const char* k_coreServicesProp = "ro.atrace.core.services"; const char* kVendorCategoriesPath = "/vendor/etc/atrace/atrace_categories.txt"; typedef enum { OPT, REQ } requiredness; struct TracingCategory { Loading Loading @@ -255,7 +258,20 @@ static const TracingCategory k_categories[] = { } }, }; struct TracingVendorCategory { // A category in the vendor categories file. struct TracingVendorFileCategory { // The name identifying the category. std::string name; // If the category is enabled through command. bool enabled = false; // Paths to the ftrace enable files (relative to g_traceFolder). std::vector<std::string> ftrace_enable_paths; }; // A category in the vendor HIDL HAL. struct TracingVendorHalCategory { // The name identifying the category. std::string name; Loading @@ -265,11 +281,8 @@ struct TracingVendorCategory { // If the category is enabled through command. bool enabled; TracingVendorCategory(string &&name, string &&description, bool enabled) : name(std::move(name)) , description(std::move(description)) , enabled(enabled) {} TracingVendorHalCategory(string&& name, string&& description, bool enabled) : name(std::move(name)), description(std::move(description)), enabled(enabled) {} }; /* Command line options */ Loading @@ -289,8 +302,9 @@ static bool g_tracePdx = false; static bool g_traceAborted = false; static bool g_categoryEnables[arraysize(k_categories)] = {}; static std::string g_traceFolder; static std::vector<TracingVendorFileCategory> g_vendorFileCategories; static sp<IAtraceDevice> g_atraceHal; static std::vector<TracingVendorCategory> g_vendorCategories; static std::vector<TracingVendorHalCategory> g_vendorHalCategories; /* Sys file paths */ static const char* k_traceClockPath = Loading Loading @@ -647,6 +661,13 @@ static bool disableKernelTraceEvents() { } } } for (const TracingVendorFileCategory& c : g_vendorFileCategories) { for (const std::string& path : c.ftrace_enable_paths) { if (fileIsWritable(path.c_str())) { ok &= setKernelOptionEnable(path.c_str(), false); } } } return ok; } Loading Loading @@ -726,7 +747,13 @@ static bool setKernelTraceFuncs(const char* funcs) static bool setCategoryEnable(const char* name) { bool vendor_found = false; for (auto &c : g_vendorCategories) { for (auto& c : g_vendorFileCategories) { if (strcmp(name, c.name.c_str()) == 0) { c.enabled = true; vendor_found = true; } } for (auto& c : g_vendorHalCategories) { if (strcmp(name, c.name.c_str()) == 0) { c.enabled = true; vendor_found = true; Loading Loading @@ -872,6 +899,16 @@ static bool setUpKernelTracing() } } for (const TracingVendorFileCategory& c : g_vendorFileCategories) { if (c.enabled) { for (const std::string& path : c.ftrace_enable_paths) { if (fileIsWritable(path.c_str())) { ok &= setKernelOptionEnable(path.c_str(), true); } } } } return ok; } Loading Loading @@ -1057,7 +1094,10 @@ static void listSupportedCategories() printf(" %10s - %s\n", c.name, c.longname); } } for (const auto &c : g_vendorCategories) { for (const auto& c : g_vendorFileCategories) { printf(" %10s - (VENDOR)\n", c.name.c_str()); } for (const auto& c : g_vendorHalCategories) { printf(" %10s - %s (HAL)\n", c.name.c_str(), c.description.c_str()); } } Loading Loading @@ -1116,8 +1156,38 @@ bool findTraceFiles() return true; } void initVendorCategories() { void initVendorCategoriesFromFile() { std::ifstream is(kVendorCategoriesPath); for (std::string line; std::getline(is, line);) { if (line.empty()) { continue; } if (android::base::StartsWith(line, ' ') || android::base::StartsWith(line, '\t')) { if (g_vendorFileCategories.empty()) { fprintf(stderr, "Malformed vendor categories file\n"); exit(1); return; } std::string_view path = std::string_view(line).substr(1); while (android::base::StartsWith(path, ' ') || android::base::StartsWith(path, '\t')) { path.remove_prefix(1); } if (path.empty()) { continue; } std::string enable_path = "events/"; enable_path += path; enable_path += "/enable"; g_vendorFileCategories.back().ftrace_enable_paths.push_back(std::move(enable_path)); } else { TracingVendorFileCategory cat; cat.name = line; g_vendorFileCategories.push_back(std::move(cat)); } } } void initVendorCategoriesFromHal() { g_atraceHal = IAtraceDevice::getService(); if (g_atraceHal == nullptr) { Loading @@ -1125,11 +1195,10 @@ void initVendorCategories() return; } Return<void> ret = g_atraceHal->listCategories( [](const auto& list) { g_vendorCategories.reserve(list.size()); Return<void> ret = g_atraceHal->listCategories([](const auto& list) { g_vendorHalCategories.reserve(list.size()); for (const auto& category : list) { g_vendorCategories.emplace_back(category.name, category.description, false); g_vendorHalCategories.emplace_back(category.name, category.description, false); } }); if (!ret.isOk()) { Loading @@ -1137,15 +1206,23 @@ void initVendorCategories() } } static bool setUpVendorTracing() { void initVendorCategories() { // If kVendorCategoriesPath exists on the filesystem, do not use the HAL. if (access(kVendorCategoriesPath, F_OK) != -1) { initVendorCategoriesFromFile(); } else { initVendorCategoriesFromHal(); } } static bool setUpVendorTracingWithHal() { if (g_atraceHal == nullptr) { // No atrace HAL return true; } std::vector<hidl_string> categories; for (const auto &c : g_vendorCategories) { for (const auto& c : g_vendorHalCategories) { if (c.enabled) { categories.emplace_back(c.name); } Loading @@ -1166,15 +1243,14 @@ static bool setUpVendorTracing() return true; } static bool cleanUpVendorTracing() { static bool cleanUpVendorTracingWithHal() { if (g_atraceHal == nullptr) { // No atrace HAL return true; } if (!g_vendorCategories.size()) { // No vendor categories if (!g_vendorHalCategories.size()) { // No vendor HAL categories return true; } Loading Loading @@ -1328,7 +1404,7 @@ int main(int argc, char **argv) if (ok && traceStart && !onlyUserspace) { ok &= setUpKernelTracing(); ok &= setUpVendorTracing(); ok &= setUpVendorTracingWithHal(); ok &= startTrace(); } Loading Loading @@ -1399,7 +1475,7 @@ int main(int argc, char **argv) if (traceStop) { cleanUpUserspaceTracing(); if (!onlyUserspace) { cleanUpVendorTracing(); cleanUpVendorTracingWithHal(); cleanUpKernelTracing(); } } Loading
include/android/performance_hint.h +17 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,23 @@ int APerformanceHint_reportActualWorkDuration( void APerformanceHint_closeSession( APerformanceHintSession* session) __INTRODUCED_IN(__ANDROID_API_T__); /** * Set a list of threads to the performance hint session. This operation will replace * the current list of threads with the given list of threads. * * @param session The performance hint session instance for the threads. * @param threadIds The list of threads to be associated with this session. They must be part of * this app's thread group. * @param size the size of the list of threadIds. * @return 0 on success. * EINVAL if the list of thread ids is empty or if any of the thread ids is not part of the thread group. * EPIPE if communication with the system service has failed. */ int APerformanceHint_setThreads( APerformanceHintSession* session, const int32_t* threadIds, size_t size) __INTRODUCED_IN(__ANDROID_API_U__); __END_DECLS #endif // ANDROID_NATIVE_PERFORMANCE_HINT_H
include/private/performance_hint_private.h +6 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,12 @@ enum SessionHint { */ int APerformanceHint_sendHint(void* session, int hint); /** * Return the list of thread ids, this API should only be used for testing only. */ int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds, size_t* const size); __END_DECLS #endif // ANDROID_PRIVATE_NATIVE_PERFORMANCE_HINT_PRIVATE_H
libs/binder/Parcel.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1475,7 +1475,7 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { #ifdef BINDER_WITH_KERNEL_IPC flat_binder_object obj; obj.hdr.type = BINDER_TYPE_FD; obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj.flags = 0; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.handle = fd; obj.cookie = takeOwnership ? 1 : 0; Loading