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: 115338 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp3365656qgn; Mon, 9 Oct 2017 22:48:26 -0700 (PDT) X-Received: by 10.84.209.238 with SMTP id y101mr11087896plh.211.1507614506093; Mon, 09 Oct 2017 22:48:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507614506; cv=none; d=google.com; s=arc-20160816; b=iczQ+MJiN04mkyM9Qx+vycxNO6qEJb5Duqks6zQ3aC0pIEOWnDcxW/cIXTEAN/ABpk m38O5srTWW1/2rOOjs9PRQfrIveHXE/vonEacQPjMiDdH5rBEPvDSnuRWNHeQrz/fFbU hbNvmez+9KLS/iz4Y3ohJajAFmQJUXsHkkOTFv9G834Hn1X7bJVU0mdZPec/xYLrUXLN 7VmVTqWA8XW7XaKX/Al2As76TO04BJ/JFtlykeL7w8oO6cYE8aPx3pKvSGZSyXRIdqXp grDViNdyS/hODJN+YjbR8kG+VXgALuTMVROcI5PcKicBLnjmV5LnytmJ3grIrvqEoz4M ieHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=gx8EZ8cqA3MO9GcqahNnuDSkPvYQ+VWuIkUDsFIlkcg=; b=KNrC83ThkVDnVwh+ZkLpQt/WZk4fkaAIm/+cjM0ddV3Rn3f4H9DdJQBhrJi5SCyZ+h 0BUi5T7y3QFqWsQ7rJHyx1tWKlgNdplIWoKrGtCxmai4Qba/V+JFoFN1I6FKiTD20TkA 71e1ilVN8OktOuEze+Surjx11/MxrgCP4oR+JWK9rK3h+aZ2InwylrYiT9WJE0dz+Xgv F0VZVVTmvmHHlwcx6+BEd7oDKWnRzbgynO+U/hqi2MapIGYmDY0USPcws5o9QiJdB8nT 6E7QJsOOTMdsTHtGcuf1zAig87G+EATqOVNDAulcW0QS2AIvmMfWQrwq70ETRKxa3wi7 yYyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Cy+/iiey; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o33si8273268plb.77.2017.10.09.22.48.25; Mon, 09 Oct 2017 22:48:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Cy+/iiey; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752444AbdJJFsX (ORCPT + 26 others); Tue, 10 Oct 2017 01:48:23 -0400 Received: from mail-pf0-f177.google.com ([209.85.192.177]:46062 "EHLO mail-pf0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751809AbdJJFsW (ORCPT ); Tue, 10 Oct 2017 01:48:22 -0400 Received: by mail-pf0-f177.google.com with SMTP id d28so1435126pfe.2 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=YfV3yM7lpoIQUrpbeje5hjKhfpAmx8bfGztxQSLnbydKnKC3ZFHti4CsYxQSTLZpZz CE+P1i1IiY27y9UdihGdx1rAl/iyWcXDogWva3Xno6A5j4uMa7BcAmga8S10dN+gUtI6 PxCb/YbDrmY9XWflDMZ2EdJsFSIL1M8w8fBzVDtSkDy1jxWy/IkxlC2fvW9Lb08GrF+L XkhvJxl0SHVS8lJf9H6HXcAWt0cWAiQD5wjfU8VRWPY2aJtao2ZRegr34L/RKMg1BHkp OtUNk+ZQ7dbDqmSTgYiW8yI7tzewcnnalbSjSdoKjE2llDTzHjmtM86p5CNyt6z8adNz lkEw== X-Gm-Message-State: AMCzsaWzd+FpX02KO7qmAmANnVWcFGfF7POPpfCqy5p1oa5oWuTh1jVk PZg0fq6LSAvKxFLzcAbXS+YJew== 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-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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") --- drivers/cpuidle/cpuidle-arm.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) -- 2.7.4 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); } From patchwork Tue Oct 10 05:47:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 115339 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp3365747qgn; Mon, 9 Oct 2017 22:48:32 -0700 (PDT) X-Received: by 10.99.3.7 with SMTP id 7mr11236882pgd.295.1507614511937; Mon, 09 Oct 2017 22:48:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507614511; cv=none; d=google.com; s=arc-20160816; b=ZlMleEQOKSNljfkCtU45G8fJdqZ2d0I0U3RgS1y5Z0ZTICDhwIw9+yMfKE8uBpMv+g LwO+uUYuBXJpZPhHzsa2qDaRJOPyEsEJDaqaEQYpoueCdBNg82stB7ZGwuUMNfIZMGbI zG/rCeJo47o8a1YqfvzaXyO0Avvb4X5f0NIlANSOnaSdtRRr/SefxJ6JZBW2N+KxqEu/ a12gw7clbJFsDjJLQ+6JKyNq76M+CqiNvctMeYlXeGyk3uHKRn9gStQVWM2lt5QZBLlH tYMYe3IFHy4TldntB7OlsqU0NI4rj7yr/1F4Zr2Xunn+Y9jb7Q3AB7BjWH5YuBwvCjbl bcOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=gM59t77kxXu9xYcbpkzcKwCrS+NdzXXdceaSJibdQSs=; b=Ppiq+rBr8Ywp5z7ksrPcMdycHL5JZnUuGQj4MGSWIXdZe7/eQV9QMfNJYFfvOGw1+M wwuZIYjF5JrHfoOSqokFM3B7O5X2p8gl1gVsU2MoIZWzmD+newx0ZIamWyLtdShTpCvs Ljk5XQx+SD8HjAyKZ0iFXlQTktsaJFVkFFxFFY0CQYN2wJy2bj4SZs/BnbhBypDTv2Cl VGTRPrP5ps898AjE1s+UFpDS7+0ejRvU1LlUnPCPEtwCNNijlQW7K2bJOgqDft63hz7E F0SYcAeA9YP/SjOtPcWZ5ZpyCxrad4fS45crirmL2bZXJJMJx+jFVKnOgE2nQF1ho8mm LQmQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=J/qAYlTX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o33si8273268plb.77.2017.10.09.22.48.31; Mon, 09 Oct 2017 22:48:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=J/qAYlTX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754416AbdJJFsa (ORCPT + 26 others); Tue, 10 Oct 2017 01:48:30 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:43253 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752492AbdJJFs2 (ORCPT ); Tue, 10 Oct 2017 01:48:28 -0400 Received: by mail-pf0-f171.google.com with SMTP id d2so12948972pfh.0 for ; Mon, 09 Oct 2017 22:48:27 -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:in-reply-to:references; bh=gM59t77kxXu9xYcbpkzcKwCrS+NdzXXdceaSJibdQSs=; b=J/qAYlTXuNf+AU66phPF1RSOqEt64oKD8NSeHs4gCtd0/oPsgCzH25HQfUJecKyAqt Zl2fskzOy6pG0CFBxUUBhNpJqavYyAnWEEQmWt6Cl8kxlLxCG0zS67UbcyYbp4lA5w2z VX0rn2PSR2PnZ5sP/Ai0DNRB6Y2r/U22Z95CI= 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:in-reply-to :references; bh=gM59t77kxXu9xYcbpkzcKwCrS+NdzXXdceaSJibdQSs=; b=r349POinFJ9/rbqvj/p4lZ7223FQN2YZIFNo9/NtJZ/A7uFw+je1xeeIkyGmbrEm51 b2C9DkxQuIADAewK7L5M0XEOsLfgX5KgNfTQzJ9/vGS8GCKGeT1ha5s0kvUXyPLaaPwy sK0EQOl5uGKaCzKRKDjs0TN1NAR4sDn9s8WDUV7ROxjFuj602zs7GvozkqlgVfyQWAod plYIwDW+um8hZ27L4CgjR2fKxfmYAtR+/ulLgzSLiDa+6KP2CRfl9j5zPRs84F/g/mEb TZzp4qH1wJdCEQMvFdOMJwjkQfWCaDMECTctFSGHMi1dzYtRSpIMTihdb1Wt9Hw0Ceea 29TQ== X-Gm-Message-State: AMCzsaXbblLpTDU0T5YpNQV/Vb5Npwhu5oJvtnNBkVNkl9pmVdNrWQVt SAUpdTbh8MC3jqQ2JMg1bZErBQ== X-Google-Smtp-Source: AOwi7QAC9rJN9kgFSNlrpxsLMaHG2vUZYA38in95pe6gyAKoNNEmQUCBrvFEGGRqA/tR6kMKIOPBcA== X-Received: by 10.98.220.29 with SMTP id t29mr8524417pfg.25.1507614507515; Mon, 09 Oct 2017 22:48:27 -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.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Oct 2017 22:48:26 -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 2/2] ARM: cpuidle: Refactor rollback operations if init fails Date: Tue, 10 Oct 2017 13:47:56 +0800 Message-Id: <1507614476-16054-2-git-send-email-leo.yan@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1507614476-16054-1-git-send-email-leo.yan@linaro.org> References: <1507614476-16054-1-git-send-email-leo.yan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If init fails, we need execute two levels rollback operations: the first level is for the failed CPU rollback operations, the second level is to iterate all succeeded CPUs to cancel their registration; currently the code uses one function to finish these two levels rollback operations. This commit is to refactor rollback operations, so it adds a new function arm_idle_init_cpu() to encapsulate one specified CPU driver registration and rollback the first level operations; and use function arm_idle_init() to iterate all CPUs and finish the second level's rollback operations. Suggested-by: Daniel Lezcano Signed-off-by: Leo Yan --- drivers/cpuidle/cpuidle-arm.c | 145 ++++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 63 deletions(-) -- 2.7.4 diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index f47c545..ddee1b6 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -72,79 +72,74 @@ static const struct of_device_id arm_idle_state_match[] __initconst = { }; /* - * arm_idle_init + * arm_idle_init_cpu * * Registers the arm specific cpuidle driver with the cpuidle * framework. It relies on core code to parse the idle states * and initialize them using driver data structures accordingly. */ -static int __init arm_idle_init(void) +static int __init arm_idle_init_cpu(int cpu) { - int cpu, ret; + int ret; struct cpuidle_driver *drv; struct cpuidle_device *dev; - for_each_possible_cpu(cpu) { + drv = kmemdup(&arm_idle_driver, sizeof(*drv), GFP_KERNEL); + if (!drv) + return -ENOMEM; - drv = kmemdup(&arm_idle_driver, sizeof(*drv), GFP_KERNEL); - if (!drv) { - ret = -ENOMEM; - goto out_fail; - } - - drv->cpumask = (struct cpumask *)cpumask_of(cpu); - - /* - * Initialize idle states data, starting at index 1. This - * driver is DT only, if no DT idle states are detected (ret - * == 0) let the driver initialization fail accordingly since - * there is no reason to initialize the idle driver if only - * wfi is supported. - */ - ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); - if (ret <= 0) { - ret = ret ? : -ENODEV; - goto out_kfree_drv; - } - - ret = cpuidle_register_driver(drv); - if (ret) { - pr_err("Failed to register cpuidle driver\n"); - goto out_kfree_drv; - } - - /* - * Call arch CPU operations in order to initialize - * idle states suspend back-end specific data - */ - ret = arm_cpuidle_init(cpu); - - /* - * Skip the cpuidle device initialization if the reported - * failure is a HW misconfiguration/breakage (-ENXIO). - */ - if (ret == -ENXIO) - continue; - - if (ret) { - pr_err("CPU %d failed to init idle CPU ops\n", cpu); - goto out_unregister_drv; - } - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - pr_err("Failed to allocate cpuidle device\n"); - ret = -ENOMEM; - goto out_unregister_drv; - } - dev->cpu = cpu; - - ret = cpuidle_register_device(dev); - if (ret) { - pr_err("Failed to register cpuidle device for CPU %d\n", - cpu); - goto out_kfree_dev; - } + drv->cpumask = (struct cpumask *)cpumask_of(cpu); + + /* + * Initialize idle states data, starting at index 1. This + * driver is DT only, if no DT idle states are detected (ret + * == 0) let the driver initialization fail accordingly since + * there is no reason to initialize the idle driver if only + * wfi is supported. + */ + ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); + if (ret <= 0) { + ret = ret ? : -ENODEV; + goto out_kfree_drv; + } + + ret = cpuidle_register_driver(drv); + if (ret) { + pr_err("Failed to register cpuidle driver\n"); + goto out_kfree_drv; + } + + /* + * Call arch CPU operations in order to initialize + * idle states suspend back-end specific data + */ + ret = arm_cpuidle_init(cpu); + + /* + * Skip the cpuidle device initialization if the reported + * failure is a HW misconfiguration/breakage (-ENXIO). + */ + if (ret == -ENXIO) + return 0; + + if (ret) { + pr_err("CPU %d failed to init idle CPU ops\n", cpu); + goto out_unregister_drv; + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + pr_err("Failed to allocate cpuidle device\n"); + ret = -ENOMEM; + goto out_unregister_drv; + } + dev->cpu = cpu; + + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("Failed to register cpuidle device for CPU %d\n", + cpu); + goto out_kfree_dev; } return 0; @@ -155,6 +150,30 @@ static int __init arm_idle_init(void) cpuidle_unregister_driver(drv); out_kfree_drv: kfree(drv); + return ret; +} + +/* + * arm_idle_init - Initializes arm cpuidle driver + * + * Initializes arm cpuidle driver for all CPUs, if any CPU fails + * to register cpuidle driver then rollback to cancel all CPUs + * registeration. + */ +static int __init arm_idle_init(void) +{ + int cpu, ret; + struct cpuidle_driver *drv; + struct cpuidle_device *dev; + + for_each_possible_cpu(cpu) { + ret = arm_idle_init_cpu(cpu); + if (ret) + goto out_fail; + } + + return 0; + out_fail: while (--cpu >= 0) { dev = per_cpu(cpuidle_devices, cpu);