Message ID | 5f5f81da4b9773854fba72359cb911d2660e2957.1476952750.git.viresh.kumar@linaro.org (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On 10/20, Viresh Kumar wrote: > Pass the entire supply structure instead of all of its fields. > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > --- This patch should be combined with the previous one. I'm still not sure if it even makes sense to do this though. Do we really have to make duplicate "OPP snapshot" structures just because of how OPPs use RCU?
On 24-10-16, 16:14, Stephen Boyd wrote: > On 10/20, Viresh Kumar wrote: > > Pass the entire supply structure instead of all of its fields. > > > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > > --- > > This patch should be combined with the previous one. I think it is a fair to do this separately as this is a completely different logical change. > I'm still > not sure if it even makes sense to do this though. :) > Do we really > have to make duplicate "OPP snapshot" structures just because of > how OPPs use RCU? I agree. With RCU, yes this change is probably required. But I am not sure if RCU fits that well to OPP core anymore. A rw-lock may be much easier to help.
On 10/25, Viresh Kumar wrote: > On 24-10-16, 16:14, Stephen Boyd wrote: > > On 10/20, Viresh Kumar wrote: > > > Pass the entire supply structure instead of all of its fields. > > > > > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > > > --- > > > > This patch should be combined with the previous one. > > I think it is a fair to do this separately as this is a completely different > logical change. Let's agree to disagree. > > > I'm still > > not sure if it even makes sense to do this though. > > :) > > > Do we really > > have to make duplicate "OPP snapshot" structures just because of > > how OPPs use RCU? > > I agree. With RCU, yes this change is probably required. But I am not sure if > RCU fits that well to OPP core anymore. A rw-lock may be much easier to help. > For things like AVS we'll probably want to do that, although it's sort of funny because replacing RCU with rw-locks is the opposite direction most people go. With AVS we would be updating the voltage(s) in use for the current OPP, and we would want that update to block any OPP transition until the voltage is adjusted. I don't know how we would do that with RCU very well. Plus, RCU is for reader heavy things, but we mostly have one or two readers. I guess it's ok for now to do all this copying, but it feels like we'll need to undo a large portion of it later with things like AVS. Or at least we'll be doing copies for almost no reason because we'll want to hold the read lock across the whole OPP transition. I was going to suggest we pass around information about what we want to grab from the RCU protected data structures, think index of regulator, etc. and then have small RCU read-side critical sections to grab that info during the OPP transition but I'm not sure that's any better. It might be worse because the OPP could change during the OPP transition and we could be using half of the old and half of the new data.
On 25-10-16, 13:26, Stephen Boyd wrote: > For things like AVS we'll probably want to do that, although it's > sort of funny because replacing RCU with rw-locks is the opposite > direction most people go. Yes, that would be very funny :) > With AVS we would be updating the > voltage(s) in use for the current OPP, and we would want that > update to block any OPP transition until the voltage is adjusted. > I don't know how we would do that with RCU very well. Plus, RCU > is for reader heavy things, but we mostly have one or two > readers. Not just that, think of opp_disable() function. What guarantees currently that an OPP being disabled isn't already used right now? Or is on the way of getting used? I strongly feel RCU is not the best fit for OPP core at least. > I guess it's ok for now to do all this copying, but it feels like > we'll need to undo a large portion of it later with things like > AVS. Yes. > Or at least we'll be doing copies for almost no reason > because we'll want to hold the read lock across the whole OPP > transition. I was going to suggest we pass around information > about what we want to grab from the RCU protected data > structures, think index of regulator, etc. and then have small > RCU read-side critical sections to grab that info during the OPP > transition but I'm not sure that's any better. It might be worse > because the OPP could change during the OPP transition and we > could be using half of the old and half of the new data. The problem is that this code is getting harder to read for everybody. If we are finding it difficult to understand, what about newbies..
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 8d6006151c9a..37fad2eb0f47 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -542,8 +542,7 @@ static struct clk *_get_opp_clk(struct device *dev) } static int _set_opp_voltage(struct device *dev, struct regulator *reg, - unsigned long u_volt, unsigned long u_volt_min, - unsigned long u_volt_max) + struct dev_pm_opp_supply *supply) { int ret; @@ -554,14 +553,15 @@ static int _set_opp_voltage(struct device *dev, struct regulator *reg, return 0; } - dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__, u_volt_min, - u_volt, u_volt_max); + dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__, + supply->u_volt_min, supply->u_volt, supply->u_volt_max); - ret = regulator_set_voltage_triplet(reg, u_volt_min, u_volt, - u_volt_max); + ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, + supply->u_volt, supply->u_volt_max); if (ret) dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n", - __func__, u_volt_min, u_volt, u_volt_max, ret); + __func__, supply->u_volt_min, supply->u_volt, + supply->u_volt_max, ret); return ret; } @@ -583,8 +583,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) struct regulator *reg; struct clk *clk; unsigned long freq, old_freq; - unsigned long u_volt, u_volt_min, u_volt_max; - unsigned long old_u_volt, old_u_volt_min, old_u_volt_max; + struct dev_pm_opp_supply old_supply, new_supply; int ret; if (unlikely(!target_freq)) { @@ -634,17 +633,12 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) return ret; } - if (IS_ERR(old_opp)) { - old_u_volt = 0; - } else { - old_u_volt = old_opp->supply.u_volt; - old_u_volt_min = old_opp->supply.u_volt_min; - old_u_volt_max = old_opp->supply.u_volt_max; - } + if (IS_ERR(old_opp)) + old_supply.u_volt = 0; + else + memcpy(&old_supply, &old_opp->supply, sizeof(old_supply)); - u_volt = opp->supply.u_volt; - u_volt_min = opp->supply.u_volt_min; - u_volt_max = opp->supply.u_volt_max; + memcpy(&new_supply, &opp->supply, sizeof(new_supply)); reg = opp_table->regulator; @@ -652,8 +646,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) /* Scaling up? Scale voltage before frequency */ if (freq > old_freq) { - ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, - u_volt_max); + ret = _set_opp_voltage(dev, reg, &new_supply); if (ret) goto restore_voltage; } @@ -672,8 +665,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) /* Scaling down? Scale voltage after frequency */ if (freq < old_freq) { - ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, - u_volt_max); + ret = _set_opp_voltage(dev, reg, &new_supply); if (ret) goto restore_freq; } @@ -686,10 +678,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) __func__, old_freq); restore_voltage: /* This shouldn't harm even if the voltages weren't updated earlier */ - if (old_u_volt) { - _set_opp_voltage(dev, reg, old_u_volt, old_u_volt_min, - old_u_volt_max); - } + if (old_supply.u_volt) + _set_opp_voltage(dev, reg, &old_supply); return ret; }
Pass the entire supply structure instead of all of its fields. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> --- drivers/base/power/opp/core.c | 44 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 27 deletions(-)