From patchwork Mon Apr 10 13:02:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Slaby X-Patchwork-Id: 97129 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp1351274qgd; Mon, 10 Apr 2017 06:02:55 -0700 (PDT) X-Received: by 10.99.181.86 with SMTP id u22mr56227390pgo.102.1491829375172; Mon, 10 Apr 2017 06:02:55 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t88si4956649pfj.1.2017.04.10.06.02.55; Mon, 10 Apr 2017 06:02:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753239AbdDJNCy (ORCPT + 5 others); Mon, 10 Apr 2017 09:02:54 -0400 Received: from mx2.suse.de ([195.135.220.15]:46720 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752963AbdDJNCw (ORCPT ); Mon, 10 Apr 2017 09:02:52 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id B9E2CACD5; Mon, 10 Apr 2017 13:02:51 +0000 (UTC) From: Jiri Slaby To: stable@vger.kernel.org Cc: Viresh Kumar , "Rafael J . Wysocki" , Jiri Slaby Subject: [patch added to 3.12-stable] cpufreq: move policy kobj to policy->cpu at resume Date: Mon, 10 Apr 2017 15:02:43 +0200 Message-Id: <20170410130249.26822-5-jslaby@suse.cz> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170410130249.26822-1-jslaby@suse.cz> References: <20170410130249.26822-1-jslaby@suse.cz> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Viresh Kumar This patch has been added to the 3.12 stable tree. If you have any objections, please let us know. -- 2.12.2 =============== commit 92c14bd9477a20a83144f08c0ca25b0308bf0730 upstream. This is only relevant to implementations with multiple clusters, where clusters have separate clock lines but all CPUs within a cluster share it. Consider a dual cluster platform with 2 cores per cluster. During suspend we start hot unplugging CPUs in order 1 to 3. When CPU2 is removed, policy->kobj would be moved to CPU3 and when CPU3 goes down we wouldn't free policy or its kobj as we want to retain permissions/values/etc. Now on resume, we will get CPU2 before CPU3 and will call __cpufreq_add_dev(). We will recover the old policy and update policy->cpu from 3 to 2 from update_policy_cpu(). But the kobj is still tied to CPU3 and isn't moved to CPU2. We wouldn't create a link for CPU2, but would try that for CPU3 while bringing it online. Which will report errors as CPU3 already has kobj assigned to it. This bug got introduced with commit 42f921a, which overlooked this scenario. To fix this, lets move kobj to the new policy->cpu while bringing first CPU of a cluster back. Also do a WARN_ON() if kobject_move failed, as we would reach here only for the first CPU of a non-boot cluster. And we can't recover from this situation, if kobject_move() fails. Fixes: 42f921a6f10c (cpufreq: remove sysfs files for CPUs which failed to come back after resume) Reported-and-tested-by: Bu Yitian Reported-by: Saravana Kannan Reviewed-by: Srivatsa S. Bhat Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki Signed-off-by: Jiri Slaby --- drivers/cpufreq/cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 776bdefb5517..6237f687c5d3 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1061,10 +1061,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, * the creation of a brand new one. So we need to perform this update * by invoking update_policy_cpu(). */ - if (frozen && cpu != policy->cpu) + if (frozen && cpu != policy->cpu) { update_policy_cpu(policy, cpu); - else + WARN_ON(kobject_move(&policy->kobj, &dev->kobj)); + } else { policy->cpu = cpu; + } policy->governor = CPUFREQ_DEFAULT_GOVERNOR; cpumask_copy(policy->cpus, cpumask_of(cpu));