diff mbox series

[net-next,3/3] net: dsa: mv88e6xxx: leds: fix leds refcount

Message ID 20241008-mv88e6xxx_leds_fwnode_put-v1-3-cfd7758cd176@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net, device property: fix led node releases in mv88e6xxx with new macro | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 6 this patch: 6
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 6 this patch: 6
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 5 this patch: 5
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 16 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Javier Carrasco Oct. 8, 2024, 4:10 p.m. UTC
The 'leds' fwnode_handle is initialized by calling
fwnode_get_named_child_node(), which requires an explicit call to
fwnode_handle_put() when the node is not required anymore.

Instead of adding the missing call, and considering that this driver was
recently introduced, use the automatic clenaup mechanism to release the
node when it goes out of scope.

Fixes: 94a2a84f5e9e ("net: dsa: mv88e6xxx: Support LED control")
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
---
 drivers/net/dsa/mv88e6xxx/leds.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Andrew Lunn Oct. 8, 2024, 4:40 p.m. UTC | #1
> -	leds = fwnode_get_named_child_node(p->fwnode, "leds");
> +	struct fwnode_handle *leds __free(fwnode_handle) =
> +		fwnode_get_named_child_node(p->fwnode, "leds");

https://docs.kernel.org/process/maintainer-netdev.html#using-device-managed-and-cleanup-h-constructs

  Low level cleanup constructs (such as __free()) can be used when
  building APIs and helpers, especially scoped iterators. However,
  direct use of __free() within networking core and drivers is
  discouraged. Similar guidance applies to declaring variables
  mid-function.

    Andrew

---
pw-bot: cr
Javier Carrasco Oct. 8, 2024, 11:31 p.m. UTC | #2
On 08/10/2024 18:40, Andrew Lunn wrote:
>> -	leds = fwnode_get_named_child_node(p->fwnode, "leds");
>> +	struct fwnode_handle *leds __free(fwnode_handle) =
>> +		fwnode_get_named_child_node(p->fwnode, "leds");
> 
> https://docs.kernel.org/process/maintainer-netdev.html#using-device-managed-and-cleanup-h-constructs
> 
>   Low level cleanup constructs (such as __free()) can be used when
>   building APIs and helpers, especially scoped iterators. However,
>   direct use of __free() within networking core and drivers is
>   discouraged. Similar guidance applies to declaring variables
>   mid-function.
> 
>     Andrew
> 
> ---
> pw-bot: cr


Hi Andrew,

Thanks for your review. I have seen that the __free() macro is used in
multiple net drivers, especially (but not only) __free(kfree). Why would
this one would be discouraged?

I would have nothing against declaring the variable at the top and
initializing it to NULL if that is the preferred way in the networking
subsystem, but the __free() macro seems to be well established, and it
simplifies the code.

Otherwise 4 calls to fwnode_handle_put() or a couple of goto jumps will
be required to get the same result. Moreover, if any other error path is
introduced, the mechanism will automatically account for it.

Best regards,
Javier Carrasco
Andy Shevchenko Oct. 10, 2024, 2:33 p.m. UTC | #3
On Tue, Oct 08, 2024 at 06:10:29PM +0200, Javier Carrasco wrote:
> The 'leds' fwnode_handle is initialized by calling
> fwnode_get_named_child_node(), which requires an explicit call to
> fwnode_handle_put() when the node is not required anymore.
> 
> Instead of adding the missing call, and considering that this driver was
> recently introduced, use the automatic clenaup mechanism to release the
> node when it goes out of scope.

...

> -	leds = fwnode_get_named_child_node(p->fwnode, "leds");
> +	struct fwnode_handle *leds __free(fwnode_handle) =
> +		fwnode_get_named_child_node(p->fwnode, "leds");

Can it be const?
Javier Carrasco Oct. 10, 2024, 7:15 p.m. UTC | #4
On 10/10/2024 16:33, Andy Shevchenko wrote:
> On Tue, Oct 08, 2024 at 06:10:29PM +0200, Javier Carrasco wrote:
>> The 'leds' fwnode_handle is initialized by calling
>> fwnode_get_named_child_node(), which requires an explicit call to
>> fwnode_handle_put() when the node is not required anymore.
>>
>> Instead of adding the missing call, and considering that this driver was
>> recently introduced, use the automatic clenaup mechanism to release the
>> node when it goes out of scope.
> 
> ...
> 
>> -	leds = fwnode_get_named_child_node(p->fwnode, "leds");
>> +	struct fwnode_handle *leds __free(fwnode_handle) =
>> +		fwnode_get_named_child_node(p->fwnode, "leds");
> 
> Can it be const?
> 

Hi Andy,

in its current form, it could be const as its only assignment occurs in
its declaration. But if the final decision is moving it to the top and
giving it an initial NULL value, then that will not be possible for
obvious reasons.

I am fine with any of those options for v2.

Best regards,
Javier Carrasco
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
index 92a57552beda..b9959e1f3c9e 100644
--- a/drivers/net/dsa/mv88e6xxx/leds.c
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
@@ -744,7 +744,6 @@  mv88e6xxx_led1_hw_control_get_device(struct led_classdev *ldev)
 
 int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port)
 {
-	struct fwnode_handle *leds = NULL;
 	struct led_init_data init_data = { };
 	enum led_default_state state;
 	struct mv88e6xxx_port *p;
@@ -763,7 +762,8 @@  int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port)
 
 	dev = chip->dev;
 
-	leds = fwnode_get_named_child_node(p->fwnode, "leds");
+	struct fwnode_handle *leds __free(fwnode_handle) =
+		fwnode_get_named_child_node(p->fwnode, "leds");
 	if (!leds) {
 		dev_dbg(dev, "No Leds node specified in device tree for port %d!\n",
 			port);