Message ID | 20230721-clk-fix-kunit-lockdep-v1-0-32cdba4c8fc1@kernel.org |
---|---|
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9010:0:b0:3e4:2afc:c1 with SMTP id l16csp29012vqg; Fri, 21 Jul 2023 00:27:41 -0700 (PDT) X-Google-Smtp-Source: APBJJlHdOcmjeirUoA4yovabUEkigcJLazghpnsFhVR2me0yiZU4ej/3ywH0RAUWhfeylEnQ5GI4 X-Received: by 2002:a05:6a20:508:b0:134:951c:acb3 with SMTP id 8-20020a056a20050800b00134951cacb3mr1308780pzp.35.1689924461337; Fri, 21 Jul 2023 00:27:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689924461; cv=none; d=google.com; s=arc-20160816; b=GVISHeidrYaSwmL4LDufQWTWgFVmU4AQeDZjfHELHnte8m+s3r25BTA49skxWVEqkk P1D84+hqcIBpmg25qfWp2Aqctj4H1KSVGjU+jsK4yxZrCRn9Lp8kMYfcf7whR+5iLiQa L/2eMl2VGh/+2XhspEQebuVwOV4NZUaTb+oxZxLzs4cyCsV4Hjh3eIiKfpcOlrVbbXQE Et9Ynkl/E0VvIiBqu1007Dbds9zLHCtvgzmKo74LbrVe/o7LiLD9HA8+4D9eVunO8ObS VFkuzOgU1w12vhP/02w7O9YhN/4/XLcZrBP/FYwCfPZ3iomHCf6DUyROUaMOzzlXEUgu qKzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:content-transfer-encoding:mime-version :message-id:date:subject:from:dkim-signature; bh=iAOiSp4mY7gGAjBqJ0F8zE6FJQ2fZBIj/G+V5JTZjw8=; fh=360HmAXND8A05iRBc7UoIp+5mY0SlJN6aKBr9AaO02M=; b=M0VYq2SfMyBhsZ2JgVwudLMW6vrWhkxFTBorCaZeNWy2wYyk+6uFw1JzI4FSv1JjwF I88PX6dg8rZqe5ai8GxQHR+yhj/XO7Pvm5WzSHPTHRZOkLeM1GcR6eRKVNipGvCYZSmk uP7bbql7egzS5G2IPQlVt6v0sL6tscfwCVJQiOnxCxweZ2QXP+4GugsdwKNM2nzqDK4o 4O1kt6G5fJJWDwCKwVfHnI7Ioq+DCcHvSbihyzApCNUz+2cLLLyzAj8Ov4lIz7BKId4x SAHAMztE3sVKLc0+EuKH4r73jd5aF7Lm4MpHfsPTqBnP7SiwrwV5JWG2ktGYCkdSJg06 MXbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rAya1kdn; 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=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bt8-20020a632908000000b0055387ef9633si2354798pgb.804.2023.07.21.00.27.27; Fri, 21 Jul 2023 00:27:41 -0700 (PDT) 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=@kernel.org header.s=k20201202 header.b=rAya1kdn; 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=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230253AbjGUHJq (ORCPT <rfc822;assdfgzxcv4@gmail.com> + 99 others); Fri, 21 Jul 2023 03:09:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229977AbjGUHJh (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 21 Jul 2023 03:09:37 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F72A273E; Fri, 21 Jul 2023 00:09:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AC515612DC; Fri, 21 Jul 2023 07:09:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89FBFC433CB; Fri, 21 Jul 2023 07:09:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1689923374; bh=C+hSLA99pkHkutteaL+7ugfOymbqI1rh00LNugXxXk8=; h=From:Subject:Date:To:Cc:From; b=rAya1kdnXPDmZtSY2+DBS12KXK317VALunTFx7o2wIXjLWxMHYIN7YiaH9eMx3kxo SYIWkbRVmVdJNpQ9NkGQAOWP86pmcoOjgADDJ6yAueBy4KJqPbyprGA8UlJXECbqqF SriZm6Lz2RqqBD7yH2EdKmS/LJ56P5TbLYtYaj1ERwuR9QKxwuMLSWCycroe86iONY EAXeOOo32mPEvjp94dAn73BGeHcJ+Bzn45MrVQuABxj8yiyxmOXlaawBem+7L6uJyG BAPG3o7k1wKsP8hai57YabillO1swJ/l05dbEeXZvIAFfQUJhwNCdPm8tRosz+F9zV Jj0hQQ0jXRgxA== From: Maxime Ripard <mripard@kernel.org> Subject: [PATCH 0/2] clk: kunit: Fix the lockdep warnings Date: Fri, 21 Jul 2023 09:09:31 +0200 Message-Id: <20230721-clk-fix-kunit-lockdep-v1-0-32cdba4c8fc1@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-B4-Tracking: v=1; b=H4sIACsvumQC/x2M2wpAQBBAf0XzbMqMXPIr8sAaTKulXaTk320eT 51zHgjiVQI0yQNeLg26uQiUJmCW3s2COkYGzjjPKiY0q8VJb7Sn0wPXzdhRdjSFlDwwE1ENsd2 9ROn/tt37fp0ybF9nAAAA To: Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org> Cc: linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Maxime Ripard <mripard@kernel.org>, Guenter Roeck <linux@roeck-us.net>, kernel test robot <yujie.liu@intel.com> X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1036; i=mripard@kernel.org; h=from:subject:message-id; bh=C+hSLA99pkHkutteaL+7ugfOymbqI1rh00LNugXxXk8=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDCm79HV0V25qLbwkUS32L8Vu94l9USpui8vl+Rpkimbuf Lbu3RXfjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAExkZxvDf6/uBY83hPhdDLt2 +3BSYmPKWZ9AtgtWRyedWHCkqrbG7gEjwyTvxGtmnqs/J5UayXy5bCDBe5Hpl9n9U/PkJXhZjJa a8QEA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED 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: INBOX X-GMAIL-THRID: 1772014231791440435 X-GMAIL-MSGID: 1772014231791440435 |
Series |
clk: kunit: Fix the lockdep warnings
|
|
Message
Maxime Ripard
July 21, 2023, 7:09 a.m. UTC
Hi,
Here's a small series to address the lockdep warning we have when
running the clk kunit tests with lockdep enabled.
For the record, it can be tested with:
$ ./tools/testing/kunit/kunit.py run \
--kunitconfig=drivers/clk \
--cross_compile aarch64-linux-gnu- --arch arm64 \
--kconfig_add CONFIG_DEBUG_KERNEL=y \
--kconfig_add CONFIG_PROVE_LOCKING=y
Let me know what you think,
Maxime
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Maxime Ripard (2):
clk: Introduce kunit wrapper around clk_hw_init_rate_request
clk: Introduce kunit wrapper around __clk_determine_rate
drivers/clk/clk.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
drivers/clk/clk_test.c | 4 ++--
include/linux/clk-provider.h | 21 ++++++++++++++++++
3 files changed, 74 insertions(+), 2 deletions(-)
---
base-commit: c58c49dd89324b18a812762a2bfa5a0458e4f252
change-id: 20230721-clk-fix-kunit-lockdep-c5e62b221118
Best regards,
Comments
On Fri, Jul 21, 2023 at 09:09:31AM +0200, Maxime Ripard wrote: > Hi, > > Here's a small series to address the lockdep warning we have when > running the clk kunit tests with lockdep enabled. > > For the record, it can be tested with: > > $ ./tools/testing/kunit/kunit.py run \ > --kunitconfig=drivers/clk \ > --cross_compile aarch64-linux-gnu- --arch arm64 \ > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > --kconfig_add CONFIG_PROVE_LOCKING=y > > Let me know what you think, The series fixes the problem for me. I sent Tested-by: tags for both patches individually. Thanks, Guenter > Maxime > > Signed-off-by: Maxime Ripard <mripard@kernel.org> > --- > Maxime Ripard (2): > clk: Introduce kunit wrapper around clk_hw_init_rate_request > clk: Introduce kunit wrapper around __clk_determine_rate > > drivers/clk/clk.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ > drivers/clk/clk_test.c | 4 ++-- > include/linux/clk-provider.h | 21 ++++++++++++++++++ > 3 files changed, 74 insertions(+), 2 deletions(-) > --- > base-commit: c58c49dd89324b18a812762a2bfa5a0458e4f252 > change-id: 20230721-clk-fix-kunit-lockdep-c5e62b221118 > > Best regards, > -- > Maxime Ripard <mripard@kernel.org> >
+kunit-dev Quoting Maxime Ripard (2023-07-21 00:09:31) > Hi, > > Here's a small series to address the lockdep warning we have when > running the clk kunit tests with lockdep enabled. > > For the record, it can be tested with: > > $ ./tools/testing/kunit/kunit.py run \ > --kunitconfig=drivers/clk \ > --cross_compile aarch64-linux-gnu- --arch arm64 \ > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > --kconfig_add CONFIG_PROVE_LOCKING=y > > Let me know what you think, Thanks for doing this. I want to roll these helpers into the clk_kunit.c file that I had created for some other clk tests[1]. That's mostly because clk.c is already super long and adding kunit code there makes that problem worse. I'll try to take that patch out of the rest of the series and then add this series on top and resend. I don't know what to do about the case where CONFIG_KUNIT=m though. We have to export clk_prepare_lock/unlock()? I really don't want to do that even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there was a GPL version of that, so proprietary modules can't get at kernel internals on kunit enabled kernels. But I also like the approach taken here of adding a small stub around the call to make sure a test is running. Maybe I'll make a kunit namespaced exported gpl symbol that bails if a test isn't running and calls the clk_prepare_lock/unlock functions inside clk.c and then move the rest of the code to clk_kunit.c to get something more strict. [1] https://lore.kernel.org/all/20230327222159.3509818-9-sboyd@kernel.org/
On 8/9/23 16:21, Stephen Boyd wrote: > +kunit-dev > > Quoting Maxime Ripard (2023-07-21 00:09:31) >> Hi, >> >> Here's a small series to address the lockdep warning we have when >> running the clk kunit tests with lockdep enabled. >> >> For the record, it can be tested with: >> >> $ ./tools/testing/kunit/kunit.py run \ >> --kunitconfig=drivers/clk \ >> --cross_compile aarch64-linux-gnu- --arch arm64 \ >> --kconfig_add CONFIG_DEBUG_KERNEL=y \ >> --kconfig_add CONFIG_PROVE_LOCKING=y >> >> Let me know what you think, > > Thanks for doing this. I want to roll these helpers into the clk_kunit.c > file that I had created for some other clk tests[1]. That's mostly > because clk.c is already super long and adding kunit code there makes > that problem worse. I'll try to take that patch out of the rest of the > series and then add this series on top and resend. > > I don't know what to do about the case where CONFIG_KUNIT=m though. We > have to export clk_prepare_lock/unlock()? I really don't want to do that > even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there > was a GPL version of that, so proprietary modules can't get at kernel > internals on kunit enabled kernels. > EXPORT_SYMBOL_IF_KUNIT defines a module namespace. You could go a step further and define a CLK_KUNIT module namespace or similar. That would of course still permit abuse, but it would have to be _very_ intentional. There is an EXPORT_SYMBOL_NS_GPL(), so you could further restrict it to GPL only. Guenter
Quoting Stephen Boyd (2023-08-09 16:21:50) > +kunit-dev > > Quoting Maxime Ripard (2023-07-21 00:09:31) > > Hi, > > > > Here's a small series to address the lockdep warning we have when > > running the clk kunit tests with lockdep enabled. > > > > For the record, it can be tested with: > > > > $ ./tools/testing/kunit/kunit.py run \ > > --kunitconfig=drivers/clk \ > > --cross_compile aarch64-linux-gnu- --arch arm64 \ > > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > > --kconfig_add CONFIG_PROVE_LOCKING=y > > > > Let me know what you think, > > Thanks for doing this. I want to roll these helpers into the clk_kunit.c > file that I had created for some other clk tests[1]. That's mostly > because clk.c is already super long and adding kunit code there makes > that problem worse. I'll try to take that patch out of the rest of the > series and then add this series on top and resend. > > I don't know what to do about the case where CONFIG_KUNIT=m though. We > have to export clk_prepare_lock/unlock()? I really don't want to do that > even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there > was a GPL version of that, so proprietary modules can't get at kernel > internals on kunit enabled kernels. > > But I also like the approach taken here of adding a small stub around > the call to make sure a test is running. Maybe I'll make a kunit > namespaced exported gpl symbol that bails if a test isn't running and > calls the clk_prepare_lock/unlock functions inside clk.c and then move > the rest of the code to clk_kunit.c to get something more strict. > What if we don't try to do any wrapper or export symbols and test __clk_determine_rate() how it is called from the clk framework? The downside is the code is not as simple because we have to check things from within the clk_ops::determine_rate(), but the upside is that we can avoid exporting internal clk APIs or wrap them so certain preconditions are met like requiring them to be called from within a clk_op. I also find it very odd to call clk_mux_determine_rate_closest() from a clk that has one parent. Maybe the clk op should call clk_hw_forward_rate_request() followed by __clk_determine_rate() on the parent so we can test what the test comment says it wants to test. -----8<----- diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c index a154ec9d0111..b5b4f504b284 100644 --- a/drivers/clk/clk_test.c +++ b/drivers/clk/clk_test.c @@ -2155,6 +2155,53 @@ static struct kunit_suite clk_range_minimize_test_suite = { struct clk_leaf_mux_ctx { struct clk_multiple_parent_ctx mux_ctx; struct clk_hw hw; + struct kunit *test; + bool determine_rate_called; +}; + +static int clk_leaf_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct clk_leaf_mux_ctx *ctx = container_of(hw, struct clk_leaf_mux_ctx, hw); + struct kunit *test = ctx->test; + + KUNIT_ASSERT_EQ(test, req->rate, DUMMY_CLOCK_RATE_2); + KUNIT_ASSERT_EQ(test, 0, __clk_mux_determine_rate_closest(hw, req)); + + KUNIT_EXPECT_EQ(test, req->rate, DUMMY_CLOCK_RATE_2); + KUNIT_EXPECT_EQ(test, req->best_parent_rate, DUMMY_CLOCK_RATE_2); + KUNIT_EXPECT_PTR_EQ(test, req->best_parent_hw, &ctx->mux_ctx.hw); + + ctx->determine_rate_called = true; + + return 0; +} + +static const struct clk_ops clk_leaf_mux_set_rate_parent_ops = { + .determine_rate = clk_leaf_mux_determine_rate, + .set_parent = clk_dummy_single_set_parent, + .get_parent = clk_dummy_single_get_parent, +}; + +/* + * Test that, for a clock that will forward any rate request to its + * parent, the rate request structure returned by __clk_determine_rate + * is sane and will be what we expect. + */ +static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test) +{ + struct clk_leaf_mux_ctx *ctx = test->priv; + struct clk_hw *hw = &ctx->hw; + struct clk *clk = clk_hw_get_clk(hw, NULL); + + KUNIT_EXPECT_EQ(test, DUMMY_CLOCK_RATE_2, clk_round_rate(clk, DUMMY_CLOCK_RATE_2)); + KUNIT_EXPECT_TRUE(test, ctx->determine_rate_called); + + clk_put(clk); +} + +static struct kunit_case clk_leaf_mux_set_rate_parent_test_cases[] = { + KUNIT_CASE(clk_leaf_mux_set_rate_parent_determine_rate), + {} }; static int @@ -2168,6 +2215,7 @@ clk_leaf_mux_set_rate_parent_test_init(struct kunit *test) if (!ctx) return -ENOMEM; test->priv = ctx; + ctx->test = test; ctx->mux_ctx.parents_ctx[0].hw.init = CLK_HW_INIT_NO_PARENT("parent-0", &clk_dummy_rate_ops, @@ -2194,7 +2242,7 @@ clk_leaf_mux_set_rate_parent_test_init(struct kunit *test) return ret; ctx->hw.init = CLK_HW_INIT_HW("test-clock", &ctx->mux_ctx.hw, - &clk_dummy_single_parent_ops, + &clk_leaf_mux_set_rate_parent_ops, CLK_SET_RATE_PARENT); ret = clk_hw_register(NULL, &ctx->hw); if (ret) @@ -2213,40 +2261,6 @@ static void clk_leaf_mux_set_rate_parent_test_exit(struct kunit *test) clk_hw_unregister(&ctx->mux_ctx.parents_ctx[1].hw); } -/* - * Test that, for a clock that will forward any rate request to its - * parent, the rate request structure returned by __clk_determine_rate - * is sane and will be what we expect. - */ -static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test) -{ - struct clk_leaf_mux_ctx *ctx = test->priv; - struct clk_hw *hw = &ctx->hw; - struct clk *clk = clk_hw_get_clk(hw, NULL); - struct clk_rate_request req; - unsigned long rate; - int ret; - - rate = clk_get_rate(clk); - KUNIT_ASSERT_EQ(test, rate, DUMMY_CLOCK_RATE_1); - - clk_hw_init_rate_request(hw, &req, DUMMY_CLOCK_RATE_2); - - ret = __clk_determine_rate(hw, &req); - KUNIT_ASSERT_EQ(test, ret, 0); - - KUNIT_EXPECT_EQ(test, req.rate, DUMMY_CLOCK_RATE_2); - KUNIT_EXPECT_EQ(test, req.best_parent_rate, DUMMY_CLOCK_RATE_2); - KUNIT_EXPECT_PTR_EQ(test, req.best_parent_hw, &ctx->mux_ctx.hw); - - clk_put(clk); -} - -static struct kunit_case clk_leaf_mux_set_rate_parent_test_cases[] = { - KUNIT_CASE(clk_leaf_mux_set_rate_parent_determine_rate), - {} -}; - /* * Test suite for a clock whose parent is a mux with multiple parents. * The leaf clock has CLK_SET_RATE_PARENT, and will forward rate
Hi Stephen, On Wed, Aug 09, 2023 at 06:37:30PM -0700, Stephen Boyd wrote: > Quoting Stephen Boyd (2023-08-09 16:21:50) > > +kunit-dev > > > > Quoting Maxime Ripard (2023-07-21 00:09:31) > > > Hi, > > > > > > Here's a small series to address the lockdep warning we have when > > > running the clk kunit tests with lockdep enabled. > > > > > > For the record, it can be tested with: > > > > > > $ ./tools/testing/kunit/kunit.py run \ > > > --kunitconfig=drivers/clk \ > > > --cross_compile aarch64-linux-gnu- --arch arm64 \ > > > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > > > --kconfig_add CONFIG_PROVE_LOCKING=y > > > > > > Let me know what you think, > > > > Thanks for doing this. I want to roll these helpers into the clk_kunit.c > > file that I had created for some other clk tests[1]. That's mostly > > because clk.c is already super long and adding kunit code there makes > > that problem worse. I'll try to take that patch out of the rest of the > > series and then add this series on top and resend. > > > > I don't know what to do about the case where CONFIG_KUNIT=m though. We > > have to export clk_prepare_lock/unlock()? I really don't want to do that > > even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there > > was a GPL version of that, so proprietary modules can't get at kernel > > internals on kunit enabled kernels. > > > > But I also like the approach taken here of adding a small stub around > > the call to make sure a test is running. Maybe I'll make a kunit > > namespaced exported gpl symbol that bails if a test isn't running and > > calls the clk_prepare_lock/unlock functions inside clk.c and then move > > the rest of the code to clk_kunit.c to get something more strict. > > > > What if we don't try to do any wrapper or export symbols and test > __clk_determine_rate() how it is called from the clk framework? The > downside is the code is not as simple because we have to check things > from within the clk_ops::determine_rate(), but the upside is that we can > avoid exporting internal clk APIs or wrap them so certain preconditions > are met like requiring them to be called from within a clk_op. The main reason for that test was linked to commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent"). Prior to it, if a clock had CLK_SET_RATE_PARENT, we could end up with its parent's parent hw struct and rate in best_parent_*. So that test was mostly about making sure that __clk_determine_rate will properly set the best_parent fields to match the clock's parent. If we do a proper clock that uses __clk_determine_rate, we lose the ability to check the content of the clk_rate_request returned by __clk_determine_rate. It's up to you to tell whether it's a bad thing or not :) > I also find it very odd to call clk_mux_determine_rate_closest() from a > clk that has one parent. Yeah, the behaviour difference between determine_rate and determine_rate_closest is weird to me too. We discussed it recently here: https://lore.kernel.org/linux-clk/mlgxmfim3poke2j45vwh2htkn66hrrjd6ozjebtqhbf4wwljwo@hzi4dyplhdqg/ > Maybe the clk op should call clk_hw_forward_rate_request() followed by > __clk_determine_rate() on the parent so we can test what the test > comment says it wants to test. I guess that would work too :) Maxime
Quoting Maxime Ripard (2023-08-21 04:16:12) > Hi Stephen, > > On Wed, Aug 09, 2023 at 06:37:30PM -0700, Stephen Boyd wrote: > > Quoting Stephen Boyd (2023-08-09 16:21:50) > > > +kunit-dev > > > > > > Quoting Maxime Ripard (2023-07-21 00:09:31) > > > > Hi, > > > > > > > > Here's a small series to address the lockdep warning we have when > > > > running the clk kunit tests with lockdep enabled. > > > > > > > > For the record, it can be tested with: > > > > > > > > $ ./tools/testing/kunit/kunit.py run \ > > > > --kunitconfig=drivers/clk \ > > > > --cross_compile aarch64-linux-gnu- --arch arm64 \ > > > > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > > > > --kconfig_add CONFIG_PROVE_LOCKING=y > > > > > > > > Let me know what you think, > > > > > > Thanks for doing this. I want to roll these helpers into the clk_kunit.c > > > file that I had created for some other clk tests[1]. That's mostly > > > because clk.c is already super long and adding kunit code there makes > > > that problem worse. I'll try to take that patch out of the rest of the > > > series and then add this series on top and resend. > > > > > > I don't know what to do about the case where CONFIG_KUNIT=m though. We > > > have to export clk_prepare_lock/unlock()? I really don't want to do that > > > even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there > > > was a GPL version of that, so proprietary modules can't get at kernel > > > internals on kunit enabled kernels. > > > > > > But I also like the approach taken here of adding a small stub around > > > the call to make sure a test is running. Maybe I'll make a kunit > > > namespaced exported gpl symbol that bails if a test isn't running and > > > calls the clk_prepare_lock/unlock functions inside clk.c and then move > > > the rest of the code to clk_kunit.c to get something more strict. > > > > > > > What if we don't try to do any wrapper or export symbols and test > > __clk_determine_rate() how it is called from the clk framework? The > > downside is the code is not as simple because we have to check things > > from within the clk_ops::determine_rate(), but the upside is that we can > > avoid exporting internal clk APIs or wrap them so certain preconditions > > are met like requiring them to be called from within a clk_op. > > The main reason for that test was linked to commit 262ca38f4b6e ("clk: > Stop forwarding clk_rate_requests to the parent"). Prior to it, if a > clock had CLK_SET_RATE_PARENT, we could end up with its parent's parent > hw struct and rate in best_parent_*. > > So that test was mostly about making sure that __clk_determine_rate will > properly set the best_parent fields to match the clock's parent. > > If we do a proper clock that uses __clk_determine_rate, we lose the > ability to check the content of the clk_rate_request returned by > __clk_determine_rate. It's up to you to tell whether it's a bad thing or > not :) I'm a little confused here. Was the test trying to check the changed lines in clk_core_round_rate_nolock() that were made in commit 262ca38f4b6e under the CLK_SET_RATE_PARENT condition? From what I can tell that doesn't get tested here. Instead, the test calls __clk_determine_rate() that calls clk_core_round_rate_nolock() which falls into the clk_core_can_round() condition because the hw has clk_dummy_single_parent_ops which has .determine_rate op set to __clk_mux_determine_rate_closest(). Once we find that the clk can round, we call __clk_mux_determine_rate_closest(). This patch still calls __clk_mux_determine_rate_closest() like __clk_determine_rate() was doing in the test, and checks that the request structure has the expected parent in the req->best_parent_hw. If we wanted to test the changed lines in clk_core_round_rate_nolock() we should have called __clk_determine_rate() on a clk_hw that didn't have a .determine_rate or .round_rate clk_op. Then it would have fallen into the if (core->flags & CLK_SET_RATE_PARENT) condition in clk_core_round_rate_nolock() and made sure that the request structure returned was properly forwarded to the parent. We can still do that by making a child of the leaf, set clk_ops on that to be this new determine_rate clk op that calls to the parent (the leaf today), and make that leaf clk not have any determine_rate clk_op. Then we will fall into the CLK_SET_RATE_PARENT condition and can make sure the request structure returned points at the parent instead of the mux. > > > I also find it very odd to call clk_mux_determine_rate_closest() from a > > clk that has one parent. > > Yeah, the behaviour difference between determine_rate and > determine_rate_closest is weird to me too. We discussed it recently here: > https://lore.kernel.org/linux-clk/mlgxmfim3poke2j45vwh2htkn66hrrjd6ozjebtqhbf4wwljwo@hzi4dyplhdqg/ Sure, but I'm saying that the clk has one parent, not more than one, so by definition it isn't a mux. It can only choose one parent. It's odd that "mux" is in the name. > > > Maybe the clk op should call clk_hw_forward_rate_request() followed by > > __clk_determine_rate() on the parent so we can test what the test > > comment says it wants to test. > > I guess that would work too :) > Ok, but I think it doesn't test what was intended to be tested?
Hi Stephen, On Wed, Aug 23, 2023 at 12:50:46PM -0700, Stephen Boyd wrote: > Quoting Maxime Ripard (2023-08-21 04:16:12) > > Hi Stephen, > > > > On Wed, Aug 09, 2023 at 06:37:30PM -0700, Stephen Boyd wrote: > > > Quoting Stephen Boyd (2023-08-09 16:21:50) > > > > +kunit-dev > > > > > > > > Quoting Maxime Ripard (2023-07-21 00:09:31) > > > > > Hi, > > > > > > > > > > Here's a small series to address the lockdep warning we have when > > > > > running the clk kunit tests with lockdep enabled. > > > > > > > > > > For the record, it can be tested with: > > > > > > > > > > $ ./tools/testing/kunit/kunit.py run \ > > > > > --kunitconfig=drivers/clk \ > > > > > --cross_compile aarch64-linux-gnu- --arch arm64 \ > > > > > --kconfig_add CONFIG_DEBUG_KERNEL=y \ > > > > > --kconfig_add CONFIG_PROVE_LOCKING=y > > > > > > > > > > Let me know what you think, > > > > > > > > Thanks for doing this. I want to roll these helpers into the clk_kunit.c > > > > file that I had created for some other clk tests[1]. That's mostly > > > > because clk.c is already super long and adding kunit code there makes > > > > that problem worse. I'll try to take that patch out of the rest of the > > > > series and then add this series on top and resend. > > > > > > > > I don't know what to do about the case where CONFIG_KUNIT=m though. We > > > > have to export clk_prepare_lock/unlock()? I really don't want to do that > > > > even if kunit is enabled (see EXPORT_SYMBOL_IF_KUNIT). Maybe if there > > > > was a GPL version of that, so proprietary modules can't get at kernel > > > > internals on kunit enabled kernels. > > > > > > > > But I also like the approach taken here of adding a small stub around > > > > the call to make sure a test is running. Maybe I'll make a kunit > > > > namespaced exported gpl symbol that bails if a test isn't running and > > > > calls the clk_prepare_lock/unlock functions inside clk.c and then move > > > > the rest of the code to clk_kunit.c to get something more strict. > > > > > > > > > > What if we don't try to do any wrapper or export symbols and test > > > __clk_determine_rate() how it is called from the clk framework? The > > > downside is the code is not as simple because we have to check things > > > from within the clk_ops::determine_rate(), but the upside is that we can > > > avoid exporting internal clk APIs or wrap them so certain preconditions > > > are met like requiring them to be called from within a clk_op. > > > > The main reason for that test was linked to commit 262ca38f4b6e ("clk: > > Stop forwarding clk_rate_requests to the parent"). Prior to it, if a > > clock had CLK_SET_RATE_PARENT, we could end up with its parent's parent > > hw struct and rate in best_parent_*. > > > > So that test was mostly about making sure that __clk_determine_rate will > > properly set the best_parent fields to match the clock's parent. > > > > If we do a proper clock that uses __clk_determine_rate, we lose the > > ability to check the content of the clk_rate_request returned by > > __clk_determine_rate. It's up to you to tell whether it's a bad thing or > > not :) > > I'm a little confused here. Was the test trying to check the changed > lines in clk_core_round_rate_nolock() that were made in commit > 262ca38f4b6e under the CLK_SET_RATE_PARENT condition? That's what I was trying to test, yeah. Not necessarily this function in particular (there's several affected), but at least we would get something sane in a common case. > From what I can tell that doesn't get tested here. > > Instead, the test calls __clk_determine_rate() that calls > clk_core_round_rate_nolock() which falls into the clk_core_can_round() > condition because the hw has clk_dummy_single_parent_ops which has > .determine_rate op set to __clk_mux_determine_rate_closest(). Once we > find that the clk can round, we call __clk_mux_determine_rate_closest(). clk_mux_determine_rate_flags was also affected by the same issue. > This patch still calls __clk_mux_determine_rate_closest() like > __clk_determine_rate() was doing in the test, and checks that the > request structure has the expected parent in the req->best_parent_hw. > > If we wanted to test the changed lines in clk_core_round_rate_nolock() > we should have called __clk_determine_rate() on a clk_hw that didn't > have a .determine_rate or .round_rate clk_op. Then it would have fallen > into the if (core->flags & CLK_SET_RATE_PARENT) condition in > clk_core_round_rate_nolock() and made sure that the request structure > returned was properly forwarded to the parent. > > We can still do that by making a child of the leaf, set clk_ops on that > to be this new determine_rate clk op that calls to the parent (the leaf > today), and make that leaf clk not have any determine_rate clk_op. Then > we will fall into the CLK_SET_RATE_PARENT condition and can make sure > the request structure returned points at the parent instead of the mux. But you're right clk_core_round_rate_nolock() wasn't properly tested. I guess, if we find it worth it, we should add a test for that one too? clk_mux_determine_rate_flags with multiple parents and CLK_SET_RATE_PARENT was also affected and fixed in the commit mentioned above. Maxime