git: 713abc9880aa - main - sysctl(9): Ease exporting struct sizes; Discourage doing that
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 07 May 2025 10:14:23 UTC
The branch main has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=713abc9880aabe0ff924ff644bceb6ff404ed3cd
commit 713abc9880aabe0ff924ff644bceb6ff404ed3cd
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-05-01 16:02:44 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-05-07 10:13:40 +0000
sysctl(9): Ease exporting struct sizes; Discourage doing that
Introduce two helpers, the more general SYSCTL_SIZEOF() and
a struct-specific one SYSCTL_SIZEOF_STRUCT() which prepends 'struct' in
the description and in the use of sizeof() but uses the raw structure
name as the knob's name. The size of the object/structure is exported
under 'debug.sizeof'.
Existing knobs under 'debug.sizeof' were all converted to use the
helpers.
Add a note before the helpers discouraging the introduction of new
leaves for ad-hoc reasons. List alternative means for developers to
obtain the size of arbitrary kernel structures easily (thanks to markj@
for providing these).
No functional change (intended).
Reviewed by: kib, markj
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D50121
---
.../openzfs/module/os/freebsd/zfs/zfs_znode_os.c | 4 ++++
sys/fs/devfs/devfs_devs.c | 7 ++-----
sys/geom/geom_kern.c | 15 +++++----------
sys/kern/kern_mib.c | 18 ++++++------------
sys/kern/subr_devstat.c | 3 +--
sys/kern/vfs_cache.c | 3 +--
sys/sys/sysctl.h | 21 +++++++++++++++++++++
7 files changed, 40 insertions(+), 31 deletions(-)
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
index ce7b93d20a47..e97a0dd84040 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
@@ -67,8 +67,12 @@
#include "zfs_comutil.h"
/* Used by fstat(1). */
+#ifdef SYSCTL_SIZEOF
+SYSCTL_SIZEOF(znode, znode_t);
+#else
SYSCTL_INT(_debug_sizeof, OID_AUTO, znode, CTLFLAG_RD,
SYSCTL_NULL_INT_PTR, sizeof (znode_t), "sizeof(znode_t)");
+#endif
/*
* Define ZNODE_STATS to turn on statistic gathering. By default, it is only
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index c6dcd4fc7646..124f9f0449af 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -121,11 +121,8 @@ SYSCTL_PROC(_kern, OID_AUTO, devname,
CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_MPSAFE,
NULL, 0, sysctl_devname, "", "devname(3) handler");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct cdev), "sizeof(struct cdev)");
-
-SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev_priv, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct cdev_priv), "sizeof(struct cdev_priv)");
+SYSCTL_SIZEOF_STRUCT(cdev);
+SYSCTL_SIZEOF_STRUCT(cdev_priv);
struct cdev *
devfs_alloc(int flags)
diff --git a/sys/geom/geom_kern.c b/sys/geom/geom_kern.c
index 7f767da99dfc..c6ffd540bc9b 100644
--- a/sys/geom/geom_kern.c
+++ b/sys/geom/geom_kern.c
@@ -229,13 +229,8 @@ SYSCTL_INT(_kern_geom, OID_AUTO, collectstats, CTLFLAG_RW,
&g_collectstats, 0,
"Control statistics collection on GEOM providers and consumers");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct g_class), "sizeof(struct g_class)");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct g_geom), "sizeof(struct g_geom)");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct g_provider), "sizeof(struct g_provider)");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct g_consumer), "sizeof(struct g_consumer)");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct g_bioq), "sizeof(struct g_bioq)");
+SYSCTL_SIZEOF_STRUCT(g_class);
+SYSCTL_SIZEOF_STRUCT(g_geom);
+SYSCTL_SIZEOF_STRUCT(g_provider);
+SYSCTL_SIZEOF_STRUCT(g_consumer);
+SYSCTL_SIZEOF_STRUCT(g_bioq);
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index f8f90fce87cf..97742aefe8f7 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -730,11 +730,9 @@ SYSCTL_STRING(_user, USER_LOCALBASE, localbase, CTLFLAG_RWTUN,
localbase, sizeof(localbase), "Prefix used to install and locate add-on packages");
#include <sys/vnode.h>
-SYSCTL_INT(_debug_sizeof, OID_AUTO, vnode, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct vnode), "sizeof(struct vnode)");
+SYSCTL_SIZEOF_STRUCT(vnode);
-SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct proc), "sizeof(struct proc)");
+SYSCTL_SIZEOF_STRUCT(proc);
static int
sysctl_kern_pid_max(SYSCTL_HANDLER_ARGS)
@@ -770,19 +768,15 @@ SYSCTL_INT(_kern, OID_AUTO, pid_max_limit, CTLFLAG_RD,
#include <sys/bio.h>
#include <sys/buf.h>
-SYSCTL_INT(_debug_sizeof, OID_AUTO, bio, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct bio), "sizeof(struct bio)");
-SYSCTL_INT(_debug_sizeof, OID_AUTO, buf, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct buf), "sizeof(struct buf)");
+SYSCTL_SIZEOF_STRUCT(bio);
+SYSCTL_SIZEOF_STRUCT(buf);
#include <sys/user.h>
-SYSCTL_INT(_debug_sizeof, OID_AUTO, kinfo_proc, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct kinfo_proc), "sizeof(struct kinfo_proc)");
+SYSCTL_SIZEOF_STRUCT(kinfo_proc);
/* Used by kernel debuggers. */
const int pcb_size = sizeof(struct pcb);
-SYSCTL_INT(_debug_sizeof, OID_AUTO, pcb, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct pcb), "sizeof(struct pcb)");
+SYSCTL_SIZEOF_STRUCT(pcb);
/* XXX compatibility, remove for 6.0 */
#include <sys/imgact.h>
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index f7e2595aa7cf..07a9cc0f57be 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -599,5 +599,4 @@ devstat_free(struct devstat *dsp)
}
}
-SYSCTL_INT(_debug_sizeof, OID_AUTO, devstat, CTLFLAG_RD,
- SYSCTL_NULL_INT_PTR, sizeof(struct devstat), "sizeof(struct devstat)");
+SYSCTL_SIZEOF_STRUCT(devstat);
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 9089c0fd78b4..ff671e80b803 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -627,8 +627,7 @@ SYSCTL_INT(_debug, OID_AUTO, vfscache, CTLFLAG_RW, &doingcache, 0,
#endif
/* Export size information to userland */
-SYSCTL_INT(_debug_sizeof, OID_AUTO, namecache, CTLFLAG_RD, SYSCTL_NULL_INT_PTR,
- sizeof(struct namecache), "sizeof(struct namecache)");
+SYSCTL_SIZEOF_STRUCT(namecache);
/*
* The new name cache statistics
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 0eb9ff274c1b..902f5bde9c37 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -36,6 +36,7 @@
#define _SYS_SYSCTL_H_
#ifdef _KERNEL
+#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/tree.h>
#endif
@@ -932,6 +933,26 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
CTLFLAG_RD | CTLFLAG_CAPRD | CTLTYPE_INT | CTLFLAG_MPSAFE, \
NULL, 1, sysctl_handle_int, "I", desc, "feature");
+/*
+ * Adding new leaves to the 'debug.sizeof' MIB tree for ad-hoc reasons is
+ * discouraged, and in particular for reporting to developers the size of some
+ * kernel structures, which can be obtained by the following alternative means:
+ * 1. In GDB, load a full kernel image and use 'print(sizeof(struct XXX))'.
+ * Alternatively, use 'ptype/o struct XXX' to additionally get the offsets
+ * and size of all structure's fields.
+ * 2. If the structure is allocated from UMA, then 'vmstat -z' reports its size
+ * (the mapping between structure types and zones is usually
+ * straightforward).
+ */
+/* Generates a read-only sysctl reporting the size of an object/structure. */
+#define SYSCTL_SIZEOF(name, expr) \
+ SYSCTL_INT(_debug_sizeof, OID_AUTO, name, CTLFLAG_RD, \
+ SYSCTL_NULL_INT_PTR, sizeof(expr), \
+ "sizeof(" __STRING(expr) ")");
+/* Same, specialized for structures. */
+#define SYSCTL_SIZEOF_STRUCT(struct_name) \
+ SYSCTL_SIZEOF(struct_name, struct struct_name)
+
#endif /* _KERNEL */
/*