From patchwork Fri Dec 20 05:08:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 22661 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f200.google.com (mail-pd0-f200.google.com [209.85.192.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9D81923FC6 for ; Fri, 20 Dec 2013 05:08:31 +0000 (UTC) Received: by mail-pd0-f200.google.com with SMTP id p10sf5004168pdj.11 for ; Thu, 19 Dec 2013 21:08:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe:content-type:content-transfer-encoding; bh=0qByrrR7diAibqE8xmxGOeyNNG7vfmzO4Im5SzdEp4U=; b=kLTrPje71UeBMHnqFCaI+MI+u1LremJ+dILvr6Aswr9K9Lu+nJ1g/APFS/J2KG4YgU V3OIx8ruboolC0Mcez9Vwo1NEzkm1l8kIQFIikLLmH+RNOvOvLOvqJROSUZm3PqKqiS4 c78dmwN/o220mOeiqlGCVZDfTVx+d0MSkWKNioUKKxl8hOMN2K9rpxbR0Mfji0Aw7OVk 17yCq4/iRZW6C17MfCfYMFAiDnzhQCggyrOgaJKQgtRVJaYsTqpGjnLE7X7xhLA7CaEm 3yzq+oTnNAAIOwLNyJqqgPBkikfDOvwJh9o49NZMon9MiraSZUujT9719LNfzZX5x2Z4 VjKw== X-Gm-Message-State: ALoCoQkr9LpHd0JFgUyTmOg5bLHpLHvkcobAW2kczn+Cg06Dm/a1ZGfhI/poE9XpXGnV51rMU9x7 X-Received: by 10.68.91.226 with SMTP id ch2mr2526081pbb.1.1387516109994; Thu, 19 Dec 2013 21:08:29 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.17.163 with SMTP id p3ls613057qed.41.gmail; Thu, 19 Dec 2013 21:08:29 -0800 (PST) X-Received: by 10.58.217.169 with SMTP id oz9mr42863vec.42.1387516109796; Thu, 19 Dec 2013 21:08:29 -0800 (PST) Received: from mail-ve0-f173.google.com (mail-ve0-f173.google.com [209.85.128.173]) by mx.google.com with ESMTPS id pv1si1221495veb.56.2013.12.19.21.08.29 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 19 Dec 2013 21:08:29 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.173; Received: by mail-ve0-f173.google.com with SMTP id oz11so1261182veb.32 for ; Thu, 19 Dec 2013 21:08:29 -0800 (PST) X-Received: by 10.220.17.131 with SMTP id s3mr274648vca.20.1387516109703; Thu, 19 Dec 2013 21:08:29 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp34913ved; Thu, 19 Dec 2013 21:08:29 -0800 (PST) X-Received: by 10.49.94.212 with SMTP id de20mr10266533qeb.51.1387516108998; Thu, 19 Dec 2013 21:08:28 -0800 (PST) Received: from mail-qa0-f51.google.com (mail-qa0-f51.google.com [209.85.216.51]) by mx.google.com with ESMTPS id f1si4856524qar.84.2013.12.19.21.08.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 19 Dec 2013 21:08:28 -0800 (PST) Received-SPF: neutral (google.com: 209.85.216.51 is neither permitted nor denied by best guess record for domain of viresh.kumar@linaro.org) client-ip=209.85.216.51; Received: by mail-qa0-f51.google.com with SMTP id o15so2286928qap.17 for ; Thu, 19 Dec 2013 21:08:28 -0800 (PST) X-Received: by 10.224.88.70 with SMTP id z6mr6816797qal.14.1387516108571; Thu, 19 Dec 2013 21:08:28 -0800 (PST) Received: from localhost (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id v1sm4674055qas.15.2013.12.19.21.08.24 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 19 Dec 2013 21:08:28 -0800 (PST) From: Viresh Kumar To: rjw@rjwysocki.net Cc: linaro-kernel@lists.linaro.org, patches@linaro.org, cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, srivatsa.bhat@linux.vnet.ibm.com, Viresh Kumar Subject: [PATCH] cpufreq: remove sysfs files for CPU which failed to come back after resume Date: Fri, 20 Dec 2013 10:38:20 +0530 Message-Id: X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e MIME-Version: 1.0 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There are cases where cpufreq_add_dev() may fail for some CPUs during resume. With the current code we will still have sysfs cpufreq files for such CPUs, and struct cpufreq_policy would be already freed for them. Hence any operation on those sysfs files would result in kernel warnings. To fix this, lets remove those sysfs files or put the associated kobject in case of such errors. Also, to make it simple lets remove the sysfs links from all the CPUs (except policy->cpu) during suspend as that operation wouldn't result with a loss of sysfs file permissions. And so we will create those links during resume as well. Reported-and-tested-by: Bjørn Mork Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 61 ++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 02d534d..cea96c9 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -845,8 +845,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) #ifdef CONFIG_HOTPLUG_CPU static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, - unsigned int cpu, struct device *dev, - bool frozen) + unsigned int cpu, struct device *dev) { int ret = 0; unsigned long flags; @@ -877,9 +876,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, } } - /* Don't touch sysfs links during light-weight init */ - if (!frozen) - ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); + ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); return ret; } @@ -926,6 +923,27 @@ err_free_policy: return NULL; } +static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy) +{ + struct kobject *kobj; + struct completion *cmp; + + down_read(&policy->rwsem); + kobj = &policy->kobj; + cmp = &policy->kobj_unregister; + up_read(&policy->rwsem); + kobject_put(kobj); + + /* + * We need to make sure that the underlying kobj is + * actually not referenced anymore by anybody before we + * proceed with unloading. + */ + pr_debug("waiting for dropping of refcount\n"); + wait_for_completion(cmp); + pr_debug("wait complete\n"); +} + static void cpufreq_policy_free(struct cpufreq_policy *policy) { free_cpumask_var(policy->related_cpus); @@ -986,7 +1004,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen); + ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev); up_read(&cpufreq_rwsem); return ret; } @@ -1096,7 +1114,10 @@ err_get_freq: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); err_set_policy_cpu: + if (frozen) + cpufreq_policy_put_kobj(policy); cpufreq_policy_free(policy); + nomem_out: up_read(&cpufreq_rwsem); @@ -1118,7 +1139,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) } static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, - unsigned int old_cpu, bool frozen) + unsigned int old_cpu) { struct device *cpu_dev; int ret; @@ -1126,10 +1147,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, /* first sibling now owns the new sysfs dir */ cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu)); - /* Don't touch sysfs files during light-weight tear-down */ - if (frozen) - return cpu_dev->id; - sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); ret = kobject_move(&policy->kobj, &cpu_dev->kobj); if (ret) { @@ -1196,7 +1213,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, if (!frozen) sysfs_remove_link(&dev->kobj, "cpufreq"); } else if (cpus > 1) { - new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); + new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); if (new_cpu >= 0) { update_policy_cpu(policy, new_cpu); @@ -1218,8 +1235,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev, int ret; unsigned long flags; struct cpufreq_policy *policy; - struct kobject *kobj; - struct completion *cmp; read_lock_irqsave(&cpufreq_driver_lock, flags); policy = per_cpu(cpufreq_cpu_data, cpu); @@ -1249,22 +1264,8 @@ static int __cpufreq_remove_dev_finish(struct device *dev, } } - if (!frozen) { - down_read(&policy->rwsem); - kobj = &policy->kobj; - cmp = &policy->kobj_unregister; - up_read(&policy->rwsem); - kobject_put(kobj); - - /* - * We need to make sure that the underlying kobj is - * actually not referenced anymore by anybody before we - * proceed with unloading. - */ - pr_debug("waiting for dropping of refcount\n"); - wait_for_completion(cmp); - pr_debug("wait complete\n"); - } + if (!frozen) + cpufreq_policy_put_kobj(policy); /* * Perform the ->exit() even during light-weight tear-down,