On Wednesday, 3 October 2012, Paul E. McKenney <paulmck@linux.vnet.ibm.com> wrote:
> On Tue, Oct 02, 2012 at 04:02:05AM +0200, Rafael J. Wysocki wrote:
>> On Monday 01 of October 2012 15:42:39 Vincent Guittot wrote:
>> > Hi Rafael,
>> >
>> > Ping.
>>
>> I'm considering this for v3.8, but I'd like Paul (CCed) to tell me what he
>> thinks about it.
>
> Looks good to me -- the only thing deferred is the freeing of memory.
> The only risk is that fast repeated invocation of opp_set_availability()
> could result in a lot of memory waiting for RCU grace periods, but
> call_rcu() has code to prevent this. So:
>
> Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Hi Paul,
Thanks for the review.
Regards,
Vincent
>
>> Thanks,
>> Rafael
>>
>>
>> > On 25 September 2012 15:42, Vincent Guittot <vincent.guittot@linaro.org> wrote:
>> > > 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: Vincent Guittot <vincent.guittot@linaro.org>
>> > > ---
>> > > drivers/base/power/opp.c | 19 ++++++++++++++-----
>> > > 1 file changed, 14 insertions(+), 5 deletions(-)
>> > >
>> > > diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
>> > > index ac993ea..49e4626 100644
>> > > --- a/drivers/base/power/opp.c
>> > > +++ b/drivers/base/power/opp.c
>> > > @@ -64,6 +64,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)
>> > > }
>> > >
>> > > /**
>> > > + * 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
>> > > * @freq: OPP frequency to modify availability
>> > > @@ -511,7 +523,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)
>> > > @@ -521,13 +533,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;
>> > > }
>> > > --
>> > > 1.7.9.5
>> > >
>> > --
>> > 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
>> >
>>
>
>