Re: [PATCH 09/13] platform/chrome: cros_ec_proto: use devm_krealloc()

From: Guenter Roeck
Date: Mon Jun 06 2022 - 12:04:27 EST


On Mon, Jun 6, 2022 at 7:12 AM Tzung-Bi Shih <tzungbi@xxxxxxxxxx> wrote:
>
> Use devm_krealloc() to re-allocate `din` and `dout`.
>
> Also remove the unneeded devm_kfree() in error handling path as they are
> device managed memory.
>

Problem with that is that the callers don't always handle error
returns from calls to cros_ec_query_all(), that the call isn't
typically from the probe function, and that the release function would
not be called after partial allocation failures until the driver is
unloaded. This would result in memory leaks, making the memory
situation even worse. I am not sure if using devm_ functions to
allocate the memory really makes sense here.

Guenter

> Signed-off-by: Tzung-Bi Shih <tzungbi@xxxxxxxxxx>
> ---
> drivers/platform/chrome/cros_ec_proto.c | 25 ++++++--------------
> drivers/platform/chrome/cros_ec_proto_test.c | 3 +--
> 2 files changed, 8 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
> index abb30a685567..5f4414f05d66 100644
> --- a/drivers/platform/chrome/cros_ec_proto.c
> +++ b/drivers/platform/chrome/cros_ec_proto.c
> @@ -479,21 +479,13 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
> }
> }
>
> - devm_kfree(dev, ec_dev->din);
> - devm_kfree(dev, ec_dev->dout);
> -
> - ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
> - if (!ec_dev->din) {
> - ret = -ENOMEM;
> - goto exit;
> - }
> + ec_dev->din = devm_krealloc(dev, ec_dev->din, ec_dev->din_size, GFP_KERNEL | __GFP_ZERO);
> + if (!ec_dev->din)
> + return -ENOMEM;
>
> - ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
> - if (!ec_dev->dout) {
> - devm_kfree(dev, ec_dev->din);
> - ret = -ENOMEM;
> - goto exit;
> - }
> + ec_dev->dout = devm_krealloc(dev, ec_dev->dout, ec_dev->dout_size, GFP_KERNEL | __GFP_ZERO);
> + if (!ec_dev->dout)
> + return -ENOMEM;
>
> /* Probe if MKBP event is supported */
> ret = cros_ec_get_host_command_version_mask(ec_dev,
> @@ -542,10 +534,7 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
> "failed to retrieve wake mask: %d\n", ret);
> }
>
> - ret = 0;
> -
> -exit:
> - return ret;
> + return 0;
> }
> EXPORT_SYMBOL(cros_ec_query_all);
>
> diff --git a/drivers/platform/chrome/cros_ec_proto_test.c b/drivers/platform/chrome/cros_ec_proto_test.c
> index 79150bf511fb..22f9322787f4 100644
> --- a/drivers/platform/chrome/cros_ec_proto_test.c
> +++ b/drivers/platform/chrome/cros_ec_proto_test.c
> @@ -180,8 +180,7 @@ static void cros_ec_proto_test_query_all_pretest(struct kunit *test)
>
> /*
> * cros_ec_query_all() will free din and dout and allocate them again to fit the usage by
> - * calling devm_kfree() and devm_kzalloc(). Set them to NULL as they aren't managed by
> - * ec_dev->dev.
> + * calling devm_krealloc(). Set them to NULL as they aren't managed by ec_dev->dev.
> */
> ec_dev->din = NULL;
> ec_dev->dout = NULL;
> --
> 2.36.1.255.ge46751e96f-goog
>