提交 dde8437d 编写于 作者: V Vincent Guittot 提交者: Rafael J. Wysocki

PM / OPP: RCU reclaim

synchronize_rcu() blocks the caller of opp_enable/disbale
for a complete grace period. This blocking duration prevents
any intensive use of the functions. Replace synchronize_rcu()
by call_rcu() which will call our function for freeing the old
opp element.

The duration of opp_enable() and opp_disable() will be no more
dependant of the grace period.
Signed-off-by: NVincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: NPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
上级 77b67063
......@@ -65,6 +65,7 @@ struct opp {
unsigned long u_volt;
struct device_opp *dev_opp;
struct rcu_head head;
};
/**
......@@ -441,6 +442,17 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
return 0;
}
/**
* opp_free_rcu() - helper to clear the struct opp when grace period has
* elapsed without blocking the the caller of opp_set_availability
*/
static void opp_free_rcu(struct rcu_head *head)
{
struct opp *opp = container_of(head, struct opp, head);
kfree(opp);
}
/**
* opp_set_availability() - helper to set the availability of an opp
* @dev: device for which we do this operation
......@@ -512,7 +524,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
list_replace_rcu(&opp->node, &new_opp->node);
mutex_unlock(&dev_opp_list_lock);
synchronize_rcu();
call_rcu(&opp->head, opp_free_rcu);
/* Notify the change of the OPP availability */
if (availability_req)
......@@ -522,13 +534,10 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE,
new_opp);
/* clean up old opp */
new_opp = opp;
goto out;
return 0;
unlock:
mutex_unlock(&dev_opp_list_lock);
out:
kfree(new_opp);
return r;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册