0001
0002 .. _local_ops:
0003
0004 =================================================
0005 Semantics and Behavior of Local Atomic Operations
0006 =================================================
0007
0008 :Author: Mathieu Desnoyers
0009
0010
0011 This document explains the purpose of the local atomic operations, how
0012 to implement them for any given architecture and shows how they can be used
0013 properly. It also stresses on the precautions that must be taken when reading
0014 those local variables across CPUs when the order of memory writes matters.
0015
0016 .. note::
0017
0018 Note that ``local_t`` based operations are not recommended for general
0019 kernel use. Please use the ``this_cpu`` operations instead unless there is
0020 really a special purpose. Most uses of ``local_t`` in the kernel have been
0021 replaced by ``this_cpu`` operations. ``this_cpu`` operations combine the
0022 relocation with the ``local_t`` like semantics in a single instruction and
0023 yield more compact and faster executing code.
0024
0025
0026 Purpose of local atomic operations
0027 ==================================
0028
0029 Local atomic operations are meant to provide fast and highly reentrant per CPU
0030 counters. They minimize the performance cost of standard atomic operations by
0031 removing the LOCK prefix and memory barriers normally required to synchronize
0032 across CPUs.
0033
0034 Having fast per CPU atomic counters is interesting in many cases: it does not
0035 require disabling interrupts to protect from interrupt handlers and it permits
0036 coherent counters in NMI handlers. It is especially useful for tracing purposes
0037 and for various performance monitoring counters.
0038
0039 Local atomic operations only guarantee variable modification atomicity wrt the
0040 CPU which owns the data. Therefore, care must taken to make sure that only one
0041 CPU writes to the ``local_t`` data. This is done by using per cpu data and
0042 making sure that we modify it from within a preemption safe context. It is
0043 however permitted to read ``local_t`` data from any CPU: it will then appear to
0044 be written out of order wrt other memory writes by the owner CPU.
0045
0046
0047 Implementation for a given architecture
0048 =======================================
0049
0050 It can be done by slightly modifying the standard atomic operations: only
0051 their UP variant must be kept. It typically means removing LOCK prefix (on
0052 i386 and x86_64) and any SMP synchronization barrier. If the architecture does
0053 not have a different behavior between SMP and UP, including
0054 ``asm-generic/local.h`` in your architecture's ``local.h`` is sufficient.
0055
0056 The ``local_t`` type is defined as an opaque ``signed long`` by embedding an
0057 ``atomic_long_t`` inside a structure. This is made so a cast from this type to
0058 a ``long`` fails. The definition looks like::
0059
0060 typedef struct { atomic_long_t a; } local_t;
0061
0062
0063 Rules to follow when using local atomic operations
0064 ==================================================
0065
0066 * Variables touched by local ops must be per cpu variables.
0067 * *Only* the CPU owner of these variables must write to them.
0068 * This CPU can use local ops from any context (process, irq, softirq, nmi, ...)
0069 to update its ``local_t`` variables.
0070 * Preemption (or interrupts) must be disabled when using local ops in
0071 process context to make sure the process won't be migrated to a
0072 different CPU between getting the per-cpu variable and doing the
0073 actual local op.
0074 * When using local ops in interrupt context, no special care must be
0075 taken on a mainline kernel, since they will run on the local CPU with
0076 preemption already disabled. I suggest, however, to explicitly
0077 disable preemption anyway to make sure it will still work correctly on
0078 -rt kernels.
0079 * Reading the local cpu variable will provide the current copy of the
0080 variable.
0081 * Reads of these variables can be done from any CPU, because updates to
0082 "``long``", aligned, variables are always atomic. Since no memory
0083 synchronization is done by the writer CPU, an outdated copy of the
0084 variable can be read when reading some *other* cpu's variables.
0085
0086
0087 How to use local atomic operations
0088 ==================================
0089
0090 ::
0091
0092 #include <linux/percpu.h>
0093 #include <asm/local.h>
0094
0095 static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0);
0096
0097
0098 Counting
0099 ========
0100
0101 Counting is done on all the bits of a signed long.
0102
0103 In preemptible context, use ``get_cpu_var()`` and ``put_cpu_var()`` around
0104 local atomic operations: it makes sure that preemption is disabled around write
0105 access to the per cpu variable. For instance::
0106
0107 local_inc(&get_cpu_var(counters));
0108 put_cpu_var(counters);
0109
0110 If you are already in a preemption-safe context, you can use
0111 ``this_cpu_ptr()`` instead::
0112
0113 local_inc(this_cpu_ptr(&counters));
0114
0115
0116
0117 Reading the counters
0118 ====================
0119
0120 Those local counters can be read from foreign CPUs to sum the count. Note that
0121 the data seen by local_read across CPUs must be considered to be out of order
0122 relatively to other memory writes happening on the CPU that owns the data::
0123
0124 long sum = 0;
0125 for_each_online_cpu(cpu)
0126 sum += local_read(&per_cpu(counters, cpu));
0127
0128 If you want to use a remote local_read to synchronize access to a resource
0129 between CPUs, explicit ``smp_wmb()`` and ``smp_rmb()`` memory barriers must be used
0130 respectively on the writer and the reader CPUs. It would be the case if you use
0131 the ``local_t`` variable as a counter of bytes written in a buffer: there should
0132 be a ``smp_wmb()`` between the buffer write and the counter increment and also a
0133 ``smp_rmb()`` between the counter read and the buffer read.
0134
0135
0136 Here is a sample module which implements a basic per cpu counter using
0137 ``local.h``::
0138
0139 /* test-local.c
0140 *
0141 * Sample module for local.h usage.
0142 */
0143
0144
0145 #include <asm/local.h>
0146 #include <linux/module.h>
0147 #include <linux/timer.h>
0148
0149 static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0);
0150
0151 static struct timer_list test_timer;
0152
0153 /* IPI called on each CPU. */
0154 static void test_each(void *info)
0155 {
0156 /* Increment the counter from a non preemptible context */
0157 printk("Increment on cpu %d\n", smp_processor_id());
0158 local_inc(this_cpu_ptr(&counters));
0159
0160 /* This is what incrementing the variable would look like within a
0161 * preemptible context (it disables preemption) :
0162 *
0163 * local_inc(&get_cpu_var(counters));
0164 * put_cpu_var(counters);
0165 */
0166 }
0167
0168 static void do_test_timer(unsigned long data)
0169 {
0170 int cpu;
0171
0172 /* Increment the counters */
0173 on_each_cpu(test_each, NULL, 1);
0174 /* Read all the counters */
0175 printk("Counters read from CPU %d\n", smp_processor_id());
0176 for_each_online_cpu(cpu) {
0177 printk("Read : CPU %d, count %ld\n", cpu,
0178 local_read(&per_cpu(counters, cpu)));
0179 }
0180 mod_timer(&test_timer, jiffies + 1000);
0181 }
0182
0183 static int __init test_init(void)
0184 {
0185 /* initialize the timer that will increment the counter */
0186 timer_setup(&test_timer, do_test_timer, 0);
0187 mod_timer(&test_timer, jiffies + 1);
0188
0189 return 0;
0190 }
0191
0192 static void __exit test_exit(void)
0193 {
0194 del_timer_sync(&test_timer);
0195 }
0196
0197 module_init(test_init);
0198 module_exit(test_exit);
0199
0200 MODULE_LICENSE("GPL");
0201 MODULE_AUTHOR("Mathieu Desnoyers");
0202 MODULE_DESCRIPTION("Local Atomic Ops");