Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751244AbaLEWZx (ORCPT ); Fri, 5 Dec 2014 17:25:53 -0500 Received: from v094114.home.net.pl ([79.96.170.134]:60619 "HELO v094114.home.net.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1750988AbaLEWZw (ORCPT ); Fri, 5 Dec 2014 17:25:52 -0500 From: "Rafael J. Wysocki" To: Dave Gerlach Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Pavel Machek , Len Brown , Nishanth Menon Subject: Re: [PATCH] PM QoS: Add debugfs support to view the list of constraints Date: Fri, 05 Dec 2014 23:47:19 +0100 Message-ID: <2285210.ohmJzh2omj@vostro.rjw.lan> User-Agent: KMail/4.11.5 (Linux/3.16.0-rc5+; KDE/4.11.5; x86_64; ; ) In-Reply-To: <1417799948-48440-1-git-send-email-d-gerlach@ti.com> References: <1417799948-48440-1-git-send-email-d-gerlach@ti.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="utf-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Friday, December 05, 2014 11:19:08 AM Dave Gerlach wrote: > From: Nishanth Menon > > PM QoS requests are notoriously hard to debug and made even > more so due to their highly dynamic nature. Having visibility > into the internal data representation per constraint allows > us to have much better appreciation of potential issues or > bad usage by drivers in the system. > > So introduce for all classes of PM QoS, an entry in > /sys/kernel/debug/pm_qos that shall show all the current > requests as well as the snapshot of the value these requests > boil down to. For example: > ==> /sys/kernel/debug/pm_qos/cpu_dma_latency <== > 1: 4444: Active > 2: 2000000000: Default > 3: 2000000000: Default > 4: 2000000000: Default > Type=Minimum, Value=4444, Requests: active=1 / total=4 > > ==> /sys/kernel/debug/pm_qos/memory_bandwidth <== > Empty! > > ... > > The actual value listed will have their meaning based > on the QoS it is on, the 'Type' indicates what logic > it would use to collate the information - Minimum, > Maximum, or Sum. Value is the collation of all requests. > This interface also compares the values with the defaults > for the QoS class and marks the ones that are > currently active. > > Signed-off-by: Nishanth Menon > Signed-off-by: Dave Gerlach This is fine by me, but let's wait and see if there are any comments. > --- > kernel/power/qos.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 89 insertions(+), 2 deletions(-) > > diff --git a/kernel/power/qos.c b/kernel/power/qos.c > index 5f4c006..97b0df7 100644 > --- a/kernel/power/qos.c > +++ b/kernel/power/qos.c > @@ -41,6 +41,8 @@ > #include > #include > #include > +#include > +#include > > #include > #include > @@ -182,6 +184,81 @@ static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) > c->target_value = value; > } > > +static inline int pm_qos_get_value(struct pm_qos_constraints *c); > +static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused) > +{ > + struct pm_qos_object *qos = (struct pm_qos_object *)s->private; > + struct pm_qos_constraints *c; > + struct pm_qos_request *req; > + char *type; > + unsigned long flags; > + int tot_reqs = 0; > + int active_reqs = 0; > + > + if (IS_ERR_OR_NULL(qos)) { > + pr_err("%s: bad qos param!\n", __func__); > + return -EINVAL; > + } > + c = qos->constraints; > + if (IS_ERR_OR_NULL(c)) { > + pr_err("%s: Bad constraints on qos?\n", __func__); > + return -EINVAL; > + } > + > + /* Lock to ensure we have a snapshot */ > + spin_lock_irqsave(&pm_qos_lock, flags); > + if (plist_head_empty(&c->list)) { > + seq_puts(s, "Empty!\n"); > + goto out; > + } > + > + switch (c->type) { > + case PM_QOS_MIN: > + type = "Minimum"; > + break; > + case PM_QOS_MAX: > + type = "Maximum"; > + break; > + case PM_QOS_SUM: > + type = "Sum"; > + break; > + default: > + type = "Unknown"; > + } > + > + plist_for_each_entry(req, &c->list, node) { > + char *state = "Default"; > + > + if ((req->node).prio != c->default_value) { > + active_reqs++; > + state = "Active"; > + } > + tot_reqs++; > + seq_printf(s, "%d: %d: %s\n", tot_reqs, > + (req->node).prio, state); > + } > + > + seq_printf(s, "Type=%s, Value=%d, Requests: active=%d / total=%d\n", > + type, pm_qos_get_value(c), active_reqs, tot_reqs); > + > +out: > + spin_unlock_irqrestore(&pm_qos_lock, flags); > + return 0; > +} > + > +static int pm_qos_dbg_open(struct inode *inode, struct file *file) > +{ > + return single_open(file, pm_qos_dbg_show_requests, > + inode->i_private); > +} > + > +static const struct file_operations pm_qos_debug_fops = { > + .open = pm_qos_dbg_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > /** > * pm_qos_update_target - manages the constraints list and calls the notifiers > * if needed > @@ -509,12 +586,17 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) > EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); > > /* User space interface to PM QoS classes via misc devices */ > -static int register_pm_qos_misc(struct pm_qos_object *qos) > +static int register_pm_qos_misc(struct pm_qos_object *qos, struct dentry *d) > { > qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; > qos->pm_qos_power_miscdev.name = qos->name; > qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; > > + if (d) { > + (void)debugfs_create_file(qos->name, S_IRUGO, d, > + (void *)qos, &pm_qos_debug_fops); > + } > + > return misc_register(&qos->pm_qos_power_miscdev); > } > > @@ -608,11 +690,16 @@ static int __init pm_qos_power_init(void) > { > int ret = 0; > int i; > + struct dentry *d; > > BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); > > + d = debugfs_create_dir("pm_qos", NULL); > + if (IS_ERR_OR_NULL(d)) > + d = NULL; > + > for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { > - ret = register_pm_qos_misc(pm_qos_array[i]); > + ret = register_pm_qos_misc(pm_qos_array[i], d); > if (ret < 0) { > printk(KERN_ERR "pm_qos_param: %s setup failed\n", > pm_qos_array[i]->name); > -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/