path: root/sys/sys/pcpu.h
diff options
authorMateusz Guzik <mjg@FreeBSD.org>2019-09-16 21:37:47 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2019-09-16 21:37:47 +0000
commit4cace859c2a5929e41352d23750b3d5f02978869 (patch)
tree8f59296adfa0ef815747865415e707fb13e4698e /sys/sys/pcpu.h
parente87f3f72f11d16c6d37e9671c46c055b35fc4473 (diff)
vfs: convert struct mount counters to per-cpu
There are 3 counters modified all the time in this structure - one for keeping the structure alive, one for preventing unmount and one for tracking active writers. Exact values of these counters are very rarely needed, which makes them a prime candidate for conversion to a per-cpu scheme, resulting in much better performance. Sample benchmark performing fstatfs (modifying 2 out of 3 counters) on a 104-way 2 socket Skylake system: before: 852393 ops/s after: 76682077 ops/s Reviewed by: kib, jeff Tested by: pho Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21637
Notes: svn path=/head/; revision=352427
Diffstat (limited to 'sys/sys/pcpu.h')
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index 5298f38fe4ec..5813b8dd0c90 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -243,6 +243,18 @@ zpcpu_get_cpu(void *base, int cpu)
+ * This operation is NOT atomic and does not post any barriers.
+ * If you use this the assumption is that the target CPU will not
+ * be modifying this variable.
+ * If you need atomicity use xchg.
+ * */
+#define zpcpu_replace_cpu(base, val, cpu) ({ \
+ __typeof(val) _old = *(__typeof(val) *)zpcpu_get_cpu(base, cpu);\
+ *(__typeof(val) *)zpcpu_get_cpu(base, cpu) = val; \
+ _old; \
* Machine dependent callouts. cpu_pcpu_init() is responsible for
* initializing machine dependent fields of struct pcpu, and
* db_show_mdpcpu() is responsible for handling machine dependent