summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2025-09-04 20:28:18 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2026-01-16 19:37:49 +0000
commit62d86be3d64d65ba207f81f18d0dbf38f57935ee (patch)
tree3f4c2f0ffac95009b74871c9ab60fa0a2668f8d4
parentfa3f62df151532a2e6b2934d5d5dc632b923c2b5 (diff)
LinuxKPI: devres: divorce dem_kfree from lkpi_devm_kmalloc_release
dem_kfree() is called from all over the place and should actually do something; contrary to lkpi_devm_kmalloc_release() it can also take a const void *. We have to __DECONST() that though as the entire devres framework does otherwise not take a const argument. This was discovered during the rtw89 update to 6.16. Sponsored by: The FreeBSD Foundation (initially) Reviewed by: dumbbell Differential Revision: https://reviews.freebsd.org/D52082 (cherry picked from commit 4ab64e34911ab06e567caaf07ed18f7770a61cc8) (cherry picked from commit f20a09e161f07874c3a01b1579e8a5d2356df8ce)
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h5
-rw-r--r--sys/compat/linuxkpi/common/src/linux_devres.c26
2 files changed, 28 insertions, 3 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index de7e66d9a4ad..ab53add4be54 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -4,7 +4,7 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
* All rights reserved.
- * Copyright (c) 2021-2022 The FreeBSD Foundation
+ * Copyright (c) 2021-2025 The FreeBSD Foundation
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -282,7 +282,8 @@ int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *)
void lkpi_devres_release_free_list(struct device *);
void lkpi_devres_unlink(struct device *, void *);
void lkpi_devm_kmalloc_release(struct device *, void *);
-#define devm_kfree(_d, _p) lkpi_devm_kmalloc_release(_d, _p)
+void lkpi_devm_kfree(struct device *, const void *);
+#define devm_kfree(_d, _p) lkpi_devm_kfree(_d, _p)
static inline const char *
dev_driver_string(const struct device *dev)
diff --git a/sys/compat/linuxkpi/common/src/linux_devres.c b/sys/compat/linuxkpi/common/src/linux_devres.c
index 84f03ba0dd7d..23c91cb5ab2f 100644
--- a/sys/compat/linuxkpi/common/src/linux_devres.c
+++ b/sys/compat/linuxkpi/common/src/linux_devres.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
*
* This software was developed by Bj\xc3\xb6rn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -223,6 +223,30 @@ lkpi_devm_kmalloc_release(struct device *dev __unused, void *p __unused)
/* Nothing to do. Freed with the devres. */
}
+static int
+lkpi_devm_kmalloc_match(struct device *dev __unused, void *p, void *mp)
+{
+ return (p == mp);
+}
+
+void
+lkpi_devm_kfree(struct device *dev, const void *p)
+{
+ void *mp;
+ int error;
+
+ if (p == NULL)
+ return;
+
+ /* I assume Linux simply casts the const away... */
+ mp = __DECONST(void *, p);
+ error = lkpi_devres_destroy(dev, lkpi_devm_kmalloc_release,
+ lkpi_devm_kmalloc_match, mp);
+ if (error != 0)
+ dev_warn(dev, "%s: lkpi_devres_destroy failed with %d\n",
+ __func__, error);
+}
+
struct devres_action {
void *data;
void (*action)(void *);