mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-12 00:15:33 -04:00
As with evlist this a no-op for most of the perf tool. The reference count is set to 1 at allocation, the put will see the 1, decrement it and perform the delete. The purpose for adding the reference count is for the python code. Prior to this change the python code would clone evsels, but this has issues if events are opened, etc. leading to assertion failures. With a reference count the same evsel can be used and the reference count incremented for the python usage. To not change the python evsel API getset functions are added for the evsel members, no set function is provided for size as it doesn't make sense to alter this. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alice Rogers <alice.mei.rogers@gmail.com> Cc: Dapeng Mi <dapeng1.mi@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Leo Yan <leo.yan@linux.dev> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Richter <tmricht@linux.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
85 lines
2.1 KiB
C
85 lines
2.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <errno.h>
|
|
#include <inttypes.h>
|
|
#include <api/fs/tracing_path.h>
|
|
#include <linux/err.h>
|
|
#include <linux/string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include "thread_map.h"
|
|
#include "evsel.h"
|
|
#include "debug.h"
|
|
#include "tests.h"
|
|
#include "util/counts.h"
|
|
|
|
static int test__openat_syscall_event(struct test_suite *test __maybe_unused,
|
|
int subtest __maybe_unused)
|
|
{
|
|
int err = TEST_FAIL, fd;
|
|
struct evsel *evsel;
|
|
unsigned int nr_openat_calls = 111, i;
|
|
struct perf_thread_map *threads = thread_map__new_by_tid(getpid());
|
|
char sbuf[STRERR_BUFSIZE];
|
|
char errbuf[BUFSIZ];
|
|
|
|
if (threads == NULL) {
|
|
pr_debug("thread_map__new\n");
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
evsel = evsel__newtp("syscalls", "sys_enter_openat");
|
|
if (IS_ERR(evsel)) {
|
|
tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat");
|
|
pr_debug("%s\n", errbuf);
|
|
err = TEST_SKIP;
|
|
goto out_thread_map_delete;
|
|
}
|
|
|
|
if (evsel__open_per_thread(evsel, threads) < 0) {
|
|
pr_debug("failed to open counter: %s, "
|
|
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
|
|
str_error_r(errno, sbuf, sizeof(sbuf)));
|
|
err = TEST_SKIP;
|
|
goto out_evsel_put;
|
|
}
|
|
|
|
for (i = 0; i < nr_openat_calls; ++i) {
|
|
fd = openat(0, "/etc/passwd", O_RDONLY);
|
|
close(fd);
|
|
}
|
|
|
|
if (evsel__read_on_cpu(evsel, 0, 0) < 0) {
|
|
pr_debug("evsel__read_on_cpu\n");
|
|
goto out_close_fd;
|
|
}
|
|
|
|
if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) {
|
|
pr_debug("evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
|
|
nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val);
|
|
goto out_close_fd;
|
|
}
|
|
|
|
err = TEST_OK;
|
|
out_close_fd:
|
|
perf_evsel__close_fd(&evsel->core);
|
|
out_evsel_put:
|
|
evsel__put(evsel);
|
|
out_thread_map_delete:
|
|
perf_thread_map__put(threads);
|
|
return err;
|
|
}
|
|
|
|
static struct test_case tests__openat_syscall_event[] = {
|
|
TEST_CASE_REASON("Detect openat syscall event",
|
|
openat_syscall_event,
|
|
"permissions"),
|
|
{ .name = NULL, }
|
|
};
|
|
|
|
struct test_suite suite__openat_syscall_event = {
|
|
.desc = "Detect openat syscall event",
|
|
.test_cases = tests__openat_syscall_event,
|
|
};
|