From patchwork Sat Aug 20 01:29:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 9291503 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5544F607FF for ; Sat, 20 Aug 2016 01:26:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4050529546 for ; Sat, 20 Aug 2016 01:26:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 34F3C29562; Sat, 20 Aug 2016 01:26:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AC42829546 for ; Sat, 20 Aug 2016 01:26:18 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bav1K-0001DL-OL; Sat, 20 Aug 2016 01:24:22 +0000 Received: from cloudserver094114.home.net.pl ([79.96.170.134]) by bombadil.infradead.org with smtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bav1G-0001C2-Fn for linux-arm-kernel@lists.infradead.org; Sat, 20 Aug 2016 01:24:20 +0000 Received: from 217.96.253.97.ipv4.supernova.orange.pl (217.96.253.97) (HELO vostro.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer v0.80.3) id 90d4ab1dcda757da; Sat, 20 Aug 2016 03:23:51 +0200 From: "Rafael J. Wysocki" To: Russell King - ARM Linux Subject: Re: Kernel warning in cpufreq_add_dev() Date: Sat, 20 Aug 2016 03:29:27 +0200 Message-ID: <1601399.OxUAWWKTJN@vostro.rjw.lan> User-Agent: KMail/4.11.5 (Linux/4.8.0-rc1+; KDE/4.11.5; x86_64; ; ) In-Reply-To: <20160819110032.GM1041@n2100.armlinux.org.uk> References: <20160819110032.GM1041@n2100.armlinux.org.uk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160819_182418_748308_00A841BF X-CRM114-Status: GOOD ( 18.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Viresh Kumar , linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP On Friday, August 19, 2016 12:00:32 PM Russell King - ARM Linux wrote: > While checking the kernel on SA1110 Assabet, CPUFREQ issues a warning: > > ------------[ cut here ]------------ > WARNING: CPU: 0 PID: 1 at /home/rmk/git/linux-rmk/drivers/cpufreq/cpufreq.c:1080 cpufreq_add_dev+0x140/0x62c > Modules linked in: > CPU: 0 PID: 1 Comm: swapper Not tainted 4.8.0-rc2+ #883 > Hardware name: Intel-Assabet > Backtrace: > [] (dump_backtrace) from [] (show_stack+0x18/0x1c) > r6:00000000 r5:c05e87c3 r4:00000000 > [] (show_stack) from [] (dump_stack+0x20/0x28) > [] (dump_stack) from [] (__warn+0xd0/0xfc) > [] (__warn) from [] (warn_slowpath_null+0x28/0x30) > r10:00000000 r8:00000000 r7:00000000 r6:c064525c r5:00000000 r4:00000000 > [] (warn_slowpath_null) from [] (cpufreq_add_dev+0x140/0x62c) > [] (cpufreq_add_dev) from [] (bus_probe_device+0x5c/0x84) > r10:00000000 r8:00000000 r7:00000000 r6:c064525c r5:c0657d60 r4:c065a9f8 > [] (bus_probe_device) from [] (device_add+0x390/0x520) > r6:c0645264 r5:00000000 r4:c064525c > [] (device_add) from [] (device_register+0x1c/0x20) > r10:c0639848 r8:c061e524 r7:00000001 r6:00000000 r5:c064525c r4:c064525c > [] (device_register) from [] (register_cpu+0x88/0xac) > r4:c0645254 > [] (register_cpu) from [] (topology_init+0x20/0x2c) > r7:c0660b20 r6:c063f4a0 r5:c0639834 r4:00000000 > [] (topology_init) from [] (do_one_initcall+0xc0/0x178) > r4:00000004 > [] (do_one_initcall) from [] (kernel_init_freeable+0xfc/0x1c4) > r10:c0639848 r9:00000000 r8:00000088 r7:c0660b20 r6:c063f4a0 r5:c0639834 > r4:00000004 > [] (kernel_init_freeable) from [] (kernel_init+0x10/0xf4) > r10:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c050d720 r4:00000000 > [] (kernel_init) from [] (ret_from_fork+0x14/0x24) > r4:00000000 > ---[ end trace df94656649275917 ]--- > > This is because of an incompatibility between the expectations of cpufreq > and how register_cpu() works: > > int register_cpu(struct cpu *cpu, int num) > { > ... > error = device_register(&cpu->dev); > if (!error) > per_cpu(cpu_sys_devices, num) = &cpu->dev; > > When the device is registered via device_register(), any subsystems > registered for the cpu_subsys will have their "add_dev" method called. > > The cpufreq add_dev, via cpufreq_online() and cpufreq_policy_alloc(), > tries to get the CPU device: > > static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) > { > struct device *dev = get_cpu_device(cpu); > if (WARN_ON(!dev)) > return NULL; > > but this fails: > > struct device *get_cpu_device(unsigned cpu) > { > if (cpu < nr_cpu_ids && cpu_possible(cpu)) > return per_cpu(cpu_sys_devices, cpu); > > because the percpu data has not yet been written - it'll be written > after a successful device registration. So, using get_cpu_device() > from within cpufreq_add_dev() is broken, and results in the above > kernel warning. Ironically enough, cpufreq_policy_alloc() doesn't even use the value of dev for anything other than the check, so we can simply get rid of it (as per the appended patch). add_cpu_dev_symlink() will still be problematic, though, if I'm not mistaken. I wonder how that works on other platforms. --- drivers/cpufreq/cpufreq.c | 4 ---- 1 file changed, 4 deletions(-) Index: linux-pm/drivers/cpufreq/cpufreq.c =================================================================== --- linux-pm.orig/drivers/cpufreq/cpufreq.c +++ linux-pm/drivers/cpufreq/cpufreq.c @@ -1073,13 +1073,9 @@ static void handle_update(struct work_st static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) { - struct device *dev = get_cpu_device(cpu); struct cpufreq_policy *policy; int ret; - if (WARN_ON(!dev)) - return NULL; - policy = kzalloc(sizeof(*policy), GFP_KERNEL); if (!policy) return NULL;