0001
0002 #ifndef _LINUX_LOCAL_LOCK_H
0003 # error "Do not include directly, include linux/local_lock.h"
0004 #endif
0005
0006 #include <linux/percpu-defs.h>
0007 #include <linux/lockdep.h>
0008
0009 #ifndef CONFIG_PREEMPT_RT
0010
0011 typedef struct {
0012 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0013 struct lockdep_map dep_map;
0014 struct task_struct *owner;
0015 #endif
0016 } local_lock_t;
0017
0018 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0019 # define LOCAL_LOCK_DEBUG_INIT(lockname) \
0020 .dep_map = { \
0021 .name = #lockname, \
0022 .wait_type_inner = LD_WAIT_CONFIG, \
0023 .lock_type = LD_LOCK_PERCPU, \
0024 }, \
0025 .owner = NULL,
0026
0027 static inline void local_lock_acquire(local_lock_t *l)
0028 {
0029 lock_map_acquire(&l->dep_map);
0030 DEBUG_LOCKS_WARN_ON(l->owner);
0031 l->owner = current;
0032 }
0033
0034 static inline void local_lock_release(local_lock_t *l)
0035 {
0036 DEBUG_LOCKS_WARN_ON(l->owner != current);
0037 l->owner = NULL;
0038 lock_map_release(&l->dep_map);
0039 }
0040
0041 static inline void local_lock_debug_init(local_lock_t *l)
0042 {
0043 l->owner = NULL;
0044 }
0045 #else
0046 # define LOCAL_LOCK_DEBUG_INIT(lockname)
0047 static inline void local_lock_acquire(local_lock_t *l) { }
0048 static inline void local_lock_release(local_lock_t *l) { }
0049 static inline void local_lock_debug_init(local_lock_t *l) { }
0050 #endif
0051
0052 #define INIT_LOCAL_LOCK(lockname) { LOCAL_LOCK_DEBUG_INIT(lockname) }
0053
0054 #define __local_lock_init(lock) \
0055 do { \
0056 static struct lock_class_key __key; \
0057 \
0058 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
0059 lockdep_init_map_type(&(lock)->dep_map, #lock, &__key, \
0060 0, LD_WAIT_CONFIG, LD_WAIT_INV, \
0061 LD_LOCK_PERCPU); \
0062 local_lock_debug_init(lock); \
0063 } while (0)
0064
0065 #define __local_lock(lock) \
0066 do { \
0067 preempt_disable(); \
0068 local_lock_acquire(this_cpu_ptr(lock)); \
0069 } while (0)
0070
0071 #define __local_lock_irq(lock) \
0072 do { \
0073 local_irq_disable(); \
0074 local_lock_acquire(this_cpu_ptr(lock)); \
0075 } while (0)
0076
0077 #define __local_lock_irqsave(lock, flags) \
0078 do { \
0079 local_irq_save(flags); \
0080 local_lock_acquire(this_cpu_ptr(lock)); \
0081 } while (0)
0082
0083 #define __local_unlock(lock) \
0084 do { \
0085 local_lock_release(this_cpu_ptr(lock)); \
0086 preempt_enable(); \
0087 } while (0)
0088
0089 #define __local_unlock_irq(lock) \
0090 do { \
0091 local_lock_release(this_cpu_ptr(lock)); \
0092 local_irq_enable(); \
0093 } while (0)
0094
0095 #define __local_unlock_irqrestore(lock, flags) \
0096 do { \
0097 local_lock_release(this_cpu_ptr(lock)); \
0098 local_irq_restore(flags); \
0099 } while (0)
0100
0101 #else
0102
0103
0104
0105
0106
0107 typedef spinlock_t local_lock_t;
0108
0109 #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
0110
0111 #define __local_lock_init(l) \
0112 do { \
0113 local_spin_lock_init((l)); \
0114 } while (0)
0115
0116 #define __local_lock(__lock) \
0117 do { \
0118 migrate_disable(); \
0119 spin_lock(this_cpu_ptr((__lock))); \
0120 } while (0)
0121
0122 #define __local_lock_irq(lock) __local_lock(lock)
0123
0124 #define __local_lock_irqsave(lock, flags) \
0125 do { \
0126 typecheck(unsigned long, flags); \
0127 flags = 0; \
0128 __local_lock(lock); \
0129 } while (0)
0130
0131 #define __local_unlock(__lock) \
0132 do { \
0133 spin_unlock(this_cpu_ptr((__lock))); \
0134 migrate_enable(); \
0135 } while (0)
0136
0137 #define __local_unlock_irq(lock) __local_unlock(lock)
0138
0139 #define __local_unlock_irqrestore(lock, flags) __local_unlock(lock)
0140
0141 #endif