On 2015/2/2 12:54, Viresh Kumar wrote:
On 2 February 2015 at 10:15, ethan zhao ethan.zhao@oracle.com wrote:
On 2015/2/2 12:26, Viresh Kumar wrote: But there is no checking against refcount in or before
cpufreq_policy_free(), that is one issue I mentioned.
As I said earlier, the completion will only fire once the refcount is zero. And so there is no need of any check here.
That routines doesn't have any tricks and simply frees the policy. Because, before calling cpufreq_policy_put_kobj(), we have set the per-cpu variable to NULL, nobody else will get the policy
It is possible cpufreq_cpu_get() within the PPC thread was called just before __cpufreq_remove_dev_finish() is to be called in another thread, so you set the per_cpu(cpufreq_cpu_data, cpu) to NULL will not prevent the actions between cpufreq_cpu_get and cpufreq_cpu_put().
And then the freeing happens in __cpufreq_remove_dev_finish().
It will.. You aren't looking closely enough. If cpufreq_cpu_get() is called just before remove-dev, then cpufreq_cpu_get() will take:
read_lock_irqsave(&cpufreq_driver_lock, flags);
And it will do:
read_unlock_irqrestore(&cpufreq_driver_lock, flags);
only after increasing the refcount with kobject_get().
While on the other side __cpufreq_remove_dev_finish() will do this:
write_lock_irqsave(&cpufreq_driver_lock, flags); policy = per_cpu(cpufreq_cpu_data, cpu); per_cpu(cpufreq_cpu_data, cpu) = NULL; write_unlock_irqrestore(&cpufreq_driver_lock, flags);
So, it will wait for the read_lock in cpufreq_cpu_get() to finish before setting per-cpu variable to NULL. And so, after kobject_put() in cpufreq_policy_put_kobj(), we will wait for the completion to fire
Closely enough this time, understood, thanks for your explanation.
Ethan
and that will only happen once a corresponding cpufreq_cpu_put() is issued.