From patchwork Tue Oct 10 05:47:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 9995037 X-Patchwork-Delegate: rjw@sisk.pl 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 A1E3A60230 for ; Tue, 10 Oct 2017 05:48:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9422327031 for ; Tue, 10 Oct 2017 05:48:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 890BC274A3; Tue, 10 Oct 2017 05:48:48 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 409E927031 for ; Tue, 10 Oct 2017 05:48:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752087AbdJJFsX (ORCPT ); Tue, 10 Oct 2017 01:48:23 -0400 Received: from mail-pf0-f169.google.com ([209.85.192.169]:49981 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752075AbdJJFsW (ORCPT ); Tue, 10 Oct 2017 01:48:22 -0400 Received: by mail-pf0-f169.google.com with SMTP id l188so16141481pfc.6 for ; Mon, 09 Oct 2017 22:48:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=gx8EZ8cqA3MO9GcqahNnuDSkPvYQ+VWuIkUDsFIlkcg=; b=Cy+/iiey679N57HptC5bhnvg6pLM/bGQawJgu0+qi8/vsv5RcSgCL5wgnxubKMZ/R1 m3bI6A2BVYR/nbp9o2fm88peJK79EDvp8t9tKnr9z0WbK+scetne1jgy9dG2cP9A4Crf Sb+pH5ttoSv+68iOmmyMc9pwl8oSU4U/fAw0s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gx8EZ8cqA3MO9GcqahNnuDSkPvYQ+VWuIkUDsFIlkcg=; b=DWolmLlnLkrbBUDghVtmwbWH1cfCB7Emd2dFkWyjBurdxs+LGa7jiSZxIw5QWLfeKu idLXGodwvHqmlA7Or9VovkiVCJqaNWqQvCYjR/t6mACacjnmhhElrt7lfpJ1kY4nUOlr OkRDLeZGA5+jqALYBJDuKhrk85wDwKGINIEsususRlxYvRQeE7g/M7JpBi4cyT4cSsoC jtHmc8endA0dWVBY7psgdpAXpdVYHjqXKibr796S5lpFcVBQrQogECt4qDCXj8L/G6YL Npk/Ts2AamB7crvcOjYIMFFOfx+WgRip0X9Ql4fLMEwqzTRTr6ekj+NbosCMKks2n2NV AmpA== X-Gm-Message-State: AMCzsaW0D7nBuXxWKPFzOzJH3zZVmZlKXWaS7Uwx68ecdinkRb8ZmfbO RXkPUpWCqs6Q1FVRBRmi/4u0UUVmKgs= X-Google-Smtp-Source: AOwi7QBDxCA62l1lOi+cCaudJbeTkgIozoel/hSfnI5zAPZnhCHafScgrqVflsjuCanISrwSo/Rg0w== X-Received: by 10.99.127.67 with SMTP id p3mr11361854pgn.321.1507614501830; Mon, 09 Oct 2017 22:48:21 -0700 (PDT) Received: from localhost.localdomain (li1568-49.members.linode.com. [139.162.88.49]) by smtp.gmail.com with ESMTPSA id m25sm18870469pfi.113.2017.10.09.22.48.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Oct 2017 22:48:20 -0700 (PDT) From: Leo Yan To: "Rafael J. Wysocki" , Daniel Lezcano , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Leo Yan Subject: [PATCH v2 1/2] ARM: cpuidle: Correct driver unregistration if init fails Date: Tue, 10 Oct 2017 13:47:55 +0800 Message-Id: <1507614476-16054-1-git-send-email-leo.yan@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If cpuidle init fails, the code misses to unregister the driver for current CPU. Furthermore, we also need to rollback to cancel all previous CPUs registration; but the code retrieves driver handler by using function cpuidle_get_driver(), this function returns back current CPU driver handler but not previous CPU's handler, which leads to the failure handling code cannot unregister previous CPUs driver. This commit fixes two mentioned issues, it adds error handling path 'goto out_unregister_drv' for current CPU driver unregistration; and it is to replace cpuidle_get_driver() with cpuidle_get_cpu_driver(), the later function can retrieve driver handler for previous CPUs according to the CPU device handler so can unregister the driver properly. This patch also adds extra error handling paths 'goto out_kfree_dev' and 'goto out_kfree_drv' and adjusts the freeing sentences for previous CPUs; so make the code more readable for freeing 'dev' and 'drv' structures. Suggested-by: Daniel Lezcano Signed-off-by: Leo Yan Fixes: d50a7d8acd78 ("ARM: cpuidle: Support asymmetric idle definition") Acked-by: Daniel Lezcano --- drivers/cpuidle/cpuidle-arm.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 52a7505..f47c545 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -104,13 +104,13 @@ static int __init arm_idle_init(void) ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); if (ret <= 0) { ret = ret ? : -ENODEV; - goto init_fail; + goto out_kfree_drv; } ret = cpuidle_register_driver(drv); if (ret) { pr_err("Failed to register cpuidle driver\n"); - goto init_fail; + goto out_kfree_drv; } /* @@ -128,14 +128,14 @@ static int __init arm_idle_init(void) if (ret) { pr_err("CPU %d failed to init idle CPU ops\n", cpu); - goto out_fail; + goto out_unregister_drv; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { pr_err("Failed to allocate cpuidle device\n"); ret = -ENOMEM; - goto out_fail; + goto out_unregister_drv; } dev->cpu = cpu; @@ -143,21 +143,25 @@ static int __init arm_idle_init(void) if (ret) { pr_err("Failed to register cpuidle device for CPU %d\n", cpu); - kfree(dev); - goto out_fail; + goto out_kfree_dev; } } return 0; -init_fail: + +out_kfree_dev: + kfree(dev); +out_unregister_drv: + cpuidle_unregister_driver(drv); +out_kfree_drv: kfree(drv); out_fail: while (--cpu >= 0) { dev = per_cpu(cpuidle_devices, cpu); + drv = cpuidle_get_cpu_driver(dev); cpuidle_unregister_device(dev); - kfree(dev); - drv = cpuidle_get_driver(); cpuidle_unregister_driver(drv); + kfree(dev); kfree(drv); }