Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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 /* CONFIG_DEBUG_LOCK_ALLOC */
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 /* !CONFIG_DEBUG_LOCK_ALLOC */
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 /* !CONFIG_PREEMPT_RT */
0102 
0103 /*
0104  * On PREEMPT_RT local_lock maps to a per CPU spinlock, which protects the
0105  * critical section while staying preemptible.
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 /* CONFIG_PREEMPT_RT */