Message ID | 889729ac-3fc5-4666-b9f5-ce6e588a341a@web.de (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: typec: anx7411: Use scope-based resource management in anx7411_typec_port_probe() | expand |
On Wed, Jun 05, 2024 at 07:11:04PM +0200, Markus Elfring wrote: > From: Markus Elfring <elfring@users.sourceforge.net> > Date: Wed, 5 Jun 2024 18:56:19 +0200 > > Scope-based resource management became supported also for another > programming interface by contributions of Jonathan Cameron on 2024-02-17. > See also the commit 59ed5e2d505bf5f9b4af64d0021cd0c96aec1f7c ("device > property: Add cleanup.h based fwnode_handle_put() scope based cleanup."). > > * Thus use the attribute “__free(fwnode_handle)”. > > * Reduce the scope for the local variable “fwnode”. > > Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support") > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Was the fwnode leaked, or why else is this a "fix"? It's not clear from the commit message. In any case: Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/usb/typec/anx7411.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c > index b12a07edc71b..9fb52f233a30 100644 > --- a/drivers/usb/typec/anx7411.c > +++ b/drivers/usb/typec/anx7411.c > @@ -16,6 +16,7 @@ > #include <linux/of_graph.h> > #include <linux/of_platform.h> > #include <linux/pm_runtime.h> > +#include <linux/property.h> > #include <linux/regulator/consumer.h> > #include <linux/slab.h> > #include <linux/types.h> > @@ -1142,11 +1143,11 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, > { > struct typec_capability *cap = &ctx->typec.caps; > struct typec_params *typecp = &ctx->typec; > - struct fwnode_handle *fwnode; > const char *buf; > int ret, i; > > - fwnode = device_get_named_child_node(dev, "connector"); > + struct fwnode_handle *fwnode __free(fwnode_handle) > + = device_get_named_child_node(dev, "connector"); > if (!fwnode) > return -EINVAL; > > @@ -1237,7 +1238,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, > typecp->caps_flags |= HAS_SINK_WATT; > } > > - cap->fwnode = fwnode; > + cap->fwnode = no_free_ptr(fwnode); > > ctx->typec.role_sw = usb_role_switch_get(dev); > if (IS_ERR(ctx->typec.role_sw)) { > -- > 2.45.1
>> Scope-based resource management became supported also for another >> programming interface by contributions of Jonathan Cameron on 2024-02-17. >> See also the commit 59ed5e2d505bf5f9b4af64d0021cd0c96aec1f7c ("device >> property: Add cleanup.h based fwnode_handle_put() scope based cleanup."). >> >> * Thus use the attribute “__free(fwnode_handle)”. >> >> * Reduce the scope for the local variable “fwnode”. >> >> Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support") >> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> > > Was the fwnode leaked, or why else is this a "fix"? It's not clear > from the commit message. Can you notice that fwnode_handle_put() calls were forgotten in the mentioned function implementation? https://elixir.bootlin.com/linux/v6.10-rc2/source/drivers/usb/typec/anx7411.c#L1140 I propose another code cleanup accordingly. Will development attention grow anyhow for information in the available API documentation? Example: device_get_named_child_node() https://elixir.bootlin.com/linux/v6.10-rc2/source/drivers/base/property.c#L839 Regards, Markus
On Wed, 5 Jun 2024 19:11:04 +0200 Markus Elfring <Markus.Elfring@web.de> wrote: > From: Markus Elfring <elfring@users.sourceforge.net> > Date: Wed, 5 Jun 2024 18:56:19 +0200 > > Scope-based resource management became supported also for another > programming interface by contributions of Jonathan Cameron on 2024-02-17. > See also the commit 59ed5e2d505bf5f9b4af64d0021cd0c96aec1f7c ("device > property: Add cleanup.h based fwnode_handle_put() scope based cleanup."). > > * Thus use the attribute “__free(fwnode_handle)”. > > * Reduce the scope for the local variable “fwnode”. > > Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support") > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Hi Markus, Good catch. However in this case I think this is insufficient. Also your patch description should more clearly state the bug rather and impacts (a potential resource leak). I'm not 100% sure how this should work though. If the expectation is that a reference to the fwnode is held when we enter typec_register_port(), then if that errors out then we need fwnode_handle_put(). If expectation is that the reference is not held, then we should always call fwnode_handle_put() before that is called. Internally it just uses this to fill in port->dev.fwnode. Given typec_get_fw_cap() is called from there and doesn't get a reference I think expectation is that the fwnode is held by the driver calling typec_register_port() until that is unregistered. Hence should be put in the error path of that call in the calling driver. ctx->typec.port = typec_register_port(dev, cap); if (IS_ERR(ctx->typec.port)) { // fwnode_handle_put() in here. ret = PTR_ERR(ctx->typec.port); ctx->typec.port = NULL; dev_err(dev, "Failed to register type c port %d\n", ret); return ret; } That makes it tricky to use no_free_ptr() so I wonder if this is a case where the old fashioned fix of adding all the relevant fwnode_handle_put() calls is the better option. The __free() approach doesn't always fit. Jonathan > --- > drivers/usb/typec/anx7411.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c > index b12a07edc71b..9fb52f233a30 100644 > --- a/drivers/usb/typec/anx7411.c > +++ b/drivers/usb/typec/anx7411.c > @@ -16,6 +16,7 @@ > #include <linux/of_graph.h> > #include <linux/of_platform.h> > #include <linux/pm_runtime.h> > +#include <linux/property.h> > #include <linux/regulator/consumer.h> > #include <linux/slab.h> > #include <linux/types.h> > @@ -1142,11 +1143,11 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, > { > struct typec_capability *cap = &ctx->typec.caps; > struct typec_params *typecp = &ctx->typec; > - struct fwnode_handle *fwnode; > const char *buf; > int ret, i; > > - fwnode = device_get_named_child_node(dev, "connector"); > + struct fwnode_handle *fwnode __free(fwnode_handle) > + = device_get_named_child_node(dev, "connector"); > if (!fwnode) > return -EINVAL; > > @@ -1237,7 +1238,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, > typecp->caps_flags |= HAS_SINK_WATT; > } > > - cap->fwnode = fwnode; > + cap->fwnode = no_free_ptr(fwnode); > > ctx->typec.role_sw = usb_role_switch_get(dev); > if (IS_ERR(ctx->typec.role_sw)) { > -- > 2.45.1 >
> That makes it tricky to use no_free_ptr() so I wonder if this is > a case where the old fashioned fix of adding all the relevant > fwnode_handle_put() calls is the better option. The __free() > approach doesn't always fit. Can involved development concerns be clarified better anyhow? Regards, Markus
diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c index b12a07edc71b..9fb52f233a30 100644 --- a/drivers/usb/typec/anx7411.c +++ b/drivers/usb/typec/anx7411.c @@ -16,6 +16,7 @@ #include <linux/of_graph.h> #include <linux/of_platform.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/types.h> @@ -1142,11 +1143,11 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, { struct typec_capability *cap = &ctx->typec.caps; struct typec_params *typecp = &ctx->typec; - struct fwnode_handle *fwnode; const char *buf; int ret, i; - fwnode = device_get_named_child_node(dev, "connector"); + struct fwnode_handle *fwnode __free(fwnode_handle) + = device_get_named_child_node(dev, "connector"); if (!fwnode) return -EINVAL; @@ -1237,7 +1238,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, typecp->caps_flags |= HAS_SINK_WATT; } - cap->fwnode = fwnode; + cap->fwnode = no_free_ptr(fwnode); ctx->typec.role_sw = usb_role_switch_get(dev); if (IS_ERR(ctx->typec.role_sw)) {