From: mgross <mgross@linux.intel.com>
To: Ai Li <aili@codeaurora.org>
Cc: linux-pm@lists.linux-foundation.org
Subject: Re: adding handles to pm_qos?
Date: Tue, 3 Nov 2009 12:29:54 -0800 [thread overview]
Message-ID: <20091103202954.GA25275@linux.intel.com> (raw)
In-Reply-To: <000001ca59cc$fc6999e0$f53ccda0$@org>
Thanks, I'll look at it over the next few days.
--mgross
On Fri, Oct 30, 2009 at 07:53:42PM -0600, Ai Li wrote:
> > Oh.
> >
> > This will not scale with the aggregation logic very well at all
> > if
> > pm_qos update requirement gets hit per transaction through a
> > driver code
> > path, then I think some thought on the scalability is needed and
> > perhaps
> > a change to the aggregation design for such uses.
> >
> > Do you have a patch for the handle implementation I could look
> > at?
>
> 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.
>
>
> --- include/linux/pm_qos_params.h.orig
> +++ include/linux/pm_qos_params.h
> @@ -16,7 +16,11 @@
>
> 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);
> +int pm_qos_remove_requirement(int qos, char *name);
> +
> +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);
>
> int pm_qos_requirement(int qos);
>
> --- kernel/pm_qos_params.c.orig
> +++ kernel/pm_qos_params.c
> @@ -55,6 +55,8 @@ struct requirement_list {
> s32 kbps;
> };
> char *name;
> + int pm_qos_class;
> + int handle_count;
> };
>
> static s32 max_compare(s32 v1, s32 v2);
> @@ -210,7 +212,9 @@ EXPORT_SYMBOL_GPL(pm_qos_requirement);
> int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value)
> {
> struct requirement_list *dep;
> + struct requirement_list *node;
> unsigned long flags;
> + int retval;
>
> dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL);
> if (dep) {
> @@ -219,10 +223,25 @@ int pm_qos_add_requirement(int pm_qos_class,
> char *name, s32 value)
> else
> dep->value = value;
> dep->name = kstrdup(name, GFP_KERNEL);
> - if (!dep->name)
> + if (!dep->name) {
> + retval = -ENOMEM;
> goto cleanup;
> + }
> + dep->pm_qos_class = pm_qos_class;
>
> spin_lock_irqsave(&pm_qos_lock, flags);
> + /* make sure the new name is unique */
> + list_for_each_entry(node,
> +
> &pm_qos_array[pm_qos_class]->requirements.list, list) {
> + if (strcmp(node->name, name) == 0) {
> + spin_unlock_irqrestore(&pm_qos_lock,
> flags);
> +
> + kfree(dep->name);
> + retval = -EINVAL;
> + goto cleanup;
> + }
> + }
> +
> list_add(&dep->list,
>
> &pm_qos_array[pm_qos_class]->requirements.list);
> spin_unlock_irqrestore(&pm_qos_lock, flags);
> @@ -231,9 +250,11 @@ int pm_qos_add_requirement(int pm_qos_class,
> char *name, s32 value)
> return 0;
> }
>
> + retval = -ENOMEM;
> +
> cleanup:
> kfree(dep);
> - return -ENOMEM;
> + return retval;
> }
> EXPORT_SYMBOL_GPL(pm_qos_add_requirement);
>
> @@ -282,8 +303,10 @@ EXPORT_SYMBOL_GPL(pm_qos_update_requirement);
> *
> * Will remove named qos request from pm_qos_class list of
> parameters and
> * recompute the current target value for the pm_qos_class.
> + *
> + * If there are outstanding handles to the request, -EBUSY is
> returned.
> */
> -void pm_qos_remove_requirement(int pm_qos_class, char *name)
> +int pm_qos_remove_requirement(int pm_qos_class, char *name)
> {
> unsigned long flags;
> struct requirement_list *node;
> @@ -293,6 +316,11 @@ void pm_qos_remove_requirement(int pm_qos_class,
> char *name)
> list_for_each_entry(node,
> &pm_qos_array[pm_qos_class]->requirements.list, list)
> {
> if (strcmp(node->name, name) == 0) {
> + if (node->handle_count > 0) {
> + spin_unlock_irqrestore(&pm_qos_lock,
> flags);
> + return -EBUSY;
> + }
> +
> kfree(node->name);
> list_del(&node->list);
> kfree(node);
> @@ -303,9 +331,83 @@ void pm_qos_remove_requirement(int pm_qos_class,
> char *name)
> spin_unlock_irqrestore(&pm_qos_lock, flags);
> if (pending_update)
> update_target(pm_qos_class);
> +
> + return 0;
> }
> EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
>
> +/* pm_qos_get - returns an opaque handle to the existing qos request
> + * @pm_qos_class: identifies which list of qos request to us
> + * @name: identifies the request
> + *
> + * Will increment the reference count as well.
> + *
> + * If the named request isn't in the list then NULL is returned.
> + */
> +void *pm_qos_get(int pm_qos_class, char *name)
> +{
> + unsigned long flags;
> + struct requirement_list *node;
> + struct requirement_list *handle = NULL;
> +
> + 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) {
> + node->handle_count++;
> + handle = node;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(&pm_qos_lock, flags);
> + return handle;
> +}
> +EXPORT_SYMBOL_GPL(pm_qos_get);
> +
> +/* pm_qos_put - release the handle of the existing qos request
> + * @handle: previously acquired through pm_qos_get
> + *
> + * Will decrement the reference count as well. Caller should no
> + * longer use the handle after this call.
> + */
> +int pm_qos_put(void *handle)
> +{
> + unsigned long flags;
> + struct requirement_list *node = (struct requirement_list *)
> handle;
> +
> + spin_lock_irqsave(&pm_qos_lock, flags);
> + BUG_ON(node->handle_count == 0);
> + node->handle_count--;
> + spin_unlock_irqrestore(&pm_qos_lock, flags);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(pm_qos_put);
> +
> +/* pm_qos_update_requirement_direct - modifies an existing qos
> request
> + * @handle: previously acquired through pm_qos_get
> + * @value: defines the qos request
> + *
> + * Updates an existing qos requirement for the pm_qos_class of
> parameters along
> + * with updating the target pm_qos_class value.
> + */
> +int pm_qos_update_requirement_direct(void *handle, s32 new_value)
> +{
> + unsigned long flags;
> + struct requirement_list *node = (struct requirement_list *)
> handle;
> +
> + spin_lock_irqsave(&pm_qos_lock, flags);
> + if (new_value == PM_QOS_DEFAULT_VALUE)
> + node->value =
> pm_qos_array[node->pm_qos_class]->default_value;
> + else
> + node->value = new_value;
> + spin_unlock_irqrestore(&pm_qos_lock, flags);
> + update_target(node->pm_qos_class);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(pm_qos_update_requirement_direct);
> +
> /**
> * pm_qos_add_notifier - sets notification entry for changes to
> target value
> * @pm_qos_class: identifies which qos target changes should be
> notified.
>
>
> ~Ai
next prev parent reply other threads:[~2009-11-03 20:29 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 [this message]
2009-11-18 1:06 ` Ai Li
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=20091103202954.GA25275@linux.intel.com \
--to=mgross@linux.intel.com \
--cc=aili@codeaurora.org \
--cc=linux-pm@lists.linux-foundation.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox