lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 13 Jun 2013 15:19:22 +0800
From:	Xiaoguang Chen <chenxg.marvell@...il.com>
To:	Viresh Kumar <viresh.kumar@...aro.org>
Cc:	Xiaoguang Chen <chenxg@...vell.com>,
	"Rafael J. Wysocki" <rjw@...k.pl>, cpufreq@...r.kernel.org,
	linux-pm@...r.kernel.org,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	njiang1@...vell.com, zjwu@...vell.com, ylmao@...vell.com
Subject: Re: [PATCH v4] cpufreq: fix governor start/stop race condition

2013/6/13 Viresh Kumar <viresh.kumar@...aro.org>:
> On 13 June 2013 11:10, Xiaoguang Chen <chenxg.marvell@...il.com> wrote:
>> 2013/6/12 Viresh Kumar <viresh.kumar@...aro.org>:
>>> On 12 June 2013 14:39, Xiaoguang Chen <chenxg@...vell.com> wrote:
>>>
>>>>         ret = policy->governor->governor(policy, event);
>>>
>>> We again reached to the same problem. We shouldn't call
>>> this between taking locks, otherwise recursive locks problems
>>> would be seen again.
>>
>> But this is not the same lock as the deadlock case, it is a new lock,
>> and only used in this function. no other functions use this lock.
>> I don't know how can we get dead lock again?
>
> I believe I have seen the recursive lock issue with different locks but
> I am not sure. Anyway, I believe the implementation can be simpler than
> that.
>
> Check below patch (attached too):
>
> ------------x------------------x----------------
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 2d53f47..80b9798 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -46,6 +46,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *,
> cpufreq_cpu_data);
>  static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
>  #endif
>  static DEFINE_RWLOCK(cpufreq_driver_lock);
> +static DEFINE_MUTEX(cpufreq_governor_lock);
>
>  /*
>   * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
> @@ -1541,7 +1542,6 @@ static int __cpufreq_governor(struct
> cpufreq_policy *policy,
>  #else
>         struct cpufreq_governor *gov = NULL;
>  #endif
> -
>         if (policy->governor->max_transition_latency &&
>             policy->cpuinfo.transition_latency >
>             policy->governor->max_transition_latency) {
> @@ -1562,6 +1562,21 @@ static int __cpufreq_governor(struct
> cpufreq_policy *policy,
>
>         pr_debug("__cpufreq_governor for CPU %u, event %u\n",
>                                                 policy->cpu, event);
> +
> +       mutex_lock(&cpufreq_governor_lock);
> +       if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
> +           (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
> +               mutex_unlock(&cpufreq_governor_lock);
> +               return -EBUSY;
> +       }
> +
> +       if (event == CPUFREQ_GOV_STOP)
> +               policy->governor_enabled = 0;
> +       else if (event == CPUFREQ_GOV_START)
> +               policy->governor_enabled = 1;
> +
> +       mutex_unlock(&cpufreq_governor_lock);
> +
>         ret = policy->governor->governor(policy, event);
>
>         if (!ret) {
> @@ -1569,6 +1584,14 @@ static int __cpufreq_governor(struct
> cpufreq_policy *policy,
>                         policy->governor->initialized++;
>                 else if (event == CPUFREQ_GOV_POLICY_EXIT)
>                         policy->governor->initialized--;
> +       } else {
> +               /* Restore original values */
> +               mutex_lock(&cpufreq_governor_lock);
> +               if (event == CPUFREQ_GOV_STOP)
> +                       policy->governor_enabled = 1;
> +               else if (event == CPUFREQ_GOV_START)
> +                       policy->governor_enabled = 0;
> +               mutex_unlock(&cpufreq_governor_lock);
>         }
>
>         /* we keep one module reference alive for
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 037d36a..c12db73 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -107,6 +107,7 @@ struct cpufreq_policy {
>         unsigned int            policy; /* see above */
>         struct cpufreq_governor *governor; /* see below */
>         void                    *governor_data;
> +       int                     governor_enabled; /* governor start/stop flag */
>
>         struct work_struct      update; /* if update_policy() needs to be
>                                          * called, but you're in IRQ context */

Thanks
So you add the return value checking, I was about to do it in another patch :)
this patch is simpler than my previous patch,  it is ok for me.
Do I need to submit it again or it can be merged?

Thanks
Xiaoguang
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ