perf record: Introduce data file at mmap buffer object
Introduce data file objects into mmap object so it could be used to process and store data stream from the corresponding kernel data buffer. Initialize data files located at mmap buffer objects so trace data can be written into several data file located at data directory. Signed-off-by: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com> Tested-by: Jiri Olsa <jolsa@kernel.org> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Namhyung Kim <namhyung@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Antonov <alexander.antonov@linux.intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexei Budankov <abudankov@huawei.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Riccardo Mancini <rickyman7@gmail.com> Link: https://lore.kernel.org/r/177077f7734b63e5c999ccd75ac6dc3c694f0d0d.1642440724.git.alexey.v.bayduraev@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
3217e9fecf
commit
56f735fff3
@ -205,12 +205,16 @@ static int record__write(struct record *rec, struct mmap *map __maybe_unused,
|
||||
{
|
||||
struct perf_data_file *file = &rec->session->data->file;
|
||||
|
||||
if (map && map->file)
|
||||
file = map->file;
|
||||
|
||||
if (perf_data_file__write(file, bf, size) < 0) {
|
||||
pr_err("failed to write perf data, error: %m\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rec->bytes_written += size;
|
||||
if (!(map && map->file))
|
||||
rec->bytes_written += size;
|
||||
|
||||
if (record__output_max_size_exceeded(rec) && !done) {
|
||||
fprintf(stderr, "[ perf record: perf size limit reached (%" PRIu64 " KB),"
|
||||
@ -1103,7 +1107,7 @@ out_free:
|
||||
static int record__mmap_evlist(struct record *rec,
|
||||
struct evlist *evlist)
|
||||
{
|
||||
int ret;
|
||||
int i, ret;
|
||||
struct record_opts *opts = &rec->opts;
|
||||
bool auxtrace_overwrite = opts->auxtrace_snapshot_mode ||
|
||||
opts->auxtrace_sample_mode;
|
||||
@ -1142,6 +1146,18 @@ static int record__mmap_evlist(struct record *rec,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (record__threads_enabled(rec)) {
|
||||
ret = perf_data__create_dir(&rec->data, evlist->core.nr_mmaps);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||
if (evlist->mmap)
|
||||
evlist->mmap[i].file = &rec->data.dir.files[i];
|
||||
if (evlist->overwrite_mmap)
|
||||
evlist->overwrite_mmap[i].file = &rec->data.dir.files[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1448,8 +1464,12 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
|
||||
/*
|
||||
* Mark the round finished in case we wrote
|
||||
* at least one event.
|
||||
*
|
||||
* No need for round events in directory mode,
|
||||
* because per-cpu maps and files have data
|
||||
* sorted by kernel.
|
||||
*/
|
||||
if (bytes_written != rec->bytes_written)
|
||||
if (!record__threads_enabled(rec) && bytes_written != rec->bytes_written)
|
||||
rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event));
|
||||
|
||||
if (overwrite)
|
||||
@ -1566,7 +1586,9 @@ static void record__init_features(struct record *rec)
|
||||
if (!rec->opts.use_clockid)
|
||||
perf_header__clear_feat(&session->header, HEADER_CLOCK_DATA);
|
||||
|
||||
perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
|
||||
if (!record__threads_enabled(rec))
|
||||
perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
|
||||
|
||||
if (!record__comp_enabled(rec))
|
||||
perf_header__clear_feat(&session->header, HEADER_COMPRESSED);
|
||||
|
||||
@ -1576,6 +1598,7 @@ static void record__init_features(struct record *rec)
|
||||
static void
|
||||
record__finish_output(struct record *rec)
|
||||
{
|
||||
int i;
|
||||
struct perf_data *data = &rec->data;
|
||||
int fd = perf_data__fd(data);
|
||||
|
||||
@ -1584,6 +1607,10 @@ record__finish_output(struct record *rec)
|
||||
|
||||
rec->session->header.data_size += rec->bytes_written;
|
||||
data->file.size = lseek(perf_data__fd(data), 0, SEEK_CUR);
|
||||
if (record__threads_enabled(rec)) {
|
||||
for (i = 0; i < data->dir.nr; i++)
|
||||
data->dir.files[i].size = lseek(data->dir.files[i].fd, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
if (!rec->no_buildid) {
|
||||
process_buildids(rec);
|
||||
@ -3330,7 +3357,7 @@ int cmd_record(int argc, const char **argv)
|
||||
goto out_opts;
|
||||
}
|
||||
|
||||
if (rec->opts.kcore)
|
||||
if (rec->opts.kcore || record__threads_enabled(rec))
|
||||
rec->data.is_dir = true;
|
||||
|
||||
if (rec->opts.comp_level != 0) {
|
||||
|
@ -45,6 +45,7 @@ struct mmap {
|
||||
struct mmap_cpu_mask affinity_mask;
|
||||
void *data;
|
||||
int comp_level;
|
||||
struct perf_data_file *file;
|
||||
};
|
||||
|
||||
struct mmap_params {
|
||||
|
Loading…
Reference in New Issue
Block a user