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 LOCAL_LOCK_DEBUG_INIT(lockname) \ 18 .dep_map = { \ 19 .name = #lockname, \ 20 .wait_type_inner = LD_WAIT_CONFIG, \ 21 .lock_type = LD_LOCK_PERCPU, \ 22 }, \ 23 .owner = NULL, 24 25 static inline void local_lock_acquire(local_lock_t *l) 26 { 27 lock_map_acquire(&l->dep_map); 28 DEBUG_LOCKS_WARN_ON(l->owner); 29 l->owner = current; 30 } 31 32 static inline void local_lock_release(local_lock_t *l) 33 { 34 DEBUG_LOCKS_WARN_ON(l->owner != current); 35 l->owner = NULL; 36 lock_map_release(&l->dep_map); 37 } 38 39 static inline void local_lock_debug_init(local_lock_t *l) 40 { 41 l->owner = NULL; 42 } 43 #else /* CONFIG_DEBUG_LOCK_ALLOC */ 44 # define LOCAL_LOCK_DEBUG_INIT(lockname) 45 static inline void local_lock_acquire(local_lock_t *l) { } 46 static inline void local_lock_release(local_lock_t *l) { } 47 static inline void local_lock_debug_init(local_lock_t *l) { } 48 #endif /* !CONFIG_DEBUG_LOCK_ALLOC */ 49 50 #define INIT_LOCAL_LOCK(lockname) { LOCAL_LOCK_DEBUG_INIT(lockname) } 51 52 #define __local_lock_init(lock) \ 53 do { \ 54 static struct lock_class_key __key; \ 55 \ 56 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\ 57 lockdep_init_map_type(&(lock)->dep_map, #lock, &__key, \ 58 0, LD_WAIT_CONFIG, LD_WAIT_INV, \ 59 LD_LOCK_PERCPU); \ 60 local_lock_debug_init(lock); \ 61 } while (0) 62 63 #define __local_lock(lock) \ 64 do { \ 65 preempt_disable(); \ 66 local_lock_acquire(this_cpu_ptr(lock)); \ 67 } while (0) 68 69 #define __local_lock_irq(lock) \ 70 do { \ 71 local_irq_disable(); \ 72 local_lock_acquire(this_cpu_ptr(lock)); \ 73 } while (0) 74 75 #define __local_lock_irqsave(lock, flags) \ 76 do { \ 77 local_irq_save(flags); \ 78 local_lock_acquire(this_cpu_ptr(lock)); \ 79 } while (0) 80 81 #define __local_unlock(lock) \ 82 do { \ 83 local_lock_release(this_cpu_ptr(lock)); \ 84 preempt_enable(); \ 85 } while (0) 86 87 #define __local_unlock_irq(lock) \ 88 do { \ 89 local_lock_release(this_cpu_ptr(lock)); \ 90 local_irq_enable(); \ 91 } while (0) 92 93 #define __local_unlock_irqrestore(lock, flags) \ 94 do { \ 95 local_lock_release(this_cpu_ptr(lock)); \ 96 local_irq_restore(flags); \ 97 } while (0) 98