From patchwork Mon Nov 24 09:08:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomeu Vizoso X-Patchwork-Id: 5364081 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 774D3C11AC for ; Mon, 24 Nov 2014 09:08:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EBC2120361 for ; Mon, 24 Nov 2014 09:08:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0D281202E6 for ; Mon, 24 Nov 2014 09:08:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751096AbaKXJIU (ORCPT ); Mon, 24 Nov 2014 04:08:20 -0500 Received: from mail-wg0-f43.google.com ([74.125.82.43]:45539 "EHLO mail-wg0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750834AbaKXJIT (ORCPT ); Mon, 24 Nov 2014 04:08:19 -0500 Received: by mail-wg0-f43.google.com with SMTP id l18so11691041wgh.2 for ; Mon, 24 Nov 2014 01:08:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=4gZW5Xir41M6uTEY/5jXKho++XgVGLtOznFdKoC1TvY=; b=by5+N2VAb+wHlasjTnD90+IPut9E+VJNlCThJ9bqKgpwWFC+i4yCpvDdJE14WrNGmo A+vwCN/41sgC91+pXT9nk6lhKQnSObwcI6yxFAlI8rrZHh8qWjqa2/0HxkPZmMXWN0wR hcdTAktx8NEn4+Ffom/6uUHtUH2t7Ey2SmEQplXD7JEw/Hs1illlAAspmdLHLkrcbUc1 AcXiIT5woEUcHtiRJhr+Mz/q65Dz+IlORIgQnXNOHGh3QkRN8mwrl1pAlR2MQ+vnm/tV 3GsSb4fL8G5Qb+twarEW3Y5NTZ7KZgqm3vIavsaZHb1BwI3d3DL4Vw888DDMiwbC2gez QXew== X-Received: by 10.194.79.227 with SMTP id m3mr18827534wjx.126.1416820097592; Mon, 24 Nov 2014 01:08:17 -0800 (PST) Received: from cizrna.lan (37-48-39-106.tmcz.cz. [37.48.39.106]) by mx.google.com with ESMTPSA id h2sm11135738wix.5.2014.11.24.01.08.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Nov 2014 01:08:16 -0800 (PST) From: Tomeu Vizoso To: linux-pm@vger.kernel.org Cc: Javier Martinez Canillas , Tomeu Vizoso , "Rafael J. Wysocki" , Viresh Kumar , linux-kernel@vger.kernel.org Subject: [PATCH v2] cpufreq: Ref the policy object sooner Date: Mon, 24 Nov 2014 10:08:03 +0100 Message-Id: <1416820083-20902-1-git-send-email-tomeu.vizoso@collabora.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Do it before it's assigned to cpufreq_cpu_data, otherwise when a driver tries to get the cpu frequency during initialization the policy kobj is referenced and we get this warning: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 64 at include/linux/kref.h:47 kobject_get+0x64/0x70() Modules linked in: CPU: 1 PID: 64 Comm: irq/77-tegra-ac Not tainted 3.18.0-rc4-next-20141114ccu-00050-g3eff942 #326 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x98/0xd8) [] (dump_stack) from [] (warn_slowpath_common+0x84/0xb4) [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [] (warn_slowpath_null) from [] (kobject_get+0x64/0x70) [] (kobject_get) from [] (cpufreq_cpu_get+0x88/0xc8) [] (cpufreq_cpu_get) from [] (cpufreq_get+0xc/0x64) [] (cpufreq_get) from [] (actmon_thread_isr+0x134/0x198) [] (actmon_thread_isr) from [] (irq_thread_fn+0x1c/0x40) [] (irq_thread_fn) from [] (irq_thread+0x134/0x174) [] (irq_thread) from [] (kthread+0xdc/0xf4) [] (kthread) from [] (ret_from_fork+0x14/0x3c) ---[ end trace b7bd64a81b340c59 ]--- Signed-off-by: Tomeu Vizoso Acked-by: Viresh Kumar --- v2: * Properly unwind when erroring out. --- drivers/cpufreq/cpufreq.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4473eba..ae27ea6 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -898,46 +898,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, struct freq_attr **drv_attr; int ret = 0; - /* prepare interface data */ - ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, - &dev->kobj, "cpufreq"); - if (ret) - return ret; - /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; while ((drv_attr) && (*drv_attr)) { ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); if (ret) - goto err_out_kobj_put; + return ret; drv_attr++; } if (cpufreq_driver->get) { ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); if (ret) - goto err_out_kobj_put; + return ret; } ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); if (ret) - goto err_out_kobj_put; + return ret; if (cpufreq_driver->bios_limit) { ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); if (ret) - goto err_out_kobj_put; + return ret; } - ret = cpufreq_add_dev_symlink(policy); - if (ret) - goto err_out_kobj_put; - - return ret; - -err_out_kobj_put: - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - return ret; + return cpufreq_add_dev_symlink(policy); } static void cpufreq_init_policy(struct cpufreq_policy *policy) @@ -1196,6 +1181,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) goto err_set_policy_cpu; } + down_write(&policy->rwsem); + /* related cpus should atleast have policy->cpus */ cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); @@ -1208,9 +1195,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) if (!recover_policy) { policy->user_policy.min = policy->min; policy->user_policy.max = policy->max; + + /* prepare interface data */ + 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_init_policy_kobj; + } } - down_write(&policy->rwsem); write_lock_irqsave(&cpufreq_driver_lock, flags); for_each_cpu(j, policy->cpus) per_cpu(cpufreq_cpu_data, j) = policy; @@ -1301,6 +1296,11 @@ err_get_freq: per_cpu(cpufreq_cpu_data, j) = NULL; write_unlock_irqrestore(&cpufreq_driver_lock, flags); + if (!recover_policy) { + kobject_put(&policy->kobj); + wait_for_completion(&policy->kobj_unregister); + } +err_init_policy_kobj: up_write(&policy->rwsem); if (cpufreq_driver->exit)