linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: toddpoynor@google.com (Todd Poynor)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 6/8] OMAP2+: omap_device: implement the constraints management code
Date: Wed, 4 May 2011 15:11:38 -0700	[thread overview]
Message-ID: <BANLkTinVCLiXYoPcP905Fhv2ejUH1QfLBw@mail.gmail.com> (raw)
In-Reply-To: <1304516117-9334-7-git-send-email-j-pihet@ti.com>

On Wed, May 4, 2011 at 6:35 AM, <jean.pihet@newoldbits.com> wrote:

> ...
> diff --git a/arch/arm/plat-omap/omap_device.c
> b/arch/arm/plat-omap/omap_device.c
> index 9bbda9a..1d075cb 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -292,10 +292,196 @@ static void _add_optional_clock_clkdev(struct
> omap_device *od,
>        }
>  }
>
> +/* Spinlock that protects the constraints lists */
> +static spinlock_t _constraints_lock;
> +
> +/*
> + * _store_constraint: add/update/remove a constraint from a plist. There
> is
> + *  one plist per omap_device.
> + *
> + * @constraints_list: plist to use
> + * @req_dev: constraint requester, used to track the requests
> + * @dev: device constraint target, used to track the requests
> + * @value: constraint value. The plist is sorted by the value. -1 remove
> the
> + *  constraint from the list
> + * @ascending: return the lowest constraint value if set to 1, return the
> + *  highest value if not.
> + *
> + * Tracks the constraints by req_dev and dev.
> + * Returns the strongest constraint value for the given device, 0 in the
> + * case there is no constraint or a negative value in case of error.
> + *
> + * The caller must check the validity of the parameters.
> + */
> +static long _store_constraint(struct plist_head *constraints_list,
> +                             struct device *req_dev, struct device *dev,
> +                             long value, int ascending)
> +{
> +       struct omap_device_constraints_entry *user = NULL, *tmp_user;
> +       int ret = 0;
> +       unsigned long flags;
> +
> +       /* Check if there already is a constraint for dev and req_dev */
> +       spin_lock_irqsave(&_constraints_lock, flags);
> +       plist_for_each_entry(tmp_user, constraints_list, node) {
> +               if ((tmp_user->req_dev == req_dev) && (tmp_user->dev ==
> dev)) {
> +                       user = tmp_user;
> +                       break;
> +               }
> +       }
> +       spin_unlock_irqrestore(&_constraints_lock, flags);
> +
> +       if (value >= 0) {
> +               /* Nothing to update, job done */
> +               if (user && (user->node.prio == value))
> +                       goto exit_ok;
> +
> +               /* Add new entry to the list or update existing request */
> +               if (!user) {
> +                       user = kzalloc(
> +                               sizeof(struct
> omap_device_constraints_entry),
> +                               GFP_KERNEL);
> +                       if (!user) {
> +                               pr_err("%s: FATAL ERROR: kzalloc failed\n",
> +                                      __func__);
> +                               ret = -ENOMEM;
> +                               goto exit_error;
> +                       }
> +                       user->req_dev = req_dev;
> +                       user->dev = dev;
> +               } else {
> +                       spin_lock_irqsave(&_constraints_lock, flags);
> +                       plist_del(&user->node, constraints_list);
>

spinlock was dropped, no ref counting, not safe to assume user is still
valid.


> +                       spin_unlock_irqrestore(&_constraints_lock, flags);
> +               }
> +
> +               spin_lock_irqsave(&_constraints_lock, flags);
> +               plist_node_init(&user->node, value);
>

and user may be invalid here


> +               plist_add(&user->node, constraints_list);
> +               spin_unlock_irqrestore(&_constraints_lock, flags);
> +       } else {
> +               /* Remove the constraint from the list */
> +               if (!user) {
> +                       pr_err("%s: Error: no prior constraint to
> release\n",
> +                              __func__);
> +                       ret = -EINVAL;
> +                       goto exit_error;
> +               }
> +
> +               spin_lock_irqsave(&_constraints_lock, flags);
> +               plist_del(&user->node, constraints_list);
>

and here


> +               spin_unlock_irqrestore(&_constraints_lock, flags);
> +               kfree(user);
> +       }
> +
> +exit_ok:
> +       /* Find the strongest constraint for the given device */
> +       if (!plist_head_empty(constraints_list)) {
> +               spin_lock_irqsave(&_constraints_lock, flags);
>

Deref of plist_first/last() should happen after a plist_head_empty() check
with the spinlock held.


> +               if (ascending) {
> +                       /* Find the lowest (i.e. first) value */
> +                       ret = plist_first(constraints_list)->prio;
> +               } else {
> +                       /* Find the highest (i.e. last) value */
> +                       ret = plist_last(constraints_list)->prio;
> +               }
> +               spin_unlock_irqrestore(&_constraints_lock, flags);
> +       }
> +
> +exit_error:
> +       return ret;
> +}
> ...
>

Todd
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110504/49eafa40/attachment-0001.html>

  reply	other threads:[~2011-05-04 22:11 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-04 13:35 [PATCH v4 0/8] OMAP: add PM_CONSTRAINTS framework jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 1/8] OMAP PM: create a PM layer plugin for per-device constraints jean.pihet at newoldbits.com
2011-05-04 13:59   ` Tony Lindgren
2011-05-04 14:36     ` Kevin Hilman
2011-05-05  6:00       ` Tony Lindgren
2011-05-06  6:20         ` Tony Lindgren
2011-05-04 13:35 ` [PATCH 2/8] OMAP2+: powerdomain: control power domains next state jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 3/8] OMAP3: powerdomain data: add wake-up latency figures jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 4/8] OMAP2+: omap_hwmod: manage the omap_devices the wake-up latency constraints jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 5/8] OMAP: PM CONSTRAINTS: add an enum for the classes of constraint jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 6/8] OMAP2+: omap_device: implement the constraints management code jean.pihet at newoldbits.com
2011-05-04 22:11   ` Todd Poynor [this message]
2011-05-04 13:35 ` [PATCH 7/8] OMAP: PM CONSTRAINTS: implement wake-up latency constraints jean.pihet at newoldbits.com
2011-05-04 13:35 ` [PATCH 8/8] OMAP PM: early init of the pwrdms states jean.pihet at newoldbits.com
  -- strict thread matches above, loose matches on Subject: below --
2011-03-30 15:19 [PATCH v3 0/8] OMAP: add PM CONSTRAINTS framework jean.pihet at newoldbits.com
2011-03-30 15:19 ` [PATCH 6/8] OMAP2+: omap_device: implement the constraints management code jean.pihet at newoldbits.com

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=BANLkTinVCLiXYoPcP905Fhv2ejUH1QfLBw@mail.gmail.com \
    --to=toddpoynor@google.com \
    --cc=linux-arm-kernel@lists.infradead.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;
as well as URLs for NNTP newsgroup(s).