Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 May 2025 12:42:45 GMT
From:      Olivier Certner <olce@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: de6a4418eec9 - releng/14.3 - sysctl(9): Ease exporting struct sizes; Discourage doing that
Message-ID:  <202505131242.54DCgjkM072761@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/14.3 has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=de6a4418eec91dc8802defce0159c126a2c7b6d2

commit de6a4418eec91dc8802defce0159c126a2c7b6d2
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-05-01 16:02:44 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-05-13 12:41:33 +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
    
    (cherry picked from commit 713abc9880aabe0ff924ff644bceb6ff404ed3cd)
    (cherry picked from commit efce9f8a510b60736994e50288b78fc7b32b5d90)
    
    Approved by:    re (cperciva)
---
 .../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 fea34273baef..61a59be9f78b 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
@@ -66,8 +66,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 14707403215d..f8f99087ad9c 100644
--- a/sys/geom/geom_kern.c
+++ b/sys/geom/geom_kern.c
@@ -230,13 +230,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 d60c72a00f63..f69275fc3d1d 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -722,11 +722,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)
@@ -758,19 +756,15 @@ SYSCTL_PROC(_kern, OID_AUTO, pid_max, CTLTYPE_INT |
 
 #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 6c0977d1cc35..3a107ac30390 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -600,5 +600,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 ab28540be8a8..92e9d77eb891 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -511,8 +511,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 5fce4b8e1713..f08080d4e4fa 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -38,6 +38,7 @@
 #define	_SYS_SYSCTL_H_
 
 #ifdef _KERNEL
+#include <sys/cdefs.h>
 #include <sys/queue.h>
 #include <sys/tree.h>
 #endif
@@ -934,6 +935,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 */
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505131242.54DCgjkM072761>