diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-11-18 03:34:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-11-18 03:34:44 -0500 |
commit | ec05a2311c35243cea08bca00bcf53a576ee41a2 (patch) | |
tree | b6feae6520bdeeb40f5c08e509b108d84199db7b /kernel | |
parent | a7a0aaa17ace589897021d668e09d474e7fc4c4d (diff) | |
parent | 5258f386ea4e8454bc801fb443e8a4217da1947c (diff) |
Merge branch 'sched/urgent' into sched/core
Merge in fixes before we queue up dependent bits, to avoid conflicts.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/auto_group.c | 68 | ||||
-rw-r--r-- | kernel/sched/auto_group.h | 9 | ||||
-rw-r--r-- | kernel/sched/fair.c | 2 | ||||
-rw-r--r-- | kernel/sched/features.h | 5 | ||||
-rw-r--r-- | kernel/sysctl.c | 6 |
5 files changed, 20 insertions, 70 deletions
diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c index 0984a21076a3..0f1bacb005a4 100644 --- a/kernel/sched/auto_group.c +++ b/kernel/sched/auto_group.c | |||
@@ -110,6 +110,9 @@ out_fail: | |||
110 | 110 | ||
111 | bool task_wants_autogroup(struct task_struct *p, struct task_group *tg) | 111 | bool task_wants_autogroup(struct task_struct *p, struct task_group *tg) |
112 | { | 112 | { |
113 | if (!sysctl_sched_autogroup_enabled) | ||
114 | return false; | ||
115 | |||
113 | if (tg != &root_task_group) | 116 | if (tg != &root_task_group) |
114 | return false; | 117 | return false; |
115 | 118 | ||
@@ -143,15 +146,11 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) | |||
143 | 146 | ||
144 | p->signal->autogroup = autogroup_kref_get(ag); | 147 | p->signal->autogroup = autogroup_kref_get(ag); |
145 | 148 | ||
146 | if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled)) | ||
147 | goto out; | ||
148 | |||
149 | t = p; | 149 | t = p; |
150 | do { | 150 | do { |
151 | sched_move_task(t); | 151 | sched_move_task(t); |
152 | } while_each_thread(p, t); | 152 | } while_each_thread(p, t); |
153 | 153 | ||
154 | out: | ||
155 | unlock_task_sighand(p, &flags); | 154 | unlock_task_sighand(p, &flags); |
156 | autogroup_kref_put(prev); | 155 | autogroup_kref_put(prev); |
157 | } | 156 | } |
@@ -159,8 +158,11 @@ out: | |||
159 | /* Allocates GFP_KERNEL, cannot be called under any spinlock */ | 158 | /* Allocates GFP_KERNEL, cannot be called under any spinlock */ |
160 | void sched_autogroup_create_attach(struct task_struct *p) | 159 | void sched_autogroup_create_attach(struct task_struct *p) |
161 | { | 160 | { |
162 | struct autogroup *ag = autogroup_create(); | 161 | struct autogroup *ag; |
163 | 162 | ||
163 | if (!sysctl_sched_autogroup_enabled) | ||
164 | return; | ||
165 | ag = autogroup_create(); | ||
164 | autogroup_move_group(p, ag); | 166 | autogroup_move_group(p, ag); |
165 | /* drop extra reference added by autogroup_create() */ | 167 | /* drop extra reference added by autogroup_create() */ |
166 | autogroup_kref_put(ag); | 168 | autogroup_kref_put(ag); |
@@ -176,11 +178,15 @@ EXPORT_SYMBOL(sched_autogroup_detach); | |||
176 | 178 | ||
177 | void sched_autogroup_fork(struct signal_struct *sig) | 179 | void sched_autogroup_fork(struct signal_struct *sig) |
178 | { | 180 | { |
181 | if (!sysctl_sched_autogroup_enabled) | ||
182 | return; | ||
179 | sig->autogroup = autogroup_task_get(current); | 183 | sig->autogroup = autogroup_task_get(current); |
180 | } | 184 | } |
181 | 185 | ||
182 | void sched_autogroup_exit(struct signal_struct *sig) | 186 | void sched_autogroup_exit(struct signal_struct *sig) |
183 | { | 187 | { |
188 | if (!sysctl_sched_autogroup_enabled) | ||
189 | return; | ||
184 | autogroup_kref_put(sig->autogroup); | 190 | autogroup_kref_put(sig->autogroup); |
185 | } | 191 | } |
186 | 192 | ||
@@ -193,58 +199,6 @@ static int __init setup_autogroup(char *str) | |||
193 | 199 | ||
194 | __setup("noautogroup", setup_autogroup); | 200 | __setup("noautogroup", setup_autogroup); |
195 | 201 | ||
196 | #ifdef CONFIG_PROC_FS | ||
197 | |||
198 | int proc_sched_autogroup_set_nice(struct task_struct *p, int nice) | ||
199 | { | ||
200 | static unsigned long next = INITIAL_JIFFIES; | ||
201 | struct autogroup *ag; | ||
202 | int err; | ||
203 | |||
204 | if (nice < -20 || nice > 19) | ||
205 | return -EINVAL; | ||
206 | |||
207 | err = security_task_setnice(current, nice); | ||
208 | if (err) | ||
209 | return err; | ||
210 | |||
211 | if (nice < 0 && !can_nice(current, nice)) | ||
212 | return -EPERM; | ||
213 | |||
214 | /* this is a heavy operation taking global locks.. */ | ||
215 | if (!capable(CAP_SYS_ADMIN) && time_before(jiffies, next)) | ||
216 | return -EAGAIN; | ||
217 | |||
218 | next = HZ / 10 + jiffies; | ||
219 | ag = autogroup_task_get(p); | ||
220 | |||
221 | down_write(&ag->lock); | ||
222 | err = sched_group_set_shares(ag->tg, prio_to_weight[nice + 20]); | ||
223 | if (!err) | ||
224 | ag->nice = nice; | ||
225 | up_write(&ag->lock); | ||
226 | |||
227 | autogroup_kref_put(ag); | ||
228 | |||
229 | return err; | ||
230 | } | ||
231 | |||
232 | void proc_sched_autogroup_show_task(struct task_struct *p, struct seq_file *m) | ||
233 | { | ||
234 | struct autogroup *ag = autogroup_task_get(p); | ||
235 | |||
236 | if (!task_group_is_autogroup(ag->tg)) | ||
237 | goto out; | ||
238 | |||
239 | down_read(&ag->lock); | ||
240 | seq_printf(m, "/autogroup-%ld nice %d\n", ag->id, ag->nice); | ||
241 | up_read(&ag->lock); | ||
242 | |||
243 | out: | ||
244 | autogroup_kref_put(ag); | ||
245 | } | ||
246 | #endif /* CONFIG_PROC_FS */ | ||
247 | |||
248 | #ifdef CONFIG_SCHED_DEBUG | 202 | #ifdef CONFIG_SCHED_DEBUG |
249 | int autogroup_path(struct task_group *tg, char *buf, int buflen) | 203 | int autogroup_path(struct task_group *tg, char *buf, int buflen) |
250 | { | 204 | { |
diff --git a/kernel/sched/auto_group.h b/kernel/sched/auto_group.h index 8bd047142816..4552c6bf79d2 100644 --- a/kernel/sched/auto_group.h +++ b/kernel/sched/auto_group.h | |||
@@ -4,11 +4,6 @@ | |||
4 | #include <linux/rwsem.h> | 4 | #include <linux/rwsem.h> |
5 | 5 | ||
6 | struct autogroup { | 6 | struct autogroup { |
7 | /* | ||
8 | * reference doesn't mean how many thread attach to this | ||
9 | * autogroup now. It just stands for the number of task | ||
10 | * could use this autogroup. | ||
11 | */ | ||
12 | struct kref kref; | 7 | struct kref kref; |
13 | struct task_group *tg; | 8 | struct task_group *tg; |
14 | struct rw_semaphore lock; | 9 | struct rw_semaphore lock; |
@@ -29,9 +24,7 @@ extern bool task_wants_autogroup(struct task_struct *p, struct task_group *tg); | |||
29 | static inline struct task_group * | 24 | static inline struct task_group * |
30 | autogroup_task_group(struct task_struct *p, struct task_group *tg) | 25 | autogroup_task_group(struct task_struct *p, struct task_group *tg) |
31 | { | 26 | { |
32 | int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled); | 27 | if (task_wants_autogroup(p, tg)) |
33 | |||
34 | if (enabled && task_wants_autogroup(p, tg)) | ||
35 | return p->signal->autogroup->tg; | 28 | return p->signal->autogroup->tg; |
36 | 29 | ||
37 | return tg; | 30 | return tg; |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a319d56c7605..59e072b2db97 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -3330,7 +3330,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ | |||
3330 | * Batch and idle tasks do not preempt non-idle tasks (their preemption | 3330 | * Batch and idle tasks do not preempt non-idle tasks (their preemption |
3331 | * is driven by the tick): | 3331 | * is driven by the tick): |
3332 | */ | 3332 | */ |
3333 | if (unlikely(p->policy != SCHED_NORMAL)) | 3333 | if (unlikely(p->policy != SCHED_NORMAL) || !sched_feat(WAKEUP_PREEMPTION)) |
3334 | return; | 3334 | return; |
3335 | 3335 | ||
3336 | find_matching_se(&se, &pse); | 3336 | find_matching_se(&se, &pse); |
diff --git a/kernel/sched/features.h b/kernel/sched/features.h index eebefcad7027..e68e69ab917d 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h | |||
@@ -32,6 +32,11 @@ SCHED_FEAT(LAST_BUDDY, true) | |||
32 | SCHED_FEAT(CACHE_HOT_BUDDY, true) | 32 | SCHED_FEAT(CACHE_HOT_BUDDY, true) |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Allow wakeup-time preemption of the current task: | ||
36 | */ | ||
37 | SCHED_FEAT(WAKEUP_PREEMPTION, true) | ||
38 | |||
39 | /* | ||
35 | * Use arch dependent cpu power functions | 40 | * Use arch dependent cpu power functions |
36 | */ | 41 | */ |
37 | SCHED_FEAT(ARCH_POWER, true) | 42 | SCHED_FEAT(ARCH_POWER, true) |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 26f65eaa01f9..b0fa5ad09873 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -367,10 +367,8 @@ static struct ctl_table kern_table[] = { | |||
367 | .procname = "sched_autogroup_enabled", | 367 | .procname = "sched_autogroup_enabled", |
368 | .data = &sysctl_sched_autogroup_enabled, | 368 | .data = &sysctl_sched_autogroup_enabled, |
369 | .maxlen = sizeof(unsigned int), | 369 | .maxlen = sizeof(unsigned int), |
370 | .mode = 0644, | 370 | .mode = 0444, |
371 | .proc_handler = proc_dointvec_minmax, | 371 | .proc_handler = proc_dointvec, |
372 | .extra1 = &zero, | ||
373 | .extra2 = &one, | ||
374 | }, | 372 | }, |
375 | #endif | 373 | #endif |
376 | #ifdef CONFIG_CFS_BANDWIDTH | 374 | #ifdef CONFIG_CFS_BANDWIDTH |