From: Alexey Klimov <alexey.klimov@arm.com>
To: Prashanth Prakash <pprakash@codeaurora.org>
Cc: linux-acpi@vger.kernel.org, rjw@rjwysocki.net, hotran@apm.com,
cov@codeaurora.org, Ashwin Chaugule <ashwin.chaugule@linaro.org>
Subject: Re: [PATCH 5/5] ACPI/CPPC: add sysfs support to compute delivered performance
Date: Thu, 14 Jul 2016 14:25:35 +0100 [thread overview]
Message-ID: <20160714132535.GA5796@arm.com> (raw)
In-Reply-To: <1467309758-26536-6-git-send-email-pprakash@codeaurora.org>
Hi Prashanth and Ashwin,
On Thu, Jun 30, 2016 at 12:02:38PM -0600, Prashanth Prakash wrote:
> From: Ashwin Chaugule <ashwin.chaugule@linaro.org>
>
> The CPPC tables contain entries for per CPU feedback counters which
> allows us to compute the delivered performance over a given interval
> of time.
>
> The math for delivered performance per the CPPCv5.0+ spec is:
> reference perf * delta(delivered perf ctr)/delta(ref perf ctr)
>
> Maintaining deltas of the counters in the kernel is messy, as it
> depends on when the reads are triggered. (e.g. via the cpufreq
> ->get() interface). Also the ->get() interace only returns one
> value, so cant return raw values. So instead, leave it to userspace
> to keep track of raw values and do its math for CPUs it cares about.
>
> delivered and reference perf counters are exposed via the same
> sysfs file to avoid the potential "skid", if these values are read
> individually from userspace.
>
> Signed-off-by: Prashanth Prakash <pprakash@codeaurora.org>
> Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> ---
> drivers/acpi/cppc_acpi.c | 94 +++++++++++++++++++++++++++++++++++++++++++-----
> include/acpi/cppc_acpi.h | 3 +-
> 2 files changed, 86 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index 7844e4c..8bd501f 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -95,6 +95,17 @@ static unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
> (cpc)->cpc_entry.reg.space_id == \
> ACPI_ADR_SPACE_PLATFORM_COMM)
>
> +/* Evalutes to True if reg is a NULL register descriptor */
> +#define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \
> + (reg)->address == 0 && \
> + (reg)->bit_width == 0 && \
> + (reg)->bit_offset == 0 && \
> + (reg)->access_width == 0)
> +
> +/* Evalutes to True if an optional cpc field is supported */
> +#define CPC_SUPPORTED(cpc) ((cpc)->type == ACPI_TYPE_INTEGER ? \
> + !!(cpc)->cpc_entry.int_value : \
> + !IS_NULL_REG(&(cpc)->cpc_entry.reg))
> /*
> * Arbitrary Retries in case the remote processor is slow to respond
> * to PCC commands. Keeping it high enough to cover emulators where
> @@ -102,6 +113,61 @@ static unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
> */
> #define NUM_RETRIES 500
>
> +struct cppc_attr {
> + struct attribute attr;
> + ssize_t (*show)(struct kobject *kobj,
> + struct attribute *attr, char *buf);
> + ssize_t (*store)(struct kobject *kobj,
> + struct attribute *attr, const char *c, ssize_t count);
> +};
> +
> +#define define_one_cppc_ro(_name) \
> +static struct cppc_attr _name = \
> +__ATTR(_name, 0444, show_##_name, NULL)
> +
> +#define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
> +
> +static ssize_t show_feedback_ctrs(struct kobject *kobj,
> + struct attribute *attr, char *buf)
> +{
> + struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
> + struct cppc_perf_fb_ctrs fb_ctrs = {0};
> +
> + cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
> +
> + return scnprintf(buf, PAGE_SIZE, "ref:%lld del:%lld\n",
> + fb_ctrs.reference, fb_ctrs.delivered);
> +}
> +define_one_cppc_ro(feedback_ctrs);
> +
> +static ssize_t show_reference_perf(struct kobject *kobj,
> + struct attribute *attr, char *buf)
> +{
> + struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
> + struct cppc_perf_caps perf_caps;
> +
> + cppc_get_perf_caps(cpc_ptr->cpu_id, &perf_caps);
> +
> + if (perf_caps.reference_perf)
> + return scnprintf(buf, PAGE_SIZE, "%u\n",
> + perf_caps.reference_perf);
> +
> + return scnprintf(buf, PAGE_SIZE, "%u\n",
> + perf_caps.nominal_perf);
> +}
What do you think about exporting Counter Wraparound Time register
as well if it's present?
Best regards,
Alexey Klimov
> +define_one_cppc_ro(reference_perf);
> +
> +static struct attribute *cppc_attrs[] = {
> + &feedback_ctrs.attr,
> + &reference_perf.attr,
> + NULL
> +};
> +
> +static struct kobj_type cppc_ktype = {
> + .sysfs_ops = &kobj_sysfs_ops,
> + .default_attrs = cppc_attrs,
> +};
> +
> static int check_pcc_chan(void)
> {
> int ret = -EIO;
> @@ -544,6 +610,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
> union acpi_object *out_obj, *cpc_obj;
> struct cpc_desc *cpc_ptr;
> struct cpc_reg *gas_t;
> + struct device *cpu_dev;
> acpi_handle handle = pr->handle;
> unsigned int num_ent, i, cpc_rev;
> acpi_status status;
> @@ -666,6 +733,16 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
> /* Everything looks okay */
> pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
>
> + /* Add per logical CPU nodes for reading its feedback counters. */
> + cpu_dev = get_cpu_device(pr->id);
> + if (!cpu_dev)
> + goto out_free;
> +
> + ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
> + "acpi_cppc");
> + if (ret)
> + goto out_free;
> +
> kfree(output.pointer);
> return 0;
>
> @@ -695,6 +772,7 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr)
> struct cpc_desc *cpc_ptr;
> unsigned int i;
> void __iomem *addr;
> +
> cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
>
> /* Free all the mapped sys mem areas for this CPU */
> @@ -704,6 +782,7 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr)
> iounmap(addr);
> }
>
> + kobject_put(&cpc_ptr->kobj);
> kfree(cpc_ptr);
> }
> EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
> @@ -721,7 +800,7 @@ static int cpc_read(struct cpc_register_resource *reg_res, u64 *val)
> struct cpc_reg *reg = ®_res->cpc_entry.reg;
>
> if (reg_res->type == ACPI_TYPE_INTEGER) {
> - *val = reg_res->int_value;
> + *val = reg_res->cpc_entry.int_value;
> return ret_val;
> }
>
> @@ -836,8 +915,11 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
> cpc_read(lowest_reg, &low);
> perf_caps->lowest_perf = low;
>
> - cpc_read(ref_perf, &ref);
> - perf_caps->reference_perf = ref;
> + perf_caps->reference_perf = 0;
> + if (CPC_SUPPORTED(ref_perf)) {
> + cpc_read(ref_perf, &ref);
> + perf_caps->reference_perf = ref;
> + }
>
> cpc_read(nom_perf, &nom);
> perf_caps->nominal_perf = nom;
> @@ -899,12 +981,6 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
> perf_fb_ctrs->delivered = delivered;
> perf_fb_ctrs->reference = reference;
>
> - perf_fb_ctrs->delivered -= perf_fb_ctrs->prev_delivered;
> - perf_fb_ctrs->reference -= perf_fb_ctrs->prev_reference;
> -
> - perf_fb_ctrs->prev_delivered = delivered;
> - perf_fb_ctrs->prev_reference = reference;
> -
> out_err:
> if (regs_in_pcc)
> up_write(&pcc_lock);
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index 7b7e2e1..2bf9db1 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -63,6 +63,7 @@ struct cpc_desc {
> int cpu_id;
> struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
> struct acpi_psd_package domain_info;
> + struct kobject kobj;
> };
>
> /* These are indexes into the per-cpu cpc_regs[]. Order is important. */
> @@ -109,9 +110,7 @@ struct cppc_perf_ctrls {
>
> struct cppc_perf_fb_ctrs {
> u64 reference;
> - u64 prev_reference;
> u64 delivered;
> - u64 prev_delivered;
> };
>
> /* Per CPU container for runtime CPPC management. */
> --
> Qualcomm Technologies, Inc. on behalf
> of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc.
> is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
>
next prev parent reply other threads:[~2016-07-14 13:25 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-30 18:02 [PATCH 0/5] CPPC enhancements Prashanth Prakash
2016-06-30 18:02 ` [PATCH 1/5] ACPI/CPPC: restructure read/writes for efficient sys mapped reg ops Prashanth Prakash
2016-07-14 23:54 ` Hoan Tran
2016-07-15 20:26 ` Prakash, Prashanth
2016-06-30 18:02 ` [PATCH 2/5] ACPI/CPPC: acquire pcc_lock only while accessing PCC subspace Prashanth Prakash
2016-06-30 18:02 ` [PATCH 3/5] ACPI/CPPC: support for batching CPPC requests Prashanth Prakash
2016-06-30 18:02 ` [PATCH 4/5] ACPI/CPPC: set a non-zero value for transition_latency Prashanth Prakash
2016-07-20 15:51 ` Alexey Klimov
2016-07-20 23:44 ` Prakash, Prashanth
2016-06-30 18:02 ` [PATCH 5/5] ACPI/CPPC: add sysfs support to compute delivered performance Prashanth Prakash
2016-07-14 13:25 ` Alexey Klimov [this message]
2016-07-14 15:44 ` Prakash, Prashanth
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=20160714132535.GA5796@arm.com \
--to=alexey.klimov@arm.com \
--cc=ashwin.chaugule@linaro.org \
--cc=cov@codeaurora.org \
--cc=hotran@apm.com \
--cc=linux-acpi@vger.kernel.org \
--cc=pprakash@codeaurora.org \
--cc=rjw@rjwysocki.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).