From patchwork Fri Jan 3 19:36:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= X-Patchwork-Id: 11317361 X-Patchwork-Delegate: viresh.linux@gmail.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 974F3930 for ; Fri, 3 Jan 2020 19:36:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6CE9022314 for ; Fri, 3 Jan 2020 19:36:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=rere.qmqm.pl header.i=@rere.qmqm.pl header.b="kS8dJ/Jr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728503AbgACTgX (ORCPT ); Fri, 3 Jan 2020 14:36:23 -0500 Received: from rere.qmqm.pl ([91.227.64.183]:60729 "EHLO rere.qmqm.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728376AbgACTgW (ORCPT ); Fri, 3 Jan 2020 14:36:22 -0500 Received: from remote.user (localhost [127.0.0.1]) by rere.qmqm.pl (Postfix) with ESMTPSA id 47qFWm2pbWzGW; Fri, 3 Jan 2020 20:36:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rere.qmqm.pl; s=1; t=1578080180; bh=VyRZ0woKa5nUH9vcXSMRuDeYWl1RDXs9EIlAHgOsp5s=; h=Date:From:Subject:To:Cc:From; b=kS8dJ/JrAVOWxQXVBQIuMv7na0R3QsPb70Ka4iRyXek7E3XDGV2pxp6HTdfBtunDd Ekeq8Xe2S1CP7A/jkgNbdwDrjTWPEoCgY0bixAhLsyyAzHVmD67GJEH7Gn5M7tKhfD BRA8weEDS0700d/PzgvmeAfFeD9V6aDipr2GFGXmmDmHX1q4NzpZgPi/kFlePv+2OQ t8OgEHJ6H2tNi+NCgz4Bm/ZloZHMbVAUP6KjCjGVTQ8uJfjro13N2y7FaHFNW4tH6K glYegntUjKwjT3ucTpks2q/ELYoBjeI7gblo+Yj3xY8qaXgCveTYwYzrhuW65Lzajo rup0fqgjhbmJA== X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.101.4 at mail Date: Fri, 03 Jan 2020 20:36:20 +0100 Message-Id: From: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= Subject: [PATCH 1/2] opp: fix of_node leak for unsupported entries MIME-Version: 1.0 To: Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org When parsing OPP v2 table, unsupported entries return NULL from _opp_add_static_v2(). In this case node reference is leaked. Make _opp_add_static_v2() always assume ownership of the reference to fix this. Commit 7978db344719 ("PM / OPP: Add missing of_node_put(np)") already fixed this for the error returns. The leak remained for filtered-out entries from the initial code commit. The Fixes-tagged commit is just a last one that altered the code around. Fixes: 11e1a1648298 ("opp: Don't decrement uninitialized list_kref") Signed-off-by: Michał Mirosław --- drivers/opp/of.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 1cbb58240b80..fba515e432a4 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -555,8 +555,10 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, bool rate_not_available = false; new_opp = _opp_allocate(opp_table); - if (!new_opp) - return ERR_PTR(-ENOMEM); + if (!new_opp) { + ret = -ENOMEM; + goto free_node; + } ret = of_property_read_u64(np, "opp-hz", &rate); if (ret < 0) { @@ -646,6 +648,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, _of_opp_free_required_opps(opp_table, new_opp); free_opp: _opp_free(new_opp); +free_node: + of_node_put(np); return ERR_PTR(ret); } @@ -677,7 +681,6 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) ret = PTR_ERR(opp); dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, ret); - of_node_put(np); return ret; } else if (opp) { count++; From patchwork Fri Jan 3 19:36:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= X-Patchwork-Id: 11317363 X-Patchwork-Delegate: viresh.linux@gmail.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1BED2930 for ; Fri, 3 Jan 2020 19:36:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EE9DE215A4 for ; Fri, 3 Jan 2020 19:36:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=rere.qmqm.pl header.i=@rere.qmqm.pl header.b="Ylp4VpqJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728376AbgACTg0 (ORCPT ); Fri, 3 Jan 2020 14:36:26 -0500 Received: from rere.qmqm.pl ([91.227.64.183]:14131 "EHLO rere.qmqm.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728488AbgACTgX (ORCPT ); Fri, 3 Jan 2020 14:36:23 -0500 Received: from remote.user (localhost [127.0.0.1]) by rere.qmqm.pl (Postfix) with ESMTPSA id 47qFWn074BzJf; Fri, 3 Jan 2020 20:36:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rere.qmqm.pl; s=1; t=1578080181; bh=WlFGQ9P8prWFa6CvEQ+uJYVkZQz0/FIh1Zkijr+EcIw=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=Ylp4VpqJCIcbkxk/NePZyFq9GAuIM/miWnraMy0CIBf3Gjobl56vY5VprhAAUmF3G 9cdWHtm6N3kf0M7Hvy/7q8sv1DeIj4/lc+6acXNlrDS3vosq27NdvD/rVlNOkRx20Z WPj51r+d07qC1TV4634m0ILyi5aVS+SSX7Qfa8Mr5C9bSwJdPd1AQQ4DmbvYBDTzuc Lk/FuqJjSMLXtRlHOu1w6ZHK0IYu1i18e7NfMFnugy5MuRQLcGBFMA6GKJeqP39fMD Cjcl/nhZS2FMjPHArZE+AWBa65ETPJ+NRMRo7PBDUSWQo+eF9bnP7XDm3Ho1C9GiYK Oy3+1LyKfguAA== X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.101.4 at mail Date: Fri, 03 Jan 2020 20:36:20 +0100 Message-Id: <5c2d6548aef35c690535fd8c985b980316745e91.1578077228.git.mirq-linux@rere.qmqm.pl> In-Reply-To: References: From: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= Subject: [PATCH 2/2] opp: quiet down WARN when no valid OPPs remain MIME-Version: 1.0 To: Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Per CPU screenful of backtraces is not really that useful. Replace WARN with a diagnostic discriminating common causes of empty OPP table. Signed-off-by: Michał Mirosław --- drivers/opp/of.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index fba515e432a4..59d7667b56f0 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -534,12 +534,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); * Return: * Valid OPP pointer: * On success - * NULL: + * ERR_PTR(-EBUSY): * Duplicate OPPs (both freq and volt are same) and opp->available - * OR if the OPP is not supported by hardware. * ERR_PTR(-EEXIST): * Freq are same and volt are different OR * Duplicate OPPs (both freq and volt are same) and !opp->available + * ERR_PTR(-ENODEV): + * The OPP is not supported by hardware. * ERR_PTR(-ENOMEM): * Memory allocation failure * ERR_PTR(-EINVAL): @@ -583,6 +584,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, /* Check if the OPP supports hardware's hierarchy of versions or not */ if (!_opp_is_supported(dev, opp_table, np)) { dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate); + ret = -ENODEV; goto free_opp; } @@ -607,12 +609,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, new_opp->pstate = pm_genpd_opp_to_performance_state(dev, new_opp); ret = _opp_add(dev, new_opp, opp_table, rate_not_available); - if (ret) { - /* Don't return error for duplicate OPPs */ - if (ret == -EBUSY) - ret = 0; + if (ret) goto free_required_opps; - } /* OPP to select on device suspend */ if (of_property_read_bool(np, "opp-suspend")) { @@ -658,7 +656,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) { struct device_node *np; - int ret, count = 0, pstate_count = 0; + int ret, count = 0, filtered = 0, pstate_count = 0; struct dev_pm_opp *opp; /* OPP table is already initialized for the device */ @@ -677,19 +675,32 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) /* We have opp-table node now, iterate over it and add OPPs */ for_each_available_child_of_node(opp_table->np, np) { opp = _opp_add_static_v2(opp_table, dev, np); - if (IS_ERR(opp)) { - ret = PTR_ERR(opp); + ret = PTR_ERR_OR_ZERO(opp); + if (!ret) { + count++; + } else if (ret == -ENODEV) { + filtered++; + } else if (ret != -EBUSY) { dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, ret); return ret; - } else if (opp) { - count++; } } - /* There should be one of more OPP defined */ - if (WARN_ON(!count)) + /* There should be one or more OPPs defined */ + if (!count) { + if (!filtered) + /* all can't be duplicates, so there must be none */ + dev_err(dev, "%s: OPP table empty", __func__); + else if (!opp_table->supported_hw) + dev_err(dev, + "%s: all OPPs match hw version, but platform did not provide it", + __func__); + else + dev_err(dev, "%s: no supported OPPs", __func__); + return -ENOENT; + } list_for_each_entry(opp, &opp_table->opp_list, node) pstate_count += !!opp->pstate;