From patchwork Mon Jul 20 09:47:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 51270 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f69.google.com (mail-wg0-f69.google.com [74.125.82.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 6CAD4228F7 for ; Mon, 20 Jul 2015 09:47:23 +0000 (UTC) Received: by wgqq19 with SMTP id q19sf10080564wgq.1 for ; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=Wv0piAR6JALzCeAer/FgOvCXJy74osCxTV18P6kWtXI=; b=afcqhvmYNak+O/0chQLBxao2YsOAk8w30RDr2ACL7Jp416IjCJ+iW8LYNVAENk1T8w 5cM+MLAAmfbWI3P37bnybbq22eoxRshc7bDCBbcgYbKWlEzVeTKFEWr/yu21nr0TkKmF Lt/h5iSirqq/xdq7OhUVH9P9m5wqVSCZ+khjToZGQMdQsLQdVHoSY87D1eVdrXSJeYQh 8GwlxLZCUQQOxOcNne7/mBa+R52HmmxuQFyNbvG/l86uv8L5bF0c37LPQ1miIb21zhSH c+UV1rjoqtzclT3Y9jYvaIRcXli+KpR4ndfqc9+obMd4+2sWk+tlMqPExMa6bkWnXOCe 8LNA== X-Gm-Message-State: ALoCoQkNtCMmFrLdAlBCqHiC/w/qJxGtKNTFb/yIA8+Q5ubQb9tQJI7YW1tvYKyumWgZk6gRUVKW X-Received: by 10.112.54.166 with SMTP id k6mr14568033lbp.0.1437385642724; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.203.197 with SMTP id ks5ls698900lac.64.gmail; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) X-Received: by 10.112.209.106 with SMTP id ml10mr26489512lbc.112.1437385642561; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) Received: from mail-la0-f50.google.com (mail-la0-f50.google.com. [209.85.215.50]) by mx.google.com with ESMTPS id ej7si17468855lad.149.2015.07.20.02.47.22 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Jul 2015 02:47:22 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.50 as permitted sender) client-ip=209.85.215.50; Received: by lahh5 with SMTP id h5so93633321lah.2 for ; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) X-Received: by 10.152.18.162 with SMTP id x2mr26959093lad.73.1437385642435; Mon, 20 Jul 2015 02:47:22 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp692625lba; Mon, 20 Jul 2015 02:47:21 -0700 (PDT) X-Received: by 10.70.8.33 with SMTP id o1mr21651434pda.88.1437385640464; Mon, 20 Jul 2015 02:47:20 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id kl8si34838062pdb.48.2015.07.20.02.47.19; Mon, 20 Jul 2015 02:47:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752644AbbGTJrS (ORCPT + 12 others); Mon, 20 Jul 2015 05:47:18 -0400 Received: from mail-pd0-f170.google.com ([209.85.192.170]:35401 "EHLO mail-pd0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752460AbbGTJrR (ORCPT ); Mon, 20 Jul 2015 05:47:17 -0400 Received: by pdrg1 with SMTP id g1so99468251pdr.2 for ; Mon, 20 Jul 2015 02:47:16 -0700 (PDT) X-Received: by 10.67.30.102 with SMTP id kd6mr58080240pad.132.1437385636734; Mon, 20 Jul 2015 02:47:16 -0700 (PDT) Received: from localhost ([122.171.186.190]) by smtp.gmail.com with ESMTPSA id j4sm20716549pdg.64.2015.07.20.02.47.14 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 20 Jul 2015 02:47:15 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , linux@arm.linux.org.uk Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, Viresh Kumar , linux-kernel@vger.kernel.org (open list) Subject: [PATCH] cpufreq: Avoid double addition/removal of sysfs links Date: Mon, 20 Jul 2015 15:17:10 +0530 Message-Id: X-Mailer: git-send-email 2.4.0 In-Reply-To: <20150718163149.GP7557@n2100.arm.linux.org.uk> References: <20150718163149.GP7557@n2100.arm.linux.org.uk> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.50 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Consider a dual core (0/1) system with two CPUs: - sharing clock/voltage rails and hence cpufreq-policy - CPU1 is offline while the cpufreq driver is registered - cpufreq_add_dev() is called from subsys callback for CPU0 and we create the policy for the CPUs and create link for CPU1. - cpufreq_add_dev() is called from subsys callback for CPU1, we find that the cpu is offline and we try to create a sysfs link for CPU1. - This results in double addition of the sysfs link and we get this: WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x60/0x7c() sysfs: cannot create duplicate filename '/devices/system/cpu/cpu1/cpufreq' Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0-rc2+ #1704 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) Backtrace: [] (dump_backtrace) from [] (show_stack+0x18/0x1c) r6:c01a1f30 r5:0000001f r4:00000000 r3:00000000 [] (show_stack) from [] (dump_stack+0x7c/0x98) [] (dump_stack) from [] (warn_slowpath_common+0x80/0xbc) r4:d74abbd0 r3:d74c0000 [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x38/0x40) r8:ffffffef r7:00000000 r6:d75a8960 r5:c0993280 r4:d6b4d000 [] (warn_slowpath_fmt) from [] (sysfs_warn_dup+0x60/0x7c) r3:d6b4dfe7 r2:c0930750 [] (sysfs_warn_dup) from [] (sysfs_do_create_link_sd+0xb8/0xc0) r6:d75a8960 r5:c0993280 r4:d00aba20 [] (sysfs_do_create_link_sd) from [] (sysfs_create_link+0x2c/0x3c) r10:00000001 r8:c14db3c8 r7:d7b89010 r6:c0ae7c60 r5:d7b89010 r4:d00d1200 [] (sysfs_create_link) from [] (add_cpu_dev_symlink+0x34/0x5c) [] (add_cpu_dev_symlink) from [] (cpufreq_add_dev+0x674/0x794) r5:00000001 r4:00000000 [] (cpufreq_add_dev) from [] (subsys_interface_register+0x8c/0xd0) r10:00000003 r9:d7bb01f0 r8:c14db3c8 r7:00106738 r6:c0ae7c60 r5:c0acbd08 r4:c0ae7e20 [] (subsys_interface_register) from [] (cpufreq_register_driver+0x104/0x1f4) The check for offline-cpu in cpufreq_add_dev() is present to ensure that link gets added for the CPUs, that weren't physically present earlier and we missed the case where a CPU is offline while registering the driver. Fix this by keeping track of CPUs for which link is already created, and avoiding duplicate sysfs entries. Fixes: 87549141d516 ("cpufreq: Stop migrating sysfs files on hotplug") Reported-by: Russell King Signed-off-by: Viresh Kumar --- Russell, Can you please give this a try? (completely untested). drivers/cpufreq/cpufreq.c | 26 +++++++++++++++++++++++--- include/linux/cpufreq.h | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cdbe0676d246..12d089b78cad 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -984,17 +984,26 @@ EXPORT_SYMBOL(cpufreq_sysfs_remove_file); static int add_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu) { struct device *cpu_dev; + int ret; pr_debug("%s: Adding symlink for CPU: %u\n", __func__, cpu); if (!policy) return 0; + /* Already added for offline CPUS from subsys callback */ + if (cpumask_test_cpu(cpu, policy->symlinks)) + return 0; + cpu_dev = get_cpu_device(cpu); if (WARN_ON(!cpu_dev)) return 0; - return sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); + ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); + if (!ret) + cpumask_set_cpu(cpu, policy->symlinks); + + return ret; } static void remove_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu) @@ -1007,6 +1016,7 @@ static void remove_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu) if (WARN_ON(!cpu_dev)) return; + cpumask_clear_cpu(cpu, policy->symlinks); sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); } @@ -1038,6 +1048,10 @@ static void cpufreq_remove_dev_symlink(struct cpufreq_policy *policy) if (j == policy->kobj_cpu) continue; + /* Already removed for offline CPUS from subsys callback */ + if (!cpumask_test_cpu(j, policy->symlinks)) + continue; + remove_cpu_dev_symlink(policy, j); } } @@ -1172,11 +1186,14 @@ static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev) if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) goto err_free_cpumask; + if (!zalloc_cpumask_var(&policy->symlinks, GFP_KERNEL)) + goto err_free_related_cpumask; + ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &dev->kobj, "cpufreq"); if (ret) { pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret); - goto err_free_rcpumask; + goto err_free_symlink_cpumask; } INIT_LIST_HEAD(&policy->policy_list); @@ -1193,7 +1210,9 @@ static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev) return policy; -err_free_rcpumask: +err_free_symlink_cpumask: + free_cpumask_var(policy->symlinks); +err_free_related_cpumask: free_cpumask_var(policy->related_cpus); err_free_cpumask: free_cpumask_var(policy->cpus); @@ -1243,6 +1262,7 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy, bool notify) write_unlock_irqrestore(&cpufreq_driver_lock, flags); cpufreq_policy_put_kobj(policy, notify); + free_cpumask_var(policy->symlinks); free_cpumask_var(policy->related_cpus); free_cpumask_var(policy->cpus); kfree(policy); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index a82049683016..b4812f6977c6 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -62,6 +62,7 @@ struct cpufreq_policy { /* CPUs sharing clock, require sw coordination */ cpumask_var_t cpus; /* Online CPUs only */ cpumask_var_t related_cpus; /* Online + Offline CPUs */ + cpumask_var_t symlinks; /* CPUs for which cpufreq sysfs directory is present */ unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs should set cpufreq */