Linux uses pseudo-attribute __read_mostly to tag variables that are read frequently but written seldom. These variables are grouped together at link time. This improves cache usage by reducing false sharing.
__read_mostly has been adopted by FreeBSD, DragonFly BSD and NetBSD. The former two also have __read_frequently. It aims to improve the placement of hot variables even further. The following patch shows an implementation of __read_mostly on amd64 and a few samples of the tag's usage. It does not add __read_frequently as this attribute seems somewhat redundant. A downside of this is that it becomes easier to guess the addresses of the tagged variables. Index: arch/amd64/conf/ld.script =================================================================== RCS file: src/sys/arch/amd64/conf/ld.script,v retrieving revision 1.17 diff -u -p -r1.17 ld.script --- arch/amd64/conf/ld.script 7 Mar 2021 23:10:54 -0000 1.17 +++ arch/amd64/conf/ld.script 20 Mar 2022 05:49:46 -0000 @@ -117,6 +117,8 @@ SECTIONS .data : AT (__kernel_data_phys) { __data_start = ABSOLUTE(.); + *(.data.read_mostly) + . = ALIGN(128); *(.data .data.*) } :data =0xcccccccc Index: dev/dt/dt_dev.c =================================================================== RCS file: src/sys/dev/dt/dt_dev.c,v retrieving revision 1.22 diff -u -p -r1.22 dt_dev.c --- dev/dt/dt_dev.c 27 Feb 2022 10:14:01 -0000 1.22 +++ dev/dt/dt_dev.c 20 Mar 2022 05:49:46 -0000 @@ -110,7 +110,7 @@ unsigned int dt_nprobes; /* [I] # of p SIMPLEQ_HEAD(, dt_probe) dt_probe_list; /* [I] list of probes */ struct rwlock dt_lock = RWLOCK_INITIALIZER("dtlk"); -volatile uint32_t dt_tracing = 0; /* [K] # of processes tracing */ +volatile __read_mostly uint32_t dt_tracing = 0; /* [K] # of processes tracing */ int allowdt; Index: dev/pci/drm/include/linux/compiler.h =================================================================== RCS file: src/sys/dev/pci/drm/include/linux/compiler.h,v retrieving revision 1.8 diff -u -p -r1.8 compiler.h --- dev/pci/drm/include/linux/compiler.h 19 Jan 2022 02:49:05 -0000 1.8 +++ dev/pci/drm/include/linux/compiler.h 20 Mar 2022 05:49:46 -0000 @@ -12,7 +12,6 @@ #define __force #define __acquires(x) #define __releases(x) -#define __read_mostly #define __iomem #define __must_check #define __init Index: kern/init_main.c =================================================================== RCS file: src/sys/kern/init_main.c,v retrieving revision 1.315 diff -u -p -r1.315 init_main.c --- kern/init_main.c 22 Feb 2022 01:15:01 -0000 1.315 +++ kern/init_main.c 20 Mar 2022 05:49:47 -0000 @@ -131,7 +131,7 @@ extern struct user *proc0paddr; struct vnode *rootvp, *swapdev_vp; int boothowto; -int db_active = 0; +__read_mostly int db_active = 0; int ncpus = 1; int ncpusfound = 1; /* number of cpus we find */ volatile int start_init_exec; /* semaphore for start_init() */ Index: kern/subr_prf.c =================================================================== RCS file: src/sys/kern/subr_prf.c,v retrieving revision 1.105 diff -u -p -r1.105 subr_prf.c --- kern/subr_prf.c 20 Jan 2022 17:11:30 -0000 1.105 +++ kern/subr_prf.c 20 Mar 2022 05:49:47 -0000 @@ -97,8 +97,13 @@ struct mutex kprintf_mutex = */ extern int log_open; /* subr_log: is /dev/klog open? */ -const char *panicstr; /* arg to first call to panic (used as a flag - to indicate that panic has already been called). */ + +/* + * arg to first call to panic (used as a flag + * to indicate that panic has already been called). + */ +__read_mostly const char *panicstr; + #ifdef DDB /* * Enter ddb on panic. Index: sys/systm.h =================================================================== RCS file: src/sys/sys/systm.h,v retrieving revision 1.155 diff -u -p -r1.155 systm.h --- sys/systm.h 9 Dec 2021 00:26:10 -0000 1.155 +++ sys/systm.h 20 Mar 2022 05:49:47 -0000 @@ -315,6 +315,8 @@ int uiomove(void *, size_t, struct uio * #include <sys/rwlock.h> +#define __read_mostly __attribute__((__section__(".data.read_mostly"))) + extern struct rwlock netlock; /*