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_disable() \ 31 do { \ 32 inc_preempt_count(); \ 33 barrier(); \ 34 } while (0) 35 36 #define preempt_enable_no_resched() \ 37 do { \ 38 barrier(); \ 39 dec_preempt_count(); \ 40 } while (0) 41 42 #define preempt_check_resched() \ 43 do { \ 44 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ 45 preempt_schedule(); \ 46 } while (0) 47 48 #define preempt_enable() \ 49 do { \ 50 preempt_enable_no_resched(); \ 51 barrier(); \ 52 preempt_check_resched(); \ 53 } while (0) 54 55 /* For debugging and tracer internals only! */ 56 #define add_preempt_count_notrace(val) \ 57 do { preempt_count() += (val); } while (0) 58 #define sub_preempt_count_notrace(val) \ 59 do { preempt_count() -= (val); } while (0) 60 #define inc_preempt_count_notrace() add_preempt_count_notrace(1) 61 #define dec_preempt_count_notrace() sub_preempt_count_notrace(1) 62 63 #define preempt_disable_notrace() \ 64 do { \ 65 inc_preempt_count_notrace(); \ 66 barrier(); \ 67 } while (0) 68 69 #define preempt_enable_no_resched_notrace() \ 70 do { \ 71 barrier(); \ 72 dec_preempt_count_notrace(); \ 73 } while (0) 74 75 /* preempt_check_resched is OK to trace */ 76 #define preempt_enable_notrace() \ 77 do { \ 78 preempt_enable_no_resched_notrace(); \ 79 barrier(); \ 80 preempt_check_resched(); \ 81 } while (0) 82 83 #else 84 85 #define preempt_disable() do { } while (0) 86 #define preempt_enable_no_resched() do { } while (0) 87 #define preempt_enable() do { } while (0) 88 #define preempt_check_resched() do { } while (0) 89 90 #define preempt_disable_notrace() do { } while (0) 91 #define preempt_enable_no_resched_notrace() do { } while (0) 92 #define preempt_enable_notrace() do { } while (0) 93 94 #endif 95 96 #ifdef CONFIG_PREEMPT_NOTIFIERS 97 98 struct preempt_notifier; 99 100 /** 101 * preempt_ops - notifiers called when a task is preempted and rescheduled 102 * @sched_in: we're about to be rescheduled: 103 * notifier: struct preempt_notifier for the task being scheduled 104 * cpu: cpu we're scheduled on 105 * @sched_out: we've just been preempted 106 * notifier: struct preempt_notifier for the task being preempted 107 * next: the task that's kicking us out 108 * 109 * Please note that sched_in and out are called under different 110 * contexts. sched_out is called with rq lock held and irq disabled 111 * while sched_in is called without rq lock and irq enabled. This 112 * difference is intentional and depended upon by its users. 113 */ 114 struct preempt_ops { 115 void (*sched_in)(struct preempt_notifier *notifier, int cpu); 116 void (*sched_out)(struct preempt_notifier *notifier, 117 struct task_struct *next); 118 }; 119 120 /** 121 * preempt_notifier - key for installing preemption notifiers 122 * @link: internal use 123 * @ops: defines the notifier functions to be called 124 * 125 * Usually used in conjunction with container_of(). 126 */ 127 struct preempt_notifier { 128 struct hlist_node link; 129 struct preempt_ops *ops; 130 }; 131 132 void preempt_notifier_register(struct preempt_notifier *notifier); 133 void preempt_notifier_unregister(struct preempt_notifier *notifier); 134 preempt_notifier_init(struct preempt_notifier * notifier,struct preempt_ops * ops)135static inline void preempt_notifier_init(struct preempt_notifier *notifier, 136 struct preempt_ops *ops) 137 { 138 INIT_HLIST_NODE(¬ifier->link); 139 notifier->ops = ops; 140 } 141 142 #endif 143 144 #endif /* __LINUX_PREEMPT_H */ 145