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 - 1.17
+++ arch/amd64/conf/ld.script 20 Mar 2022 05:49:46 -
@@ -117,6 +117,8 @@ SECTIONS
.data : AT (__kernel_data_phys)
{
__data_start = ABSOLUTE(.);
+ *(.data.read_mostly)
+ . = ALIGN(128);
*(.data .data.*)
} :data =0x
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 - 1.22
+++ dev/dt/dt_dev.c 20 Mar 2022 05:49:46 -
@@ -110,7 +110,7 @@ unsigned intdt_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_tdt_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.h19 Jan 2022 02:49:05 -
1.8
+++ dev/pci/drm/include/linux/compiler.h20 Mar 2022 05:49:46 -
@@ -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.c22 Feb 2022 01:15:01 - 1.315
+++ kern/init_main.c20 Mar 2022 05:49:47 -
@@ -131,7 +131,7 @@ extern struct user *proc0paddr;
struct vnode *rootvp, *swapdev_vp;
intboothowto;
-intdb_active = 0;
+__read_mostly int db_active = 0;
intncpus = 1;
intncpusfound = 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 - 1.105
+++ kern/subr_prf.c 20 Mar 2022 05:49:47 -
@@ -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 - 1.155
+++ sys/systm.h 20 Mar 2022 05:49:47 -
@@ -315,6 +315,8 @@ int uiomove(void *, size_t, struct uio *
#include
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
extern struct rwlock netlock;
/*