From 4cace859c2a5929e41352d23750b3d5f02978869 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Mon, 16 Sep 2019 21:37:47 +0000 Subject: 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 --- sys/sys/pcpu.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sys/sys/pcpu.h') 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 @@ -242,6 +242,18 @@ zpcpu_get_cpu(void *base, int cpu) return ((char *)(base) + UMA_PCPU_ALLOC_SIZE * 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 -- cgit v1.2.3