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

Reply via email to