• Tejun Heo's avatar
    cpufreq/powernow-k8: workqueue user shouldn't migrate the kworker to another CPU · 6889125b
    Tejun Heo authored
    powernowk8_target() runs off a per-cpu work item and if the
    cpufreq_policy->cpu is different from the current one, it migrates the
    kworker to the target CPU by manipulating current->cpus_allowed.  The
    function migrates the kworker back to the original CPU but this is
    still broken.  Workqueue concurrency management requires the kworkers
    to stay on the same CPU and powernowk8_target() ends up triggerring
    BUG_ON(rq != this_rq()) in try_to_wake_up_local() if it contends on
    fidvid_mutex and sleeps.
    
    It is unclear why this bug is being reported now.  Duncan says it
    appeared to be a regression of 3.6-rc1 and couldn't reproduce it on
    3.5.  Bisection seemed to point to 63d95a91 "workqueue: use @pool
    instead of @gcwq or @cpu where applicable" which is an non-functional
    change.  Given that the reproduce case sometimes took upto days to
    trigger, it's easy to be misled while bisecting.  Maybe something made
    contention on fidvid_mutex more likely?  I don't know.
    
    This patch fixes the bug by using work_on_cpu() instead if @pol->cpu
    isn't the same as the current one.  The code assumes that
    cpufreq_policy->cpu is kept online by the caller, which Rafael tells
    me is the case.
    
    stable: ed48ece2 ("workqueue: reimplement work_on_cpu() using
            system_wq") should be applied before this; otherwise, the
            behavior could be horrible.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarDuncan <1i5t5.duncan@cox.net>
    Tested-by: default avatarDuncan <1i5t5.duncan@cox.net>
    Cc: Rafael J. Wysocki <rjw@sisk.pl>
    Cc: Andreas Herrmann <andreas.herrmann3@amd.com>
    Cc: stable@vger.kernel.org
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=47301
    6889125b
powernow-k8.c 40.6 KB