All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ai Li" <aili@codeaurora.org>
To: mgross@linux.intel.com
Cc: linux-pm@lists.linux-foundation.org
Subject: Re: adding handles to pm_qos?
Date: Tue, 17 Nov 2009 18:06:56 -0700	[thread overview]
Message-ID: <000001ca67eb$6cfee4e0$46fcaea0$@org> (raw)
In-Reply-To: <20091103202954.GA25275@linux.intel.com>

> Thanks, I'll look at it over the next few days.
> 
> --mgross
> 
> > Here is the patch that I use with the test code.  There are
> three new
> > functions:
> >
> > void *pm_qos_get(int qos, char *name);
> > int pm_qos_put(void *handle);
> > int pm_qos_update_requirement_direct(void *handle, s32
> new_value);
> >
> > In the test, I wanted to keep the existing interface intact so
> I
> > could compare them at the same time.  For the formal code
> submission,
> > a different approach may work better.


Here is an alternate way of adding handles to pm_qos_params that I
was alluding to.  This approach may be more preferable because it
does not bloat the API and the handles become an integral part of
pm_qos_params.  In my previous patch, handles are kind of bolted onto
pm_qos_params and it needs separate calls (pm_qos_get, pm_qos_put) to
acquire and release the handle.  In this patch,
pm_qos_add_requirement and pm_qos_remove_requirement automatically
take care of the handles.


--- include/linux/pm_qos_params.h.orig
+++ include/linux/pm_qos_params.h
@@ -14,9 +14,11 @@
 #define PM_QOS_NUM_CLASSES 4
 #define PM_QOS_DEFAULT_VALUE -1
 
-int pm_qos_add_requirement(int qos, char *name, s32 value);
-int pm_qos_update_requirement(int qos, char *name, s32 new_value);
-void pm_qos_remove_requirement(int qos, char *name);
+struct requirement_list;
+
+struct requirement_list *pm_qos_add_requirement(int qos, char *name,
s32 value);
+int pm_qos_update_requirement(struct requirement_list *qos, s32
new_value);
+void pm_qos_remove_requirement(struct requirement_list *qos);
 
 int pm_qos_requirement(int qos);
 
--- kernel/pm_qos_params.c.orig
+++ kernel/pm_qos_params.c
@@ -49,6 +49,7 @@
  */
 struct requirement_list {
 	struct list_head list;
+	int pm_qos_class;
 	union {
 		s32 value;
 		s32 usec;
@@ -207,13 +208,16 @@ EXPORT_SYMBOL_GPL(pm_qos_requirement);
  * performance characteristics.  It recomputes the aggregate QoS
expectations
  * for the pm_qos_class of parameters.
  */
-int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value)
+struct requirement_list *pm_qos_add_requirement(int pm_qos_class,
char *name,
+		s32 value)
 {
 	struct requirement_list *dep;
 	unsigned long flags;
 
 	dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL);
 	if (dep) {
+		dep->pm_qos_class = pm_qos_class;
+
 		if (value == PM_QOS_DEFAULT_VALUE)
 			dep->value =
pm_qos_array[pm_qos_class]->default_value;
 		else
@@ -228,48 +232,37 @@ int pm_qos_add_requirement(int pm_qos_class,
char *name, s32 value)
 		spin_unlock_irqrestore(&pm_qos_lock, flags);
 		update_target(pm_qos_class);
 
-		return 0;
+		return dep;
 	}
 
 cleanup:
 	kfree(dep);
-	return -ENOMEM;
+	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL_GPL(pm_qos_add_requirement);
 
 /**
  * pm_qos_update_requirement - modifies an existing qos request
- * @pm_qos_class: identifies which list of qos request to us
- * @name: identifies the request
+ * @qos: identifies the qos request to us
  * @value: defines the qos request
  *
- * Updates an existing qos requirement for the pm_qos_class of
parameters along
+ * Updates an existing qos requirement along
  * with updating the target pm_qos_class value.
- *
- * If the named request isn't in the list then no change is made.
  */
-int pm_qos_update_requirement(int pm_qos_class, char *name, s32
new_value)
+int pm_qos_update_requirement(struct requirement_list *qos, s32
new_value)
 {
 	unsigned long flags;
-	struct requirement_list *node;
 	int pending_update = 0;
 
 	spin_lock_irqsave(&pm_qos_lock, flags);
-	list_for_each_entry(node,
-		&pm_qos_array[pm_qos_class]->requirements.list, list)
{
-		if (strcmp(node->name, name) == 0) {
-			if (new_value == PM_QOS_DEFAULT_VALUE)
-				node->value =
-
pm_qos_array[pm_qos_class]->default_value;
-			else
-				node->value = new_value;
-			pending_update = 1;
-			break;
-		}
-	}
+	if (new_value == PM_QOS_DEFAULT_VALUE)
+		qos->value =
pm_qos_array[qos->pm_qos_class]->default_value;
+	else
+		qos->value = new_value;
+	pending_update = 1;
 	spin_unlock_irqrestore(&pm_qos_lock, flags);
 	if (pending_update)
-		update_target(pm_qos_class);
+		update_target(qos->pm_qos_class);
 
 	return 0;
 }
@@ -277,32 +270,26 @@ EXPORT_SYMBOL_GPL(pm_qos_update_requirement);
 
 /**
  * pm_qos_remove_requirement - modifies an existing qos request
- * @pm_qos_class: identifies which list of qos request to us
+ * @qos: identifies the qos request to us
  * @name: identifies the request
  *
- * Will remove named qos request from pm_qos_class list of
parameters and
+ * Will remove qos request from pm_qos_class list and
  * recompute the current target value for the pm_qos_class.
  */
-void pm_qos_remove_requirement(int pm_qos_class, char *name)
+void pm_qos_remove_requirement(struct requirement_list *qos)
 {
 	unsigned long flags;
-	struct requirement_list *node;
 	int pending_update = 0;
 
 	spin_lock_irqsave(&pm_qos_lock, flags);
-	list_for_each_entry(node,
-		&pm_qos_array[pm_qos_class]->requirements.list, list)
{
-		if (strcmp(node->name, name) == 0) {
-			kfree(node->name);
-			list_del(&node->list);
-			kfree(node);
-			pending_update = 1;
-			break;
-		}
-	}
+	list_del(&qos->list);
+	pending_update = 1;
 	spin_unlock_irqrestore(&pm_qos_lock, flags);
 	if (pending_update)
-		update_target(pm_qos_class);
+		update_target(qos->pm_qos_class);
+
+	kfree(qos->name);
+	kfree(qos);
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
 
@@ -345,37 +332,42 @@ int pm_qos_remove_notifier(int pm_qos_class,
struct notifier_block *notifier)
 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
 #define PID_NAME_LEN sizeof("process_1234567890")
-static char name[PID_NAME_LEN];
 
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
 	int ret;
 	long pm_qos_class;
+	char name[PID_NAME_LEN];
+	struct requirement_list *qos;
 
 	lock_kernel();
 	pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
-	if (pm_qos_class >= 0) {
-		filp->private_data = (void *)pm_qos_class;
-		sprintf(name, "process_%d", current->pid);
-		ret = pm_qos_add_requirement(pm_qos_class, name,
-					PM_QOS_DEFAULT_VALUE);
-		if (ret >= 0) {
-			unlock_kernel();
-			return 0;
-		}
+	if (pm_qos_class < 0) {
+		ret = -EPERM;
+		goto power_open_exit;
 	}
-	unlock_kernel();
 
-	return -EPERM;
+	sprintf(name, "process_%d", current->pid);
+	qos = pm_qos_add_requirement(pm_qos_class, name,
PM_QOS_DEFAULT_VALUE);
+	if (IS_ERR(qos)) {
+		ret = PTR_ERR(qos);
+		goto power_open_exit;
+	}
+
+	filp->private_data = qos;
+	ret = 0;
+
+power_open_exit:
+	unlock_kernel();
+	return ret;
 }
 
 static int pm_qos_power_release(struct inode *inode, struct file
*filp)
 {
-	int pm_qos_class;
+	struct requirement_list *qos;
 
-	pm_qos_class = (long)filp->private_data;
-	sprintf(name, "process_%d", current->pid);
-	pm_qos_remove_requirement(pm_qos_class, name);
+	qos = (struct requirement_list *)filp->private_data;
+	pm_qos_remove_requirement(qos);
 
 	return 0;
 }
@@ -384,15 +376,15 @@ static ssize_t pm_qos_power_write(struct file
*filp, const char __user *buf,
 		size_t count, loff_t *f_pos)
 {
 	s32 value;
-	int pm_qos_class;
+	struct requirement_list *qos;
 
-	pm_qos_class = (long)filp->private_data;
 	if (count != sizeof(s32))
 		return -EINVAL;
 	if (copy_from_user(&value, buf, sizeof(s32)))
 		return -EFAULT;
-	sprintf(name, "process_%d", current->pid);
-	pm_qos_update_requirement(pm_qos_class, name, value);
+
+	qos = (struct requirement_list *)filp->private_data;
+	pm_qos_update_requirement(qos, value);
 
 	return  sizeof(s32);
 }


~Ai

  reply	other threads:[~2009-11-18  1:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-14 17:24 adding handles to pm_qos? Ai Li
2009-10-23 22:53 ` mgross
2009-10-28  0:37   ` Ai Li
2009-10-30 14:56     ` mgross
2009-10-31  1:53       ` Ai Li
2009-11-03 20:29         ` mgross
2009-11-18  1:06           ` Ai Li [this message]
2009-11-27 17:23             ` 640E9920

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='000001ca67eb$6cfee4e0$46fcaea0$@org' \
    --to=aili@codeaurora.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=mgross@linux.intel.com \
    /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.