1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_LOCAL_LOCK_H 3 # error "Do not include directly, include linux/local_lock.h" 4 #endif 5 6 #include <linux/percpu-defs.h> 7 #include <linux/lockdep.h> 8 9 typedef struct { 10 #ifdef CONFIG_DEBUG_LOCK_ALLOC 11 struct lockdep_map dep_map; 12 struct task_struct *owner; 13 #endif 14 } local_lock_t; 15 16 #ifdef CONFIG_DEBUG_LOCK_ALLOC 17 # define LL_DEP_MAP_INIT(lockname) \ 18 .dep_map = { \ 19 .name = #lockname, \ 20 .wait_type_inner = LD_WAIT_CONFIG, \ 21 } 22 #else 23 # define LL_DEP_MAP_INIT(lockname) 24 #endif 25 26 #define INIT_LOCAL_LOCK(lockname) { LL_DEP_MAP_INIT(lockname) } 27 28 #define __local_lock_init(lock) \ 29 do { \ 30 static struct lock_class_key __key; \ 31 \ 32 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\ 33 lockdep_init_map_wait(&(lock)->dep_map, #lock, &__key, 0, LD_WAIT_CONFIG);\ 34 } while (0) 35 36 #ifdef CONFIG_DEBUG_LOCK_ALLOC 37 static inline void local_lock_acquire(local_lock_t *l) 38 { 39 lock_map_acquire(&l->dep_map); 40 DEBUG_LOCKS_WARN_ON(l->owner); 41 l->owner = current; 42 } 43 44 static inline void local_lock_release(local_lock_t *l) 45 { 46 DEBUG_LOCKS_WARN_ON(l->owner != current); 47 l->owner = NULL; 48 lock_map_release(&l->dep_map); 49 } 50 51 #else /* CONFIG_DEBUG_LOCK_ALLOC */ 52 static inline void local_lock_acquire(local_lock_t *l) { } 53 static inline void local_lock_release(local_lock_t *l) { } 54 #endif /* !CONFIG_DEBUG_LOCK_ALLOC */ 55 56 #define __local_lock(lock) \ 57 do { \ 58 preempt_disable(); \ 59 local_lock_acquire(this_cpu_ptr(lock)); \ 60 } while (0) 61 62 #define __local_lock_irq(lock) \ 63 do { \ 64 local_irq_disable(); \ 65 local_lock_acquire(this_cpu_ptr(lock)); \ 66 } while (0) 67 68 #define __local_lock_irqsave(lock, flags) \ 69 do { \ 70 local_irq_save(flags); \ 71 local_lock_acquire(this_cpu_ptr(lock)); \ 72 } while (0) 73 74 #define __local_unlock(lock) \ 75 do { \ 76 local_lock_release(this_cpu_ptr(lock)); \ 77 preempt_enable(); \ 78 } while (0) 79 80 #define __local_unlock_irq(lock) \ 81 do { \ 82 local_lock_release(this_cpu_ptr(lock)); \ 83 local_irq_enable(); \ 84 } while (0) 85 86 #define __local_unlock_irqrestore(lock, flags) \ 87 do { \ 88 local_lock_release(this_cpu_ptr(lock)); \ 89 local_irq_restore(flags); \ 90 } while (0) 91