• Rafael J. Wysocki's avatar
    cpufreq: Avoid attempts to create duplicate symbolic links · 559ed407
    Rafael J. Wysocki authored
    After commit 87549141 (cpufreq: Stop migrating sysfs files on
    hotplug) there is a problem with CPUs that share cpufreq policy
    objects with other CPUs and are initially offline.
    
    Say CPU1 shares a policy with CPU0 which is online and is registered
    first.  As part of the registration process, cpufreq_add_dev() is
    called for it.  It creates the policy object and a symbolic link
    to it from the CPU1's sysfs directory.  If CPU1 is registered
    subsequently and it is offline at that time, cpufreq_add_dev() will
    attempt to create a symbolic link to the policy object for it, but
    that link is present already, so a warning about that will be
    triggered.
    
    To avoid that warning, make cpufreq use an additional CPU mask
    containing related CPUs that are actually present for each policy
    object.  That mask is initialized when the policy object is populated
    after its creation (for the first online CPU using it) and it includes
    CPUs from the "policy CPUs" mask returned by the cpufreq driver's
    ->init() callback that are physically present at that time.  Symbolic
    links to the policy are created only for the CPUs in that mask.
    
    If cpufreq_add_dev() is invoked for an offline CPU, it checks the
    new mask and only creates the symlink if the CPU was not in it (the
    CPU is added to the mask at the same time).
    
    In turn, cpufreq_remove_dev() drops the given CPU from the new mask,
    removes its symlink to the policy object and returns, unless it is
    the CPU owning the policy object.  In that case, the policy object
    is moved to a new CPU's sysfs directory or deleted if the CPU being
    removed was the last user of the policy.
    
    While at it, notice that cpufreq_remove_dev() can't fail, because
    its return value is ignored, so make it ignore return values from
    __cpufreq_remove_dev_prepare() and __cpufreq_remove_dev_finish()
    and prevent these functions from aborting on errors returned by
    __cpufreq_governor().  Also drop the now unused sif argument from
    them.
    
    Fixes: 87549141 (cpufreq: Stop migrating sysfs files on hotplug)
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Reported-and-tested-by: default avatarRussell King <linux@arm.linux.org.uk>
    Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    559ed407
cpufreq.c 67.3 KB