Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea826794 authored by Carmen Jackson's avatar Carmen Jackson
Browse files

Set the atrace clock to the best available value: boot, mono, or global.

This reverts commit dc340974.
"Revert "Set the atrace clock to boot when possible and mono otherwise.""

...and includes a fix for devices that break with that change. Write will
fail with an Invalid Argument exception if we programmatically write a
value to the trace_file that doesn't exist in the file. So, we'll check
for both potential values we might set. If neither of them exist, fall
back to setting to 'global', which should be safe since we were doing it
before without checking.

Bug: 32379831
Test: cts-tradefed run singleCommand cts-dev --module
CtsAtraceHostTestCases passed.
Test: Manually examining trace_clock before and after running atrace shows that the
trace_clock changes as expected (for this test I disabled atrace.rc and added an
additional debug print statement):
$ cat /d/tracing/trace_clock
[local] global counter uptime perf mono boot
$ atrace --async_start freq
capturing trace...marlin:/ $ cat /d/tracing/trace_clock
local global counter uptime perf mono [boot]
$ atrace --async_stop > /dev/null
$ cat /d/tracing/trace_clock
local global counter uptime perf mono [boot]
$ atrace --async_start freq
clock is already correct!
$ atrace --async_stop > /dev/null

Change-Id: I267056d19bcdbea58881ab2b32f093caac5f14c1
parent fb8cedea
Loading
Loading
Loading
Loading
+21 −46
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <zlib.h>

#include <fstream>
#include <memory>

#include <binder/IBinder.h>
@@ -436,56 +437,31 @@ static bool setTraceBufferSizeKB(int size)
    return writeStr(k_traceBufferSizePath, str);
}

// Read the trace_clock sysfs file and return true if it matches the requested
// value.  The trace_clock file format is:
// local [global] counter uptime perf
static bool isTraceClock(const char *mode)
{
    int fd = open((g_traceFolder + k_traceClockPath).c_str(), O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "error opening %s: %s (%d)\n", k_traceClockPath,
            strerror(errno), errno);
        return false;
    }

    char buf[4097];
    ssize_t n = read(fd, buf, 4096);
    close(fd);
    if (n == -1) {
        fprintf(stderr, "error reading %s: %s (%d)\n", k_traceClockPath,
            strerror(errno), errno);
        return false;
    }
    buf[n] = '\0';

    char *start = strchr(buf, '[');
    if (start == NULL) {
        return false;
    }
    start++;

    char *end = strchr(start, ']');
    if (end == NULL) {
        return false;
    }
    *end = '\0';

    return strcmp(mode, start) == 0;
}

// Enable or disable the kernel's use of the global clock.  Disabling the global
// clock will result in the kernel using a per-CPU local clock.
// Set the clock to the best available option while tracing. Use 'boot' if it's
// available; otherwise, use 'mono'. If neither are available use 'global'.
// Any write to the trace_clock sysfs file will reset the buffer, so only
// update it if the requested value is not the current value.
static bool setGlobalClockEnable(bool enable)
static bool setClock()
{
    const char *clock = enable ? "global" : "local";
    std::ifstream clockFile((g_traceFolder + k_traceClockPath).c_str(), O_RDONLY);
    std::string clockStr((std::istreambuf_iterator<char>(clockFile)),
        std::istreambuf_iterator<char>());

    std::string newClock;
    if (clockStr.find("boot") != std::string::npos) {
        newClock = "boot";
    } else if (clockStr.find("mono") != std::string::npos) {
        newClock = "mono";
    } else {
        newClock = "global";
    }

    if (isTraceClock(clock)) {
    size_t begin = clockStr.find("[") + 1;
    size_t end = clockStr.find("]");
    if (newClock.compare(0, std::string::npos, clockStr, begin, end-begin) == 0) {
        return true;
    }

    return writeStr(k_traceClockPath, clock);
    return writeStr(k_traceClockPath, newClock.c_str());
}

static bool setPrintTgidEnableIfPresent(bool enable)
@@ -781,7 +757,7 @@ static bool setUpTrace()
    ok &= setCategoriesEnableFromFile(g_categoriesFile);
    ok &= setTraceOverwriteEnable(g_traceOverwrite);
    ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
    ok &= setGlobalClockEnable(true);
    ok &= setClock();
    ok &= setPrintTgidEnableIfPresent(true);
    ok &= setKernelTraceFuncs(g_kernelTraceFuncs);

@@ -855,7 +831,6 @@ static void cleanUpTrace()
    // Set the options back to their defaults.
    setTraceOverwriteEnable(true);
    setTraceBufferSizeKB(1);
    setGlobalClockEnable(false);
    setPrintTgidEnableIfPresent(false);
    setKernelTraceFuncs(NULL);
}
+5 −0
Original line number Diff line number Diff line
@@ -124,6 +124,11 @@ on post-fs
    write /sys/kernel/debug/tracing/tracing_on 0
    write /sys/kernel/tracing/tracing_on 0

    # Set the trace clock to boot; falling back to mono or boot
    write /d/tracing/trace_clock global
    write /d/tracing/trace_clock mono
    write /d/tracing/trace_clock boot

# Allow only the shell group to read and truncate the kernel trace.
    chown root shell /sys/kernel/debug/tracing/trace
    chown root shell /sys/kernel/tracing/trace