lkml.org 
[lkml]   [2019]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH v2 02/17] perf tools: Configure timestsamp generation in CPU-wide mode
From
Date


On 24/05/2019 18:34, Mathieu Poirier wrote:
> When operating in CPU-wide mode tracers need to generate timestamps in
> order to correlate the code being traced on one CPU with what is executed
> on other CPUs.
>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> ---
> tools/perf/arch/arm/util/cs-etm.c | 57 +++++++++++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
>
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 3912f0bf04ed..be1e4f20affa 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -99,6 +99,54 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
> return err;
> }
>
> +static int cs_etm_set_timestamp(struct auxtrace_record *itr,
> + struct perf_evsel *evsel, int cpu)
> +{
> + struct cs_etm_recording *ptr;
> + struct perf_pmu *cs_etm_pmu;
> + char path[PATH_MAX];
> + int err = -EINVAL;
> + u32 val;
> +
> + ptr = container_of(itr, struct cs_etm_recording, itr);
> + cs_etm_pmu = ptr->cs_etm_pmu;
> +
> + if (!cs_etm_is_etmv4(itr, cpu))
> + goto out;
> +
> + /* Get a handle on TRCIRD0 */
> + snprintf(path, PATH_MAX, "cpu%d/%s",
> + cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
> + err = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
> +
> + /* There was a problem reading the file, bailing out */
> + if (err != 1) {
> + pr_err("%s: can't read file %s\n",
> + CORESIGHT_ETM_PMU_NAME, path);
> + goto out;
> + }
> +
> + /*
> + * TRCIDR0.TSSIZE, bit [28-24], indicates whether global timestamping
> + * is supported:
> + * 0b00000 Global timestamping is not implemented
> + * 0b00110 Implementation supports a maximum timestamp of 48bits.
> + * 0b01000 Implementation supports a maximum timestamp of 64bits.
> + */
> + val &= GENMASK(28, 24);
> + if (!val) {
> + err = -EINVAL;
> + goto out;
> + }
> +
> + /* All good, let the kernel know */
> + evsel->attr.config |= (1 << ETM_OPT_TS);
> + err = 0;
> +
> +out:
> + return err;
> +}
> +
> static int cs_etm_set_option(struct auxtrace_record *itr,
> struct perf_evsel *evsel, u32 option)
> {
> @@ -118,6 +166,11 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
> if (err)
> goto out;
> break;
> + case ETM_OPT_TS:
> + err = cs_etm_set_timestamp(itr, evsel, i);
> + if (err)
> + goto out;
> + break;
> default:
> goto out;
> }
> @@ -343,6 +396,10 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
> err = cs_etm_set_option(itr, cs_etm_evsel, ETM_OPT_CTXTID);
> if (err)
> goto out;
> +
> + err = cs_etm_set_option(itr, cs_etm_evsel, ETM_OPT_TS);
> + if (err)
> + goto out;

nit: Could we not do this in one shot, say :

cs_etm_set_option(itr, cs_etm_evsel, ETM_OPT_TS | ETM_OPT_CTXTID) ?

rather than iterating over the per-CPU events twice ? The cs_etm_set_option()
could simply replace the switch() to :

if (option & ETM_OPT_1)
do_something_for_1()
if (option & ETM_OPT_2)
do_something_for_2();
if (option & ~(ETM_OPT_1 | ETM_OPT_2 |...))
/* do unsupported option */


Cheers
Suzuki

\
 
 \ /
  Last update: 2019-06-07 11:42    [W:0.509 / U:0.576 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site