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:   Tue, 29 Nov 2016 10:41:15 +0530
From:   Viresh Kumar <viresh.kumar@...aro.org>
To:     Stephen Boyd <sboyd@...eaurora.org>
Cc:     Rafael Wysocki <rjw@...ysocki.net>, jy0922.shim@...sung.com,
        Viresh Kumar <vireshk@...nel.org>, Nishanth Menon <nm@...com>,
        linaro-kernel@...ts.linaro.org, linux-pm@...r.kernel.org,
        linux-kernel@...r.kernel.org, stable@...r.kernel.org
Subject: Re: [PATCH] PM / OPP: Allow inactive opp_device to be present in dev
 list

On 28-11-16, 18:46, Stephen Boyd wrote:
> Anyway, rant over, how about handing out the opp table pointer to
> the caller so they can pass it back in when they call the put
> side? That should fix the same problem if I understand correctly.

Hmm, so the problem is that all below routines (and their callers) need to get
updated:

int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
void dev_pm_opp_put_supported_hw(struct device *dev);
int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
void dev_pm_opp_put_prop_name(struct device *dev);
struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name);
void dev_pm_opp_put_regulator(struct opp_table *opp_table);

And that will make it difficult to get it back to stable kernels, specially
because they were all added in different kernel releases after 4.4.

And we also need to fix them properly, with something like a cookie instead of a
plain opp_table pointer.

I suggest this patch for the time being, with a big FIXME in it, so that we can
get it to stable kernels.

-------------------------8<-------------------------

diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c
index 8c3434bdb26d..2e96efdb10b2 100644
--- a/drivers/base/power/opp/cpu.c
+++ b/drivers/base/power/opp/cpu.c
@@ -118,26 +118,45 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev,
 EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
 #endif /* CONFIG_CPU_FREQ */
 
+void _cpu_remove_table(unsigned int cpu, bool of)
+{
+       struct device *cpu_dev = get_cpu_device(cpu);
+
+       if (!cpu_dev) {
+               pr_err("%s: failed to get cpu%d device\n", __func__, cpu);
+               return;
+       }
+
+       if (of)
+               dev_pm_opp_of_remove_table(cpu_dev);
+       else
+               dev_pm_opp_remove_table(cpu_dev);
+}
+
 void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
 {
        struct device *cpu_dev;
-       int cpu;
+       int cpu, first_cpu;
 
        WARN_ON(cpumask_empty(cpumask));
 
-       for_each_cpu(cpu, cpumask) {
-               cpu_dev = get_cpu_device(cpu);
-               if (!cpu_dev) {
-                       pr_err("%s: failed to get cpu%d device\n", __func__,
-                              cpu);
-                       continue;
-               }
-
-               if (of)
-                       dev_pm_opp_of_remove_table(cpu_dev);
-               else
-                       dev_pm_opp_remove_table(cpu_dev);
-       }
+       /*
+        * The first cpu in the cpumask is important as that is used to create
+        * the opp-table initially and routines like dev_pm_opp_put_regulator()
+        * will expect the list-dev for the first CPU to be present while such
+        * routines are called, otherwise we will fail to find the opp-table for
+        * such devices.
+        *
+        * FIXME: Cleanup this mess and implement cookie based solutions instead
+        * of working on the device pointer.
+        */
+       first_cpu = cpumask_first(cpumask);
+       cpumask_clear_cpu(first_cpu, cpumask);
+
+       for_each_cpu(cpu, cpumask)
+               _cpu_remove_table(cpu, of);
+
+       _cpu_remove_table(first_cpu, of);
 }
 
 /**

-- 
viresh

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ