Skip to content

Commit 8ed9eac

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf fixes from Arnaldo Carvalho de Melo: * Set name of tracepoints when reading the perf.data headers, so that we don't end up using the local ones, from /sys. * Fix default output file for perf stat, from Stephane Eranian. * Fix endian handling of features bitmask in perf.data header, from David Ahern. Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents a702704 + cb9dd49 commit 8ed9eac

File tree

5 files changed

+61
-8
lines changed

5 files changed

+61
-8
lines changed

tools/perf/builtin-stat.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
11791179
fprintf(stderr, "cannot use both --output and --log-fd\n");
11801180
usage_with_options(stat_usage, options);
11811181
}
1182+
1183+
if (output_fd < 0) {
1184+
fprintf(stderr, "argument to --log-fd must be a > 0\n");
1185+
usage_with_options(stat_usage, options);
1186+
}
1187+
11821188
if (!output) {
11831189
struct timespec tm;
11841190
mode = append_file ? "a" : "w";
@@ -1190,7 +1196,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
11901196
}
11911197
clock_gettime(CLOCK_REALTIME, &tm);
11921198
fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1193-
} else if (output_fd != 2) {
1199+
} else if (output_fd > 0) {
11941200
mode = append_file ? "a" : "w";
11951201
output = fdopen(output_fd, mode);
11961202
if (!output) {

tools/perf/util/header.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,7 +1942,6 @@ int perf_file_header__read(struct perf_file_header *header,
19421942
else
19431943
return -1;
19441944
} else if (ph->needs_swap) {
1945-
unsigned int i;
19461945
/*
19471946
* feature bitmap is declared as an array of unsigned longs --
19481947
* not good since its size can differ between the host that
@@ -1958,14 +1957,17 @@ int perf_file_header__read(struct perf_file_header *header,
19581957
* file), punt and fallback to the original behavior --
19591958
* clearing all feature bits and setting buildid.
19601959
*/
1961-
for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i)
1962-
header->adds_features[i] = bswap_64(header->adds_features[i]);
1960+
mem_bswap_64(&header->adds_features,
1961+
BITS_TO_U64(HEADER_FEAT_BITS));
19631962

19641963
if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
1965-
for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) {
1966-
header->adds_features[i] = bswap_64(header->adds_features[i]);
1967-
header->adds_features[i] = bswap_32(header->adds_features[i]);
1968-
}
1964+
/* unswap as u64 */
1965+
mem_bswap_64(&header->adds_features,
1966+
BITS_TO_U64(HEADER_FEAT_BITS));
1967+
1968+
/* unswap as u32 */
1969+
mem_bswap_32(&header->adds_features,
1970+
BITS_TO_U32(HEADER_FEAT_BITS));
19691971
}
19701972

19711973
if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
@@ -2091,6 +2093,35 @@ static int read_attr(int fd, struct perf_header *ph,
20912093
return ret <= 0 ? -1 : 0;
20922094
}
20932095

2096+
static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel)
2097+
{
2098+
struct event_format *event = trace_find_event(evsel->attr.config);
2099+
char bf[128];
2100+
2101+
if (event == NULL)
2102+
return -1;
2103+
2104+
snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
2105+
evsel->name = strdup(bf);
2106+
if (event->name == NULL)
2107+
return -1;
2108+
2109+
return 0;
2110+
}
2111+
2112+
static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist)
2113+
{
2114+
struct perf_evsel *pos;
2115+
2116+
list_for_each_entry(pos, &evlist->entries, node) {
2117+
if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2118+
perf_evsel__set_tracepoint_name(pos))
2119+
return -1;
2120+
}
2121+
2122+
return 0;
2123+
}
2124+
20942125
int perf_session__read_header(struct perf_session *session, int fd)
20952126
{
20962127
struct perf_header *header = &session->header;
@@ -2172,6 +2203,9 @@ int perf_session__read_header(struct perf_session *session, int fd)
21722203

21732204
lseek(fd, header->data_offset, SEEK_SET);
21742205

2206+
if (perf_evlist__set_tracepoint_names(session->evlist))
2207+
goto out_delete_evlist;
2208+
21752209
header->frozen = 1;
21762210
return 0;
21772211
out_errno:

tools/perf/util/include/linux/bitops.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#define BITS_PER_LONG __WORDSIZE
99
#define BITS_PER_BYTE 8
1010
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
11+
#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
12+
#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
1113

1214
#define for_each_set_bit(bit, addr, size) \
1315
for ((bit) = find_first_bit((addr), (size)); \

tools/perf/util/session.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,16 @@ static void perf_tool__fill_defaults(struct perf_tool *tool)
442442
tool->finished_round = process_finished_round_stub;
443443
}
444444
}
445+
446+
void mem_bswap_32(void *src, int byte_size)
447+
{
448+
u32 *m = src;
449+
while (byte_size > 0) {
450+
*m = bswap_32(*m);
451+
byte_size -= sizeof(u32);
452+
++m;
453+
}
454+
}
445455

446456
void mem_bswap_64(void *src, int byte_size)
447457
{

tools/perf/util/session.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct branch_info *machine__resolve_bstack(struct machine *self,
8080
bool perf_session__has_traces(struct perf_session *self, const char *msg);
8181

8282
void mem_bswap_64(void *src, int byte_size);
83+
void mem_bswap_32(void *src, int byte_size);
8384
void perf_event__attr_swap(struct perf_event_attr *attr);
8485

8586
int perf_session__create_kernel_maps(struct perf_session *self);

0 commit comments

Comments
 (0)