aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-12-09 23:15:31 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-12-10 16:18:33 -0500
commit1c6a662f898ecd1615d25fecb8098ea646720a7a (patch)
tree560c037188ceecdd96725634736612071227ee0c
parent2a6127d037de96e8add0b09e0200b331a4db54be (diff)
PM / OPP: replace kfree with kfree_rcu while freeing 'struct device_opp'
Somehow one of the instance of freeing resources failed to use kfree_rcu() and used kfree() instead. This might cause problems as the node might be referenced by readers under rcu locks and we must wait for the rcu grace period as well. While we are at it, also update comment over 'struct device_opp' to mention why we are waiting for both rcu and srcu grace periods. Fixes: 129eec55df6a (PM / OPP Introduce APIs to remove OPPs) Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/opp.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index 1bbef8e838e7..e1807268cbf2 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -84,7 +84,11 @@ struct dev_pm_opp {
84 * 84 *
85 * This is an internal data structure maintaining the link to opps attached to 85 * This is an internal data structure maintaining the link to opps attached to
86 * a device. This structure is not meant to be shared to users as it is 86 * a device. This structure is not meant to be shared to users as it is
87 * meant for book keeping and private to OPP library 87 * meant for book keeping and private to OPP library.
88 *
89 * Because the opp structures can be used from both rcu and srcu readers, we
90 * need to wait for the grace period of both of them before freeing any
91 * resources. And so we have used kfree_rcu() from within call_srcu() handlers.
88 */ 92 */
89struct device_opp { 93struct device_opp {
90 struct list_head node; 94 struct list_head node;
@@ -511,7 +515,7 @@ static void kfree_device_rcu(struct rcu_head *head)
511{ 515{
512 struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head); 516 struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head);
513 517
514 kfree(device_opp); 518 kfree_rcu(device_opp, rcu_head);
515} 519}
516 520
517void __dev_pm_opp_remove(struct device_opp *dev_opp, struct dev_pm_opp *opp) 521void __dev_pm_opp_remove(struct device_opp *dev_opp, struct dev_pm_opp *opp)