Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.0-rc6 145 lines 5.7 kB view raw
1=========================================================================== 2Proper Locking Under a Preemptible Kernel: Keeping Kernel Code Preempt-Safe 3=========================================================================== 4 5:Author: Robert Love <rml@tech9.net> 6 7 8Introduction 9============ 10 11 12A preemptible kernel creates new locking issues. The issues are the same as 13those under SMP: concurrency and reentrancy. Thankfully, the Linux preemptible 14kernel model leverages existing SMP locking mechanisms. Thus, the kernel 15requires explicit additional locking for very few additional situations. 16 17This document is for all kernel hackers. Developing code in the kernel 18requires protecting these situations. 19 20 21RULE #1: Per-CPU data structures need explicit protection 22^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 23 24 25Two similar problems arise. An example code snippet:: 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 32First, since the data is per-CPU, it may not have explicit SMP locking, but 33require it otherwise. Second, when a preempted task is finally rescheduled, 34the previous value of smp_processor_id may not equal the current. You must 35protect these situations by disabling preemption around them. 36 37You can also use put_cpu() and get_cpu(), which will disable preemption. 38 39 40RULE #2: CPU state must be protected. 41^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 42 43 44Under preemption, the state of the CPU must be protected. This is arch- 45dependent, but includes CPU structures and state not preserved over a context 46switch. For example, on x86, entering and exiting FPU mode is now a critical 47section that must occur while preemption is disabled. Think what would happen 48if the kernel is executing a floating-point instruction and is then preempted. 49Remember, the kernel does not save FPU state except for user tasks. Therefore, 50upon preemption, the FPU registers will be sold to the lowest bidder. Thus, 51preemption must be disabled around such regions. 52 53Note, some FPU functions are already explicitly preempt safe. For example, 54kernel_fpu_begin and kernel_fpu_end will disable and enable preemption. 55However, fpu__restore() must be called with preemption disabled. 56 57 58RULE #3: Lock acquire and release must be performed by same task 59^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 60 61 62A lock acquired in one task must be released by the same task. This 63means you can't do oddball things like acquire a lock and go off to 64play while another task releases it. If you want to do something 65like this, acquire and release the task in the same code path and 66have the caller wait on an event by the other task. 67 68 69Solution 70======== 71 72 73Data protection under preemption is achieved by disabling preemption for the 74duration of the critical region. 75 76:: 77 78 preempt_enable() decrement the preempt counter 79 preempt_disable() increment the preempt counter 80 preempt_enable_no_resched() decrement, but do not immediately preempt 81 preempt_check_resched() if needed, reschedule 82 preempt_count() return the preempt counter 83 84The functions are nestable. In other words, you can call preempt_disable 85n-times in a code path, and preemption will not be reenabled until the n-th 86call to preempt_enable. The preempt statements define to nothing if 87preemption is not enabled. 88 89Note that you do not need to explicitly prevent preemption if you are holding 90any locks or interrupts are disabled, since preemption is implicitly disabled 91in those cases. 92 93But keep in mind that 'irqs disabled' is a fundamentally unsafe way of 94disabling preemption - any cond_resched() or cond_resched_lock() might trigger 95a reschedule if the preempt count is 0. A simple printk() might trigger a 96reschedule. So use this implicit preemption-disabling property only if you 97know that the affected codepath does not do any of this. Best policy is to use 98this only for small, atomic code that you wrote and which calls no complex 99functions. 100 101Example:: 102 103 cpucache_t *cc; /* this is per-CPU */ 104 preempt_disable(); 105 cc = cc_data(searchp); 106 if (cc && cc->avail) { 107 __free_block(searchp, cc_entry(cc), cc->avail); 108 cc->avail = 0; 109 } 110 preempt_enable(); 111 return 0; 112 113Notice how the preemption statements must encompass every reference of the 114critical variables. Another example:: 115 116 int buf[NR_CPUS]; 117 set_cpu_val(buf); 118 if (buf[smp_processor_id()] == -1) printf(KERN_INFO "wee!\n"); 119 spin_lock(&buf_lock); 120 /* ... */ 121 122This code is not preempt-safe, but see how easily we can fix it by simply 123moving the spin_lock up two lines. 124 125 126Preventing preemption using interrupt disabling 127=============================================== 128 129 130It is possible to prevent a preemption event using local_irq_disable and 131local_irq_save. Note, when doing so, you must be very careful to not cause 132an event that would set need_resched and result in a preemption check. When 133in doubt, rely on locking or explicit preemption disabling. 134 135Note in 2.5 interrupt disabling is now only per-CPU (e.g. local). 136 137An additional concern is proper usage of local_irq_disable and local_irq_save. 138These may be used to protect from preemption, however, on exit, if preemption 139may be enabled, a test to see if preemption is required should be done. If 140these are called from the spin_lock and read/write lock macros, the right thing 141is done. They may also be called within a spin-lock protected region, however, 142if they are ever called outside of this context, a test for preemption should 143be made. Do note that calls from interrupt context or bottom half/ tasklets 144are also protected by preemption locks and so may use the versions which do 145not check preemption.