mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
perf record: Implement COMPRESSED event record and its attributes
Implemented PERF_RECORD_COMPRESSED event, related data types, header feature and functions to write, read and print feature attributes from the trace header section. comp_mmap_len preserves the size of mmaped kernel buffer that was used during collection. comp_mmap_len size is used on loading stage as the size of decomp buffer for decompression of COMPRESSED events content. Committer notes: Fixed up conflict with BPF_PROG_INFO and BTF_BTF header features. Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com> Reviewed-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/ebbaf031-8dda-3864-ebc6-7922d43ee515@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d3c8c08e75
commit
42e1fd80a5
@ -272,6 +272,19 @@ struct {
|
||||
|
||||
Two uint64_t for the time of first sample and the time of last sample.
|
||||
|
||||
HEADER_COMPRESSED = 27,
|
||||
|
||||
struct {
|
||||
u32 version;
|
||||
u32 type;
|
||||
u32 level;
|
||||
u32 ratio;
|
||||
u32 mmap_len;
|
||||
};
|
||||
|
||||
Indicates that trace contains records of PERF_RECORD_COMPRESSED type
|
||||
that have perf_events records in compressed form.
|
||||
|
||||
other bits are reserved and should ignored for now
|
||||
HEADER_FEAT_BITS = 256,
|
||||
|
||||
@ -437,6 +450,17 @@ struct auxtrace_error_event {
|
||||
Describes a header feature. These are records used in pipe-mode that
|
||||
contain information that otherwise would be in perf.data file's header.
|
||||
|
||||
PERF_RECORD_COMPRESSED = 81,
|
||||
|
||||
struct compressed_event {
|
||||
struct perf_event_header header;
|
||||
char data[];
|
||||
};
|
||||
|
||||
The header is followed by compressed data frame that can be decompressed
|
||||
into array of perf trace records. The size of the entire compressed event
|
||||
record including the header is limited by the max value of header.size.
|
||||
|
||||
Event types
|
||||
|
||||
Define the event attributes with their IDs.
|
||||
|
@ -372,6 +372,11 @@ static int record__mmap_flush_parse(const struct option *opt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int record__comp_enabled(struct record *rec)
|
||||
{
|
||||
return rec->opts.comp_level > 0;
|
||||
}
|
||||
|
||||
static int process_synthesized_event(struct perf_tool *tool,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
@ -888,6 +893,8 @@ static void record__init_features(struct record *rec)
|
||||
perf_header__clear_feat(&session->header, HEADER_CLOCKID);
|
||||
|
||||
perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
|
||||
if (!record__comp_enabled(rec))
|
||||
perf_header__clear_feat(&session->header, HEADER_COMPRESSED);
|
||||
|
||||
perf_header__clear_feat(&session->header, HEADER_STAT);
|
||||
}
|
||||
@ -1245,6 +1252,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
||||
err = -1;
|
||||
goto out_child;
|
||||
}
|
||||
session->header.env.comp_mmap_len = session->evlist->mmap_len;
|
||||
|
||||
err = bpf__apply_obj_config();
|
||||
if (err) {
|
||||
|
@ -86,6 +86,7 @@ struct record_opts {
|
||||
int nr_cblocks;
|
||||
int affinity;
|
||||
int mmap_flush;
|
||||
unsigned int comp_level;
|
||||
};
|
||||
|
||||
enum perf_affinity {
|
||||
|
@ -63,6 +63,10 @@ struct perf_env {
|
||||
struct cpu_cache_level *caches;
|
||||
int caches_cnt;
|
||||
u32 comp_ratio;
|
||||
u32 comp_ver;
|
||||
u32 comp_type;
|
||||
u32 comp_level;
|
||||
u32 comp_mmap_len;
|
||||
struct numa_node *numa_nodes;
|
||||
struct memory_node *memory_nodes;
|
||||
unsigned long long memory_bsize;
|
||||
@ -81,6 +85,12 @@ struct perf_env {
|
||||
} bpf_progs;
|
||||
};
|
||||
|
||||
enum perf_compress_type {
|
||||
PERF_COMP_NONE = 0,
|
||||
PERF_COMP_ZSTD,
|
||||
PERF_COMP_MAX
|
||||
};
|
||||
|
||||
struct bpf_prog_info_node;
|
||||
struct btf_node;
|
||||
|
||||
|
@ -68,6 +68,7 @@ static const char *perf_event__names[] = {
|
||||
[PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE",
|
||||
[PERF_RECORD_TIME_CONV] = "TIME_CONV",
|
||||
[PERF_RECORD_HEADER_FEATURE] = "FEATURE",
|
||||
[PERF_RECORD_COMPRESSED] = "COMPRESSED",
|
||||
};
|
||||
|
||||
static const char *perf_ns__names[] = {
|
||||
|
@ -255,6 +255,7 @@ enum perf_user_event_type { /* above any possible kernel type */
|
||||
PERF_RECORD_EVENT_UPDATE = 78,
|
||||
PERF_RECORD_TIME_CONV = 79,
|
||||
PERF_RECORD_HEADER_FEATURE = 80,
|
||||
PERF_RECORD_COMPRESSED = 81,
|
||||
PERF_RECORD_HEADER_MAX
|
||||
};
|
||||
|
||||
@ -627,6 +628,11 @@ struct feature_event {
|
||||
char data[];
|
||||
};
|
||||
|
||||
struct compressed_event {
|
||||
struct perf_event_header header;
|
||||
char data[];
|
||||
};
|
||||
|
||||
union perf_event {
|
||||
struct perf_event_header header;
|
||||
struct mmap_event mmap;
|
||||
@ -660,6 +666,7 @@ union perf_event {
|
||||
struct feature_event feat;
|
||||
struct ksymbol_event ksymbol_event;
|
||||
struct bpf_event bpf_event;
|
||||
struct compressed_event pack;
|
||||
};
|
||||
|
||||
void perf_event__print_totals(void);
|
||||
|
@ -1344,6 +1344,30 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_compressed(struct feat_fd *ff __maybe_unused,
|
||||
struct perf_evlist *evlist __maybe_unused)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = do_write(ff, &(ff->ph->env.comp_ver), sizeof(ff->ph->env.comp_ver));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = do_write(ff, &(ff->ph->env.comp_type), sizeof(ff->ph->env.comp_type));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = do_write(ff, &(ff->ph->env.comp_level), sizeof(ff->ph->env.comp_level));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = do_write(ff, &(ff->ph->env.comp_ratio), sizeof(ff->ph->env.comp_ratio));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return do_write(ff, &(ff->ph->env.comp_mmap_len), sizeof(ff->ph->env.comp_mmap_len));
|
||||
}
|
||||
|
||||
static void print_hostname(struct feat_fd *ff, FILE *fp)
|
||||
{
|
||||
fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
|
||||
@ -1688,6 +1712,13 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
|
||||
}
|
||||
}
|
||||
|
||||
static void print_compressed(struct feat_fd *ff, FILE *fp)
|
||||
{
|
||||
fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
|
||||
ff->ph->env.comp_type == PERF_COMP_ZSTD ? "Zstd" : "Unknown",
|
||||
ff->ph->env.comp_level, ff->ph->env.comp_ratio);
|
||||
}
|
||||
|
||||
static void print_pmu_mappings(struct feat_fd *ff, FILE *fp)
|
||||
{
|
||||
const char *delimiter = "# pmu mappings: ";
|
||||
@ -2667,6 +2698,27 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int process_compressed(struct feat_fd *ff,
|
||||
void *data __maybe_unused)
|
||||
{
|
||||
if (do_read_u32(ff, &(ff->ph->env.comp_ver)))
|
||||
return -1;
|
||||
|
||||
if (do_read_u32(ff, &(ff->ph->env.comp_type)))
|
||||
return -1;
|
||||
|
||||
if (do_read_u32(ff, &(ff->ph->env.comp_level)))
|
||||
return -1;
|
||||
|
||||
if (do_read_u32(ff, &(ff->ph->env.comp_ratio)))
|
||||
return -1;
|
||||
|
||||
if (do_read_u32(ff, &(ff->ph->env.comp_mmap_len)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct feature_ops {
|
||||
int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
|
||||
void (*print)(struct feat_fd *ff, FILE *fp);
|
||||
@ -2730,6 +2782,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
|
||||
FEAT_OPN(DIR_FORMAT, dir_format, false),
|
||||
FEAT_OPR(BPF_PROG_INFO, bpf_prog_info, false),
|
||||
FEAT_OPR(BPF_BTF, bpf_btf, false),
|
||||
FEAT_OPR(COMPRESSED, compressed, false),
|
||||
};
|
||||
|
||||
struct header_print_data {
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
HEADER_DIR_FORMAT,
|
||||
HEADER_BPF_PROG_INFO,
|
||||
HEADER_BPF_BTF,
|
||||
HEADER_COMPRESSED,
|
||||
HEADER_LAST_FEATURE,
|
||||
HEADER_FEAT_BITS = 256,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user