diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/bottom_half.h | 32 | ||||
-rw-r--r-- | include/linux/hardirq.h | 1 | ||||
-rw-r--r-- | include/linux/init_task.h | 10 | ||||
-rw-r--r-- | include/linux/preempt.h | 37 | ||||
-rw-r--r-- | include/linux/preempt_mask.h | 16 | ||||
-rw-r--r-- | include/linux/rtmutex.h | 18 | ||||
-rw-r--r-- | include/linux/rwlock_api_smp.h | 12 | ||||
-rw-r--r-- | include/linux/sched.h | 141 | ||||
-rw-r--r-- | include/linux/sched/deadline.h | 24 | ||||
-rw-r--r-- | include/linux/sched/rt.h | 5 | ||||
-rw-r--r-- | include/linux/sched/sysctl.h | 1 | ||||
-rw-r--r-- | include/linux/spinlock_api_smp.h | 12 | ||||
-rw-r--r-- | include/linux/spinlock_api_up.h | 16 | ||||
-rw-r--r-- | include/linux/syscalls.h | 6 | ||||
-rw-r--r-- | include/linux/uaccess.h | 5 |
15 files changed, 291 insertions, 45 deletions
diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h index 27b1bcffe408..86c12c93e3cf 100644 --- a/include/linux/bottom_half.h +++ b/include/linux/bottom_half.h | |||
@@ -1,9 +1,35 @@ | |||
1 | #ifndef _LINUX_BH_H | 1 | #ifndef _LINUX_BH_H |
2 | #define _LINUX_BH_H | 2 | #define _LINUX_BH_H |
3 | 3 | ||
4 | extern void local_bh_disable(void); | 4 | #include <linux/preempt.h> |
5 | #include <linux/preempt_mask.h> | ||
6 | |||
7 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
8 | extern void __local_bh_disable_ip(unsigned long ip, unsigned int cnt); | ||
9 | #else | ||
10 | static __always_inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt) | ||
11 | { | ||
12 | preempt_count_add(cnt); | ||
13 | barrier(); | ||
14 | } | ||
15 | #endif | ||
16 | |||
17 | static inline void local_bh_disable(void) | ||
18 | { | ||
19 | __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ||
20 | } | ||
21 | |||
5 | extern void _local_bh_enable(void); | 22 | extern void _local_bh_enable(void); |
6 | extern void local_bh_enable(void); | 23 | extern void __local_bh_enable_ip(unsigned long ip, unsigned int cnt); |
7 | extern void local_bh_enable_ip(unsigned long ip); | 24 | |
25 | static inline void local_bh_enable_ip(unsigned long ip) | ||
26 | { | ||
27 | __local_bh_enable_ip(ip, SOFTIRQ_DISABLE_OFFSET); | ||
28 | } | ||
29 | |||
30 | static inline void local_bh_enable(void) | ||
31 | { | ||
32 | __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ||
33 | } | ||
8 | 34 | ||
9 | #endif /* _LINUX_BH_H */ | 35 | #endif /* _LINUX_BH_H */ |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index d9cf963ac832..12d5f972f23f 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/lockdep.h> | 5 | #include <linux/lockdep.h> |
6 | #include <linux/ftrace_irq.h> | 6 | #include <linux/ftrace_irq.h> |
7 | #include <linux/vtime.h> | 7 | #include <linux/vtime.h> |
8 | #include <asm/hardirq.h> | ||
8 | 9 | ||
9 | 10 | ||
10 | extern void synchronize_irq(unsigned int irq); | 11 | extern void synchronize_irq(unsigned int irq); |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index b0ed422e4e4a..f0e52383a001 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/user_namespace.h> | 11 | #include <linux/user_namespace.h> |
12 | #include <linux/securebits.h> | 12 | #include <linux/securebits.h> |
13 | #include <linux/seqlock.h> | 13 | #include <linux/seqlock.h> |
14 | #include <linux/rbtree.h> | ||
14 | #include <net/net_namespace.h> | 15 | #include <net/net_namespace.h> |
15 | #include <linux/sched/rt.h> | 16 | #include <linux/sched/rt.h> |
16 | 17 | ||
@@ -154,6 +155,14 @@ extern struct task_group root_task_group; | |||
154 | 155 | ||
155 | #define INIT_TASK_COMM "swapper" | 156 | #define INIT_TASK_COMM "swapper" |
156 | 157 | ||
158 | #ifdef CONFIG_RT_MUTEXES | ||
159 | # define INIT_RT_MUTEXES(tsk) \ | ||
160 | .pi_waiters = RB_ROOT, \ | ||
161 | .pi_waiters_leftmost = NULL, | ||
162 | #else | ||
163 | # define INIT_RT_MUTEXES(tsk) | ||
164 | #endif | ||
165 | |||
157 | /* | 166 | /* |
158 | * INIT_TASK is used to set up the first task table, touch at | 167 | * INIT_TASK is used to set up the first task table, touch at |
159 | * your own risk!. Base=0, limit=0x1fffff (=2MB) | 168 | * your own risk!. Base=0, limit=0x1fffff (=2MB) |
@@ -221,6 +230,7 @@ extern struct task_group root_task_group; | |||
221 | INIT_TRACE_RECURSION \ | 230 | INIT_TRACE_RECURSION \ |
222 | INIT_TASK_RCU_PREEMPT(tsk) \ | 231 | INIT_TASK_RCU_PREEMPT(tsk) \ |
223 | INIT_CPUSET_SEQ(tsk) \ | 232 | INIT_CPUSET_SEQ(tsk) \ |
233 | INIT_RT_MUTEXES(tsk) \ | ||
224 | INIT_VTIME(tsk) \ | 234 | INIT_VTIME(tsk) \ |
225 | } | 235 | } |
226 | 236 | ||
diff --git a/include/linux/preempt.h b/include/linux/preempt.h index a3d9dc8c2c00..59749fc48328 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h | |||
@@ -64,7 +64,11 @@ do { \ | |||
64 | } while (0) | 64 | } while (0) |
65 | 65 | ||
66 | #else | 66 | #else |
67 | #define preempt_enable() preempt_enable_no_resched() | 67 | #define preempt_enable() \ |
68 | do { \ | ||
69 | barrier(); \ | ||
70 | preempt_count_dec(); \ | ||
71 | } while (0) | ||
68 | #define preempt_check_resched() do { } while (0) | 72 | #define preempt_check_resched() do { } while (0) |
69 | #endif | 73 | #endif |
70 | 74 | ||
@@ -93,7 +97,11 @@ do { \ | |||
93 | __preempt_schedule_context(); \ | 97 | __preempt_schedule_context(); \ |
94 | } while (0) | 98 | } while (0) |
95 | #else | 99 | #else |
96 | #define preempt_enable_notrace() preempt_enable_no_resched_notrace() | 100 | #define preempt_enable_notrace() \ |
101 | do { \ | ||
102 | barrier(); \ | ||
103 | __preempt_count_dec(); \ | ||
104 | } while (0) | ||
97 | #endif | 105 | #endif |
98 | 106 | ||
99 | #else /* !CONFIG_PREEMPT_COUNT */ | 107 | #else /* !CONFIG_PREEMPT_COUNT */ |
@@ -116,6 +124,31 @@ do { \ | |||
116 | 124 | ||
117 | #endif /* CONFIG_PREEMPT_COUNT */ | 125 | #endif /* CONFIG_PREEMPT_COUNT */ |
118 | 126 | ||
127 | #ifdef MODULE | ||
128 | /* | ||
129 | * Modules have no business playing preemption tricks. | ||
130 | */ | ||
131 | #undef sched_preempt_enable_no_resched | ||
132 | #undef preempt_enable_no_resched | ||
133 | #undef preempt_enable_no_resched_notrace | ||
134 | #undef preempt_check_resched | ||
135 | #endif | ||
136 | |||
137 | #ifdef CONFIG_PREEMPT | ||
138 | #define preempt_set_need_resched() \ | ||
139 | do { \ | ||
140 | set_preempt_need_resched(); \ | ||
141 | } while (0) | ||
142 | #define preempt_fold_need_resched() \ | ||
143 | do { \ | ||
144 | if (tif_need_resched()) \ | ||
145 | set_preempt_need_resched(); \ | ||
146 | } while (0) | ||
147 | #else | ||
148 | #define preempt_set_need_resched() do { } while (0) | ||
149 | #define preempt_fold_need_resched() do { } while (0) | ||
150 | #endif | ||
151 | |||
119 | #ifdef CONFIG_PREEMPT_NOTIFIERS | 152 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
120 | 153 | ||
121 | struct preempt_notifier; | 154 | struct preempt_notifier; |
diff --git a/include/linux/preempt_mask.h b/include/linux/preempt_mask.h index d169820203dd..dbeec4d4a3be 100644 --- a/include/linux/preempt_mask.h +++ b/include/linux/preempt_mask.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define LINUX_PREEMPT_MASK_H | 2 | #define LINUX_PREEMPT_MASK_H |
3 | 3 | ||
4 | #include <linux/preempt.h> | 4 | #include <linux/preempt.h> |
5 | #include <asm/hardirq.h> | ||
6 | 5 | ||
7 | /* | 6 | /* |
8 | * We put the hardirq and softirq counter into the preemption | 7 | * We put the hardirq and softirq counter into the preemption |
@@ -79,6 +78,21 @@ | |||
79 | #endif | 78 | #endif |
80 | 79 | ||
81 | /* | 80 | /* |
81 | * The preempt_count offset needed for things like: | ||
82 | * | ||
83 | * spin_lock_bh() | ||
84 | * | ||
85 | * Which need to disable both preemption (CONFIG_PREEMPT_COUNT) and | ||
86 | * softirqs, such that unlock sequences of: | ||
87 | * | ||
88 | * spin_unlock(); | ||
89 | * local_bh_enable(); | ||
90 | * | ||
91 | * Work as expected. | ||
92 | */ | ||
93 | #define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_CHECK_OFFSET) | ||
94 | |||
95 | /* | ||
82 | * Are we running in atomic context? WARNING: this macro cannot | 96 | * Are we running in atomic context? WARNING: this macro cannot |
83 | * always detect atomic context; in particular, it cannot know about | 97 | * always detect atomic context; in particular, it cannot know about |
84 | * held spinlocks in non-preemptible kernels. Thus it should not be | 98 | * held spinlocks in non-preemptible kernels. Thus it should not be |
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index de17134244f3..3aed8d737e1a 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define __LINUX_RT_MUTEX_H | 13 | #define __LINUX_RT_MUTEX_H |
14 | 14 | ||
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <linux/plist.h> | 16 | #include <linux/rbtree.h> |
17 | #include <linux/spinlock_types.h> | 17 | #include <linux/spinlock_types.h> |
18 | 18 | ||
19 | extern int max_lock_depth; /* for sysctl */ | 19 | extern int max_lock_depth; /* for sysctl */ |
@@ -22,12 +22,14 @@ extern int max_lock_depth; /* for sysctl */ | |||
22 | * The rt_mutex structure | 22 | * The rt_mutex structure |
23 | * | 23 | * |
24 | * @wait_lock: spinlock to protect the structure | 24 | * @wait_lock: spinlock to protect the structure |
25 | * @wait_list: pilist head to enqueue waiters in priority order | 25 | * @waiters: rbtree root to enqueue waiters in priority order |
26 | * @waiters_leftmost: top waiter | ||
26 | * @owner: the mutex owner | 27 | * @owner: the mutex owner |
27 | */ | 28 | */ |
28 | struct rt_mutex { | 29 | struct rt_mutex { |
29 | raw_spinlock_t wait_lock; | 30 | raw_spinlock_t wait_lock; |
30 | struct plist_head wait_list; | 31 | struct rb_root waiters; |
32 | struct rb_node *waiters_leftmost; | ||
31 | struct task_struct *owner; | 33 | struct task_struct *owner; |
32 | #ifdef CONFIG_DEBUG_RT_MUTEXES | 34 | #ifdef CONFIG_DEBUG_RT_MUTEXES |
33 | int save_state; | 35 | int save_state; |
@@ -66,7 +68,7 @@ struct hrtimer_sleeper; | |||
66 | 68 | ||
67 | #define __RT_MUTEX_INITIALIZER(mutexname) \ | 69 | #define __RT_MUTEX_INITIALIZER(mutexname) \ |
68 | { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ | 70 | { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ |
69 | , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list) \ | 71 | , .waiters = RB_ROOT \ |
70 | , .owner = NULL \ | 72 | , .owner = NULL \ |
71 | __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} | 73 | __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} |
72 | 74 | ||
@@ -98,12 +100,4 @@ extern int rt_mutex_trylock(struct rt_mutex *lock); | |||
98 | 100 | ||
99 | extern void rt_mutex_unlock(struct rt_mutex *lock); | 101 | extern void rt_mutex_unlock(struct rt_mutex *lock); |
100 | 102 | ||
101 | #ifdef CONFIG_RT_MUTEXES | ||
102 | # define INIT_RT_MUTEXES(tsk) \ | ||
103 | .pi_waiters = PLIST_HEAD_INIT(tsk.pi_waiters), \ | ||
104 | INIT_RT_MUTEX_DEBUG(tsk) | ||
105 | #else | ||
106 | # define INIT_RT_MUTEXES(tsk) | ||
107 | #endif | ||
108 | |||
109 | #endif | 103 | #endif |
diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h index 9c9f0495d37c..5b9b84b20407 100644 --- a/include/linux/rwlock_api_smp.h +++ b/include/linux/rwlock_api_smp.h | |||
@@ -172,8 +172,7 @@ static inline void __raw_read_lock_irq(rwlock_t *lock) | |||
172 | 172 | ||
173 | static inline void __raw_read_lock_bh(rwlock_t *lock) | 173 | static inline void __raw_read_lock_bh(rwlock_t *lock) |
174 | { | 174 | { |
175 | local_bh_disable(); | 175 | __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
176 | preempt_disable(); | ||
177 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); | 176 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); |
178 | LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); | 177 | LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); |
179 | } | 178 | } |
@@ -200,8 +199,7 @@ static inline void __raw_write_lock_irq(rwlock_t *lock) | |||
200 | 199 | ||
201 | static inline void __raw_write_lock_bh(rwlock_t *lock) | 200 | static inline void __raw_write_lock_bh(rwlock_t *lock) |
202 | { | 201 | { |
203 | local_bh_disable(); | 202 | __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
204 | preempt_disable(); | ||
205 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); | 203 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); |
206 | LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); | 204 | LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); |
207 | } | 205 | } |
@@ -250,8 +248,7 @@ static inline void __raw_read_unlock_bh(rwlock_t *lock) | |||
250 | { | 248 | { |
251 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | 249 | rwlock_release(&lock->dep_map, 1, _RET_IP_); |
252 | do_raw_read_unlock(lock); | 250 | do_raw_read_unlock(lock); |
253 | preempt_enable_no_resched(); | 251 | __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
254 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | ||
255 | } | 252 | } |
256 | 253 | ||
257 | static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, | 254 | static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, |
@@ -275,8 +272,7 @@ static inline void __raw_write_unlock_bh(rwlock_t *lock) | |||
275 | { | 272 | { |
276 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | 273 | rwlock_release(&lock->dep_map, 1, _RET_IP_); |
277 | do_raw_write_unlock(lock); | 274 | do_raw_write_unlock(lock); |
278 | preempt_enable_no_resched(); | 275 | __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
279 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | ||
280 | } | 276 | } |
281 | 277 | ||
282 | #endif /* __LINUX_RWLOCK_API_SMP_H */ | 278 | #endif /* __LINUX_RWLOCK_API_SMP_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 53f97eb8dbc7..ffccdad050b5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -16,6 +16,7 @@ struct sched_param { | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/timex.h> | 17 | #include <linux/timex.h> |
18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
19 | #include <linux/plist.h> | ||
19 | #include <linux/rbtree.h> | 20 | #include <linux/rbtree.h> |
20 | #include <linux/thread_info.h> | 21 | #include <linux/thread_info.h> |
21 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
@@ -56,6 +57,70 @@ struct sched_param { | |||
56 | 57 | ||
57 | #include <asm/processor.h> | 58 | #include <asm/processor.h> |
58 | 59 | ||
60 | #define SCHED_ATTR_SIZE_VER0 48 /* sizeof first published struct */ | ||
61 | |||
62 | /* | ||
63 | * Extended scheduling parameters data structure. | ||
64 | * | ||
65 | * This is needed because the original struct sched_param can not be | ||
66 | * altered without introducing ABI issues with legacy applications | ||
67 | * (e.g., in sched_getparam()). | ||
68 | * | ||
69 | * However, the possibility of specifying more than just a priority for | ||
70 | * the tasks may be useful for a wide variety of application fields, e.g., | ||
71 | * multimedia, streaming, automation and control, and many others. | ||
72 | * | ||
73 | * This variant (sched_attr) is meant at describing a so-called | ||
74 | * sporadic time-constrained task. In such model a task is specified by: | ||
75 | * - the activation period or minimum instance inter-arrival time; | ||
76 | * - the maximum (or average, depending on the actual scheduling | ||
77 | * discipline) computation time of all instances, a.k.a. runtime; | ||
78 | * - the deadline (relative to the actual activation time) of each | ||
79 | * instance. | ||
80 | * Very briefly, a periodic (sporadic) task asks for the execution of | ||
81 | * some specific computation --which is typically called an instance-- | ||
82 | * (at most) every period. Moreover, each instance typically lasts no more | ||
83 | * than the runtime and must be completed by time instant t equal to | ||
84 | * the instance activation time + the deadline. | ||
85 | * | ||
86 | * This is reflected by the actual fields of the sched_attr structure: | ||
87 | * | ||
88 | * @size size of the structure, for fwd/bwd compat. | ||
89 | * | ||
90 | * @sched_policy task's scheduling policy | ||
91 | * @sched_flags for customizing the scheduler behaviour | ||
92 | * @sched_nice task's nice value (SCHED_NORMAL/BATCH) | ||
93 | * @sched_priority task's static priority (SCHED_FIFO/RR) | ||
94 | * @sched_deadline representative of the task's deadline | ||
95 | * @sched_runtime representative of the task's runtime | ||
96 | * @sched_period representative of the task's period | ||
97 | * | ||
98 | * Given this task model, there are a multiplicity of scheduling algorithms | ||
99 | * and policies, that can be used to ensure all the tasks will make their | ||
100 | * timing constraints. | ||
101 | * | ||
102 | * As of now, the SCHED_DEADLINE policy (sched_dl scheduling class) is the | ||
103 | * only user of this new interface. More information about the algorithm | ||
104 | * available in the scheduling class file or in Documentation/. | ||
105 | */ | ||
106 | struct sched_attr { | ||
107 | u32 size; | ||
108 | |||
109 | u32 sched_policy; | ||
110 | u64 sched_flags; | ||
111 | |||
112 | /* SCHED_NORMAL, SCHED_BATCH */ | ||
113 | s32 sched_nice; | ||
114 | |||
115 | /* SCHED_FIFO, SCHED_RR */ | ||
116 | u32 sched_priority; | ||
117 | |||
118 | /* SCHED_DEADLINE */ | ||
119 | u64 sched_runtime; | ||
120 | u64 sched_deadline; | ||
121 | u64 sched_period; | ||
122 | }; | ||
123 | |||
59 | struct exec_domain; | 124 | struct exec_domain; |
60 | struct futex_pi_state; | 125 | struct futex_pi_state; |
61 | struct robust_list_head; | 126 | struct robust_list_head; |
@@ -168,7 +233,6 @@ extern char ___assert_task_state[1 - 2*!!( | |||
168 | 233 | ||
169 | #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) | 234 | #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) |
170 | #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) | 235 | #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) |
171 | #define task_is_dead(task) ((task)->exit_state != 0) | ||
172 | #define task_is_stopped_or_traced(task) \ | 236 | #define task_is_stopped_or_traced(task) \ |
173 | ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) | 237 | ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) |
174 | #define task_contributes_to_load(task) \ | 238 | #define task_contributes_to_load(task) \ |
@@ -1029,6 +1093,51 @@ struct sched_rt_entity { | |||
1029 | #endif | 1093 | #endif |
1030 | }; | 1094 | }; |
1031 | 1095 | ||
1096 | struct sched_dl_entity { | ||
1097 | struct rb_node rb_node; | ||
1098 | |||
1099 | /* | ||
1100 | * Original scheduling parameters. Copied here from sched_attr | ||
1101 | * during sched_setscheduler2(), they will remain the same until | ||
1102 | * the next sched_setscheduler2(). | ||
1103 | */ | ||
1104 | u64 dl_runtime; /* maximum runtime for each instance */ | ||
1105 | u64 dl_deadline; /* relative deadline of each instance */ | ||
1106 | u64 dl_period; /* separation of two instances (period) */ | ||
1107 | u64 dl_bw; /* dl_runtime / dl_deadline */ | ||
1108 | |||
1109 | /* | ||
1110 | * Actual scheduling parameters. Initialized with the values above, | ||
1111 | * they are continously updated during task execution. Note that | ||
1112 | * the remaining runtime could be < 0 in case we are in overrun. | ||
1113 | */ | ||
1114 | s64 runtime; /* remaining runtime for this instance */ | ||
1115 | u64 deadline; /* absolute deadline for this instance */ | ||
1116 | unsigned int flags; /* specifying the scheduler behaviour */ | ||
1117 | |||
1118 | /* | ||
1119 | * Some bool flags: | ||
1120 | * | ||
1121 | * @dl_throttled tells if we exhausted the runtime. If so, the | ||
1122 | * task has to wait for a replenishment to be performed at the | ||
1123 | * next firing of dl_timer. | ||
1124 | * | ||
1125 | * @dl_new tells if a new instance arrived. If so we must | ||
1126 | * start executing it with full runtime and reset its absolute | ||
1127 | * deadline; | ||
1128 | * | ||
1129 | * @dl_boosted tells if we are boosted due to DI. If so we are | ||
1130 | * outside bandwidth enforcement mechanism (but only until we | ||
1131 | * exit the critical section). | ||
1132 | */ | ||
1133 | int dl_throttled, dl_new, dl_boosted; | ||
1134 | |||
1135 | /* | ||
1136 | * Bandwidth enforcement timer. Each -deadline task has its | ||
1137 | * own bandwidth to be enforced, thus we need one timer per task. | ||
1138 | */ | ||
1139 | struct hrtimer dl_timer; | ||
1140 | }; | ||
1032 | 1141 | ||
1033 | struct rcu_node; | 1142 | struct rcu_node; |
1034 | 1143 | ||
@@ -1065,6 +1174,7 @@ struct task_struct { | |||
1065 | #ifdef CONFIG_CGROUP_SCHED | 1174 | #ifdef CONFIG_CGROUP_SCHED |
1066 | struct task_group *sched_task_group; | 1175 | struct task_group *sched_task_group; |
1067 | #endif | 1176 | #endif |
1177 | struct sched_dl_entity dl; | ||
1068 | 1178 | ||
1069 | #ifdef CONFIG_PREEMPT_NOTIFIERS | 1179 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
1070 | /* list of struct preempt_notifier: */ | 1180 | /* list of struct preempt_notifier: */ |
@@ -1098,6 +1208,7 @@ struct task_struct { | |||
1098 | struct list_head tasks; | 1208 | struct list_head tasks; |
1099 | #ifdef CONFIG_SMP | 1209 | #ifdef CONFIG_SMP |
1100 | struct plist_node pushable_tasks; | 1210 | struct plist_node pushable_tasks; |
1211 | struct rb_node pushable_dl_tasks; | ||
1101 | #endif | 1212 | #endif |
1102 | 1213 | ||
1103 | struct mm_struct *mm, *active_mm; | 1214 | struct mm_struct *mm, *active_mm; |
@@ -1249,9 +1360,12 @@ struct task_struct { | |||
1249 | 1360 | ||
1250 | #ifdef CONFIG_RT_MUTEXES | 1361 | #ifdef CONFIG_RT_MUTEXES |
1251 | /* PI waiters blocked on a rt_mutex held by this task */ | 1362 | /* PI waiters blocked on a rt_mutex held by this task */ |
1252 | struct plist_head pi_waiters; | 1363 | struct rb_root pi_waiters; |
1364 | struct rb_node *pi_waiters_leftmost; | ||
1253 | /* Deadlock detection and priority inheritance handling */ | 1365 | /* Deadlock detection and priority inheritance handling */ |
1254 | struct rt_mutex_waiter *pi_blocked_on; | 1366 | struct rt_mutex_waiter *pi_blocked_on; |
1367 | /* Top pi_waiters task */ | ||
1368 | struct task_struct *pi_top_task; | ||
1255 | #endif | 1369 | #endif |
1256 | 1370 | ||
1257 | #ifdef CONFIG_DEBUG_MUTEXES | 1371 | #ifdef CONFIG_DEBUG_MUTEXES |
@@ -1880,7 +1994,9 @@ static inline void sched_clock_idle_wakeup_event(u64 delta_ns) | |||
1880 | * but then during bootup it turns out that sched_clock() | 1994 | * but then during bootup it turns out that sched_clock() |
1881 | * is reliable after all: | 1995 | * is reliable after all: |
1882 | */ | 1996 | */ |
1883 | extern int sched_clock_stable; | 1997 | extern int sched_clock_stable(void); |
1998 | extern void set_sched_clock_stable(void); | ||
1999 | extern void clear_sched_clock_stable(void); | ||
1884 | 2000 | ||
1885 | extern void sched_clock_tick(void); | 2001 | extern void sched_clock_tick(void); |
1886 | extern void sched_clock_idle_sleep_event(void); | 2002 | extern void sched_clock_idle_sleep_event(void); |
@@ -1959,6 +2075,8 @@ extern int sched_setscheduler(struct task_struct *, int, | |||
1959 | const struct sched_param *); | 2075 | const struct sched_param *); |
1960 | extern int sched_setscheduler_nocheck(struct task_struct *, int, | 2076 | extern int sched_setscheduler_nocheck(struct task_struct *, int, |
1961 | const struct sched_param *); | 2077 | const struct sched_param *); |
2078 | extern int sched_setattr(struct task_struct *, | ||
2079 | const struct sched_attr *); | ||
1962 | extern struct task_struct *idle_task(int cpu); | 2080 | extern struct task_struct *idle_task(int cpu); |
1963 | /** | 2081 | /** |
1964 | * is_idle_task - is the specified task an idle task? | 2082 | * is_idle_task - is the specified task an idle task? |
@@ -2038,7 +2156,7 @@ extern void wake_up_new_task(struct task_struct *tsk); | |||
2038 | #else | 2156 | #else |
2039 | static inline void kick_process(struct task_struct *tsk) { } | 2157 | static inline void kick_process(struct task_struct *tsk) { } |
2040 | #endif | 2158 | #endif |
2041 | extern void sched_fork(unsigned long clone_flags, struct task_struct *p); | 2159 | extern int sched_fork(unsigned long clone_flags, struct task_struct *p); |
2042 | extern void sched_dead(struct task_struct *p); | 2160 | extern void sched_dead(struct task_struct *p); |
2043 | 2161 | ||
2044 | extern void proc_caches_init(void); | 2162 | extern void proc_caches_init(void); |
@@ -2627,6 +2745,21 @@ static inline bool __must_check current_clr_polling_and_test(void) | |||
2627 | } | 2745 | } |
2628 | #endif | 2746 | #endif |
2629 | 2747 | ||
2748 | static inline void current_clr_polling(void) | ||
2749 | { | ||
2750 | __current_clr_polling(); | ||
2751 | |||
2752 | /* | ||
2753 | * Ensure we check TIF_NEED_RESCHED after we clear the polling bit. | ||
2754 | * Once the bit is cleared, we'll get IPIs with every new | ||
2755 | * TIF_NEED_RESCHED and the IPI handler, scheduler_ipi(), will also | ||
2756 | * fold. | ||
2757 | */ | ||
2758 | smp_mb(); /* paired with resched_task() */ | ||
2759 | |||
2760 | preempt_fold_need_resched(); | ||
2761 | } | ||
2762 | |||
2630 | static __always_inline bool need_resched(void) | 2763 | static __always_inline bool need_resched(void) |
2631 | { | 2764 | { |
2632 | return unlikely(tif_need_resched()); | 2765 | return unlikely(tif_need_resched()); |
diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h new file mode 100644 index 000000000000..9d303b8847df --- /dev/null +++ b/include/linux/sched/deadline.h | |||
@@ -0,0 +1,24 @@ | |||
1 | #ifndef _SCHED_DEADLINE_H | ||
2 | #define _SCHED_DEADLINE_H | ||
3 | |||
4 | /* | ||
5 | * SCHED_DEADLINE tasks has negative priorities, reflecting | ||
6 | * the fact that any of them has higher prio than RT and | ||
7 | * NORMAL/BATCH tasks. | ||
8 | */ | ||
9 | |||
10 | #define MAX_DL_PRIO 0 | ||
11 | |||
12 | static inline int dl_prio(int prio) | ||
13 | { | ||
14 | if (unlikely(prio < MAX_DL_PRIO)) | ||
15 | return 1; | ||
16 | return 0; | ||
17 | } | ||
18 | |||
19 | static inline int dl_task(struct task_struct *p) | ||
20 | { | ||
21 | return dl_prio(p->prio); | ||
22 | } | ||
23 | |||
24 | #endif /* _SCHED_DEADLINE_H */ | ||
diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h index 440434df3627..34e4ebea8fce 100644 --- a/include/linux/sched/rt.h +++ b/include/linux/sched/rt.h | |||
@@ -35,6 +35,7 @@ static inline int rt_task(struct task_struct *p) | |||
35 | #ifdef CONFIG_RT_MUTEXES | 35 | #ifdef CONFIG_RT_MUTEXES |
36 | extern int rt_mutex_getprio(struct task_struct *p); | 36 | extern int rt_mutex_getprio(struct task_struct *p); |
37 | extern void rt_mutex_setprio(struct task_struct *p, int prio); | 37 | extern void rt_mutex_setprio(struct task_struct *p, int prio); |
38 | extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task); | ||
38 | extern void rt_mutex_adjust_pi(struct task_struct *p); | 39 | extern void rt_mutex_adjust_pi(struct task_struct *p); |
39 | static inline bool tsk_is_pi_blocked(struct task_struct *tsk) | 40 | static inline bool tsk_is_pi_blocked(struct task_struct *tsk) |
40 | { | 41 | { |
@@ -45,6 +46,10 @@ static inline int rt_mutex_getprio(struct task_struct *p) | |||
45 | { | 46 | { |
46 | return p->normal_prio; | 47 | return p->normal_prio; |
47 | } | 48 | } |
49 | static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task) | ||
50 | { | ||
51 | return NULL; | ||
52 | } | ||
48 | # define rt_mutex_adjust_pi(p) do { } while (0) | 53 | # define rt_mutex_adjust_pi(p) do { } while (0) |
49 | static inline bool tsk_is_pi_blocked(struct task_struct *tsk) | 54 | static inline bool tsk_is_pi_blocked(struct task_struct *tsk) |
50 | { | 55 | { |
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 41467f8ff8ec..31e0193cb0c5 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h | |||
@@ -48,7 +48,6 @@ extern unsigned int sysctl_numa_balancing_scan_delay; | |||
48 | extern unsigned int sysctl_numa_balancing_scan_period_min; | 48 | extern unsigned int sysctl_numa_balancing_scan_period_min; |
49 | extern unsigned int sysctl_numa_balancing_scan_period_max; | 49 | extern unsigned int sysctl_numa_balancing_scan_period_max; |
50 | extern unsigned int sysctl_numa_balancing_scan_size; | 50 | extern unsigned int sysctl_numa_balancing_scan_size; |
51 | extern unsigned int sysctl_numa_balancing_settle_count; | ||
52 | 51 | ||
53 | #ifdef CONFIG_SCHED_DEBUG | 52 | #ifdef CONFIG_SCHED_DEBUG |
54 | extern unsigned int sysctl_sched_migration_cost; | 53 | extern unsigned int sysctl_sched_migration_cost; |
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index bdb9993f0fda..42dfab89e740 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h | |||
@@ -131,8 +131,7 @@ static inline void __raw_spin_lock_irq(raw_spinlock_t *lock) | |||
131 | 131 | ||
132 | static inline void __raw_spin_lock_bh(raw_spinlock_t *lock) | 132 | static inline void __raw_spin_lock_bh(raw_spinlock_t *lock) |
133 | { | 133 | { |
134 | local_bh_disable(); | 134 | __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
135 | preempt_disable(); | ||
136 | spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); | 135 | spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); |
137 | LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); | 136 | LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); |
138 | } | 137 | } |
@@ -174,20 +173,17 @@ static inline void __raw_spin_unlock_bh(raw_spinlock_t *lock) | |||
174 | { | 173 | { |
175 | spin_release(&lock->dep_map, 1, _RET_IP_); | 174 | spin_release(&lock->dep_map, 1, _RET_IP_); |
176 | do_raw_spin_unlock(lock); | 175 | do_raw_spin_unlock(lock); |
177 | preempt_enable_no_resched(); | 176 | __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
178 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | ||
179 | } | 177 | } |
180 | 178 | ||
181 | static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) | 179 | static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) |
182 | { | 180 | { |
183 | local_bh_disable(); | 181 | __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
184 | preempt_disable(); | ||
185 | if (do_raw_spin_trylock(lock)) { | 182 | if (do_raw_spin_trylock(lock)) { |
186 | spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); | 183 | spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); |
187 | return 1; | 184 | return 1; |
188 | } | 185 | } |
189 | preempt_enable_no_resched(); | 186 | __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); |
190 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | ||
191 | return 0; | 187 | return 0; |
192 | } | 188 | } |
193 | 189 | ||
diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index af1f47229e70..d0d188861ad6 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h | |||
@@ -24,11 +24,14 @@ | |||
24 | * flags straight, to suppress compiler warnings of unused lock | 24 | * flags straight, to suppress compiler warnings of unused lock |
25 | * variables, and to add the proper checker annotations: | 25 | * variables, and to add the proper checker annotations: |
26 | */ | 26 | */ |
27 | #define ___LOCK(lock) \ | ||
28 | do { __acquire(lock); (void)(lock); } while (0) | ||
29 | |||
27 | #define __LOCK(lock) \ | 30 | #define __LOCK(lock) \ |
28 | do { preempt_disable(); __acquire(lock); (void)(lock); } while (0) | 31 | do { preempt_disable(); ___LOCK(lock); } while (0) |
29 | 32 | ||
30 | #define __LOCK_BH(lock) \ | 33 | #define __LOCK_BH(lock) \ |
31 | do { local_bh_disable(); __LOCK(lock); } while (0) | 34 | do { __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_LOCK_OFFSET); ___LOCK(lock); } while (0) |
32 | 35 | ||
33 | #define __LOCK_IRQ(lock) \ | 36 | #define __LOCK_IRQ(lock) \ |
34 | do { local_irq_disable(); __LOCK(lock); } while (0) | 37 | do { local_irq_disable(); __LOCK(lock); } while (0) |
@@ -36,12 +39,15 @@ | |||
36 | #define __LOCK_IRQSAVE(lock, flags) \ | 39 | #define __LOCK_IRQSAVE(lock, flags) \ |
37 | do { local_irq_save(flags); __LOCK(lock); } while (0) | 40 | do { local_irq_save(flags); __LOCK(lock); } while (0) |
38 | 41 | ||
42 | #define ___UNLOCK(lock) \ | ||
43 | do { __release(lock); (void)(lock); } while (0) | ||
44 | |||
39 | #define __UNLOCK(lock) \ | 45 | #define __UNLOCK(lock) \ |
40 | do { preempt_enable(); __release(lock); (void)(lock); } while (0) | 46 | do { preempt_enable(); ___UNLOCK(lock); } while (0) |
41 | 47 | ||
42 | #define __UNLOCK_BH(lock) \ | 48 | #define __UNLOCK_BH(lock) \ |
43 | do { preempt_enable_no_resched(); local_bh_enable(); \ | 49 | do { __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_LOCK_OFFSET); \ |
44 | __release(lock); (void)(lock); } while (0) | 50 | ___UNLOCK(lock); } while (0) |
45 | 51 | ||
46 | #define __UNLOCK_IRQ(lock) \ | 52 | #define __UNLOCK_IRQ(lock) \ |
47 | do { local_irq_enable(); __UNLOCK(lock); } while (0) | 53 | do { local_irq_enable(); __UNLOCK(lock); } while (0) |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 94273bbe6050..40ed9e9a77e5 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -38,6 +38,7 @@ struct rlimit; | |||
38 | struct rlimit64; | 38 | struct rlimit64; |
39 | struct rusage; | 39 | struct rusage; |
40 | struct sched_param; | 40 | struct sched_param; |
41 | struct sched_attr; | ||
41 | struct sel_arg_struct; | 42 | struct sel_arg_struct; |
42 | struct semaphore; | 43 | struct semaphore; |
43 | struct sembuf; | 44 | struct sembuf; |
@@ -279,9 +280,14 @@ asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, | |||
279 | struct sched_param __user *param); | 280 | struct sched_param __user *param); |
280 | asmlinkage long sys_sched_setparam(pid_t pid, | 281 | asmlinkage long sys_sched_setparam(pid_t pid, |
281 | struct sched_param __user *param); | 282 | struct sched_param __user *param); |
283 | asmlinkage long sys_sched_setattr(pid_t pid, | ||
284 | struct sched_attr __user *attr); | ||
282 | asmlinkage long sys_sched_getscheduler(pid_t pid); | 285 | asmlinkage long sys_sched_getscheduler(pid_t pid); |
283 | asmlinkage long sys_sched_getparam(pid_t pid, | 286 | asmlinkage long sys_sched_getparam(pid_t pid, |
284 | struct sched_param __user *param); | 287 | struct sched_param __user *param); |
288 | asmlinkage long sys_sched_getattr(pid_t pid, | ||
289 | struct sched_attr __user *attr, | ||
290 | unsigned int size); | ||
285 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, | 291 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, |
286 | unsigned long __user *user_mask_ptr); | 292 | unsigned long __user *user_mask_ptr); |
287 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, | 293 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 9d8cf056e661..ecd3319dac33 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
@@ -25,13 +25,16 @@ static inline void pagefault_disable(void) | |||
25 | 25 | ||
26 | static inline void pagefault_enable(void) | 26 | static inline void pagefault_enable(void) |
27 | { | 27 | { |
28 | #ifndef CONFIG_PREEMPT | ||
28 | /* | 29 | /* |
29 | * make sure to issue those last loads/stores before enabling | 30 | * make sure to issue those last loads/stores before enabling |
30 | * the pagefault handler again. | 31 | * the pagefault handler again. |
31 | */ | 32 | */ |
32 | barrier(); | 33 | barrier(); |
33 | preempt_count_dec(); | 34 | preempt_count_dec(); |
34 | preempt_check_resched(); | 35 | #else |
36 | preempt_enable(); | ||
37 | #endif | ||
35 | } | 38 | } |
36 | 39 | ||
37 | #ifndef ARCH_HAS_NOCACHE_UACCESS | 40 | #ifndef ARCH_HAS_NOCACHE_UACCESS |