keep-tracking.c 3.4 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
B
Borislav Petkov 已提交
2
#include <linux/types.h>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include <unistd.h>
#include <sys/prctl.h>

#include "parse-events.h"
#include "evlist.h"
#include "evsel.h"
#include "thread_map.h"
#include "cpumap.h"
#include "tests.h"

#define CHECK__(x) {				\
	while ((x) < 0) {			\
		pr_debug(#x " failed!\n");	\
		goto out_err;			\
	}					\
}

#define CHECK_NOT_NULL__(x) {			\
	while ((x) == NULL) {			\
		pr_debug(#x " failed!\n");	\
		goto out_err;			\
	}					\
}

27
static int find_comm(struct evlist *evlist, const char *comm)
28 29
{
	union perf_event *event;
30
	struct perf_mmap *md;
31 32 33 34
	int i, found;

	found = 0;
	for (i = 0; i < evlist->nr_mmaps; i++) {
35
		md = &evlist->mmap[i];
36
		if (perf_mmap__read_init(md) < 0)
37
			continue;
38
		while ((event = perf_mmap__read_event(md)) != NULL) {
39 40 41 42 43
			if (event->header.type == PERF_RECORD_COMM &&
			    (pid_t)event->comm.pid == getpid() &&
			    (pid_t)event->comm.tid == getpid() &&
			    strcmp(event->comm.comm, comm) == 0)
				found += 1;
44
			perf_mmap__consume(md);
45
		}
46
		perf_mmap__read_done(md);
47 48 49 50 51 52 53 54 55 56 57
	}
	return found;
}

/**
 * test__keep_tracking - test using a dummy software event to keep tracking.
 *
 * This function implements a test that checks that tracking events continue
 * when an event is disabled but a dummy software event is not disabled.  If the
 * test passes %0 is returned, otherwise %-1 is returned.
 */
58
int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused)
59
{
60
	struct record_opts opts = {
61 62 63 64 65 66 67
		.mmap_pages	     = UINT_MAX,
		.user_freq	     = UINT_MAX,
		.user_interval	     = ULLONG_MAX,
		.target		     = {
			.uses_mmap   = true,
		},
	};
68
	struct perf_thread_map *threads = NULL;
69
	struct perf_cpu_map *cpus = NULL;
70
	struct evlist *evlist = NULL;
71
	struct evsel *evsel = NULL;
72 73 74 75 76 77 78 79 80
	int found, err = -1;
	const char *comm;

	threads = thread_map__new(-1, getpid(), UINT_MAX);
	CHECK_NOT_NULL__(threads);

	cpus = cpu_map__new(NULL);
	CHECK_NOT_NULL__(cpus);

81
	evlist = evlist__new();
82 83 84 85
	CHECK_NOT_NULL__(evlist);

	perf_evlist__set_maps(evlist, cpus, threads);

86 87
	CHECK__(parse_events(evlist, "dummy:u", NULL));
	CHECK__(parse_events(evlist, "cycles:u", NULL));
88

89
	perf_evlist__config(evlist, &opts, NULL);
90 91 92 93 94 95 96 97

	evsel = perf_evlist__first(evlist);

	evsel->attr.comm = 1;
	evsel->attr.disabled = 1;
	evsel->attr.enable_on_exec = 0;

	if (perf_evlist__open(evlist) < 0) {
98 99
		pr_debug("Unable to open dummy and cycles event\n");
		err = TEST_SKIP;
100 101 102
		goto out_err;
	}

103
	CHECK__(perf_evlist__mmap(evlist, UINT_MAX));
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

	/*
	 * First, test that a 'comm' event can be found when the event is
	 * enabled.
	 */

	perf_evlist__enable(evlist);

	comm = "Test COMM 1";
	CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));

	perf_evlist__disable(evlist);

	found = find_comm(evlist, comm);
	if (found != 1) {
		pr_debug("First time, failed to find tracking event.\n");
		goto out_err;
	}

	/*
	 * Secondly, test that a 'comm' event can be found when the event is
	 * disabled with the dummy event still enabled.
	 */

	perf_evlist__enable(evlist);

	evsel = perf_evlist__last(evlist);

132
	CHECK__(perf_evsel__disable(evsel));
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

	comm = "Test COMM 2";
	CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));

	perf_evlist__disable(evlist);

	found = find_comm(evlist, comm);
	if (found != 1) {
		pr_debug("Seconf time, failed to find tracking event.\n");
		goto out_err;
	}

	err = 0;

out_err:
	if (evlist) {
		perf_evlist__disable(evlist);
		perf_evlist__delete(evlist);
151
	} else {
152
		cpu_map__put(cpus);
153
		thread_map__put(threads);
154
	}
155 156 157

	return err;
}