Message ID | 20230131160829.23369-1-ansuelsmth@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp2839565wrn; Tue, 31 Jan 2023 08:12:44 -0800 (PST) X-Google-Smtp-Source: AK7set8UQ+1/pVUYunS2WS54x3sKUw3oS3bn1z0OvRoMWZVdGJMvESV2/iBPv8avHrFKKJyj/+mZ X-Received: by 2002:a05:6a20:c188:b0:be:e908:3292 with SMTP id bg8-20020a056a20c18800b000bee9083292mr2757243pzb.15.1675181563922; Tue, 31 Jan 2023 08:12:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675181563; cv=none; d=google.com; s=arc-20160816; b=FjMWF1R4rNmk3tWZ1RqnuWnhxLKqNMuiDSSEWip+ftK5B4DHwfZZjbD3w5Tu3TAA8f oEu5mrLWxAzllEMRgNt4B92KuvAvFy7ee/xUVYOkPS5UvqVm062x3Hsj0+ClsVkGRmIF D9tmOPQlM5ZO4FzR7lrPGdylQjBG0RE09qf5LeAR5DybzfaYjFsF3OTQwCAndDTcYyVJ KWSVgh9jr/rm3wFFWYyC/168VGcbtxemuHPh5lqqJWC2BfRqH6wAP/V/VwCWNJ33HKZh DivzCDUbs0vN55HcacEIK8hW+N6/iIrYNYi/DhlrBvVjeR8b9irYrDGVTjCZscM31g5F qRKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=VDJhzXE+EpJpWLKyPjwl5rb02w6NGxOvd6kEb5Nte8w=; b=Zw7vVkbcDhVbLahVyU9iCBFevQ4HyeO5hf/WRYg7fsKm1W+U4+koENP34CLmBJ1Xwo exVi7shzWkFZKAVMHSDLk+5PWPN9x3/AAjnCvjzr7y/xQBDZsG/oT3gTbKO1taab65Rr K7CZ26KsUhNzE8SbinfhDsh5dCEAhj4hbk65SskmWf3jXvi9BeiZXkTnPV1S1eB4Bm5k SRviXmz4+UAohI8rQA+IpGalhybzCvoaMuRbjtdCHv61dk+uxfxZwaAxC/5aPTyTd54a oAZQq22V6NxT2+imk+3W8qaFXliK01KLMJaat0YUnH2pwV72cleReZpP9SJ1pHktNvLa k8Tw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=ZjWU9vis; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v3-20020a170902b7c300b00178170100fasi16011216plz.337.2023.01.31.08.12.30; Tue, 31 Jan 2023 08:12:43 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=ZjWU9vis; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232069AbjAaQIm (ORCPT <rfc822;maxin.john@gmail.com> + 99 others); Tue, 31 Jan 2023 11:08:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230060AbjAaQIj (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 31 Jan 2023 11:08:39 -0500 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 501A74A224; Tue, 31 Jan 2023 08:08:38 -0800 (PST) Received: by mail-wm1-x335.google.com with SMTP id j32-20020a05600c1c2000b003dc4fd6e61dso5978374wms.5; Tue, 31 Jan 2023 08:08:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=VDJhzXE+EpJpWLKyPjwl5rb02w6NGxOvd6kEb5Nte8w=; b=ZjWU9vis4X8/Qrhodr1WlT2K9ZnNsLVgva3UtZhvNvGRHWrQnFGO/2W6fxRA36F7pe dwXAEFEGWN/qpVcv0E9L/2w0WOwrrgD3oEsIYhurtEKkO7Wh5goB22S+QtW0BhGWTkf3 i48IWtlvHzz9XJanlA3i/J9hjKjqcC0RVrF0Y69OAayeOY0X1g93s0JbSFWRbL0I3BJq g5VEMQiFCG10EU2PN79NktWsONIKWcqm28er8CwDU36EbbMlc7PU3zfjhNTd9WXWttVS rsnjAxIbqsCDUjj3hgWRKZsvCNYMEdW65DaVB9BfEaxGOd8ya7KdGA22gRp5UpdOot6F LmJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VDJhzXE+EpJpWLKyPjwl5rb02w6NGxOvd6kEb5Nte8w=; b=kzFFWDY9y3T351maNwtXCUaglT5mVB/YiepLRxiwPJDzkSJbhmR/s3oD7kvUUEAfTm +kh1EW4O0BtOflrQGGdikloCJKFhQIiu/FuF+nJcrZW9WlaCCRSN51PeVPD3CxK8BXAu G3gAKwEjIwOGFNmuIimJMnDeIr2efbA/RAHRZ+2034yr60GYg35UwMwJUSNAiuzboAv0 vgiXPMAjRePnlUaguUs3gW6L8TNKIkAQSX8iGzEyOvf6HSZPgSECjznGyezzM5rOa/qA l5CK/N3nAWUQ/qWXjaNxn85HUr46CjAnsM4aIgOy5hk9G6H5pvmelZD/N0efu4QUUW/4 6TFQ== X-Gm-Message-State: AO0yUKXD9tUMmyWUzeUOfG0EpV7KxrxqrsBuJJ1tuSks04ulhJUhFL6q tt/sj0Jsm/Ugmvw+ihQ4EbbbuoEk2MY= X-Received: by 2002:a7b:c3d3:0:b0:3de:1d31:1042 with SMTP id t19-20020a7bc3d3000000b003de1d311042mr594561wmj.23.1675181316729; Tue, 31 Jan 2023 08:08:36 -0800 (PST) Received: from localhost.localdomain (93-34-88-241.ip49.fastwebnet.it. [93.34.88.241]) by smtp.googlemail.com with ESMTPSA id ip7-20020a05600ca68700b003dc433bb5e1sm12622794wmb.9.2023.01.31.08.08.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Jan 2023 08:08:36 -0800 (PST) From: Christian Marangi <ansuelsmth@gmail.com> To: Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Christian Marangi <ansuelsmth@gmail.com> Subject: [PATCH v2 1/2] clk: Warn and add workaround on misuse of .parent_data with .name only Date: Tue, 31 Jan 2023 17:08:28 +0100 Message-Id: <20230131160829.23369-1-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756555183270887765?= X-GMAIL-MSGID: =?utf-8?q?1756555183270887765?= |
Series |
[v2,1/2] clk: Warn and add workaround on misuse of .parent_data with .name only
|
|
Commit Message
Christian Marangi
Jan. 31, 2023, 4:08 p.m. UTC
By a simple mistake in a .parent_names to .parent_data conversion it was
found that clk core assume fw_name is always provided with a parent_data
struct for each parent and never fallback to .name to get parent name even
if declared.
This is caused by clk_core_get that only checks for parent .fw_name and
doesn't handle .name.
While it's sane to request the dev to correctly do the conversion and
add both .fw_name and .name in a parent_data struct, it's not sane to
silently drop parents without a warning.
Fix this in 2 ways. Add a kernel warning when a wrong implementation is
used and copy .name in .fw_name in parent map populate function to
handle clk problems and malfunctions.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/clk.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
Comments
On Fri, Feb 10, 2023 at 04:40:29PM -0800, Stephen Boyd wrote: > Quoting Christian Marangi (2023-01-31 08:08:28) > > By a simple mistake in a .parent_names to .parent_data conversion it was > > found that clk core assume fw_name is always provided with a parent_data > > struct for each parent and never fallback to .name to get parent name even > > if declared. > > It sounds like you have clk_parent_data and the .index member is 0? Can > you show an example structure? I'm guessing it is like this: > > struct clk_parent_data pdata = { .name = "global_name" }; > An example of this problem and the relative fix is here 35dc8e101a8e08f69f4725839b98ec0f11a8e2d3 You example is also ok and this patch wants to handle just a case like that. > > > > This is caused by clk_core_get that only checks for parent .fw_name and > > doesn't handle .name. > > clk_core_get() is not supposed to operate on the .name member. It is a > firmware based lookup with clkdev as a fallback because clkdev is a > psudeo-firmware interface to assign a name to a clk when some device > pointer is used in conjunction with it. > And the problem is just that. We currently permit to have a configuration with .name but no .fw_name. In a case like that a dev may think that this configuration is valid but in reality the clk is silently ignored/not found and cause clk problem with selecting a parent. Took some good hours to discover this and to me it seems an error that everybody can do since nowhere is specificed that the following parent_data configuration is illegal. > > > > While it's sane to request the dev to correctly do the conversion and > > add both .fw_name and .name in a parent_data struct, it's not sane to > > silently drop parents without a warning. > > I suppose we can do > > WARN(parent->index >= 0 && !parent_data[i].fw_name && parent_data[i].name, ...); > > or maybe better would be to make the clk registration fail if there's a > .name field and the index is non-negative and the fw_name is NULL. > > Can you grep the code and see if anyone is assigning a .name without a > .fw_name or .index? > I can check and have some fun with a good regex. Reject registration may be an option but consider that this may cause some device to not boot at all if the error is done on a core clock driver like a gcc driver. What I would love is if there is a way to cause a compilation error but I don't think that is doable with a C macro? > > > > Fix this in 2 ways. Add a kernel warning when a wrong implementation is > > used and copy .name in .fw_name in parent map populate function to > > handle clk problems and malfunctions. > > We shouldn't be copying .name to .fw_name. They're different things. The idea here was that in theory the global name should not be that different than fw_name. But I understand this can have drammatic side effect so I agree that we should only WARN that there is something wrong. Hope with these expleination it's more clear what this patch is trying to achieve. The referenced commit should make the problem clear.
Quoting Christian Marangi (2023-01-31 08:08:28) > By a simple mistake in a .parent_names to .parent_data conversion it was > found that clk core assume fw_name is always provided with a parent_data > struct for each parent and never fallback to .name to get parent name even > if declared. It sounds like you have clk_parent_data and the .index member is 0? Can you show an example structure? I'm guessing it is like this: struct clk_parent_data pdata = { .name = "global_name" }; > > This is caused by clk_core_get that only checks for parent .fw_name and > doesn't handle .name. clk_core_get() is not supposed to operate on the .name member. It is a firmware based lookup with clkdev as a fallback because clkdev is a psudeo-firmware interface to assign a name to a clk when some device pointer is used in conjunction with it. > > While it's sane to request the dev to correctly do the conversion and > add both .fw_name and .name in a parent_data struct, it's not sane to > silently drop parents without a warning. I suppose we can do WARN(parent->index >= 0 && !parent_data[i].fw_name && parent_data[i].name, ...); or maybe better would be to make the clk registration fail if there's a .name field and the index is non-negative and the fw_name is NULL. Can you grep the code and see if anyone is assigning a .name without a .fw_name or .index? > > Fix this in 2 ways. Add a kernel warning when a wrong implementation is > used and copy .name in .fw_name in parent map populate function to > handle clk problems and malfunctions. We shouldn't be copying .name to .fw_name. They're different things.
Quoting Christian Marangi (2023-02-10 10:34:11) > On Fri, Feb 10, 2023 at 04:40:29PM -0800, Stephen Boyd wrote: > > Quoting Christian Marangi (2023-01-31 08:08:28) > > > By a simple mistake in a .parent_names to .parent_data conversion it was > > > found that clk core assume fw_name is always provided with a parent_data > > > struct for each parent and never fallback to .name to get parent name even > > > if declared. > > > > It sounds like you have clk_parent_data and the .index member is 0? Can > > you show an example structure? I'm guessing it is like this: > > > > struct clk_parent_data pdata = { .name = "global_name" }; > > > > An example of this problem and the relative fix is here > 35dc8e101a8e08f69f4725839b98ec0f11a8e2d3 > > You example is also ok and this patch wants to handle just a case like > that. Ok, so you have a firmware .index of 0. The .name is a fallback. I suppose you want the .name to be a fallback if there isn't a clocks property in the registering device node? I thought that should already work but maybe there is a bug somewhere. Presumably you have a gcc node that doesn't have a clocks property gcc: gcc@1800000 { compatible = "qcom,gcc-ipq8074"; reg = <0x01800000 0x80000>; #clock-cells = <0x1>; #power-domain-cells = <1>; #reset-cells = <0x1>; }; Looking at clk_core_get() we'll call of_parse_clkspec() and that should fail struct clk_hw *hw = ERR_PTR(-ENOENT); ... if (np && (name || index >= 0) && !of_parse_clkspec(np, index, name, &clkspec)) { ... } else if (name) { ... } if (IS_ERR(hw)) return ERR_CAST(hw); so we should have a -ENOENT clk_hw pointer in clk_core_fill_parent_index(). That should land in this if condition in clk_core_fill_parent_index() parent = clk_core_get(core, index); if (PTR_ERR(parent) == -ENOENT && entry->name) parent = clk_core_lookup(entry->name); and then entry->name should be used. > > > > > > > This is caused by clk_core_get that only checks for parent .fw_name and > > > doesn't handle .name. > > > > clk_core_get() is not supposed to operate on the .name member. It is a > > firmware based lookup with clkdev as a fallback because clkdev is a > > psudeo-firmware interface to assign a name to a clk when some device > > pointer is used in conjunction with it. > > > > And the problem is just that. We currently permit to have a > configuration with .name but no .fw_name. In a case like that a dev may > think that this configuration is valid but in reality the clk is > silently ignored/not found and cause clk problem with selecting a > parent. It is valid though. > > Took some good hours to discover this and to me it seems an error that > everybody can do since nowhere is specificed that the following > parent_data configuration is illegal. > I'll look at adding a test. Seems to be the best way to solve this.
On Wed, Feb 15, 2023 at 10:54:56AM -0800, Stephen Boyd wrote: > Quoting Christian Marangi (2023-02-10 10:34:11) > > On Fri, Feb 10, 2023 at 04:40:29PM -0800, Stephen Boyd wrote: > > > Quoting Christian Marangi (2023-01-31 08:08:28) > > > > By a simple mistake in a .parent_names to .parent_data conversion it was > > > > found that clk core assume fw_name is always provided with a parent_data > > > > struct for each parent and never fallback to .name to get parent name even > > > > if declared. > > > > > > It sounds like you have clk_parent_data and the .index member is 0? Can > > > you show an example structure? I'm guessing it is like this: > > > > > > struct clk_parent_data pdata = { .name = "global_name" }; > > > > > > > An example of this problem and the relative fix is here > > 35dc8e101a8e08f69f4725839b98ec0f11a8e2d3 > > > > You example is also ok and this patch wants to handle just a case like > > that. > > Ok, so you have a firmware .index of 0. The .name is a fallback. I > suppose you want the .name to be a fallback if there isn't a clocks > property in the registering device node? I thought that should already > work but maybe there is a bug somewhere. Presumably you have a gcc node > that doesn't have a clocks property > > gcc: gcc@1800000 { > compatible = "qcom,gcc-ipq8074"; > reg = <0x01800000 0x80000>; > #clock-cells = <0x1>; > #power-domain-cells = <1>; > #reset-cells = <0x1>; > }; > > Looking at clk_core_get() we'll call of_parse_clkspec() and that should fail > > struct clk_hw *hw = ERR_PTR(-ENOENT); > > ... > > if (np && (name || index >= 0) && > !of_parse_clkspec(np, index, name, &clkspec)) { > ... > } else if (name) { > ... > } > > if (IS_ERR(hw)) > return ERR_CAST(hw); > > so we should have a -ENOENT clk_hw pointer in > clk_core_fill_parent_index(). That should land in this if condition in > clk_core_fill_parent_index() > > parent = clk_core_get(core, index); > if (PTR_ERR(parent) == -ENOENT && entry->name) > parent = clk_core_lookup(entry->name); > > and then entry->name should be used. > Hi, thanks for making me give this an extra check... I think I found the real cause. I send a patch that should suppress this and give an extensive explaination of the problem. This is the ID: 20230215232712.17072-1-ansuelsmth@gmail.com The hint that made me get what was wrong was a problem with index and the fact that it should have returned -ENOENT... Fun to discover a clock was actually returned and the function never returned an error. > > > > > > > > > > This is caused by clk_core_get that only checks for parent .fw_name and > > > > doesn't handle .name. > > > > > > clk_core_get() is not supposed to operate on the .name member. It is a > > > firmware based lookup with clkdev as a fallback because clkdev is a > > > psudeo-firmware interface to assign a name to a clk when some device > > > pointer is used in conjunction with it. > > > > > > > And the problem is just that. We currently permit to have a > > configuration with .name but no .fw_name. In a case like that a dev may > > think that this configuration is valid but in reality the clk is > > silently ignored/not found and cause clk problem with selecting a > > parent. > > It is valid though. > > > > > Took some good hours to discover this and to me it seems an error that > > everybody can do since nowhere is specificed that the following > > parent_data configuration is illegal. > > > > I'll look at adding a test. Seems to be the best way to solve this. Eh probably a test may have made this more clear. The main problem here was that the function never returned an error but under the hood the parent was pointing to another clock.
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 57b83665e5c3..dccd4ea6f692 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4015,10 +4015,21 @@ static int clk_core_populate_parent_map(struct clk_core *core, ret = clk_cpy_name(&parent->name, parent_names[i], true); } else if (parent_data) { + const char *parent_name; + parent->hw = parent_data[i].hw; parent->index = parent_data[i].index; + parent_name = parent_data[i].fw_name; + + if (!parent_name && parent_data[i].name) { + WARN(1, "Empty .fw_name with .name in %s's .parent_data. Using .name for .fw_name declaration.\n", + core->name); + parent_name = parent_data[i].name; + } + ret = clk_cpy_name(&parent->fw_name, - parent_data[i].fw_name, false); + parent_name, false); + if (!ret) ret = clk_cpy_name(&parent->name, parent_data[i].name,