1 #ifndef __LINUX_PREEMPT_H 2 #define __LINUX_PREEMPT_H 3 4 /* 5 * include/linux/preempt.h - macros for accessing and manipulating 6 * preempt_count (used for kernel preemption, interrupt count, etc.) 7 */ 8 9 #include <linux/thread_info.h> 10 #include <linux/linkage.h> 11 #include <linux/list.h> 12 13 #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER) 14 extern void add_preempt_count(int val); 15 extern void sub_preempt_count(int val); 16 #else 17 # define add_preempt_count(val) do { preempt_count() += (val); } while (0) 18 # define sub_preempt_count(val) do { preempt_count() -= (val); } while (0) 19 #endif 20 21 #define inc_preempt_count() add_preempt_count(1) 22 #define dec_preempt_count() sub_preempt_count(1) 23 24 #define preempt_count() (current_thread_info()->preempt_count) 25 26 #ifdef CONFIG_PREEMPT 27 28 asmlinkage void preempt_schedule(void); 29 30 #define preempt_check_resched() \ 31 do { \ 32 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ 33 preempt_schedule(); \ 34 } while (0) 35 36 #else /* !CONFIG_PREEMPT */ 37 38 #define preempt_check_resched() do { } while (0) 39 40 #endif /* CONFIG_PREEMPT */ 41 42 43 #ifdef CONFIG_PREEMPT_COUNT 44 45 #define preempt_disable() \ 46 do { \ 47 inc_preempt_count(); \ 48 barrier(); \ 49 } while (0) 50 51 #define sched_preempt_enable_no_resched() \ 52 do { \ 53 barrier(); \ 54 dec_preempt_count(); \ 55 } while (0) 56 57 #define preempt_enable_no_resched() sched_preempt_enable_no_resched() 58 59 #define preempt_enable() \ 60 do { \ 61 preempt_enable_no_resched(); \ 62 barrier(); \ 63 preempt_check_resched(); \ 64 } while (0) 65 66 /* For debugging and tracer internals only! */ 67 #define add_preempt_count_notrace(val) \ 68 do { preempt_count() += (val); } while (0) 69 #define sub_preempt_count_notrace(val) \ 70 do { preempt_count() -= (val); } while (0) 71 #define inc_preempt_count_notrace() add_preempt_count_notrace(1) 72 #define dec_preempt_count_notrace() sub_preempt_count_notrace(1) 73 74 #define preempt_disable_notrace() \ 75 do { \ 76 inc_preempt_count_notrace(); \ 77 barrier(); \ 78 } while (0) 79 80 #define preempt_enable_no_resched_notrace() \ 81 do { \ 82 barrier(); \ 83 dec_preempt_count_notrace(); \ 84 } while (0) 85 86 /* preempt_check_resched is OK to trace */ 87 #define preempt_enable_notrace() \ 88 do { \ 89 preempt_enable_no_resched_notrace(); \ 90 barrier(); \ 91 preempt_check_resched(); \ 92 } while (0) 93 94 #else /* !CONFIG_PREEMPT_COUNT */ 95 96 /* 97 * Even if we don't have any preemption, we need preempt disable/enable 98 * to be barriers, so that we don't have things like get_user/put_user 99 * that can cause faults and scheduling migrate into our preempt-protected 100 * region. 101 */ 102 #define preempt_disable() barrier() 103 #define sched_preempt_enable_no_resched() barrier() 104 #define preempt_enable_no_resched() barrier() 105 #define preempt_enable() barrier() 106 107 #define preempt_disable_notrace() barrier() 108 #define preempt_enable_no_resched_notrace() barrier() 109 #define preempt_enable_notrace() barrier() 110 111 #endif /* CONFIG_PREEMPT_COUNT */ 112 113 #ifdef CONFIG_PREEMPT_NOTIFIERS 114 115 struct preempt_notifier; 116 117 /** 118 * preempt_ops - notifiers called when a task is preempted and rescheduled 119 * @sched_in: we're about to be rescheduled: 120 * notifier: struct preempt_notifier for the task being scheduled 121 * cpu: cpu we're scheduled on 122 * @sched_out: we've just been preempted 123 * notifier: struct preempt_notifier for the task being preempted 124 * next: the task that's kicking us out 125 * 126 * Please note that sched_in and out are called under different 127 * contexts. sched_out is called with rq lock held and irq disabled 128 * while sched_in is called without rq lock and irq enabled. This 129 * difference is intentional and depended upon by its users. 130 */ 131 struct preempt_ops { 132 void (*sched_in)(struct preempt_notifier *notifier, int cpu); 133 void (*sched_out)(struct preempt_notifier *notifier, 134 struct task_struct *next); 135 }; 136 137 /** 138 * preempt_notifier - key for installing preemption notifiers 139 * @link: internal use 140 * @ops: defines the notifier functions to be called 141 * 142 * Usually used in conjunction with container_of(). 143 */ 144 struct preempt_notifier { 145 struct hlist_node link; 146 struct preempt_ops *ops; 147 }; 148 149 void preempt_notifier_register(struct preempt_notifier *notifier); 150 void preempt_notifier_unregister(struct preempt_notifier *notifier); 151 preempt_notifier_init(struct preempt_notifier * notifier,struct preempt_ops * ops)152static inline void preempt_notifier_init(struct preempt_notifier *notifier, 153 struct preempt_ops *ops) 154 { 155 INIT_HLIST_NODE(¬ifier->link); 156 notifier->ops = ops; 157 } 158 159 #endif 160 161 #endif /* __LINUX_PREEMPT_H */ 162