Hi Rafael,

Ping.

Regards,
Vincent

On 25 September 2012 15:42, Vincent Guittot <vincent.guit...@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.guit...@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
>

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to