From: Huang Rui <ray.huang@amd.com>
To: "Su, Jinzhou (Joe)" <Jinzhou.Su@amd.com>
Cc: "rjw@rjwysocki.net" <rjw@rjwysocki.net>,
"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
"srinivas.pandruvada@linux.intel.com"
<srinivas.pandruvada@linux.intel.com>,
"dsmythies@telus.net" <dsmythies@telus.net>,
"viresh.kumar@linaro.org" <viresh.kumar@linaro.org>,
"todd.e.brandt@linux.intel.com" <todd.e.brandt@linux.intel.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"Sharma, Deepak" <Deepak.Sharma@amd.com>,
"Deucher, Alexander" <Alexander.Deucher@amd.com>,
"Du, Xiaojian" <Xiaojian.Du@amd.com>,
"Yuan, Perry" <Perry.Yuan@amd.com>,
"Meng, Li (Jassmine)" <Li.Meng@amd.com>
Subject: Re: [PATCH V2 1/4] cpufreq: amd-pstate: Add more tracepoint for AMD P-State module
Date: Fri, 4 Mar 2022 14:42:02 +0800 [thread overview]
Message-ID: <YiG0uqa+Ho7XyuHJ@amd.com> (raw)
In-Reply-To: <20220304060724.314582-2-Jinzhou.Su@amd.com>
On Fri, Mar 04, 2022 at 02:07:21PM +0800, Su, Jinzhou (Joe) wrote:
> Add frequency, mperf, aperf and tsc in the trace. This can be used
> to debug and tune the performance of AMD P-state driver.
>
> Use the time difference between amd_pstate_update to calculate CPU
> frequency. There could be sleep in arch_freq_get_on_cpu, so do not
> use it here.
>
> Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
> Co-developed-by: Huang Rui <ray.huang@amd.com>
> Signed-off-by: Huang Rui <ray.huang@amd.com>
Let's remove "Signed-off-by" of me, just leave "Co-developed-by".
> ---
> drivers/cpufreq/amd-pstate-trace.h | 22 ++++++++++-
> drivers/cpufreq/amd-pstate.c | 59 +++++++++++++++++++++++++++++-
> 2 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
> index 647505957d4f..35f38ae67fb1 100644
> --- a/drivers/cpufreq/amd-pstate-trace.h
> +++ b/drivers/cpufreq/amd-pstate-trace.h
> @@ -27,6 +27,10 @@ TRACE_EVENT(amd_pstate_perf,
> TP_PROTO(unsigned long min_perf,
> unsigned long target_perf,
> unsigned long capacity,
> + u64 freq,
> + u64 mperf,
> + u64 aperf,
> + u64 tsc,
> unsigned int cpu_id,
> bool changed,
> bool fast_switch
> @@ -35,6 +39,10 @@ TRACE_EVENT(amd_pstate_perf,
> TP_ARGS(min_perf,
> target_perf,
> capacity,
> + freq,
> + mperf,
> + aperf,
> + tsc,
> cpu_id,
> changed,
> fast_switch
> @@ -44,6 +52,10 @@ TRACE_EVENT(amd_pstate_perf,
> __field(unsigned long, min_perf)
> __field(unsigned long, target_perf)
> __field(unsigned long, capacity)
> + __field(unsigned long long, freq)
> + __field(unsigned long long, mperf)
> + __field(unsigned long long, aperf)
> + __field(unsigned long long, tsc)
> __field(unsigned int, cpu_id)
> __field(bool, changed)
> __field(bool, fast_switch)
> @@ -53,15 +65,23 @@ TRACE_EVENT(amd_pstate_perf,
> __entry->min_perf = min_perf;
> __entry->target_perf = target_perf;
> __entry->capacity = capacity;
> + __entry->freq = freq;
> + __entry->mperf = mperf;
> + __entry->aperf = aperf;
> + __entry->tsc = tsc;
> __entry->cpu_id = cpu_id;
> __entry->changed = changed;
> __entry->fast_switch = fast_switch;
> ),
>
> - TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u changed=%s fast_switch=%s",
> + TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
> (unsigned long)__entry->min_perf,
> (unsigned long)__entry->target_perf,
> (unsigned long)__entry->capacity,
> + (unsigned long long)__entry->freq,
> + (unsigned long long)__entry->mperf,
> + (unsigned long long)__entry->aperf,
> + (unsigned long long)__entry->tsc,
> (unsigned int)__entry->cpu_id,
> (__entry->changed) ? "true" : "false",
> (__entry->fast_switch) ? "true" : "false"
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 9ce75ed11f8e..7be38bc6a673 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -65,6 +65,18 @@ MODULE_PARM_DESC(shared_mem,
>
> static struct cpufreq_driver amd_pstate_driver;
>
> +/**
> + * struct amd_aperf_mperf
> + * @aperf: actual performance frequency clock count
> + * @mperf: maximum performance frequency clock count
> + * @tsc: time stamp counter
> + */
> +struct amd_aperf_mperf {
> + u64 aperf;
> + u64 mperf;
> + u64 tsc;
> +};
> +
> /**
> * struct amd_cpudata - private CPU data for AMD P-State
> * @cpu: CPU number
> @@ -81,6 +93,9 @@ static struct cpufreq_driver amd_pstate_driver;
> * @min_freq: the frequency that mapped to lowest_perf
> * @nominal_freq: the frequency that mapped to nominal_perf
> * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
> + * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
> + * @prev: Last Aperf/Mperf/tsc count value read from register
> + * @freq: current cpu frequency value
> * @boost_supported: check whether the Processor or SBIOS supports boost mode
> *
> * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
> @@ -102,6 +117,10 @@ struct amd_cpudata {
> u32 nominal_freq;
> u32 lowest_nonlinear_freq;
>
> + struct amd_aperf_mperf cur;
> + struct amd_aperf_mperf prev;
> +
> + u64 freq;
> bool boost_supported;
> };
>
> @@ -211,6 +230,39 @@ static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
> max_perf, fast_switch);
> }
>
> +static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
> +{
> + u64 aperf, mperf, tsc;
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + rdmsrl(MSR_IA32_APERF, aperf);
> + rdmsrl(MSR_IA32_MPERF, mperf);
> + tsc = rdtsc();
> +
> + if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
> + local_irq_restore(flags);
> + return false;
> + }
> +
> + local_irq_restore(flags);
> +
> + cpudata->cur.aperf = aperf;
> + cpudata->cur.mperf = mperf;
> + cpudata->cur.tsc = tsc;
> + cpudata->cur.aperf -= cpudata->prev.aperf;
> + cpudata->cur.mperf -= cpudata->prev.mperf;
> + cpudata->cur.tsc -= cpudata->prev.tsc;
> +
> + cpudata->prev.aperf = aperf;
> + cpudata->prev.mperf = mperf;
> + cpudata->prev.tsc = tsc;
> +
> + cpudata->freq = div64_u64((cpudata->cur.aperf * cpu_khz), cpudata->cur.mperf);
> +
> + return true;
> +}
> +
> static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
> u32 des_perf, u32 max_perf, bool fast_switch)
> {
> @@ -226,8 +278,11 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
> value &= ~AMD_CPPC_MAX_PERF(~0L);
> value |= AMD_CPPC_MAX_PERF(max_perf);
>
> - trace_amd_pstate_perf(min_perf, des_perf, max_perf,
> - cpudata->cpu, (value != prev), fast_switch);
> + if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
> + trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
> + cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
> + cpudata->cpu, (value != prev), fast_switch);
How about using struct amd_aperf_mperf pointer as one input:
trace_amd_pstate_perf(min_perf, des_perf, max_perf, &cpudata->cur, ...);
You can refer the members of struct amd_aperf_mperf in the
amd-pstate-trace.h:
__entry->mperf = cur->mperf;
__entry->aperf = cur->aperf;
__entry->tsc = cur->tsc;
Thanks,
Ray
next prev parent reply other threads:[~2022-03-04 6:42 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-04 6:07 [PATCH V2 0/4] Add tracer tool for AMD P-State driver Jinzhou Su
2022-03-04 6:07 ` [PATCH V2 1/4] cpufreq: amd-pstate: Add more tracepoint for AMD P-State module Jinzhou Su
2022-03-04 6:42 ` Huang Rui [this message]
2022-03-04 18:49 ` Rafael J. Wysocki
2022-03-07 2:53 ` Huang Rui
2022-03-09 1:23 ` Su, Jinzhou (Joe)
2022-03-09 13:29 ` Huang Rui
2022-03-04 6:07 ` [PATCH V2 2/4] tools/power/x86/intel_pstate_tracer: make tracer as a module Jinzhou Su
2022-03-04 6:44 ` Huang Rui
2022-03-04 6:07 ` [PATCH V2 3/4] tools/power/x86/amd_pstate_tracer: Add tracer tool for AMD P-state Jinzhou Su
2022-03-04 6:48 ` Huang Rui
2022-03-04 6:07 ` [PATCH V2 4/4] Documentation: amd-pstate: add tracer tool introduction Jinzhou Su
2022-03-04 6:56 ` Huang Rui
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YiG0uqa+Ho7XyuHJ@amd.com \
--to=ray.huang@amd.com \
--cc=Alexander.Deucher@amd.com \
--cc=Deepak.Sharma@amd.com \
--cc=Jinzhou.Su@amd.com \
--cc=Li.Meng@amd.com \
--cc=Perry.Yuan@amd.com \
--cc=Xiaojian.Du@amd.com \
--cc=dsmythies@telus.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=srinivas.pandruvada@linux.intel.com \
--cc=todd.e.brandt@linux.intel.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.