1 /* 2 * lib/kernel_lock.c 3 * 4 * This is the traditional BKL - big kernel lock. Largely 5 * relegated to obsolescence, but used by various less 6 * important (or lazy) subsystems. 7 */ 8 #include <linux/smp_lock.h> 9 #include <linux/module.h> 10 #include <linux/kallsyms.h> 11 #include <linux/semaphore.h> 12 13 /* 14 * The 'big kernel lock' 15 * 16 * This spinlock is taken and released recursively by lock_kernel() 17 * and unlock_kernel(). It is transparently dropped and reacquired 18 * over schedule(). It is used to protect legacy code that hasn't 19 * been migrated to a proper locking design yet. 20 * 21 * Don't use in new code. 22 */ 23 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag); 24 25 26 /* 27 * Acquire/release the underlying lock from the scheduler. 28 * 29 * This is called with preemption disabled, and should 30 * return an error value if it cannot get the lock and 31 * TIF_NEED_RESCHED gets set. 32 * 33 * If it successfully gets the lock, it should increment 34 * the preemption count like any spinlock does. 35 * 36 * (This works on UP too - _raw_spin_trylock will never 37 * return false in that case) 38 */ __reacquire_kernel_lock(void)39int __lockfunc __reacquire_kernel_lock(void) 40 { 41 while (!_raw_spin_trylock(&kernel_flag)) { 42 if (test_thread_flag(TIF_NEED_RESCHED)) 43 return -EAGAIN; 44 cpu_relax(); 45 } 46 preempt_disable(); 47 return 0; 48 } 49 __release_kernel_lock(void)50void __lockfunc __release_kernel_lock(void) 51 { 52 _raw_spin_unlock(&kernel_flag); 53 preempt_enable_no_resched(); 54 } 55 56 /* 57 * These are the BKL spinlocks - we try to be polite about preemption. 58 * If SMP is not on (ie UP preemption), this all goes away because the 59 * _raw_spin_trylock() will always succeed. 60 */ 61 #ifdef CONFIG_PREEMPT __lock_kernel(void)62static inline void __lock_kernel(void) 63 { 64 preempt_disable(); 65 if (unlikely(!_raw_spin_trylock(&kernel_flag))) { 66 /* 67 * If preemption was disabled even before this 68 * was called, there's nothing we can be polite 69 * about - just spin. 70 */ 71 if (preempt_count() > 1) { 72 _raw_spin_lock(&kernel_flag); 73 return; 74 } 75 76 /* 77 * Otherwise, let's wait for the kernel lock 78 * with preemption enabled.. 79 */ 80 do { 81 preempt_enable(); 82 while (spin_is_locked(&kernel_flag)) 83 cpu_relax(); 84 preempt_disable(); 85 } while (!_raw_spin_trylock(&kernel_flag)); 86 } 87 } 88 89 #else 90 91 /* 92 * Non-preemption case - just get the spinlock 93 */ __lock_kernel(void)94static inline void __lock_kernel(void) 95 { 96 _raw_spin_lock(&kernel_flag); 97 } 98 #endif 99 __unlock_kernel(void)100static inline void __unlock_kernel(void) 101 { 102 /* 103 * the BKL is not covered by lockdep, so we open-code the 104 * unlocking sequence (and thus avoid the dep-chain ops): 105 */ 106 _raw_spin_unlock(&kernel_flag); 107 preempt_enable(); 108 } 109 110 /* 111 * Getting the big kernel lock. 112 * 113 * This cannot happen asynchronously, so we only need to 114 * worry about other CPU's. 115 */ lock_kernel(void)116void __lockfunc lock_kernel(void) 117 { 118 int depth = current->lock_depth+1; 119 if (likely(!depth)) 120 __lock_kernel(); 121 current->lock_depth = depth; 122 } 123 unlock_kernel(void)124void __lockfunc unlock_kernel(void) 125 { 126 BUG_ON(current->lock_depth < 0); 127 if (likely(--current->lock_depth < 0)) 128 __unlock_kernel(); 129 } 130 131 EXPORT_SYMBOL(lock_kernel); 132 EXPORT_SYMBOL(unlock_kernel); 133 134