mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] OPP usage fixes for RCU locking
@ 2013-01-18 19:52 Nishanth Menon
  2013-01-18 19:52 ` [PATCH 1/4] cpufreq: OMAP: use RCU locks around usage of OPP Nishanth Menon
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Nishanth Menon @ 2013-01-18 19:52 UTC (permalink / raw)
  To: linux-pm
  Cc: Rafael, Kevin, MyungJoo Ham, lkml, lo, Jack, Alexander, Nishanth Menon

Hi,
Despite being documented in function documentation and in
Documentation/power/opp.txt, many of the users of OPP APIs
dont honor RCU lock usage appropriately.

This recently appeared in IRC discussion earlier today [1]. 
I did an audit of current usage and the following series
is a result of this.

NOTE:
1. The patch "PM / devfreq: exynos4_bus: honor RCU lock usage" has only
   been build tested as I dont have an exynos platform to try it on. I have
   tried to make it as least intrusive as possible and at least reviewed
   to ensure I haven't screwed anything up.

Other than this, I have added appropriate tested by information in requisite
patches.

Series is based off: v3.8-rc4 tag
Also available in the following location[2]:
https://github.com/nmenon/linux-2.6-playground branch: post/pm/opp-fixes-v1

Nishanth Menon (4):
  cpufreq: OMAP: use RCU locks around usage of OPP
  cpufreq: cpufreq-cpu0: use RCU locks around usage of OPP
  PM / devfreq: add locking documentation for recommend_opp
  PM / devfreq: exynos4_bus: honor RCU lock usage

 drivers/cpufreq/cpufreq-cpu0.c |    5 +++
 drivers/cpufreq/omap-cpufreq.c |    3 ++
 drivers/devfreq/devfreq.c      |    5 +++
 drivers/devfreq/exynos4_bus.c  |   94 ++++++++++++++++++++++++++++------------
 4 files changed, 80 insertions(+), 27 deletions(-)

[1] http://www.beagleboard.org/irclogs/index.php?date=2013-01-18#T14:14:07
[2] https://github.com/nmenon/linux-2.6-playground/commits/post/pm/opp-fixes-v1

Regards,
Nishanth Menon
-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] cpufreq: OMAP: use RCU locks around usage of OPP
  2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
@ 2013-01-18 19:52 ` Nishanth Menon
  2013-01-18 19:52 ` [PATCH 2/4] cpufreq: cpufreq-cpu0: " Nishanth Menon
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Nishanth Menon @ 2013-01-18 19:52 UTC (permalink / raw)
  To: linux-pm
  Cc: Rafael, Kevin, MyungJoo Ham, lkml, lo, Jack, Alexander, Nishanth Menon

OPP pointer is RCU protected, hence after finding it, de-reference
also should be protected with the same RCU context else the OPP
pointer may become invalid.

Reported-by: Alexander Holler <holler@ahsoftware.de>
Tested-by: Alexander Holler <holler@ahsoftware.de>
Acked-by: Alexander Holler <holler@ahsoftware.de>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/cpufreq/omap-cpufreq.c |    3 +++
 1 file changed, 3 insertions(+)

Fixes warning as follows: http://dpaste.de/5j4qX/
[ 5.175323] ===============================
[ 5.179901] [ INFO: suspicious RCU usage. ]
[ 5.184295] 3.7.1-beagleboard-00018-g65ab3da-dirty #180 Not tainted
[ 5.190979] -------------------------------
[ 5.195465] drivers/base/power/opp.c:155 suspicious rcu_dereference_check() usage!
[ 5.203460]
[ 5.203460] other info that might help us debug this:
[ 5.203460]
[ 5.211914]
[ 5.211914] rcu_scheduler_active = 1, debug_locks = 0
[ 5.219055] 3 locks held by swapper/1:
[ 5.222991] #0: (subsys mutex#5){+.+.+.}, at: [<c026217c>] subsys_interface_register+0x34/0xbc
[ 5.232360] #1: (&per_cpu(cpu_policy_rwsem, cpu)){+.+.+.}, at: [<c02d9374>] lock_policy_rwsem_write+0x24/0x48
[ 5.243072] #2: (&this_dbs_info->timer_mutex){+.+...}, at: [<c02db234>] cpufreq_governor_dbs+0x2e8/0x380
[ 5.253295]
[ 5.253295] stack backtrace:
[ 5.257965] [<c0013198>] (unwind_backtrace+0x0/0xe0) from [<c026bd08>] (opp_get_voltage+0x5c/0xc0)
[ 5.267395] [<c026bd08>] (opp_get_voltage+0x5c/0xc0) from [<c02db928>] (omap_target+0x180/0x364)
[ 5.276672] [<c02db928>] (omap_target+0x180/0x364) from [<c02d8bbc>] (__cpufreq_driver_target+0x38/0x54)
[ 5.303039] [<c02d8bbc>] (__cpufreq_driver_target+0x38/0x54) from [<c02db260>] (cpufreq_governor_dbs+0x314/0x380)
[ 5.313903] [<c02db260>] (cpufreq_governor_dbs+0x314/0x380) from [<c02d948c>] (__cpufreq_governor+0x70/0xb4)
[ 5.324310] [<c02d948c>] (__cpufreq_governor+0x70/0xb4) from [<c02d96fc>] (__cpufreq_set_policy+0x150/0x168)
[ 5.334686] [<c02d96fc>] (__cpufreq_set_policy+0x150/0x168) from [<c02d9ae0>] (cpufreq_add_dev_interface+0x17c/0x1f0)
[ 5.345886] [<c02d9ae0>] (cpufreq_add_dev_interface+0x17c/0x1f0) from [<c02d9c80>] (cpufreq_add_dev+0x12c/0x1d8)
[ 5.356628] [<c02d9c80>] (cpufreq_add_dev+0x12c/0x1d8) from [<c02621c4>] (subsys_interface_register+0x7c/0xbc)
[ 5.367187] [<c02621c4>] (subsys_interface_register+0x7c/0xbc) from [<c02d91bc>] (cpufreq_register_driver+0x9c/0x128)
[ 5.378387] [<c02d91bc>] (cpufreq_register_driver+0x9c/0x128) from [<c00086a0>] (do_one_initcall+0x90/0x164)
[ 5.395812] [<c00086a0>] (do_one_initcall+0x90/0x164) from [<c03d5740>] (kernel_init+0xe4/0x298)
[ 5.408569] [<c03d5740>] (kernel_init+0xe4/0x298) from [<c000de30>] (ret_from_fork+0x14/0x24)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 1f3417a..97102b0 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -110,13 +110,16 @@ static int omap_target(struct cpufreq_policy *policy,
 	freq = ret;
 
 	if (mpu_reg) {
+		rcu_read_lock();
 		opp = opp_find_freq_ceil(mpu_dev, &freq);
 		if (IS_ERR(opp)) {
+			rcu_read_unlock();
 			dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n",
 				__func__, freqs.new);
 			return -EINVAL;
 		}
 		volt = opp_get_voltage(opp);
+		rcu_read_unlock();
 		tol = volt * OPP_TOLERANCE / 100;
 		volt_old = regulator_get_voltage(mpu_reg);
 	}
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/4] cpufreq: cpufreq-cpu0: use RCU locks around usage of OPP
  2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
  2013-01-18 19:52 ` [PATCH 1/4] cpufreq: OMAP: use RCU locks around usage of OPP Nishanth Menon
@ 2013-01-18 19:52 ` Nishanth Menon
  2013-01-18 19:52 ` [PATCH 3/4] PM / devfreq: add locking documentation for recommended_opp Nishanth Menon
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Nishanth Menon @ 2013-01-18 19:52 UTC (permalink / raw)
  To: linux-pm
  Cc: Rafael, Kevin, MyungJoo Ham, lkml, lo, Jack, Alexander, Nishanth Menon

OPP pointer is RCU protected, hence after finding it, de-reference
also should be protected with the same RCU context else the OPP
pointer may become invalid.

Reported-by: Jack Mitchell <jack@embed.me.uk>
Tested-by: Alexander Holler <holler@ahsoftware.de>
Tested-by: Jack Mitchell <jack@embed.me.uk>
Acked-by: Alexander Holler <holler@ahsoftware.de>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/cpufreq/cpufreq-cpu0.c |    5 +++++
 1 file changed, 5 insertions(+)

Fixes warning as shown in: http://pastebin.com/6Y0bpCFi
Something similar to this was attempted to be addressed by: https://patchwork.kernel.org/patch/879022/
[    2.321123] ===============================
[    2.325591] [ INFO: suspicious RCU usage. ]
[    2.330063] 3.8.0-rc4-00291-gbb85e3f-dirty #2 Not tainted
[    2.335805] -------------------------------
[    2.340270] drivers/base/power/opp.c:157 suspicious rcu_dereference_check() usage!
[    2.348285] other info that might help us debug this:
[    2.356769] rcu_scheduler_active = 1, debug_locks = 1
[    2.363727] no locks held by swapper/0/1.
[    2.368006] stack backtrace:
[    2.372707] [<c0013678>] (unwind_backtrace+0x0/0xe0) from [<c03475bc>] (opp_get_voltage+0x78/0xc8)
[    2.382219] [<c03475bc>] (opp_get_voltage+0x78/0xc8) from [<c04046e4>] (cpu0_cpufreq_driver_init+0x154/0x208)
[    2.392727] [<c04046e4>] (cpu0_cpufreq_driver_init+0x154/0x208) from [<c0008878>] (do_one_initcall+0x90/0x164)
[    2.403323] [<c0008878>] (do_one_initcall+0x90/0x164) from [<c0547698>] (kernel_init+0xf8/0x290)
[    2.412646] [<c0547698>] (kernel_init+0xf8/0x290) from [<c000d9b0>] (ret_from_fork+0x14/0x24)

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index 52bf36d..debc5a7 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -71,12 +71,15 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
 	}
 
 	if (cpu_reg) {
+		rcu_read_lock();
 		opp = opp_find_freq_ceil(cpu_dev, &freq_Hz);
 		if (IS_ERR(opp)) {
+			rcu_read_unlock();
 			pr_err("failed to find OPP for %ld\n", freq_Hz);
 			return PTR_ERR(opp);
 		}
 		volt = opp_get_voltage(opp);
+		rcu_read_unlock();
 		tol = volt * voltage_tolerance / 100;
 		volt_old = regulator_get_voltage(cpu_reg);
 	}
@@ -236,12 +239,14 @@ static int cpu0_cpufreq_driver_init(void)
 		 */
 		for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
 			;
+		rcu_read_lock();
 		opp = opp_find_freq_exact(cpu_dev,
 				freq_table[0].frequency * 1000, true);
 		min_uV = opp_get_voltage(opp);
 		opp = opp_find_freq_exact(cpu_dev,
 				freq_table[i-1].frequency * 1000, true);
 		max_uV = opp_get_voltage(opp);
+		rcu_read_unlock();
 		ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV);
 		if (ret > 0)
 			transition_latency += ret * 1000;
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/4] PM / devfreq: add locking documentation for recommended_opp
  2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
  2013-01-18 19:52 ` [PATCH 1/4] cpufreq: OMAP: use RCU locks around usage of OPP Nishanth Menon
  2013-01-18 19:52 ` [PATCH 2/4] cpufreq: cpufreq-cpu0: " Nishanth Menon
@ 2013-01-18 19:52 ` Nishanth Menon
  2013-01-18 19:52 ` [PATCH 4/4] PM / devfreq: exynos4_bus: honor RCU lock usage Nishanth Menon
  2013-01-18 22:28 ` [PATCH 0/4] OPP usage fixes for RCU locking Rafael J. Wysocki
  4 siblings, 0 replies; 8+ messages in thread
From: Nishanth Menon @ 2013-01-18 19:52 UTC (permalink / raw)
  To: linux-pm
  Cc: Rafael, Kevin, MyungJoo Ham, lkml, lo, Jack, Alexander, Nishanth Menon

OPP pointers are protected by RCU locks, the pointer validity is
permissible only under the section of rcu_read_lock to rcu_read_unlock

Add documentation to the effect.

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/devfreq/devfreq.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 53766f3..3b36797 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -994,6 +994,11 @@ module_exit(devfreq_exit);
  * @freq:	The frequency given to target function
  * @flags:	Flags handed from devfreq framework.
  *
+ * Locking: This function must be called under rcu_read_lock(). opp is a rcu
+ * protected pointer. The reason for the same is that the opp pointer which is
+ * returned will remain valid for use with opp_get_{voltage, freq} only while
+ * under the locked area. The pointer returned must be used prior to unlocking
+ * with rcu_read_unlock() to maintain the integrity of the pointer.
  */
 struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
 				    u32 flags)
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/4] PM / devfreq: exynos4_bus: honor RCU lock usage
  2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
                   ` (2 preceding siblings ...)
  2013-01-18 19:52 ` [PATCH 3/4] PM / devfreq: add locking documentation for recommended_opp Nishanth Menon
@ 2013-01-18 19:52 ` Nishanth Menon
  2013-01-18 22:28 ` [PATCH 0/4] OPP usage fixes for RCU locking Rafael J. Wysocki
  4 siblings, 0 replies; 8+ messages in thread
From: Nishanth Menon @ 2013-01-18 19:52 UTC (permalink / raw)
  To: linux-pm
  Cc: Rafael, Kevin, MyungJoo Ham, lkml, lo, Jack, Alexander, Nishanth Menon

OPP pointers cannot be expected to be valid beyond the boundary
of rcu_read_lock and rcu_read_unlock. Unfortunately, the current
exynos4 busfreq driver does not honor the usage constraint and stores
the OPP pointer in struct busfreq_data. This could potentially
become invalid later such as: across devfreq opp change decisions,
resulting in unpredictable behavior.

To fix this, we introduce a busfreq specific busfreq_opp_info
structure which is used to handle OPP information. OPP information
is de-referenced to voltage and frequency pairs as needed into
busfreq_opp_info structure and used as needed.

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/devfreq/exynos4_bus.c |   94 +++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 27 deletions(-)

diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
index 80c745e..6d72f12 100644
--- a/drivers/devfreq/exynos4_bus.c
+++ b/drivers/devfreq/exynos4_bus.c
@@ -73,6 +73,16 @@ enum busclk_level_idx {
 #define EX4210_LV_NUM	(LV_2 + 1)
 #define EX4x12_LV_NUM	(LV_4 + 1)
 
+/**
+ * struct busfreq_opp_info - opp information for bus
+ * @rate:	Frequency in hertz
+ * @volt:	Voltage in microvolts corresponding to this OPP
+ */
+struct busfreq_opp_info {
+	unsigned long rate;
+	unsigned long volt;
+};
+
 struct busfreq_data {
 	enum exynos4_busf_type type;
 	struct device *dev;
@@ -80,7 +90,7 @@ struct busfreq_data {
 	bool disabled;
 	struct regulator *vdd_int;
 	struct regulator *vdd_mif; /* Exynos4412/4212 only */
-	struct opp *curr_opp;
+	struct busfreq_opp_info curr_oppinfo;
 	struct exynos4_ppmu dmc[2];
 
 	struct notifier_block pm_notifier;
@@ -296,13 +306,14 @@ static unsigned int exynos4x12_clkdiv_sclkip[][3] = {
 };
 
 
-static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
+static int exynos4210_set_busclk(struct busfreq_data *data,
+				 struct busfreq_opp_info *oppi)
 {
 	unsigned int index;
 	unsigned int tmp;
 
 	for (index = LV_0; index < EX4210_LV_NUM; index++)
-		if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk)
+		if (oppi->rate == exynos4210_busclk_table[index].clk)
 			break;
 
 	if (index == EX4210_LV_NUM)
@@ -361,13 +372,14 @@ static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
 	return 0;
 }
 
-static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp)
+static int exynos4x12_set_busclk(struct busfreq_data *data,
+				 struct busfreq_opp_info *oppi)
 {
 	unsigned int index;
 	unsigned int tmp;
 
 	for (index = LV_0; index < EX4x12_LV_NUM; index++)
-		if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk)
+		if (oppi->rate == exynos4x12_mifclk_table[index].clk)
 			break;
 
 	if (index == EX4x12_LV_NUM)
@@ -576,11 +588,12 @@ static int exynos4x12_get_intspec(unsigned long mifclk)
 	return -EINVAL;
 }
 
-static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
-			       struct opp *oldopp)
+static int exynos4_bus_setvolt(struct busfreq_data *data,
+			       struct busfreq_opp_info *oppi,
+			       struct busfreq_opp_info *oldoppi)
 {
 	int err = 0, tmp;
-	unsigned long volt = opp_get_voltage(opp);
+	unsigned long volt = oppi->volt;
 
 	switch (data->type) {
 	case TYPE_BUSF_EXYNOS4210:
@@ -595,11 +608,11 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
 		if (err)
 			break;
 
-		tmp = exynos4x12_get_intspec(opp_get_freq(opp));
+		tmp = exynos4x12_get_intspec(oppi->rate);
 		if (tmp < 0) {
 			err = tmp;
 			regulator_set_voltage(data->vdd_mif,
-					      opp_get_voltage(oldopp),
+					      oldoppi->volt,
 					      MAX_SAFEVOLT);
 			break;
 		}
@@ -609,7 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
 		/*  Try to recover */
 		if (err)
 			regulator_set_voltage(data->vdd_mif,
-					      opp_get_voltage(oldopp),
+					      oldoppi->volt,
 					      MAX_SAFEVOLT);
 		break;
 	default:
@@ -626,17 +639,26 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
 	struct platform_device *pdev = container_of(dev, struct platform_device,
 						    dev);
 	struct busfreq_data *data = platform_get_drvdata(pdev);
-	struct opp *opp = devfreq_recommended_opp(dev, _freq, flags);
-	unsigned long freq = opp_get_freq(opp);
-	unsigned long old_freq = opp_get_freq(data->curr_opp);
+	struct opp *opp;
+	unsigned long freq;
+	unsigned long old_freq = data->curr_oppinfo.rate;
+	struct busfreq_opp_info	new_oppinfo;
 
-	if (IS_ERR(opp))
+	rcu_read_lock();
+	opp = devfreq_recommended_opp(dev, _freq, flags);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
 		return PTR_ERR(opp);
+	}
+	new_oppinfo.rate = opp_get_freq(opp);
+	new_oppinfo.volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+	freq = new_oppinfo.rate;
 
 	if (old_freq == freq)
 		return 0;
 
-	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp));
+	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, new_oppinfo.volt);
 
 	mutex_lock(&data->lock);
 
@@ -644,17 +666,18 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
 		goto out;
 
 	if (old_freq < freq)
-		err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
 	if (err)
 		goto out;
 
 	if (old_freq != freq) {
 		switch (data->type) {
 		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, opp);
+			err = exynos4210_set_busclk(data, &new_oppinfo);
 			break;
 		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, opp);
+			err = exynos4x12_set_busclk(data, &new_oppinfo);
 			break;
 		default:
 			err = -EINVAL;
@@ -664,11 +687,12 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
 		goto out;
 
 	if (old_freq > freq)
-		err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
 	if (err)
 		goto out;
 
-	data->curr_opp = opp;
+	data->curr_oppinfo = new_oppinfo;
 out:
 	mutex_unlock(&data->lock);
 	return err;
@@ -702,7 +726,7 @@ static int exynos4_bus_get_dev_status(struct device *dev,
 
 	exynos4_read_ppmu(data);
 	busier_dmc = exynos4_get_busier_dmc(data);
-	stat->current_frequency = opp_get_freq(data->curr_opp);
+	stat->current_frequency = data->curr_oppinfo.rate;
 
 	if (busier_dmc)
 		addr = S5P_VA_DMC1;
@@ -933,6 +957,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
 	struct busfreq_data *data = container_of(this, struct busfreq_data,
 						 pm_notifier);
 	struct opp *opp;
+	struct busfreq_opp_info	new_oppinfo;
 	unsigned long maxfreq = ULONG_MAX;
 	int err = 0;
 
@@ -943,18 +968,29 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
 
 		data->disabled = true;
 
+		rcu_read_lock();
 		opp = opp_find_freq_floor(data->dev, &maxfreq);
+		if (IS_ERR(opp)) {
+			rcu_read_unlock();
+			dev_err(data->dev, "%s: unable to find a min freq\n",
+				__func__);
+			return PTR_ERR(opp);
+		}
+		new_oppinfo.rate = opp_get_freq(opp);
+		new_oppinfo.volt = opp_get_voltage(opp);
+		rcu_read_unlock();
 
-		err = exynos4_bus_setvolt(data, opp, data->curr_opp);
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
 		if (err)
 			goto unlock;
 
 		switch (data->type) {
 		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, opp);
+			err = exynos4210_set_busclk(data, &new_oppinfo);
 			break;
 		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, opp);
+			err = exynos4x12_set_busclk(data, &new_oppinfo);
 			break;
 		default:
 			err = -EINVAL;
@@ -962,7 +998,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
 		if (err)
 			goto unlock;
 
-		data->curr_opp = opp;
+		data->curr_oppinfo = new_oppinfo;
 unlock:
 		mutex_unlock(&data->lock);
 		if (err)
@@ -1027,13 +1063,17 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 		}
 	}
 
+	rcu_read_lock();
 	opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
 	if (IS_ERR(opp)) {
+		rcu_read_unlock();
 		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
 			exynos4_devfreq_profile.initial_freq);
 		return PTR_ERR(opp);
 	}
-	data->curr_opp = opp;
+	data->curr_oppinfo.rate = opp_get_freq(opp);
+	data->curr_oppinfo.volt = opp_get_voltage(opp);
+	rcu_read_unlock();
 
 	platform_set_drvdata(pdev, data);
 
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] OPP usage fixes for RCU locking
  2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
                   ` (3 preceding siblings ...)
  2013-01-18 19:52 ` [PATCH 4/4] PM / devfreq: exynos4_bus: honor RCU lock usage Nishanth Menon
@ 2013-01-18 22:28 ` Rafael J. Wysocki
  2013-01-21  5:45   ` MyungJoo Ham
  4 siblings, 1 reply; 8+ messages in thread
From: Rafael J. Wysocki @ 2013-01-18 22:28 UTC (permalink / raw)
  To: Nishanth Menon, MyungJoo Ham; +Cc: linux-pm, Kevin, lkml, lo, Jack, Alexander

On Friday, January 18, 2013 01:52:31 PM Nishanth Menon wrote:
> Hi,
> Despite being documented in function documentation and in
> Documentation/power/opp.txt, many of the users of OPP APIs
> dont honor RCU lock usage appropriately.
> 
> This recently appeared in IRC discussion earlier today [1]. 
> I did an audit of current usage and the following series
> is a result of this.
> 
> NOTE:
> 1. The patch "PM / devfreq: exynos4_bus: honor RCU lock usage" has only
>    been build tested as I dont have an exynos platform to try it on. I have
>    tried to make it as least intrusive as possible and at least reviewed
>    to ensure I haven't screwed anything up.
> 
> Other than this, I have added appropriate tested by information in requisite
> patches.

Thanks for the fixes.

MyungJoo, do you want me to take the devfreq ones too?

Rafael


> Series is based off: v3.8-rc4 tag
> Also available in the following location[2]:
> https://github.com/nmenon/linux-2.6-playground branch: post/pm/opp-fixes-v1
> 
> Nishanth Menon (4):
>   cpufreq: OMAP: use RCU locks around usage of OPP
>   cpufreq: cpufreq-cpu0: use RCU locks around usage of OPP
>   PM / devfreq: add locking documentation for recommend_opp
>   PM / devfreq: exynos4_bus: honor RCU lock usage
> 
>  drivers/cpufreq/cpufreq-cpu0.c |    5 +++
>  drivers/cpufreq/omap-cpufreq.c |    3 ++
>  drivers/devfreq/devfreq.c      |    5 +++
>  drivers/devfreq/exynos4_bus.c  |   94 ++++++++++++++++++++++++++++------------
>  4 files changed, 80 insertions(+), 27 deletions(-)
> 
> [1] http://www.beagleboard.org/irclogs/index.php?date=2013-01-18#T14:14:07
> [2] https://github.com/nmenon/linux-2.6-playground/commits/post/pm/opp-fixes-v1
> 
> Regards,
> Nishanth Menon
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] OPP usage fixes for RCU locking
  2013-01-18 22:28 ` [PATCH 0/4] OPP usage fixes for RCU locking Rafael J. Wysocki
@ 2013-01-21  5:45   ` MyungJoo Ham
  2013-01-21 12:40     ` Rafael J. Wysocki
  0 siblings, 1 reply; 8+ messages in thread
From: MyungJoo Ham @ 2013-01-21  5:45 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Nishanth Menon, linux-pm, Kevin, lkml, lo, Jack, Alexander

On Sat, Jan 19, 2013 at 7:28 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 18, 2013 01:52:31 PM Nishanth Menon wrote:
>> Hi,
>> Despite being documented in function documentation and in
>> Documentation/power/opp.txt, many of the users of OPP APIs
>> dont honor RCU lock usage appropriately.
>>
>> This recently appeared in IRC discussion earlier today [1].
>> I did an audit of current usage and the following series
>> is a result of this.
>>
>> NOTE:
>> 1. The patch "PM / devfreq: exynos4_bus: honor RCU lock usage" has only
>>    been build tested as I dont have an exynos platform to try it on. I have
>>    tried to make it as least intrusive as possible and at least reviewed
>>    to ensure I haven't screwed anything up.
>>
>> Other than this, I have added appropriate tested by information in requisite
>> patches.
>
> Thanks for the fixes.
>
> MyungJoo, do you want me to take the devfreq ones too?
>
> Rafael

Yes, please take RCU-OPP patches. Having those patches splitted
doesn't seem beneficial.

I'll let other devfreq patches be based on this after you get them applied.




Cheers,
MyungJoo

>
>
>> Series is based off: v3.8-rc4 tag
>> Also available in the following location[2]:
>> https://github.com/nmenon/linux-2.6-playground branch: post/pm/opp-fixes-v1
>>
>> Nishanth Menon (4):
>>   cpufreq: OMAP: use RCU locks around usage of OPP
>>   cpufreq: cpufreq-cpu0: use RCU locks around usage of OPP
>>   PM / devfreq: add locking documentation for recommend_opp
>>   PM / devfreq: exynos4_bus: honor RCU lock usage
>>
>>  drivers/cpufreq/cpufreq-cpu0.c |    5 +++
>>  drivers/cpufreq/omap-cpufreq.c |    3 ++
>>  drivers/devfreq/devfreq.c      |    5 +++
>>  drivers/devfreq/exynos4_bus.c  |   94 ++++++++++++++++++++++++++++------------
>>  4 files changed, 80 insertions(+), 27 deletions(-)
>>
>> [1] http://www.beagleboard.org/irclogs/index.php?date=2013-01-18#T14:14:07
>> [2] https://github.com/nmenon/linux-2.6-playground/commits/post/pm/opp-fixes-v1
>>
>> Regards,
>> Nishanth Menon
>>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
> --
> 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



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] OPP usage fixes for RCU locking
  2013-01-21  5:45   ` MyungJoo Ham
@ 2013-01-21 12:40     ` Rafael J. Wysocki
  0 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2013-01-21 12:40 UTC (permalink / raw)
  To: myungjoo.ham; +Cc: Nishanth Menon, linux-pm, Kevin, lkml, lo, Jack, Alexander

On Monday, January 21, 2013 02:45:32 PM MyungJoo Ham wrote:
> On Sat, Jan 19, 2013 at 7:28 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, January 18, 2013 01:52:31 PM Nishanth Menon wrote:
> >> Hi,
> >> Despite being documented in function documentation and in
> >> Documentation/power/opp.txt, many of the users of OPP APIs
> >> dont honor RCU lock usage appropriately.
> >>
> >> This recently appeared in IRC discussion earlier today [1].
> >> I did an audit of current usage and the following series
> >> is a result of this.
> >>
> >> NOTE:
> >> 1. The patch "PM / devfreq: exynos4_bus: honor RCU lock usage" has only
> >>    been build tested as I dont have an exynos platform to try it on. I have
> >>    tried to make it as least intrusive as possible and at least reviewed
> >>    to ensure I haven't screwed anything up.
> >>
> >> Other than this, I have added appropriate tested by information in requisite
> >> patches.
> >
> > Thanks for the fixes.
> >
> > MyungJoo, do you want me to take the devfreq ones too?
> >
> > Rafael
> 
> Yes, please take RCU-OPP patches. Having those patches splitted
> doesn't seem beneficial.

OK, I will take them.

> I'll let other devfreq patches be based on this after you get them applied.

OK

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-01-21 12:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-18 19:52 [PATCH 0/4] OPP usage fixes for RCU locking Nishanth Menon
2013-01-18 19:52 ` [PATCH 1/4] cpufreq: OMAP: use RCU locks around usage of OPP Nishanth Menon
2013-01-18 19:52 ` [PATCH 2/4] cpufreq: cpufreq-cpu0: " Nishanth Menon
2013-01-18 19:52 ` [PATCH 3/4] PM / devfreq: add locking documentation for recommended_opp Nishanth Menon
2013-01-18 19:52 ` [PATCH 4/4] PM / devfreq: exynos4_bus: honor RCU lock usage Nishanth Menon
2013-01-18 22:28 ` [PATCH 0/4] OPP usage fixes for RCU locking Rafael J. Wysocki
2013-01-21  5:45   ` MyungJoo Ham
2013-01-21 12:40     ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®