From nobody Mon Apr 27 00:40:35 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81487C43334 for ; Mon, 20 Jun 2022 10:43:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236034AbiFTKnM (ORCPT ); Mon, 20 Jun 2022 06:43:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232170AbiFTKnK (ORCPT ); Mon, 20 Jun 2022 06:43:10 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0232411479; Mon, 20 Jun 2022 03:43:08 -0700 (PDT) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id DE50D1C000B; Mon, 20 Jun 2022 10:43:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1655721787; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IXHVUeNmneDajw+ibD51KpGlnvzBH9kCBPP2HDS3q8I=; b=kypU7yXQ/FHnAbnNy+uO0irNGl56e/VaBhr5vCfPYqeQgWB87sR9f4AzcGFNYJzwdeqKDj ni1+AxV6u6bhZpMqIvrlCITEXOircgyRFMQfEH/n8z5batTGeXPKfctmkyTSuxVd8JdOUU XvgF3MCbeEmvfcKO8vlUiEipFZxN6NOIX70T6w2Jh+nTE5FGLdMs/BqmtvAC9Pt5RAH871 /IDH2CJbe65iniX9xUscqS5fSk8ZGxhpEWflf0hKierDj5fUYL2aMdyY4SvEg+yzrstnA9 hxglqyxDbLdn9xgbGks+B629Z9y05eQEujsByK6V89/b3fjYcpOE5lsXaCu+8Q== From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Rob Herring , Frank Rowand , Nathan Lynch , Laurent Dufour , Daniel Henrique Barboza , David Gibson , Andrew Morton , David Hildenbrand , Ohhoon Kwon , "Aneesh Kumar K.V" , YueHaibing Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Bjorn Helgaas , Lizhi Hou Subject: [PATCH v3 1/5] of: constify of_property_check_flags() prop argument Date: Mon, 20 Jun 2022 12:41:19 +0200 Message-Id: <20220620104123.341054-2-clement.leger@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620104123.341054-1-clement.leger@bootlin.com> References: <20220620104123.341054-1-clement.leger@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This argument is not modified and thus can be set as const. Signed-off-by: Cl=C3=A9ment L=C3=A9ger --- include/linux/of.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/of.h b/include/linux/of.h index f0a5d6b10c5a..d74fd82a6963 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -207,7 +207,7 @@ static inline void of_node_clear_flag(struct device_nod= e *n, unsigned long flag) } =20 #if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) -static inline int of_property_check_flag(struct property *p, unsigned long= flag) +static inline int of_property_check_flag(const struct property *p, unsigne= d long flag) { return test_bit(flag, &p->_flags); } @@ -814,7 +814,8 @@ static inline void of_node_clear_flag(struct device_nod= e *n, unsigned long flag) { } =20 -static inline int of_property_check_flag(struct property *p, unsigned long= flag) +static inline int of_property_check_flag(const struct property *p, + unsigned long flag) { return 0; } --=20 2.36.1 From nobody Mon Apr 27 00:40:35 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 100E0C43334 for ; Mon, 20 Jun 2022 10:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240635AbiFTKnS (ORCPT ); Mon, 20 Jun 2022 06:43:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240227AbiFTKnM (ORCPT ); Mon, 20 Jun 2022 06:43:12 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 466A211A03; Mon, 20 Jun 2022 03:43:11 -0700 (PDT) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id AD1C81C0007; Mon, 20 Jun 2022 10:43:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1655721789; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FGXx2eom88ptY7cKPPIRDH5FnUnjq3Iv+rK4OEn7VS8=; b=AwN5z3ljiLEMgOCUchkgjgr3BaMWw2b5mz0LuHV4E6/8WHAIjFGBQl7TYT01W1v51zWz6Z S6Hh9/dcgD0+EbeIv5Os2L1RFRDhUmpK1RaPgyZ9Pg1ghtY51/vFFnQSf7FRcBOfANUT0y ElHvx3nz/NZXf41rsqNrV6Z3duy5cDknxbx9/98NfUuhp0yp6zkM9EzOJX/7Kzzqih6gFi lCqm5uG7LamU6SH6ZuysXmA5OmXTqW0etkxSCyP4dn7YDVcMbutrRfqTdZ6Dl0Npz5QbOK AuNeN21igSSpjLnKIcCewMOpBIIlR9WULSEW8Rj9vjMS/e0wMoGBsvzEBJPEBQ== From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Rob Herring , Frank Rowand , Nathan Lynch , Laurent Dufour , Daniel Henrique Barboza , David Gibson , Andrew Morton , David Hildenbrand , Ohhoon Kwon , "Aneesh Kumar K.V" , YueHaibing Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Bjorn Helgaas , Lizhi Hou Subject: [PATCH v3 2/5] of: remove __of_node_dup() allocflags parameter Date: Mon, 20 Jun 2022 12:41:20 +0200 Message-Id: <20220620104123.341054-3-clement.leger@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620104123.341054-1-clement.leger@bootlin.com> References: <20220620104123.341054-1-clement.leger@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The alloclags are always set to GFP_KERNEL so remove this specific flag. Moreover, this function is going to be based on one that does not provides passing gfp flags, so be prepared for this. Signed-off-by: Cl=C3=A9ment L=C3=A9ger --- drivers/of/dynamic.c | 9 ++++----- drivers/of/of_private.h | 2 +- drivers/of/overlay.c | 2 +- drivers/of/unittest.c | 16 ++++++++-------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index cd3821a6444f..5560e501aedf 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -369,7 +369,6 @@ void of_node_release(struct kobject *kobj) /** * __of_prop_dup - Copy a property dynamically. * @prop: Property to copy - * @allocflags: Allocation flags (typically pass GFP_KERNEL) * * Copy a property by dynamically allocating the memory of both the * property structure and the property name & contents. The property's @@ -378,11 +377,11 @@ void of_node_release(struct kobject *kobj) * * Return: The newly allocated property or NULL on out of memory error. */ -struct property *__of_prop_dup(const struct property *prop, gfp_t allocfla= gs) +struct property *__of_prop_dup(const struct property *prop) { struct property *new; =20 - new =3D kzalloc(sizeof(*new), allocflags); + new =3D kzalloc(sizeof(*new), GFP_KERNEL); if (!new) return NULL; =20 @@ -392,8 +391,8 @@ struct property *__of_prop_dup(const struct property *p= rop, gfp_t allocflags) * of zero bytes. We do this to work around the use * of of_get_property() calls on boolean values. */ - new->name =3D kstrdup(prop->name, allocflags); - new->value =3D kmemdup(prop->value, prop->length, allocflags); + new->name =3D kstrdup(prop->name, GFP_KERNEL); + new->value =3D kmemdup(prop->value, prop->length, GFP_KERNEL); new->length =3D prop->length; if (!new->name || !new->value) goto err_free; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 9324483397f6..e319d8c2bf8b 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -115,7 +115,7 @@ extern void *__unflatten_device_tree(const void *blob, * without taking node references, so you either have to * own the devtree lock or work on detached trees only. */ -struct property *__of_prop_dup(const struct property *prop, gfp_t allocfla= gs); +struct property *__of_prop_dup(const struct property *prop); struct device_node *__of_node_dup(const struct device_node *np, const char *full_name); =20 diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 4044ddcb02c6..9c026bcbf6ab 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -339,7 +339,7 @@ static int add_changeset_property(struct overlay_change= set *ovcs, return -EINVAL; new_prop =3D dup_and_fixup_symbol_prop(ovcs, overlay_prop); } else { - new_prop =3D __of_prop_dup(overlay_prop, GFP_KERNEL); + new_prop =3D __of_prop_dup(overlay_prop); } =20 if (!new_prop) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 7f6bba18c515..23ccb74ef408 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -772,13 +772,13 @@ static void __init of_unittest_property_copy(void) struct property p2 =3D { .name =3D "p2", .length =3D 5, .value =3D "abcd"= }; struct property *new; =20 - new =3D __of_prop_dup(&p1, GFP_KERNEL); + new =3D __of_prop_dup(&p1); unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\= n"); kfree(new->value); kfree(new->name); kfree(new); =20 - new =3D __of_prop_dup(&p2, GFP_KERNEL); + new =3D __of_prop_dup(&p2); unittest(new && propcmp(&p2, new), "non-empty property didn't copy correc= tly\n"); kfree(new->value); kfree(new->name); @@ -811,19 +811,19 @@ static void __init of_unittest_changeset(void) nremove =3D of_get_child_by_name(nchangeset, "node-remove"); unittest(nremove, "testcase setup failure\n"); =20 - ppadd =3D __of_prop_dup(&padd, GFP_KERNEL); + ppadd =3D __of_prop_dup(&padd); unittest(ppadd, "testcase setup failure\n"); =20 - ppname_n1 =3D __of_prop_dup(&pname_n1, GFP_KERNEL); + ppname_n1 =3D __of_prop_dup(&pname_n1); unittest(ppname_n1, "testcase setup failure\n"); =20 - ppname_n2 =3D __of_prop_dup(&pname_n2, GFP_KERNEL); + ppname_n2 =3D __of_prop_dup(&pname_n2); unittest(ppname_n2, "testcase setup failure\n"); =20 - ppname_n21 =3D __of_prop_dup(&pname_n21, GFP_KERNEL); + ppname_n21 =3D __of_prop_dup(&pname_n21); unittest(ppname_n21, "testcase setup failure\n"); =20 - ppupdate =3D __of_prop_dup(&pupdate, GFP_KERNEL); + ppupdate =3D __of_prop_dup(&pupdate); unittest(ppupdate, "testcase setup failure\n"); =20 parent =3D nchangeset; @@ -3333,7 +3333,7 @@ static __init void of_unittest_overlay_high_level(voi= d) struct property *new_prop; for_each_property_of_node(overlay_base_symbols, prop) { =20 - new_prop =3D __of_prop_dup(prop, GFP_KERNEL); + new_prop =3D __of_prop_dup(prop); if (!new_prop) { unittest(0, "__of_prop_dup() of '%s' from overlay_base node __symbols_= _", prop->name); --=20 2.36.1 From nobody Mon Apr 27 00:40:35 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAAE0CCA479 for ; Mon, 20 Jun 2022 10:45:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240347AbiFTKp1 (ORCPT ); Mon, 20 Jun 2022 06:45:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240434AbiFTKnR (ORCPT ); Mon, 20 Jun 2022 06:43:17 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 072171274B; Mon, 20 Jun 2022 03:43:14 -0700 (PDT) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0FCE41C0009; Mon, 20 Jun 2022 10:43:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1655721792; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=y46DjK7tHUV9HplhmvL+5ZwEnd6tbYT1BTLpxUBWe/E=; b=caO5tUcNyzZNxPjabh5bB9zSqN0oeHi4b7FeTmoLB4i0CIkdMvBWS2ch7vC2oLZIMCg7T9 JsCwS2d+M7xY+XcXVSmdGaXquwKzwj4ZscuzB4womNi08zO6ZbziOphcJRow03/Lne46Op dZsvgKGrOlF/Wup2WH6u6pQV/3PMcbM8yvHVx7OZQPC+L6SR8+dlFV3ecR2OBsFLOrVToS LjhkOHHChNl9wp8LtB5O/uBwTx3upDRjYCAnelnGlMdHXNTbrwmmdz9iEuTrvrdzxd2P/O LfLxD2q2AAcNq+CflnMfSO/VjMqq0q9WNRG1M4obK5NKln1y0tqn8RJV0YJjPg== From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Rob Herring , Frank Rowand , Nathan Lynch , Laurent Dufour , Daniel Henrique Barboza , David Gibson , Andrew Morton , David Hildenbrand , Ohhoon Kwon , "Aneesh Kumar K.V" , YueHaibing Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Bjorn Helgaas , Lizhi Hou Subject: [PATCH v3 3/5] of: dynamic: add of_property_alloc() and of_property_free() Date: Mon, 20 Jun 2022 12:41:21 +0200 Message-Id: <20220620104123.341054-4-clement.leger@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620104123.341054-1-clement.leger@bootlin.com> References: <20220620104123.341054-1-clement.leger@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add function which allows to dynamically allocate and free properties. Use this function internally for all code that used the same logic. Signed-off-by: Cl=C3=A9ment L=C3=A9ger --- drivers/of/dynamic.c | 83 ++++++++++++++++++++++++----------------- drivers/of/of_private.h | 19 +++++++++- drivers/of/unittest.c | 8 +--- include/linux/of.h | 14 +++++++ 4 files changed, 83 insertions(+), 41 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 5560e501aedf..9e29000571d1 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -313,9 +313,7 @@ static void property_list_free(struct property *prop_li= st) =20 for (prop =3D prop_list; prop !=3D NULL; prop =3D next) { next =3D prop->next; - kfree(prop->name); - kfree(prop->value); - kfree(prop); + of_property_free(prop); } } =20 @@ -367,47 +365,66 @@ void of_node_release(struct kobject *kobj) } =20 /** - * __of_prop_dup - Copy a property dynamically. - * @prop: Property to copy + * of_property_free - Free a property allocated dynamically. + * @prop: Property to be freed + */ +void of_property_free(const struct property *prop) +{ + if (!of_property_check_flag(prop, OF_DYNAMIC)) + return; + + if (prop->value !=3D prop + 1) + kfree(prop->value); + + kfree(prop->name); + kfree(prop); +} +EXPORT_SYMBOL(of_property_free); + +/** + * of_property_alloc - Allocate a property dynamically. + * @name: Name of the new property + * @value: Value that will be copied into the new property value or NULL + * if only @len allocation is needed. + * @len: Length of new property value and if @value is provided, the + * length of the value to be copied * - * Copy a property by dynamically allocating the memory of both the + * Create a property by dynamically allocating the memory of both the * property structure and the property name & contents. The property's * flags have the OF_DYNAMIC bit set so that we can differentiate between * dynamically allocated properties and not. * * Return: The newly allocated property or NULL on out of memory error. */ -struct property *__of_prop_dup(const struct property *prop) + +struct property *of_property_alloc(const char *name, const void *value, + size_t len) { - struct property *new; + struct property *prop; =20 - new =3D kzalloc(sizeof(*new), GFP_KERNEL); - if (!new) + prop =3D kzalloc(sizeof(*prop) + len, GFP_KERNEL); + if (!prop) return NULL; =20 - /* - * NOTE: There is no check for zero length value. - * In case of a boolean property, this will allocate a value - * of zero bytes. We do this to work around the use - * of of_get_property() calls on boolean values. - */ - new->name =3D kstrdup(prop->name, GFP_KERNEL); - new->value =3D kmemdup(prop->value, prop->length, GFP_KERNEL); - new->length =3D prop->length; - if (!new->name || !new->value) - goto err_free; - - /* mark the property as dynamic */ - of_property_set_flag(new, OF_DYNAMIC); - - return new; - - err_free: - kfree(new->name); - kfree(new->value); - kfree(new); + prop->name =3D kstrdup(name, GFP_KERNEL); + if (!prop->name) + goto out_err; + + prop->value =3D prop + 1; + if (value) + memcpy(prop->value, value, len); + + prop->length =3D len; + of_property_set_flag(prop, OF_DYNAMIC); + + return prop; + +out_err: + of_property_free(prop); + return NULL; } +EXPORT_SYMBOL(of_property_alloc); =20 /** * __of_node_dup() - Duplicate or create an empty device node dynamically. @@ -446,9 +463,7 @@ struct device_node *__of_node_dup(const struct device_n= ode *np, if (!new_pp) goto err_prop; if (__of_add_property(node, new_pp)) { - kfree(new_pp->name); - kfree(new_pp->value); - kfree(new_pp); + of_property_free(new_pp); goto err_prop; } } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index e319d8c2bf8b..7bed5a4a8033 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -115,7 +115,24 @@ extern void *__unflatten_device_tree(const void *blob, * without taking node references, so you either have to * own the devtree lock or work on detached trees only. */ -struct property *__of_prop_dup(const struct property *prop); + +/** + * __of_prop_dup - Copy a property dynamically. + * @prop: Property to copy + * + * Copy a property by dynamically allocating the memory of both the + * property structure and the property name & contents. The property's + * flags have the OF_DYNAMIC bit set so that we can differentiate between + * dynamically allocated properties and not. + * + * Return: The newly allocated property or NULL on out of memory error. + */ +static inline +struct property *__of_prop_dup(const struct property *prop) +{ + return of_property_alloc(prop->name, prop->value, prop->length); +} + struct device_node *__of_node_dup(const struct device_node *np, const char *full_name); =20 diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 23ccb74ef408..789ed9f46e3c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -774,15 +774,11 @@ static void __init of_unittest_property_copy(void) =20 new =3D __of_prop_dup(&p1); unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\= n"); - kfree(new->value); - kfree(new->name); - kfree(new); + of_property_free(new); =20 new =3D __of_prop_dup(&p2); unittest(new && propcmp(&p2, new), "non-empty property didn't copy correc= tly\n"); - kfree(new->value); - kfree(new->name); - kfree(new); + of_property_free(new); #endif } =20 diff --git a/include/linux/of.h b/include/linux/of.h index d74fd82a6963..157248a77c4e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1464,6 +1464,10 @@ enum of_reconfig_change { }; =20 #ifdef CONFIG_OF_DYNAMIC +struct property *of_property_alloc(const char *name, const void *value, + size_t len); +void of_property_free(const struct property *prop); + extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_unregister(struct notifier_block *); extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd); @@ -1508,6 +1512,16 @@ static inline int of_changeset_update_property(struc= t of_changeset *ocs, return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); } #else /* CONFIG_OF_DYNAMIC */ + +static inline +struct property *of_property_alloc(const char *name, const void *value, + size_t len) +{ + return NULL; +} + +static inline void of_property_free(const struct property *prop) {} + static inline int of_reconfig_notifier_register(struct notifier_block *nb) { return -EINVAL; --=20 2.36.1 From nobody Mon Apr 27 00:40:35 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ABA87C43334 for ; Mon, 20 Jun 2022 10:45:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240486AbiFTKpd (ORCPT ); Mon, 20 Jun 2022 06:45:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240585AbiFTKnR (ORCPT ); Mon, 20 Jun 2022 06:43:17 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A4B7140CF; Mon, 20 Jun 2022 03:43:16 -0700 (PDT) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 8427F1C0010; Mon, 20 Jun 2022 10:43:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1655721794; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H9tOu0s0cgWNLPz2A2AsQOeQKQd5LxCVeksf9pwFpyo=; b=EXVfircBCjCVVkqsImnuJ4jrDshXCda5okp1yDm5v/V73gyvYN2+W7gOtHwu+Y0didvLIy PKAA+jhJhbohotsbZlOUBlJWOQwD6CLPbw9sXcfpDRndFz+brZzYP42vz58Vcuv8zOEAYg J5t5l76C56uPYeL7rCV4mQJidVzxNJ/43YzoM4I288s11+rM/UhLYNtH0fdzHOgCaBe+vX MH28bfG16te9aBm5Igk6+17FXTReF5mBJVFH68hl4di9pZXMaFTqj2rCjRfMQzChcilZGv 7Aix+TSv6LCtdQ3m//0ZAqD/FnBmfOQPmLrwhhYAR5Oac95eUUJYoAcZ9FX/1g== From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Rob Herring , Frank Rowand , Nathan Lynch , Laurent Dufour , Daniel Henrique Barboza , David Gibson , Andrew Morton , David Hildenbrand , Ohhoon Kwon , "Aneesh Kumar K.V" , YueHaibing Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Bjorn Helgaas , Lizhi Hou Subject: [PATCH v3 4/5] of: dynamic: add of_node_alloc() Date: Mon, 20 Jun 2022 12:41:22 +0200 Message-Id: <20220620104123.341054-5-clement.leger@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620104123.341054-1-clement.leger@bootlin.com> References: <20220620104123.341054-1-clement.leger@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add of_node_alloc() which allows to create nodes. The node full_name field is allocated as part of the node allocation and the kfree() for this field is checked at release time to allow users using their own allocated name. Signed-off-by: Cl=C3=A9ment L=C3=A9ger --- drivers/of/dynamic.c | 53 ++++++++++++++++++++++++++++++++++---------- include/linux/of.h | 5 +++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 9e29000571d1..422dfaa5aaa5 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -359,7 +359,9 @@ void of_node_release(struct kobject *kobj) property_list_free(node->deadprops); fwnode_links_purge(of_fwnode_handle(node)); =20 - kfree(node->full_name); + if (node->full_name !=3D (const char *) (node + 1)) + kfree(node->full_name); + kfree(node->data); kfree(node); } @@ -426,6 +428,42 @@ struct property *of_property_alloc(const char *name, c= onst void *value, } EXPORT_SYMBOL(of_property_alloc); =20 +/** + * of_node_alloc - Allocate a node dynamically. + * @name: Node name + * + * Create a node by dynamically allocating the memory of both the + * node structure and the node name & contents. The node's + * flags have the OF_DYNAMIC & OF_DETACHED bit set so that we can + * differentiate between dynamically allocated nodes and not. + * + * Return: The newly allocated node or NULL on out of memory error. + */ +struct device_node *of_node_alloc(const char *name) +{ + struct device_node *node; + int name_len =3D 0; + + if (name) + name_len =3D strlen(name) + 1; + + node =3D kzalloc(sizeof(*node) + name_len, GFP_KERNEL); + if (!node) + return NULL; + + if (name) { + node->full_name =3D (const char *) (node + 1); + strcpy((char *)node->full_name, name); + } + + of_node_set_flag(node, OF_DYNAMIC); + of_node_set_flag(node, OF_DETACHED); + of_node_init(node); + + return node; +} +EXPORT_SYMBOL(of_node_alloc); + /** * __of_node_dup() - Duplicate or create an empty device node dynamically. * @np: if not NULL, contains properties to be duplicated in new node @@ -442,24 +480,15 @@ struct device_node *__of_node_dup(const struct device= _node *np, { struct device_node *node; =20 - node =3D kzalloc(sizeof(*node), GFP_KERNEL); + node =3D of_node_alloc(full_name); if (!node) return NULL; - node->full_name =3D kstrdup(full_name, GFP_KERNEL); - if (!node->full_name) { - kfree(node); - return NULL; - } - - of_node_set_flag(node, OF_DYNAMIC); - of_node_set_flag(node, OF_DETACHED); - of_node_init(node); =20 /* Iterate over and duplicate all properties */ if (np) { struct property *pp, *new_pp; for_each_property_of_node(np, pp) { - new_pp =3D __of_prop_dup(pp, GFP_KERNEL); + new_pp =3D __of_prop_dup(pp); if (!new_pp) goto err_prop; if (__of_add_property(node, new_pp)) { diff --git a/include/linux/of.h b/include/linux/of.h index 157248a77c4e..650b1ac0075b 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1464,6 +1464,7 @@ enum of_reconfig_change { }; =20 #ifdef CONFIG_OF_DYNAMIC +struct device_node *of_node_alloc(const char *name); struct property *of_property_alloc(const char *name, const void *value, size_t len); void of_property_free(const struct property *prop); @@ -1512,6 +1513,10 @@ static inline int of_changeset_update_property(struc= t of_changeset *ocs, return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); } #else /* CONFIG_OF_DYNAMIC */ +static inline struct device_node *of_node_alloc(const char *name) +{ + return NULL; +} =20 static inline struct property *of_property_alloc(const char *name, const void *value, --=20 2.36.1 From nobody Mon Apr 27 00:40:35 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3481AC433EF for ; Mon, 20 Jun 2022 10:45:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239522AbiFTKpj (ORCPT ); Mon, 20 Jun 2022 06:45:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240802AbiFTKnU (ORCPT ); Mon, 20 Jun 2022 06:43:20 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2B3912602; Mon, 20 Jun 2022 03:43:18 -0700 (PDT) Received: (Authenticated sender: clement.leger@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0C8521C0006; Mon, 20 Jun 2022 10:43:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1655721797; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mtZ5GDg2s0Ck6j3n2X7qx+X5XRvzpIog8T30WAkFqFQ=; b=pgm44wZIPhXpOx2BgqOCRfX5YWrcW/GqIGjYF8fMZJBwfDRzN83yCMMOh7PLjq4AljGns/ 1eGe+9lQcWA/NcjwIq3GWpabvhcSbxR826Gwz4iLFSC6Yq2MQogQOEW4YIVV5ngVgaM6PW o4N/ifPc3us5vlbNjqfmVb6PsfmXqubXbaNhz98Xs4r8btjF8Mmp/1AMjum2LqxaPkZhpp ykiiL7JIeXQI/3makQ7MxUy+MW7V0b8KDlikImZtwcS6dI+GCkOcQbXVGdnNCTI7sbXS9T IyXc49OkQGte4PVWsODhjnL9Kxn2udn3B6UQmccZi9KUiIs3r7vjtgs2KRmv+g== From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Rob Herring , Frank Rowand , Nathan Lynch , Laurent Dufour , Daniel Henrique Barboza , David Gibson , Andrew Morton , David Hildenbrand , Ohhoon Kwon , "Aneesh Kumar K.V" , YueHaibing Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Bjorn Helgaas , Lizhi Hou Subject: [PATCH v3 5/5] powerpc/pseries: use of_property_alloc/free() and of_node_alloc() Date: Mon, 20 Jun 2022 12:41:23 +0200 Message-Id: <20220620104123.341054-6-clement.leger@bootlin.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620104123.341054-1-clement.leger@bootlin.com> References: <20220620104123.341054-1-clement.leger@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use of_property_alloc/free() and of_node_alloc() to create and free device-tree nodes and properties. In order to obtain something cleaner and allow using only of_node_put() instead of manual property deletion, a rework of the usage of node in reconfig.c has been done. Signed-off-by: Cl=C3=A9ment L=C3=A9ger --- arch/powerpc/platforms/pseries/dlpar.c | 62 +-------- .../platforms/pseries/hotplug-memory.c | 21 +-- arch/powerpc/platforms/pseries/reconfig.c | 123 ++++++------------ 3 files changed, 50 insertions(+), 156 deletions(-) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platform= s/pseries/dlpar.c index 498d6efcb5ae..c17e7b6f1dd2 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -38,75 +38,25 @@ struct cc_workarea { __be32 prop_offset; }; =20 -void dlpar_free_cc_property(struct property *prop) -{ - kfree(prop->name); - kfree(prop->value); - kfree(prop); -} - static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa) { - struct property *prop; - char *name; - char *value; - - prop =3D kzalloc(sizeof(*prop), GFP_KERNEL); - if (!prop) - return NULL; + int length; + char *name, *value; =20 name =3D (char *)ccwa + be32_to_cpu(ccwa->name_offset); - prop->name =3D kstrdup(name, GFP_KERNEL); - if (!prop->name) { - dlpar_free_cc_property(prop); - return NULL; - } - - prop->length =3D be32_to_cpu(ccwa->prop_length); + length =3D be32_to_cpu(ccwa->prop_length); value =3D (char *)ccwa + be32_to_cpu(ccwa->prop_offset); - prop->value =3D kmemdup(value, prop->length, GFP_KERNEL); - if (!prop->value) { - dlpar_free_cc_property(prop); - return NULL; - } =20 - return prop; + return of_property_alloc(name, value, length); } =20 static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) { - struct device_node *dn; const char *name; =20 - dn =3D kzalloc(sizeof(*dn), GFP_KERNEL); - if (!dn) - return NULL; - name =3D (const char *)ccwa + be32_to_cpu(ccwa->name_offset); - dn->full_name =3D kstrdup(name, GFP_KERNEL); - if (!dn->full_name) { - kfree(dn); - return NULL; - } =20 - of_node_set_flag(dn, OF_DYNAMIC); - of_node_init(dn); - - return dn; -} - -static void dlpar_free_one_cc_node(struct device_node *dn) -{ - struct property *prop; - - while (dn->properties) { - prop =3D dn->properties; - dn->properties =3D prop->next; - dlpar_free_cc_property(prop); - } - - kfree(dn->full_name); - kfree(dn); + return of_node_alloc(name); } =20 void dlpar_free_cc_nodes(struct device_node *dn) @@ -117,7 +67,7 @@ void dlpar_free_cc_nodes(struct device_node *dn) if (dn->sibling) dlpar_free_cc_nodes(dn->sibling); =20 - dlpar_free_one_cc_node(dn); + of_node_put(dn); } =20 #define COMPLETE 0 diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc= /platforms/pseries/hotplug-memory.c index 2e3a317722a8..e583814414a1 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -69,33 +69,16 @@ unsigned long pseries_memory_block_size(void) return memblock_size; } =20 -static void dlpar_free_property(struct property *prop) -{ - kfree(prop->name); - kfree(prop->value); - kfree(prop); -} - static struct property *dlpar_clone_property(struct property *prop, u32 prop_size) { - struct property *new_prop; - - new_prop =3D kzalloc(sizeof(*new_prop), GFP_KERNEL); + struct property *new_prop =3D of_property_alloc(prop->name, NULL, + prop_size); if (!new_prop) return NULL; =20 - new_prop->name =3D kstrdup(prop->name, GFP_KERNEL); - new_prop->value =3D kzalloc(prop_size, GFP_KERNEL); - if (!new_prop->name || !new_prop->value) { - dlpar_free_property(new_prop); - return NULL; - } - memcpy(new_prop->value, prop->value, prop->length); - new_prop->length =3D prop_size; =20 - of_property_set_flag(new_prop, OF_DYNAMIC); return new_prop; } =20 diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platf= orms/pseries/reconfig.c index cad7a0c93117..8704c541de3c 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -19,46 +19,29 @@ =20 #include "of_helpers.h" =20 -static int pSeries_reconfig_add_node(const char *path, struct property *pr= oplist) +static struct device_node *pSeries_reconfig_add_node(const char *path) { - struct device_node *np; - int err =3D -ENOMEM; - - np =3D kzalloc(sizeof(*np), GFP_KERNEL); - if (!np) - goto out_err; - - np->full_name =3D kstrdup(kbasename(path), GFP_KERNEL); - if (!np->full_name) - goto out_err; - - np->properties =3D proplist; - of_node_set_flag(np, OF_DYNAMIC); - of_node_init(np); + struct device_node *np, *parent; =20 - np->parent =3D pseries_of_derive_parent(path); - if (IS_ERR(np->parent)) { - err =3D PTR_ERR(np->parent); - goto out_err; + np =3D of_find_node_by_path(path) + if (np) { + of_node_put(np); + return ERR_PTR(-EINVAL); } =20 - err =3D of_attach_node(np); - if (err) { - printk(KERN_ERR "Failed to add device node %s\n", path); - goto out_err; - } + parent =3D pseries_of_derive_parent(path); + if (IS_ERR(parent)) + return parent; =20 - of_node_put(np->parent); + np =3D of_node_alloc(kbasename(path)); + if (!np) { + of_node_put(parent); + return ERR_PTR(-ENOMEM); + } =20 - return 0; + np->parent =3D parent; =20 -out_err: - if (np) { - of_node_put(np->parent); - kfree(np->full_name); - kfree(np); - } - return err; + return np; } =20 static int pSeries_reconfig_remove_node(struct device_node *np) @@ -80,24 +63,6 @@ static int pSeries_reconfig_remove_node(struct device_no= de *np) return 0; } =20 -/* - * /proc/powerpc/ofdt - yucky binary interface for adding and removing - * OF device nodes. Should be deprecated as soon as we get an - * in-kernel wrapper for the RTAS ibm,configure-connector call. - */ - -static void release_prop_list(const struct property *prop) -{ - struct property *next; - for (; prop; prop =3D next) { - next =3D prop->next; - kfree(prop->name); - kfree(prop->value); - kfree(prop); - } - -} - /** * parse_next_property - process the next property from raw input buffer * @buf: input buffer, must be nul-terminated @@ -148,7 +113,7 @@ static char * parse_next_property(char *buf, char *end,= char **name, int *length /* now we're on the value */ *value =3D tmp; tmp +=3D *length; - if (tmp > end) { + if (tmp >=3D end) { printk(KERN_ERR "property parse failed in %s at line %d\n", __func__, __LINE__); return NULL; @@ -158,6 +123,7 @@ static char * parse_next_property(char *buf, char *end,= char **name, int *length __func__, __LINE__); return NULL; } + *tmp =3D '\0'; tmp++; =20 /* and now we should be on the next name, or the end */ @@ -167,27 +133,15 @@ static char * parse_next_property(char *buf, char *en= d, char **name, int *length static struct property *new_property(const char *name, const int length, const unsigned char *value, struct property *last) { - struct property *new =3D kzalloc(sizeof(*new), GFP_KERNEL); + struct property *prop; =20 - if (!new) + prop =3D of_property_alloc(name, value, length); + if (!prop) return NULL; =20 - if (!(new->name =3D kstrdup(name, GFP_KERNEL))) - goto cleanup; - if (!(new->value =3D kmalloc(length + 1, GFP_KERNEL))) - goto cleanup; - - memcpy(new->value, value, length); - *(((char *)new->value) + length) =3D 0; - new->length =3D length; - new->next =3D last; - return new; - -cleanup: - kfree(new->name); - kfree(new->value); - kfree(new); - return NULL; + prop->next =3D last; + + return prop; } =20 static int do_add_node(char *buf, size_t bufsize) @@ -203,13 +157,13 @@ static int do_add_node(char *buf, size_t bufsize) buf =3D strchr(buf, ' '); if (!buf) return -EINVAL; + *buf =3D '\0'; buf++; =20 - if ((np =3D of_find_node_by_path(path))) { - of_node_put(np); - return -EINVAL; - } + np =3D pSeries_reconfig_add_node(path); + if (IS_ERR(np)) + return PTR_ERR(np); =20 /* rv =3D build_prop_list(tmp, bufsize - (tmp - buf), &proplist); */ while (buf < end && @@ -217,22 +171,29 @@ static int do_add_node(char *buf, size_t bufsize) struct property *last =3D prop; =20 prop =3D new_property(name, length, value, last); - if (!prop) { - rv =3D -ENOMEM; - prop =3D last; + if (!prop) goto out; - } + + np->properties =3D prop; } if (!buf) { rv =3D -EINVAL; goto out; } =20 - rv =3D pSeries_reconfig_add_node(path, prop); + rv =3D of_attach_node(np); + if (rv) { + pr_err("Failed to attach node %pOF\n", np); + goto out; + } =20 + of_node_put(np->parent); + + return 0; out: - if (rv) - release_prop_list(prop); + of_node_put(np->parent); + of_node_put(np); + return rv; } =20 --=20 2.36.1