1 ============================================== 2 Proper Locking Under a Preemptible Kernel: Kee 3 ============================================== 4 5 :Author: Robert Love <rml@tech9.net> 6 7 8 Introduction 9 ============ 10 11 12 A preemptible kernel creates new locking issue 13 those under SMP: concurrency and reentrancy. 14 kernel model leverages existing SMP locking me 15 requires explicit additional locking for very 16 17 This document is for all kernel hackers. Deve 18 requires protecting these situations. 19 20 21 RULE #1: Per-CPU data structures need explicit 22 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 23 24 25 Two similar problems arise. An example code sn 26 27 struct this_needs_locking tux[NR_CPUS] 28 tux[smp_processor_id()] = some_value; 29 /* task is preempted here... */ 30 something = tux[smp_processor_id()]; 31 32 First, since the data is per-CPU, it may not h 33 require it otherwise. Second, when a preempte 34 the previous value of smp_processor_id may not 35 protect these situations by disabling preempti 36 37 You can also use put_cpu() and get_cpu(), whic 38 39 40 RULE #2: CPU state must be protected. 41 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 42 43 44 Under preemption, the state of the CPU must be 45 dependent, but includes CPU structures and sta 46 switch. For example, on x86, entering and exi 47 section that must occur while preemption is di 48 if the kernel is executing a floating-point in 49 Remember, the kernel does not save FPU state e 50 upon preemption, the FPU registers will be sol 51 preemption must be disabled around such region 52 53 Note, some FPU functions are already explicitl 54 kernel_fpu_begin and kernel_fpu_end will disab 55 56 57 RULE #3: Lock acquire and release must be perf 58 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 59 60 61 A lock acquired in one task must be released b 62 means you can't do oddball things like acquire 63 play while another task releases it. If you w 64 like this, acquire and release the task in the 65 have the caller wait on an event by the other 66 67 68 Solution 69 ======== 70 71 72 Data protection under preemption is achieved b 73 duration of the critical region. 74 75 :: 76 77 preempt_enable() decrement the 78 preempt_disable() increment the 79 preempt_enable_no_resched() decrement, but 80 preempt_check_resched() if needed, res 81 preempt_count() return the pre 82 83 The functions are nestable. In other words, y 84 n-times in a code path, and preemption will no 85 call to preempt_enable. The preempt statement 86 preemption is not enabled. 87 88 Note that you do not need to explicitly preven 89 any locks or interrupts are disabled, since pr 90 in those cases. 91 92 But keep in mind that 'irqs disabled' is a fun 93 disabling preemption - any cond_resched() or c 94 a reschedule if the preempt count is 0. A simp 95 reschedule. So use this implicit preemption-di 96 know that the affected codepath does not do an 97 this only for small, atomic code that you wrot 98 functions. 99 100 Example:: 101 102 cpucache_t *cc; /* this is per-CPU */ 103 preempt_disable(); 104 cc = cc_data(searchp); 105 if (cc && cc->avail) { 106 __free_block(searchp, cc_entry 107 cc->avail = 0; 108 } 109 preempt_enable(); 110 return 0; 111 112 Notice how the preemption statements must enco 113 critical variables. Another example:: 114 115 int buf[NR_CPUS]; 116 set_cpu_val(buf); 117 if (buf[smp_processor_id()] == -1) pri 118 spin_lock(&buf_lock); 119 /* ... */ 120 121 This code is not preempt-safe, but see how eas 122 moving the spin_lock up two lines. 123 124 125 Preventing preemption using interrupt disablin 126 ============================================== 127 128 129 It is possible to prevent a preemption event u 130 local_irq_save. Note, when doing so, you must 131 an event that would set need_resched and resul 132 in doubt, rely on locking or explicit preempti 133 134 Note in 2.5 interrupt disabling is now only pe 135 136 An additional concern is proper usage of local 137 These may be used to protect from preemption, 138 may be enabled, a test to see if preemption is 139 these are called from the spin_lock and read/w 140 is done. They may also be called within a spi 141 if they are ever called outside of this contex 142 be made. Do note that calls from interrupt con 143 are also protected by preemption locks and so 144 not check preemption.
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.