From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932470Ab3D3Ocz (ORCPT ); Tue, 30 Apr 2013 10:32:55 -0400 Received: from mail-da0-f54.google.com ([209.85.210.54]:53655 "EHLO mail-da0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932440Ab3D3Ocw (ORCPT ); Tue, 30 Apr 2013 10:32:52 -0400 From: Viresh Kumar To: rjw@sisk.pl Cc: linaro-kernel@lists.linaro.org, patches@linaro.org, cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, robin.randhawa@arm.com, Steve.Bannister@arm.com, Liviu.Dudau@arm.com, charles.garcia-tobin@arm.com, arvind.chauhan@arm.com, Viresh Kumar Subject: [PATCH 2/2] cpufreq: Issue CPUFREQ_GOV_POLICY_EXIT notifier before dropping policy refcount Date: Tue, 30 Apr 2013 20:02:18 +0530 Message-Id: X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We must call __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT) before calling cpufreq_cpu_put(data), so that policy kobject have valid fields. Otherwise, removing last online cpu of policy->cpus causes this crash for ondemand/conservative governor. [ 146.386064] [] (sysfs_find_dirent+0xe/0xa8) from [] (sysfs_get_dirent+0x21/0x58) [ 146.413440] [] (sysfs_get_dirent+0x21/0x58) from [] (sysfs_remove_group+0x85/0xbc) [ 146.441338] [] (sysfs_remove_group+0x85/0xbc) from [] (cpufreq_governor_dbs+0x369/0x4a0) [ 146.470795] [] (cpufreq_governor_dbs+0x369/0x4a0) from [] (__cpufreq_governor+0x2b/0x8c) [ 146.500254] [] (__cpufreq_governor+0x2b/0x8c) from [] (__cpufreq_remove_dev.isra.12+0x15b/0x250) [ 146.531799] [] (__cpufreq_remove_dev.isra.12+0x15b/0x250) from [] (cpufreq_cpu_callback+0x2f/0x3c) [ 146.563860] [] (cpufreq_cpu_callback+0x2f/0x3c) from [] (notifier_call_chain+0x45/0x54) [ 146.593059] [] (notifier_call_chain+0x45/0x54) from [] (__cpu_notify+0x1d/0x34) [ 146.620177] [] (__cpu_notify+0x1d/0x34) from [] (_cpu_down+0x63/0x1ac) [ 146.644948] [] (_cpu_down+0x63/0x1ac) from [] (cpu_down+0x1b/0x30) [ 146.668675] [] (cpu_down+0x1b/0x30) from [] (store_online+0x27/0x54) [ 146.692922] [] (store_online+0x27/0x54) from [] (dev_attr_store+0x11/0x18) [ 146.718733] [] (dev_attr_store+0x11/0x18) from [] (sysfs_write_file+0xed/0x114) [ 146.745847] [] (sysfs_write_file+0xed/0x114) from [] (vfs_write+0x65/0xd8) [ 146.771656] [] (vfs_write+0x65/0xd8) from [] (sys_write+0x2f/0x50) [ 146.795384] [] (sys_write+0x2f/0x50) from [] (ret_fast_syscall+0x1/0x52) Of course this only impacted drivers which have have_governor_per_policy set to true. i.e. big LITTLE cpufreq driver. Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1b8a48e..b7acfd1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1075,14 +1075,14 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif __func__, cpu_dev->id, cpu); } + if ((cpus == 1) && (cpufreq_driver->target)) + __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); cpufreq_cpu_put(data); /* If cpu is last user of policy, free policy */ if (cpus == 1) { - if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_read(cpu); kobj = &data->kobj; cmp = &data->kobj_unregister; -- 1.7.12.rc2.18.g61b472e