linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Mohammad Merajul Islam Molla <meraj.enigma@gmail.com>,
	kernelnewbies <kernelnewbies@kernelnewbies.org>,
	linux-pm@vger.kernel.org
Subject: Re: Need help understanding the logic of __cpuidle_set_driver
Date: Thu, 21 Aug 2014 04:04:25 +0200	[thread overview]
Message-ID: <53F553A9.7050104@linaro.org> (raw)
In-Reply-To: <CAHu9=sOwSuw5igPp0UQWJe8fwMb_vt3PPrc1A9nK4pJB5QmXDA@mail.gmail.com>

On 08/15/2014 12:20 PM, Mohammad Merajul Islam Molla wrote:
> Hello,
>
> I was looking into the code of drivers/cpuidle/driver.c. I have some
> doubts regarding the implementation of __cpuidle_set_driver function
> when CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is defined.
>
> If CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is defined, the code for
> __cpuidle_set_driver/__cpuidle_unset_driver looks as -
>
>   39  * __cpuidle_unset_driver - unset per CPU driver variables.
>   40  * @drv: a valid pointer to a struct cpuidle_driver
>   41  *
>   42  * For each CPU in the driver's CPU mask, unset the registered
> driver per CPU
>   43  * variable. If @drv is different from the registered driver, the
> corresponding
>   44  * variable is not cleared.
>   45  */
>   46 static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
>   47 {
>   48         int cpu;
>   49
>   50         for_each_cpu(cpu, drv->cpumask) {
>   51
>   52                 if (drv != __cpuidle_get_cpu_driver(cpu))
>   53                         continue;
>   54
>   55                 per_cpu(cpuidle_drivers, cpu) = NULL;
>   56         }
>   57 }
>   58
>   59 /**
>   60  * __cpuidle_set_driver - set per CPU driver variables for the given driver.
>   61  * @drv: a valid pointer to a struct cpuidle_driver
>   62  *
>   63  * For each CPU in the driver's cpumask, unset the registered driver per CPU
>   64  * to @drv.
>   65  *
>   66  * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
>   67  */
>   68 static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
>   69 {
>   70         int cpu;
>   71
>   72         for_each_cpu(cpu, drv->cpumask) {
>   73
>   74                 if (__cpuidle_get_cpu_driver(cpu)) {
>   75                         __cpuidle_unset_driver(drv);
>   76                         return -EBUSY;
>   77                 }
>   78
>   79                 per_cpu(cpuidle_drivers, cpu) = drv;
>   80         }
>   81
>   82         return 0;
>   83 }
>
> Apparently, the comment should be - "set/register the driver per CPU
> to @drv" instead of "unset the registered driver per CPU to @drv" in
> case of __cpuidle_set_driver.

Right, it is a typo.

> However, regarding the logic, I have a few doubts -
>
> 1. for each cpu in drv->cpumask, if there is already a driver
> registered, its calling __cpuidle_unset_driver which loops over for
> each cpu in drv->cpumask again. Isn't it unnecessary to do this nested
> calls?

It is to rollback the previous changes done in the loop.

> 2. after calling __cpuidle_unset_driver, if drv equals already
> registered driver, it sets per_cpu driver to null? Isn't it wrong when
> we are trying to set to a new driver? Why do we need to unset and make
> the driver null when we are returning EBUSY from __cpuidle_set_driver?
>
> Would it be correct and cleaner if the code is written as below -
>
>   static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
>   {
>           int ret = -EBUSY;
>           int cpu;
>
>          for_each_cpu(cpu, drv->cpumask) {
>                  if (drv == __cpuidle_get_cpu_driver(cpu))    [if drv
> is already the registered driver, do nothing]
>                           continue;
>
>                   per_cpu(cpuidle_drivers, cpu) = drv;  [if only drv !=
> already registered driver, set per_cpu driver to drv and set ret 0]
>                   ret = 0;
>           }
>
>           return ret;     [only if all cpus already had drv as
> registered driver, return -EBUSY. Otherwise return 0]
>   }
>
>
> Please let me know your views.
>
> --
> Thanks,
> -Meraj
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


  parent reply	other threads:[~2014-08-21  2:04 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-15 10:20 Need help understanding the logic of __cpuidle_set_driver Mohammad Merajul Islam Molla
2014-08-15 12:41 ` AYAN KUMAR HALDER
2014-08-16  6:13   ` Mohammad Merajul Islam Molla
2014-08-21  2:04 ` Daniel Lezcano [this message]
2014-08-22 12:06   ` AYAN KUMAR HALDER

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=53F553A9.7050104@linaro.org \
    --to=daniel.lezcano@linaro.org \
    --cc=kernelnewbies@kernelnewbies.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=meraj.enigma@gmail.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 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).