From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Replace manual cleanup logic with __free attribute from cleanup.h. This
removes explicit kfree() calls and simplifies the error handling paths.
No functional change intended for kmalloc().
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/staging/greybus/camera.c | 27 +++++++----------------
drivers/staging/greybus/loopback.c | 35 ++++++++++--------------------
drivers/staging/greybus/raw.c | 6 ++---
3 files changed, 22 insertions(+), 46 deletions(-)
diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c
index 62b55bb28408..14a603ca2400 100644
--- a/drivers/staging/greybus/camera.c
+++ b/drivers/staging/greybus/camera.c
@@ -519,8 +519,6 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
struct gb_camera_stream_config *streams,
struct gb_camera_csi_params *csi_params)
{
- struct gb_camera_configure_streams_request *req;
- struct gb_camera_configure_streams_response *resp;
unsigned int nstreams = *num_streams;
unsigned int i;
size_t req_size;
@@ -533,11 +531,11 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
req_size = sizeof(*req) + nstreams * sizeof(req->config[0]);
resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]);
- req = kmalloc(req_size, GFP_KERNEL);
- resp = kmalloc(resp_size, GFP_KERNEL);
+ struct gb_camera_configure_streams_request *req __free(kfree) =
+ kmalloc(req_size, GFP_KERNEL);
+ struct gb_camera_configure_streams_response *resp __free(kfree) =
+ kmalloc(resp_size, GFP_KERNEL);
if (!req || !resp) {
- kfree(req);
- kfree(resp);
return -ENOMEM;
}
@@ -641,8 +639,6 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
done_skip_pm_put:
mutex_unlock(&gcam->mutex);
- kfree(req);
- kfree(resp);
return ret;
}
@@ -650,7 +646,6 @@ static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
unsigned int streams, unsigned int num_frames,
size_t settings_size, const void *settings)
{
- struct gb_camera_capture_request *req;
size_t req_size;
int ret;
@@ -658,7 +653,8 @@ static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
return -EINVAL;
req_size = sizeof(*req) + settings_size;
- req = kmalloc(req_size, GFP_KERNEL);
+ struct gb_camera_capture_request *req __free(kfree) =
+ kmalloc(req_size, GFP_KERNEL);
if (!req)
return -ENOMEM;
@@ -680,8 +676,6 @@ static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
done:
mutex_unlock(&gcam->mutex);
- kfree(req);
-
return ret;
}
@@ -870,16 +864,15 @@ static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,
&gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES];
size_t size = 1024;
unsigned int i;
- u8 *caps;
int ret;
- caps = kmalloc(size, GFP_KERNEL);
+ u8 *caps __free(kfree) = kmalloc(size, GFP_KERNEL);
if (!caps)
return -ENOMEM;
ret = gb_camera_capabilities(gcam, caps, &size);
if (ret < 0)
- goto done;
+ return ret;
/*
* hex_dump_to_buffer() doesn't return the number of bytes dumped prior
@@ -893,10 +886,6 @@ static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,
buffer->length += sprintf(buffer->data + buffer->length,
"%*ph\n", nbytes, caps + i);
}
-
-done:
- kfree(caps);
- return ret;
}
static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam,
diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
index aa9c73cb0ae5..ae729f744ac5 100644
--- a/drivers/staging/greybus/loopback.c
+++ b/drivers/staging/greybus/loopback.c
@@ -508,10 +508,10 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type,
static int gb_loopback_sync_sink(struct gb_loopback *gb, u32 len)
{
- struct gb_loopback_transfer_request *request;
int retval;
- request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ struct gb_loopback_transfer_request *request __free(kfree) =
+ kmalloc(len + sizeof(*request), GFP_KERNEL);
if (!request)
return -ENOMEM;
@@ -519,25 +519,24 @@ static int gb_loopback_sync_sink(struct gb_loopback *gb, u32 len)
retval = gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_SINK,
request, len + sizeof(*request),
NULL, 0);
- kfree(request);
return retval;
}
static int gb_loopback_sync_transfer(struct gb_loopback *gb, u32 len)
{
- struct gb_loopback_transfer_request *request;
- struct gb_loopback_transfer_response *response;
int retval;
gb->apbridge_latency_ts = 0;
gb->gbphy_latency_ts = 0;
- request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ struct gb_loopback_transfer_request *request __free(kfree) =
+ kmalloc(len + sizeof(*request), GFP_KERNEL);
if (!request)
return -ENOMEM;
- response = kmalloc(len + sizeof(*response), GFP_KERNEL);
+
+ struct gb_loopback_transfer_response *response __free(kfree) =
+ kmalloc(len + sizeof(*response), GFP_KERNEL);
if (!response) {
- kfree(request);
return -ENOMEM;
}
@@ -548,7 +547,7 @@ static int gb_loopback_sync_transfer(struct gb_loopback *gb, u32 len)
request, len + sizeof(*request),
response, len + sizeof(*response));
if (retval)
- goto gb_error;
+ return retval;
if (memcmp(request->data, response->data, len)) {
dev_err(&gb->connection->bundle->dev,
@@ -558,10 +557,6 @@ static int gb_loopback_sync_transfer(struct gb_loopback *gb, u32 len)
gb->apbridge_latency_ts = (u32)__le32_to_cpu(response->reserved0);
gb->gbphy_latency_ts = (u32)__le32_to_cpu(response->reserved1);
-gb_error:
- kfree(request);
- kfree(response);
-
return retval;
}
@@ -573,10 +568,10 @@ static int gb_loopback_sync_ping(struct gb_loopback *gb)
static int gb_loopback_async_sink(struct gb_loopback *gb, u32 len)
{
- struct gb_loopback_transfer_request *request;
int retval;
- request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ struct gb_loopback_transfer_request *request __free(kfree) =
+ kmalloc(len + sizeof(*request), GFP_KERNEL);
if (!request)
return -ENOMEM;
@@ -584,7 +579,6 @@ static int gb_loopback_async_sink(struct gb_loopback *gb, u32 len)
retval = gb_loopback_async_operation(gb, GB_LOOPBACK_TYPE_SINK,
request, len + sizeof(*request),
0, NULL);
- kfree(request);
return retval;
}
@@ -621,10 +615,10 @@ static int gb_loopback_async_transfer_complete(
static int gb_loopback_async_transfer(struct gb_loopback *gb, u32 len)
{
- struct gb_loopback_transfer_request *request;
int retval, response_len;
- request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ struct gb_loopback_transfer_request *request __free(kfree) =
+ kmalloc(len + sizeof(*request), GFP_KERNEL);
if (!request)
return -ENOMEM;
@@ -636,11 +630,6 @@ static int gb_loopback_async_transfer(struct gb_loopback *gb, u32 len)
request, len + sizeof(*request),
len + response_len,
gb_loopback_async_transfer_complete);
- if (retval)
- goto gb_error;
-
-gb_error:
- kfree(request);
return retval;
}
diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c
index 3027a2c25bcd..60a754b20432 100644
--- a/drivers/staging/greybus/raw.c
+++ b/drivers/staging/greybus/raw.c
@@ -126,15 +126,14 @@ static int gb_raw_request_handler(struct gb_operation *op)
static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
{
struct gb_connection *connection = raw->connection;
- struct gb_raw_send_request *request;
int retval;
- request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ struct gb_raw_send_request *request __free(kfree) =
+ kmalloc(len + sizeof(*request), GFP_KERNEL);
if (!request)
return -ENOMEM;
if (copy_from_user(&request->data[0], data, len)) {
- kfree(request);
return -EFAULT;
}
@@ -144,7 +143,6 @@ static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
request, len + sizeof(*request),
NULL, 0);
- kfree(request);
return retval;
}
--
2.34.1
On Wed, Mar 11, 2026 at 01:35:07AM +0530, Sanjay Chitroda wrote:
> Replace manual cleanup logic with __free attribute from cleanup.h. This
> removes explicit kfree() calls and simplifies the error handling paths.
>
> No functional change intended for kmalloc().
...
> + struct gb_camera_configure_streams_request *req __free(kfree) =
> + kmalloc(req_size, GFP_KERNEL);
> + struct gb_camera_configure_streams_response *resp __free(kfree) =
> + kmalloc(resp_size, GFP_KERNEL);
> if (!req || !resp) {
Now this check should be done in a better way.
> - kfree(req);
> - kfree(resp);
> return -ENOMEM;
> }
>
> done_skip_pm_put:
> mutex_unlock(&gcam->mutex);
To complete this, one may add a prerequisite to use guard()() first.
> - kfree(req);
> - kfree(resp);
> return ret;
> }
--
With Best Regards,
Andy Shevchenko
On Tue, Mar 10, 2026 at 11:07:16PM +0200, Andy Shevchenko wrote:
> On Wed, Mar 11, 2026 at 01:35:07AM +0530, Sanjay Chitroda wrote:
>
> > Replace manual cleanup logic with __free attribute from cleanup.h. This
> > removes explicit kfree() calls and simplifies the error handling paths.
> >
> > No functional change intended for kmalloc().
>
> ...
>
> > + struct gb_camera_configure_streams_request *req __free(kfree) =
> > + kmalloc(req_size, GFP_KERNEL);
> > + struct gb_camera_configure_streams_response *resp __free(kfree) =
> > + kmalloc(resp_size, GFP_KERNEL);
> > if (!req || !resp) {
>
> Now this check should be done in a better way.
>
Yeah, two if statements, right? Drop the curly braces at a minimum.
> > - kfree(req);
> > - kfree(resp);
> > return -ENOMEM;
> > }
> >
>
> > done_skip_pm_put:
> > mutex_unlock(&gcam->mutex);
>
> To complete this, one may add a prerequisite to use guard()() first.
>
I don't think we're encouraging people to re-write existing staging
code to use cleanup.h magic... It's unclear if I have to review these
patches or if they're auto NAKed because we're not doing the conversions.
regards,
dan carpenter
On Wed, Mar 11, 2026 at 09:51:20AM +0300, Dan Carpenter wrote: > On Tue, Mar 10, 2026 at 11:07:16PM +0200, Andy Shevchenko wrote: > > To complete this, one may add a prerequisite to use guard()() first. > > > > I don't think we're encouraging people to re-write existing staging > code to use cleanup.h magic... It's unclear if I have to review these > patches or if they're auto NAKed because we're not doing the conversions. I've already rejected them, we don't want this type of changes in staging at this point in time. thanks, greg k-h
© 2016 - 2026 Red Hat, Inc.