All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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.