On Tue, 20 Dec 2011, Pekka Enberg wrote: > To illustrate the issue, for "per cpu add" we have: > > __this_cpu_add() > this_cpu_add() > irqsafe_cpu_add() > percpu_add() > > Why do we need all of them? These are all operations that frequently occur in hot paths of the OS. On x86 all variants map to the same instruction. These will be issueing exactly one ASM instruction that is therefore irqsafe and preempt safe. The single instruction will perform the relocation of the pointer relative to the current cpu area and then perform the RMV operation without the cost of an atomic operation. For non-x86 we have the issue that typically separate instruction have to be used to perform the relocation relative to the current per cpu area and the RMW operation. The problem is that an interrupt or reschedule operation can occur between the address calculation and the RMW operation. The RMW operation may occur on the wrong processors per cpu data. So we need some way of preventing the change of processors or interrupts. The __this_cpu_add() variant simply does nothing to prevent this. Just assumes that the caller has taken a lock or disabling interrupts that provides sufficient measures to prevent the rescheduling on a different processor. The this_cpu_add() variant disables preemption, then does the operations and then reenables preemption. This is usually sufficient since most per cpu data is not accessed from an interrupt context. The irqsafe_cpu_add() variant disables interrupts, does the operations and then reenabled interrupts. It is needed if counters etc are modified from an interrupt context. percpu_add() is an older variant of the per cpu operations that is (or was?) x86 specific. this_cpu_xxx() operations are used in core code. -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html