Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp634059img; Mon, 18 Mar 2019 10:43:14 -0700 (PDT) X-Google-Smtp-Source: APXvYqw/So7pU14ArRSzGAFkHUiLKCR/IaRT/Cf7KqD4FHZGzrUWGkEyabLuk/NxdNfYli+lO4Fh X-Received: by 2002:a65:648f:: with SMTP id e15mr18703344pgv.249.1552930994266; Mon, 18 Mar 2019 10:43:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552930994; cv=none; d=google.com; s=arc-20160816; b=fm6pxcTNLI2bIxGdr1LShfc3dY0S8hIMDYBMMhQD+QtjQNIP9vkXybYA81IM8GEu3Q 731+ojJHhkoTCVwFq/ct/js8L+ViwIq1gdk7L61IzFnJZKbbq3ulr6Z/se3ExzoZTpTR 3BPZLmoCsPSdCS2N59M5S0sZqvENOHWKhMpfFZNkyQ3LsesGYxskjoSqNZACzdFEjmLE bSms86vzLU+MGt0rvRAJMBJV4TipYx/Ir7HD73+qy1q28s/4lS4Dw3cutoN96V4IjviW zuWRYi+mmG8AKI7i2Ocev2WhtmVPWzHGVDxsT/jm1pWEb8b4cRaG4x0MTkIseuodczII S8rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:organization:references:cc:to:from:subject; bh=aMot6RWrh/XJDHfCnnYvQfwcFRWzjhpVgf5ALpbDSqs=; b=GDAOd1eRH0h+mY821ABQqDb1Njidw++LN1rZFPaEq14RBYlEBat3Vq3FrutCAszATi gvFkdaP4igYDdJ7z8EerhvQcppQ1VdIPBIpyR3oguxDqYLOdgGb35zFAAV4AzIIw+Lcw pMJAveiLKjvCv0huaj2+WR982xkNJYEMpbFfccDZOM33gAj2C3aA+VnXRztH8uuC4oLx 8w481w4OV0LDD5geppx2pNqGwzQmUJmZCYCCursvHr/kdh6k01luvue84Tz9jPJZbr6N xaukt0jEue4ps0i85rt7fKdDY/K4LUhjmzQp81onaduRIgwIBqgLLdk5uOmEc5CqQBvl eaaQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b38si10117017plb.249.2019.03.18.10.42.59; Mon, 18 Mar 2019 10:43:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727622AbfCRRli (ORCPT + 99 others); Mon, 18 Mar 2019 13:41:38 -0400 Received: from mga12.intel.com ([192.55.52.136]:26474 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726884AbfCRRli (ORCPT ); Mon, 18 Mar 2019 13:41:38 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Mar 2019 10:41:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,494,1544515200"; d="scan'208";a="283714678" Received: from linux.intel.com ([10.54.29.200]) by orsmga004.jf.intel.com with ESMTP; 18 Mar 2019 10:41:37 -0700 Received: from [10.251.91.19] (abudanko-mobl.ccr.corp.intel.com [10.251.91.19]) by linux.intel.com (Postfix) with ESMTP id F40F7580238; Mon, 18 Mar 2019 10:41:34 -0700 (PDT) Subject: [PATCH v10 04/12] perf record: implement COMPRESSED event record and its attributes From: Alexey Budankov To: Arnaldo Carvalho de Melo Cc: Jiri Olsa , Namhyung Kim , Alexander Shishkin , Peter Zijlstra , Ingo Molnar , Andi Kleen , linux-kernel References: <12cce142-6238-475b-b9aa-236531c12c2b@linux.intel.com> Organization: Intel Corp. Message-ID: Date: Mon, 18 Mar 2019 20:41:33 +0300 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 In-Reply-To: <12cce142-6238-475b-b9aa-236531c12c2b@linux.intel.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Signed-off-by: Alexey Budankov --- .../Documentation/perf.data-file-format.txt | 24 ++++++++ tools/perf/builtin-record.c | 8 +++ tools/perf/perf.h | 1 + tools/perf/util/env.h | 10 ++++ tools/perf/util/event.c | 1 + tools/perf/util/event.h | 7 +++ tools/perf/util/header.c | 55 ++++++++++++++++++- tools/perf/util/header.h | 1 + 8 files changed, 106 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index 593ef49b273c..418fa0bce52e 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -272,6 +272,19 @@ struct { Two uint64_t for the time of first sample and the time of last sample. + HEADER_COMPRESSED = 24, + +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. diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 51b7f23a0c7a..7125b780c4f4 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -369,6 +369,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, @@ -885,6 +890,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); } @@ -1225,6 +1232,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) { diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 7886cc9771cf..2c6caad45b10 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -86,6 +86,7 @@ struct record_opts { int nr_cblocks; int affinity; int mmap_flush; + unsigned int comp_level; }; enum perf_affinity { diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index fb39e9af128f..7990d63ab764 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -65,6 +65,16 @@ struct perf_env { unsigned long long memory_bsize; u64 clockid_res_ns; u32 comp_ratio; + u32 comp_ver; + u32 comp_type; + u32 comp_level; + u32 comp_mmap_len; +}; + +enum perf_compress_type { + PERF_COMP_NONE = 0, + PERF_COMP_ZSTD, + PERF_COMP_MAX }; extern struct perf_env perf_env; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ba7be74fad6e..d1ad6c419724 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -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[] = { diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 36ae7e92dab1..8a13aefe734e 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -254,6 +254,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 }; @@ -626,6 +627,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; @@ -659,6 +665,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); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index b0683bf4d9f3..ee5dd3befa4b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1259,6 +1259,30 @@ static int write_mem_topology(struct feat_fd *ff __maybe_unused, 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); @@ -1557,6 +1581,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: "; @@ -2414,6 +2445,27 @@ static int process_dir_format(struct feat_fd *ff, return do_read_u64(ff, &data->dir.version); } +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); @@ -2474,7 +2526,8 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { FEAT_OPR(SAMPLE_TIME, sample_time, false), FEAT_OPR(MEM_TOPOLOGY, mem_topology, true), FEAT_OPR(CLOCKID, clockid, false), - FEAT_OPN(DIR_FORMAT, dir_format, false) + FEAT_OPN(DIR_FORMAT, dir_format, false), + FEAT_OPR(COMPRESSED, compressed, false) }; struct header_print_data { diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 6a231340238d..9ccfb204bd2c 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -40,6 +40,7 @@ enum { HEADER_MEM_TOPOLOGY, HEADER_CLOCKID, HEADER_DIR_FORMAT, + HEADER_COMPRESSED, HEADER_LAST_FEATURE, HEADER_FEAT_BITS = 256, }; -- 2.20.1