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
This commit is contained in:
Olivier Certner 2025-05-01 18:02:44 +02:00
parent da509c2908
commit 713abc9880
No known key found for this signature in database
GPG key ID: 8CA13040971E2627
7 changed files with 40 additions and 31 deletions

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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>

View file

@ -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);

View file

@ -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

View file

@ -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 */
/*