[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250401134408.37312-1-przemyslaw.kitszel@intel.com>
Date: Tue, 1 Apr 2025 15:44:08 +0200
From: Przemek Kitszel <przemyslaw.kitszel@...el.com>
To: linux-kernel@...r.kernel.org,
linux-mm@...ck.org,
vbabka@...e.cz,
torvalds@...ux-foundation.org,
peterz@...radead.org
Cc: andriy.shevchenko@...ux.intel.com,
intel-wired-lan@...ts.osuosl.org,
netdev@...r.kernel.org,
Przemek Kitszel <przemyslaw.kitszel@...el.com>
Subject: [RFC] slab: introduce auto_kfree macro
Add auto_kfree macro that acts as a higher level wrapper for manual
__free(kfree) invocation, and sets the pointer to NULL - to have both
well defined behavior also for the case code would lack other assignement.
Consider the following code:
int my_foo(int arg)
{
struct my_dev_foo *foo __free(kfree); /* no assignement */
foo = kzalloc(sizeof(*foo), GFP_KERNEL);
/* ... */
}
So far it is fine and even optimal in terms of not assigning when
not needed. But it is typical to don't touch (and sadly to don't
think about) code that is not related to the change, so let's consider
an extension to the above, namely an "early return" style to check
arg prior to allocation:
int my_foo(int arg)
{
struct my_dev_foo *foo __free(kfree); /* no assignement */
+
+ if (!arg)
+ return -EINVAL;
foo = kzalloc(sizeof(*foo), GFP_KERNEL);
/* ... */
}
Now we have uninitialized foo passed to kfree, what likely will crash.
One could argue that `= NULL` should be added to this patch, but it is
easy to forgot, especially when the foo declaration is outside of the
default git context.
With new auto_kfree, we simply will start with
struct my_dev_foo *foo auto_kfree;
and be safe against future extensions.
I believe this will open up way for broader adoption of Scope Based
Resource Management, say in networking.
I also believe that my proposed name is special enough that it will
be easy to know/spot that the assignement is hidden.
Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@...el.com>
---
include/linux/slab.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 98e07e9e9e58..b943be0ce626 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -471,6 +471,7 @@ void kfree_sensitive(const void *objp);
size_t __ksize(const void *objp);
DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
+#define auto_kfree __free(kfree) = NULL
DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T))
/**
--
2.39.3
Powered by blists - more mailing lists