Re: [RFC PATCH] introduce sys_membarrier(): process-wide memorybarrier

From: Mathieu Desnoyers
Date: Sun Jan 10 2010 - 23:35:37 EST

* Paul E. McKenney (paulmck@xxxxxxxxxxxxxxxxxx) wrote:
> > Even when taking the spinlocks, efficient iteration on active threads is
> > done with for_each_cpu(cpu, mm_cpumask(current->mm)), which depends on
> > the same cpumask, and thus requires the same memory barriers around the
> > updates.
> Ouch!!! Good point and good catch!!!
> > We could switch to an inefficient iteration on all online CPUs instead,
> > and check read runqueue ->mm with the spinlock held. Is that what you
> > propose ? This will cause reading of large amounts of runqueue
> > information, especially on large systems running few threads. The other
> > way around is to iterate on all the process threads: in this case, small
> > systems running many threads will have to read information about many
> > inactive threads, which is not much better.
> I am not all that worried about exactly what we do as long as it is
> pretty obviously correct. We can then improve performance when and as
> the need arises. We might need to use any of the strategies you
> propose, or perhaps even choose among them depending on the number of
> threads in the process, the number of CPUs, and so forth. (I hope not,
> but...)
> My guess is that an obviously correct approach would work well for a
> slowpath. If someone later runs into performance problems, we can fix
> them with the added knowledge of what they are trying to do.

OK, here is what I propose. Let's choose between two implementations
(v3a and v3b), which implement two "obviously correct" approaches. In

* baseline (based on
text data bss dec hex filename
76887 8782 2044 87713 156a1 kernel/sched.o

* v3a: ipi to many using mm_cpumask

- adds smp_mb__before_clear_bit()/smp_mb__after_clear_bit() before and
after mm_cpumask stores in context_switch(). They are only executed
when oldmm and mm are different. (it's my turn to hide behind an
appropriately-sized boulder for touching the scheduler). ;) Note that
it's not that bad, as these barriers turn into simple compiler barrier()
avr32, blackfin, cris, frb, h8300, m32r, m68k, mn10300, score, sh,
sparc, x86 and xtensa.
The less lucky architectures gaining two smp_mb() are:
alpha, arm, ia64, mips, parisc, powerpc and s390.
ia64 is gaining only one smp_mb() thanks to its acquire semantic.
- size
text data bss dec hex filename
77239 8782 2044 88065 15801 kernel/sched.o
-> adds 352 bytes of text
- Number of lines (system call source code, w/o comments) : 18

* v3b: iteration on min(num_online_cpus(), nr threads in the process),
taking runqueue spinlocks, allocating a cpumask, ipi to many to the
cpumask. Does not allocate the cpumask if only a single IPI is needed.

- only adds sys_membarrier() and related functions.
- size
text data bss dec hex filename
78047 8782 2044 88873 15b29 kernel/sched.o
-> adds 1160 bytes of text
- Number of lines (system call source code, w/o comments) : 163

I'll reply to this email with the two implementations. Comments are



Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at