[RFC,2/5] of: Introduce for_each_child_of_node_scoped() to automate of_node_put() handling
Message ID | 20240128160542.178315-3-jic23@kernel.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp113419dyb; Sun, 28 Jan 2024 08:07:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IH9HlIHKLW0asrv1MzCQ8hTR2b8f6j52J4Q2nqoP+HAcnc2ubEuQ8fudf55Re/7ifR9Z3UA X-Received: by 2002:a17:902:788f:b0:1d7:8c9a:14b0 with SMTP id q15-20020a170902788f00b001d78c9a14b0mr3409302pll.42.1706458046428; Sun, 28 Jan 2024 08:07:26 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706458046; cv=pass; d=google.com; s=arc-20160816; b=wuiJxr6qx+LSrVRQnbQcPp+mrfY2++ZRjW/Ab5YXwCGj9CPH+qrmt91afPuCdj1Z0b hEHUJJbHwlU4zdDh97cEpe7CcXFlpdDJrWPNQZVuBPP9VppGUHxFfY/yJNNXMRsM6och f6eUMJ8HTkLoqg7dOK/CPcBKbPdfkRAEGyxYnt05E22VoAAwcfqJazLQ4sdcUDympFwh 2JIzo9qQgHapsWoixasAJeosMI1E73BvjaguIe8T57/bNurI1rTbTAWt893099rL84KN eBsib5yaRScrv0BjiRhEca1K9VmHwZpKPzE9jBHJ1qHAw85u9UlFZ6q55tu/kDfs+oFC coog== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=YqgNZ+skOW1X/1tb0MZDeUqm0xdW+CN0YoSfRFfhG5g=; fh=QZniyVMMS+qc7OJnE11H0+VIi5BgZHbLL5e39gUA1jg=; b=a1B7vpw43TNJ/zv7VTd2OOSkkZcWPUYVXVNOG+uwCUGz+iq6uG7C/k46IcKsVFEJtW my7FvnbyJ6eew682e2wLSrPO4EY/yH1iY5IrSwdjw0nbMxkh1ZAITbTKqjjv/sV86aM8 91BvoeWLtJyH/Wqv2bkPXITEktE9QC0yQ8y9qJ8P6jEbVPTlB8xrHGPnmPyc16tKW8D8 aLbPbcabvB0tN8VHZip+HNjkVZ3WybLjxGaz3DtwPn3c5uoYUQBHyf/64I0hMaytcq8F OTUu9MTVBjksV82bblSWXurA1eqee/qqYb2EYtopGhwv33Zp4Bm9ZIAzhh0xjUN3ywBa M9EQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qfMWcqXQ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id k91-20020a17090a3ee400b002904ae2ecf8si2171563pjc.158.2024.01.28.08.07.26 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 08:07:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qfMWcqXQ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-41678-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 0762CB22253 for <ouuuleilei@gmail.com>; Sun, 28 Jan 2024 16:07:01 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 668072E859; Sun, 28 Jan 2024 16:06:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qfMWcqXQ" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B37B32E644; Sun, 28 Jan 2024 16:06:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706457972; cv=none; b=mDe7Fm+MLDygoinMqoVydFBKYTa6dheuWwcmjK1vTmPM9UGgATITtsI1WXReLppsRNDloZALV+Eaep2NFBokCIeGWZZdkN19iTPOlRUGwCkLvHDqgxnJDzhSw18MxpUX4qdPKsYJq3NzFMUb+2AJ24qdjmsHcO1L2/pwzCQUkXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706457972; c=relaxed/simple; bh=1UnqaSq6US/sXw4AotStqr/RUKhvvYzhNHwicWeq4pM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M3N3Bz+2ouBQ++XLHf2K7A0Sx7SLmii5qKHjPOC19xRIGB4wHf47vTnzKkWU8ZrUrHQKKayRLGLYFsbCxd/fpxXINihazidr3/J10Ui+a6uFDyMBwO55O85Bl3N5C7ozb7SdcW3/aelpDDn1AKKUh/KLlXZ7m4L8+8yeeWf26i0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qfMWcqXQ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BA3CC43394; Sun, 28 Jan 2024 16:06:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706457972; bh=1UnqaSq6US/sXw4AotStqr/RUKhvvYzhNHwicWeq4pM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qfMWcqXQJuyNNX7HTwLclM8TLDtUP6uRfAE1TNMORFXG8gztAiXwty3tUBRAD6G2w 1UEZwjtVgOM+bZFNxdcukilsqEA6dzQ+Qq70YCR/Ze57qbGW10O/CkLpgbP65ElTaC dDwM85Z+swUBxO5/RquDc23ErRWPiFKm3njXeRm8YNbQcN4Foi7Bg275xOCzOE+/me MX3NURYzHj/GYCcWB5bRqzifBc80oe7k84cb5kX8pdLuXgaR+KdC8Yq9yX2WIY1QvA lzaJUBfoTwrHZKwVCAOVVELKTozQl8zKw2kV4rKZWvgZ9NS9zM1Cnda79ZcqPjLOLZ V3O5iVUHsBbBQ== From: Jonathan Cameron <jic23@kernel.org> To: linux-iio@vger.kernel.org, Rob Herring <robh@kernel.org>, Frank Rowand <frowand.list@gmail.com>, linux-kernel@vger.kernel.org Cc: Julia Lawall <Julia.Lawall@inria.fr>, Nicolas Palix <nicolas.palix@imag.fr>, Sumera Priyadarsini <sylphrenadin@gmail.com>, "Rafael J . Wysocki" <rafael@kernel.org>, Len Brown <lenb@kernel.org>, linux-acpi@vger.kernel.org, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, =?utf-8?q?Nuno_S=C3=A1?= <nuno.sa@analog.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com> Subject: [RFC PATCH 2/5] of: Introduce for_each_child_of_node_scoped() to automate of_node_put() handling Date: Sun, 28 Jan 2024 16:05:39 +0000 Message-ID: <20240128160542.178315-3-jic23@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240128160542.178315-1-jic23@kernel.org> References: <20240128160542.178315-1-jic23@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789350952342968545 X-GMAIL-MSGID: 1789350952342968545 |
Series |
of: automate of_node_put() - new approach to loops.
|
|
Commit Message
Jonathan Cameron
Jan. 28, 2024, 4:05 p.m. UTC
From: Jonathan Cameron <Jonathan.Cameron@huawei.com> To avoid issues with out of order cleanup, or ambiguity about when the auto freed data is first instantiated, do it within the for loop definition. The disadvantage is that the struct device_node *child variable creation is not immediately obvious where this is used. However, in many cases, if there is another definition of struct device_node *child; the compiler / static analysers will notify us that it is unused, or uninitialized. Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> --- include/linux/of.h | 6 ++++++ 1 file changed, 6 insertions(+)
Comments
On Sun, Jan 28, 2024 at 10:06 AM Jonathan Cameron <jic23@kernel.org> wrote: > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > To avoid issues with out of order cleanup, or ambiguity about when the > auto freed data is first instantiated, do it within the for loop definition. > > The disadvantage is that the struct device_node *child variable creation > is not immediately obvious where this is used. > However, in many cases, if there is another definition of > struct device_node *child; the compiler / static analysers will notify us > that it is unused, or uninitialized. > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > include/linux/of.h | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/include/linux/of.h b/include/linux/of.h > index 50e882ee91da..f822226eac6d 100644 > --- a/include/linux/of.h > +++ b/include/linux/of.h > @@ -1434,6 +1434,12 @@ static inline int of_property_read_s32(const struct device_node *np, > for (child = of_get_next_available_child(parent, NULL); child != NULL; \ > child = of_get_next_available_child(parent, child)) > > +#define for_each_child_of_node_scoped(parent, child) \ > + for (struct device_node *child __free(device_node) = \ > + of_get_next_child(parent, NULL); \ > + child != NULL; \ > + child = of_get_next_available_child(parent, child)) Doesn't this need to match the initializer (of_get_next_child)? Otherwise it seems like the first node could be a disabled node but no other disabled nodes would be included in the iteration. It seems like we would want two macros, one for each variation, analogous to for_each_child_of_node() and for_each_available_child_of_node(). > + > #define for_each_of_cpu_node(cpu) \ > for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \ > cpu = of_get_next_cpu_node(cpu)) > -- > 2.43.0 > >
On Sun, 28 Jan 2024, David Lechner wrote: > On Sun, Jan 28, 2024 at 10:06 AM Jonathan Cameron <jic23@kernel.org> wrote: > > > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > > > To avoid issues with out of order cleanup, or ambiguity about when the > > auto freed data is first instantiated, do it within the for loop definition. > > > > The disadvantage is that the struct device_node *child variable creation > > is not immediately obvious where this is used. > > However, in many cases, if there is another definition of > > struct device_node *child; the compiler / static analysers will notify us > > that it is unused, or uninitialized. > > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > --- > > include/linux/of.h | 6 ++++++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/include/linux/of.h b/include/linux/of.h > > index 50e882ee91da..f822226eac6d 100644 > > --- a/include/linux/of.h > > +++ b/include/linux/of.h > > @@ -1434,6 +1434,12 @@ static inline int of_property_read_s32(const struct device_node *np, > > for (child = of_get_next_available_child(parent, NULL); child != NULL; \ > > child = of_get_next_available_child(parent, child)) > > > > +#define for_each_child_of_node_scoped(parent, child) \ > > + for (struct device_node *child __free(device_node) = \ > > + of_get_next_child(parent, NULL); \ > > + child != NULL; \ > > + child = of_get_next_available_child(parent, child)) > > Doesn't this need to match the initializer (of_get_next_child)? > Otherwise it seems like the first node could be a disabled node but no > other disabled nodes would be included in the iteration. > > It seems like we would want two macros, one for each variation, > analogous to for_each_child_of_node() and > for_each_available_child_of_node(). There are a bunch of iterators, and I guess a scoped version is needed for each of them? julia > > > > + > > #define for_each_of_cpu_node(cpu) \ > > for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \ > > cpu = of_get_next_cpu_node(cpu)) > > -- > > 2.43.0 > > > > >
On Sun, Jan 28, 2024 at 03:11:01PM -0600, David Lechner wrote: > On Sun, Jan 28, 2024 at 10:06 AM Jonathan Cameron <jic23@kernel.org> wrote: > > > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > > > To avoid issues with out of order cleanup, or ambiguity about when the > > auto freed data is first instantiated, do it within the for loop definition. > > > > The disadvantage is that the struct device_node *child variable creation > > is not immediately obvious where this is used. > > However, in many cases, if there is another definition of > > struct device_node *child; the compiler / static analysers will notify us > > that it is unused, or uninitialized. > > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > --- > > include/linux/of.h | 6 ++++++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/include/linux/of.h b/include/linux/of.h > > index 50e882ee91da..f822226eac6d 100644 > > --- a/include/linux/of.h > > +++ b/include/linux/of.h > > @@ -1434,6 +1434,12 @@ static inline int of_property_read_s32(const struct device_node *np, > > for (child = of_get_next_available_child(parent, NULL); child != NULL; \ > > child = of_get_next_available_child(parent, child)) > > > > +#define for_each_child_of_node_scoped(parent, child) \ > > + for (struct device_node *child __free(device_node) = \ > > + of_get_next_child(parent, NULL); \ > > + child != NULL; \ > > + child = of_get_next_available_child(parent, child)) > > Doesn't this need to match the initializer (of_get_next_child)? > Otherwise it seems like the first node could be a disabled node but no > other disabled nodes would be included in the iteration. > > It seems like we would want two macros, one for each variation, > analogous to for_each_child_of_node() and > for_each_available_child_of_node(). Yes, but really I'd like these the other way around. 'available' should be the default as disabled should really be the same as a node not present except for a few cases where it is not. I bring it up only because if we're changing things then it is a convenient time to change this. That's really a side issue to sorting out how this new way should work. Rob
On Sun, 28 Jan 2024 15:11:01 -0600 David Lechner <dlechner@baylibre.com> wrote: > On Sun, Jan 28, 2024 at 10:06 AM Jonathan Cameron <jic23@kernel.org> wrote: > > > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > > > To avoid issues with out of order cleanup, or ambiguity about when the > > auto freed data is first instantiated, do it within the for loop definition. > > > > The disadvantage is that the struct device_node *child variable creation > > is not immediately obvious where this is used. > > However, in many cases, if there is another definition of > > struct device_node *child; the compiler / static analysers will notify us > > that it is unused, or uninitialized. > > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > --- > > include/linux/of.h | 6 ++++++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/include/linux/of.h b/include/linux/of.h > > index 50e882ee91da..f822226eac6d 100644 > > --- a/include/linux/of.h > > +++ b/include/linux/of.h > > @@ -1434,6 +1434,12 @@ static inline int of_property_read_s32(const struct device_node *np, > > for (child = of_get_next_available_child(parent, NULL); child != NULL; \ > > child = of_get_next_available_child(parent, child)) > > > > +#define for_each_child_of_node_scoped(parent, child) \ > > + for (struct device_node *child __free(device_node) = \ > > + of_get_next_child(parent, NULL); \ > > + child != NULL; \ > > + child = of_get_next_available_child(parent, child)) > > Doesn't this need to match the initializer (of_get_next_child)? > Otherwise it seems like the first node could be a disabled node but no > other disabled nodes would be included in the iteration. FwIW that was was entirely unintentional. Not sure how it happened :( Anyhow, now will be for_each_available_child_of_node_scoped() with the right first call. > > It seems like we would want two macros, one for each variation, > analogous to for_each_child_of_node() and > for_each_available_child_of_node(). > > > > + > > #define for_each_of_cpu_node(cpu) \ > > for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \ > > cpu = of_get_next_cpu_node(cpu)) > > -- > > 2.43.0 > > > >
diff --git a/include/linux/of.h b/include/linux/of.h index 50e882ee91da..f822226eac6d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1434,6 +1434,12 @@ static inline int of_property_read_s32(const struct device_node *np, for (child = of_get_next_available_child(parent, NULL); child != NULL; \ child = of_get_next_available_child(parent, child)) +#define for_each_child_of_node_scoped(parent, child) \ + for (struct device_node *child __free(device_node) = \ + of_get_next_child(parent, NULL); \ + child != NULL; \ + child = of_get_next_available_child(parent, child)) + #define for_each_of_cpu_node(cpu) \ for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \ cpu = of_get_next_cpu_node(cpu))