aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpuset.c37
-rw-r--r--kernel/time/clockevents.c15
-rw-r--r--kernel/time/ntp.c2
-rw-r--r--kernel/time/tick-broadcast.c85
-rw-r--r--kernel/time/tick-common.c5
-rw-r--r--kernel/time/tick-internal.h4
-rw-r--r--kernel/time/tick-oneshot.c44
7 files changed, 134 insertions, 58 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index f227bc172690..827cd9adccb2 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -843,37 +843,25 @@ static void cpuset_change_cpumask(struct task_struct *tsk,
843/** 843/**
844 * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. 844 * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
845 * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed 845 * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
846 * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
846 * 847 *
847 * Called with cgroup_mutex held 848 * Called with cgroup_mutex held
848 * 849 *
849 * The cgroup_scan_tasks() function will scan all the tasks in a cgroup, 850 * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
850 * calling callback functions for each. 851 * calling callback functions for each.
851 * 852 *
852 * Return 0 if successful, -errno if not. 853 * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0
854 * if @heap != NULL.
853 */ 855 */
854static int update_tasks_cpumask(struct cpuset *cs) 856static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap)
855{ 857{
856 struct cgroup_scanner scan; 858 struct cgroup_scanner scan;
857 struct ptr_heap heap;
858 int retval;
859
860 /*
861 * cgroup_scan_tasks() will initialize heap->gt for us.
862 * heap_init() is still needed here for we should not change
863 * cs->cpus_allowed when heap_init() fails.
864 */
865 retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
866 if (retval)
867 return retval;
868 859
869 scan.cg = cs->css.cgroup; 860 scan.cg = cs->css.cgroup;
870 scan.test_task = cpuset_test_cpumask; 861 scan.test_task = cpuset_test_cpumask;
871 scan.process_task = cpuset_change_cpumask; 862 scan.process_task = cpuset_change_cpumask;
872 scan.heap = &heap; 863 scan.heap = heap;
873 retval = cgroup_scan_tasks(&scan); 864 cgroup_scan_tasks(&scan);
874
875 heap_free(&heap);
876 return retval;
877} 865}
878 866
879/** 867/**
@@ -883,6 +871,7 @@ static int update_tasks_cpumask(struct cpuset *cs)
883 */ 871 */
884static int update_cpumask(struct cpuset *cs, const char *buf) 872static int update_cpumask(struct cpuset *cs, const char *buf)
885{ 873{
874 struct ptr_heap heap;
886 struct cpuset trialcs; 875 struct cpuset trialcs;
887 int retval; 876 int retval;
888 int is_load_balanced; 877 int is_load_balanced;
@@ -917,6 +906,10 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
917 if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed)) 906 if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
918 return 0; 907 return 0;
919 908
909 retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
910 if (retval)
911 return retval;
912
920 is_load_balanced = is_sched_load_balance(&trialcs); 913 is_load_balanced = is_sched_load_balance(&trialcs);
921 914
922 mutex_lock(&callback_mutex); 915 mutex_lock(&callback_mutex);
@@ -927,9 +920,9 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
927 * Scan tasks in the cpuset, and update the cpumasks of any 920 * Scan tasks in the cpuset, and update the cpumasks of any
928 * that need an update. 921 * that need an update.
929 */ 922 */
930 retval = update_tasks_cpumask(cs); 923 update_tasks_cpumask(cs, &heap);
931 if (retval < 0) 924
932 return retval; 925 heap_free(&heap);
933 926
934 if (is_load_balanced) 927 if (is_load_balanced)
935 async_rebuild_sched_domains(); 928 async_rebuild_sched_domains();
@@ -1965,7 +1958,7 @@ static void scan_for_empty_cpusets(const struct cpuset *root)
1965 nodes_empty(cp->mems_allowed)) 1958 nodes_empty(cp->mems_allowed))
1966 remove_tasks_in_empty_cpuset(cp); 1959 remove_tasks_in_empty_cpuset(cp);
1967 else { 1960 else {
1968 update_tasks_cpumask(cp); 1961 update_tasks_cpumask(cp, NULL);
1969 update_tasks_nodemask(cp, &oldmems); 1962 update_tasks_nodemask(cp, &oldmems);
1970 } 1963 }
1971 } 1964 }
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 3d1e3e1a1971..f8d968063cea 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -72,6 +72,16 @@ void clockevents_set_mode(struct clock_event_device *dev,
72} 72}
73 73
74/** 74/**
75 * clockevents_shutdown - shutdown the device and clear next_event
76 * @dev: device to shutdown
77 */
78void clockevents_shutdown(struct clock_event_device *dev)
79{
80 clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
81 dev->next_event.tv64 = KTIME_MAX;
82}
83
84/**
75 * clockevents_program_event - Reprogram the clock event device. 85 * clockevents_program_event - Reprogram the clock event device.
76 * @expires: absolute expiry time (monotonic clock) 86 * @expires: absolute expiry time (monotonic clock)
77 * 87 *
@@ -177,7 +187,7 @@ void clockevents_register_device(struct clock_event_device *dev)
177/* 187/*
178 * Noop handler when we shut down an event device 188 * Noop handler when we shut down an event device
179 */ 189 */
180static void clockevents_handle_noop(struct clock_event_device *dev) 190void clockevents_handle_noop(struct clock_event_device *dev)
181{ 191{
182} 192}
183 193
@@ -199,7 +209,6 @@ void clockevents_exchange_device(struct clock_event_device *old,
199 * released list and do a notify add later. 209 * released list and do a notify add later.
200 */ 210 */
201 if (old) { 211 if (old) {
202 old->event_handler = clockevents_handle_noop;
203 clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); 212 clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
204 list_del(&old->list); 213 list_del(&old->list);
205 list_add(&old->list, &clockevents_released); 214 list_add(&old->list, &clockevents_released);
@@ -207,7 +216,7 @@ void clockevents_exchange_device(struct clock_event_device *old,
207 216
208 if (new) { 217 if (new) {
209 BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED); 218 BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED);
210 clockevents_set_mode(new, CLOCK_EVT_MODE_SHUTDOWN); 219 clockevents_shutdown(new);
211 } 220 }
212 local_irq_restore(flags); 221 local_irq_restore(flags);
213} 222}
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 5125ddd8196b..1ad46f3df6e7 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -245,7 +245,7 @@ static void sync_cmos_clock(unsigned long dummy)
245 if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) 245 if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
246 fail = update_persistent_clock(now); 246 fail = update_persistent_clock(now);
247 247
248 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec; 248 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
249 if (next.tv_nsec <= 0) 249 if (next.tv_nsec <= 0)
250 next.tv_nsec += NSEC_PER_SEC; 250 next.tv_nsec += NSEC_PER_SEC;
251 251
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 31463d370b94..f1f3eee28113 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -175,6 +175,8 @@ static void tick_do_periodic_broadcast(void)
175 */ 175 */
176static void tick_handle_periodic_broadcast(struct clock_event_device *dev) 176static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
177{ 177{
178 ktime_t next;
179
178 tick_do_periodic_broadcast(); 180 tick_do_periodic_broadcast();
179 181
180 /* 182 /*
@@ -185,10 +187,13 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
185 187
186 /* 188 /*
187 * Setup the next period for devices, which do not have 189 * Setup the next period for devices, which do not have
188 * periodic mode: 190 * periodic mode. We read dev->next_event first and add to it
191 * when the event alrady expired. clockevents_program_event()
192 * sets dev->next_event only when the event is really
193 * programmed to the device.
189 */ 194 */
190 for (;;) { 195 for (next = dev->next_event; ;) {
191 ktime_t next = ktime_add(dev->next_event, tick_period); 196 next = ktime_add(next, tick_period);
192 197
193 if (!clockevents_program_event(dev, next, ktime_get())) 198 if (!clockevents_program_event(dev, next, ktime_get()))
194 return; 199 return;
@@ -205,7 +210,7 @@ static void tick_do_broadcast_on_off(void *why)
205 struct clock_event_device *bc, *dev; 210 struct clock_event_device *bc, *dev;
206 struct tick_device *td; 211 struct tick_device *td;
207 unsigned long flags, *reason = why; 212 unsigned long flags, *reason = why;
208 int cpu; 213 int cpu, bc_stopped;
209 214
210 spin_lock_irqsave(&tick_broadcast_lock, flags); 215 spin_lock_irqsave(&tick_broadcast_lock, flags);
211 216
@@ -223,14 +228,15 @@ static void tick_do_broadcast_on_off(void *why)
223 if (!tick_device_is_functional(dev)) 228 if (!tick_device_is_functional(dev))
224 goto out; 229 goto out;
225 230
231 bc_stopped = cpus_empty(tick_broadcast_mask);
232
226 switch (*reason) { 233 switch (*reason) {
227 case CLOCK_EVT_NOTIFY_BROADCAST_ON: 234 case CLOCK_EVT_NOTIFY_BROADCAST_ON:
228 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: 235 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
229 if (!cpu_isset(cpu, tick_broadcast_mask)) { 236 if (!cpu_isset(cpu, tick_broadcast_mask)) {
230 cpu_set(cpu, tick_broadcast_mask); 237 cpu_set(cpu, tick_broadcast_mask);
231 if (td->mode == TICKDEV_MODE_PERIODIC) 238 if (td->mode == TICKDEV_MODE_PERIODIC)
232 clockevents_set_mode(dev, 239 clockevents_shutdown(dev);
233 CLOCK_EVT_MODE_SHUTDOWN);
234 } 240 }
235 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) 241 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
236 tick_broadcast_force = 1; 242 tick_broadcast_force = 1;
@@ -245,9 +251,10 @@ static void tick_do_broadcast_on_off(void *why)
245 break; 251 break;
246 } 252 }
247 253
248 if (cpus_empty(tick_broadcast_mask)) 254 if (cpus_empty(tick_broadcast_mask)) {
249 clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 255 if (!bc_stopped)
250 else { 256 clockevents_shutdown(bc);
257 } else if (bc_stopped) {
251 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) 258 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
252 tick_broadcast_start_periodic(bc); 259 tick_broadcast_start_periodic(bc);
253 else 260 else
@@ -298,7 +305,7 @@ void tick_shutdown_broadcast(unsigned int *cpup)
298 305
299 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { 306 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
300 if (bc && cpus_empty(tick_broadcast_mask)) 307 if (bc && cpus_empty(tick_broadcast_mask))
301 clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 308 clockevents_shutdown(bc);
302 } 309 }
303 310
304 spin_unlock_irqrestore(&tick_broadcast_lock, flags); 311 spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -313,7 +320,7 @@ void tick_suspend_broadcast(void)
313 320
314 bc = tick_broadcast_device.evtdev; 321 bc = tick_broadcast_device.evtdev;
315 if (bc) 322 if (bc)
316 clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 323 clockevents_shutdown(bc);
317 324
318 spin_unlock_irqrestore(&tick_broadcast_lock, flags); 325 spin_unlock_irqrestore(&tick_broadcast_lock, flags);
319} 326}
@@ -364,16 +371,8 @@ cpumask_t *tick_get_broadcast_oneshot_mask(void)
364static int tick_broadcast_set_event(ktime_t expires, int force) 371static int tick_broadcast_set_event(ktime_t expires, int force)
365{ 372{
366 struct clock_event_device *bc = tick_broadcast_device.evtdev; 373 struct clock_event_device *bc = tick_broadcast_device.evtdev;
367 ktime_t now = ktime_get(); 374
368 int res; 375 return tick_dev_program_event(bc, expires, force);
369
370 for(;;) {
371 res = clockevents_program_event(bc, expires, now);
372 if (!res || !force)
373 return res;
374 now = ktime_get();
375 expires = ktime_add(now, ktime_set(0, bc->min_delta_ns));
376 }
377} 376}
378 377
379int tick_resume_broadcast_oneshot(struct clock_event_device *bc) 378int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
@@ -491,14 +490,52 @@ static void tick_broadcast_clear_oneshot(int cpu)
491 cpu_clear(cpu, tick_broadcast_oneshot_mask); 490 cpu_clear(cpu, tick_broadcast_oneshot_mask);
492} 491}
493 492
493static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
494{
495 struct tick_device *td;
496 int cpu;
497
498 for_each_cpu_mask_nr(cpu, *mask) {
499 td = &per_cpu(tick_cpu_device, cpu);
500 if (td->evtdev)
501 td->evtdev->next_event = expires;
502 }
503}
504
494/** 505/**
495 * tick_broadcast_setup_oneshot - setup the broadcast device 506 * tick_broadcast_setup_oneshot - setup the broadcast device
496 */ 507 */
497void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 508void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
498{ 509{
499 bc->event_handler = tick_handle_oneshot_broadcast; 510 /* Set it up only once ! */
500 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); 511 if (bc->event_handler != tick_handle_oneshot_broadcast) {
501 bc->next_event.tv64 = KTIME_MAX; 512 int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
513 int cpu = smp_processor_id();
514 cpumask_t mask;
515
516 bc->event_handler = tick_handle_oneshot_broadcast;
517 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
518
519 /* Take the do_timer update */
520 tick_do_timer_cpu = cpu;
521
522 /*
523 * We must be careful here. There might be other CPUs
524 * waiting for periodic broadcast. We need to set the
525 * oneshot_mask bits for those and program the
526 * broadcast device to fire.
527 */
528 mask = tick_broadcast_mask;
529 cpu_clear(cpu, mask);
530 cpus_or(tick_broadcast_oneshot_mask,
531 tick_broadcast_oneshot_mask, mask);
532
533 if (was_periodic && !cpus_empty(mask)) {
534 tick_broadcast_init_next_event(&mask, tick_next_period);
535 tick_broadcast_set_event(tick_next_period, 1);
536 } else
537 bc->next_event.tv64 = KTIME_MAX;
538 }
502} 539}
503 540
504/* 541/*
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 80c4336f4188..019315ebf9de 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -161,6 +161,7 @@ static void tick_setup_device(struct tick_device *td,
161 } else { 161 } else {
162 handler = td->evtdev->event_handler; 162 handler = td->evtdev->event_handler;
163 next_event = td->evtdev->next_event; 163 next_event = td->evtdev->next_event;
164 td->evtdev->event_handler = clockevents_handle_noop;
164 } 165 }
165 166
166 td->evtdev = newdev; 167 td->evtdev = newdev;
@@ -248,7 +249,7 @@ static int tick_check_new_device(struct clock_event_device *newdev)
248 * not give it back to the clockevents layer ! 249 * not give it back to the clockevents layer !
249 */ 250 */
250 if (tick_is_broadcast_device(curdev)) { 251 if (tick_is_broadcast_device(curdev)) {
251 clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN); 252 clockevents_shutdown(curdev);
252 curdev = NULL; 253 curdev = NULL;
253 } 254 }
254 clockevents_exchange_device(curdev, newdev); 255 clockevents_exchange_device(curdev, newdev);
@@ -310,7 +311,7 @@ static void tick_suspend(void)
310 unsigned long flags; 311 unsigned long flags;
311 312
312 spin_lock_irqsave(&tick_device_lock, flags); 313 spin_lock_irqsave(&tick_device_lock, flags);
313 clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); 314 clockevents_shutdown(td->evtdev);
314 spin_unlock_irqrestore(&tick_device_lock, flags); 315 spin_unlock_irqrestore(&tick_device_lock, flags);
315} 316}
316 317
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index f13f2b7f4fd4..6e9db9734aa6 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -10,6 +10,8 @@ extern int tick_do_timer_cpu __read_mostly;
10extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); 10extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
11extern void tick_handle_periodic(struct clock_event_device *dev); 11extern void tick_handle_periodic(struct clock_event_device *dev);
12 12
13extern void clockevents_shutdown(struct clock_event_device *dev);
14
13/* 15/*
14 * NO_HZ / high resolution timer shared code 16 * NO_HZ / high resolution timer shared code
15 */ 17 */
@@ -17,6 +19,8 @@ extern void tick_handle_periodic(struct clock_event_device *dev);
17extern void tick_setup_oneshot(struct clock_event_device *newdev, 19extern void tick_setup_oneshot(struct clock_event_device *newdev,
18 void (*handler)(struct clock_event_device *), 20 void (*handler)(struct clock_event_device *),
19 ktime_t nextevt); 21 ktime_t nextevt);
22extern int tick_dev_program_event(struct clock_event_device *dev,
23 ktime_t expires, int force);
20extern int tick_program_event(ktime_t expires, int force); 24extern int tick_program_event(ktime_t expires, int force);
21extern void tick_oneshot_notify(void); 25extern void tick_oneshot_notify(void);
22extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); 26extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index 450c04935b66..2e8de678e767 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -23,24 +23,56 @@
23#include "tick-internal.h" 23#include "tick-internal.h"
24 24
25/** 25/**
26 * tick_program_event 26 * tick_program_event internal worker function
27 */ 27 */
28int tick_program_event(ktime_t expires, int force) 28int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
29 int force)
29{ 30{
30 struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
31 ktime_t now = ktime_get(); 31 ktime_t now = ktime_get();
32 int i;
32 33
33 while (1) { 34 for (i = 0;;) {
34 int ret = clockevents_program_event(dev, expires, now); 35 int ret = clockevents_program_event(dev, expires, now);
35 36
36 if (!ret || !force) 37 if (!ret || !force)
37 return ret; 38 return ret;
39
40 /*
41 * We tried 2 times to program the device with the given
42 * min_delta_ns. If that's not working then we double it
43 * and emit a warning.
44 */
45 if (++i > 2) {
46 /* Increase the min. delta and try again */
47 if (!dev->min_delta_ns)
48 dev->min_delta_ns = 5000;
49 else
50 dev->min_delta_ns += dev->min_delta_ns >> 1;
51
52 printk(KERN_WARNING
53 "CE: %s increasing min_delta_ns to %lu nsec\n",
54 dev->name ? dev->name : "?",
55 dev->min_delta_ns << 1);
56
57 i = 0;
58 }
59
38 now = ktime_get(); 60 now = ktime_get();
39 expires = ktime_add(now, ktime_set(0, dev->min_delta_ns)); 61 expires = ktime_add_ns(now, dev->min_delta_ns);
40 } 62 }
41} 63}
42 64
43/** 65/**
66 * tick_program_event
67 */
68int tick_program_event(ktime_t expires, int force)
69{
70 struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
71
72 return tick_dev_program_event(dev, expires, force);
73}
74
75/**
44 * tick_resume_onshot - resume oneshot mode 76 * tick_resume_onshot - resume oneshot mode
45 */ 77 */
46void tick_resume_oneshot(void) 78void tick_resume_oneshot(void)
@@ -61,7 +93,7 @@ void tick_setup_oneshot(struct clock_event_device *newdev,
61{ 93{
62 newdev->event_handler = handler; 94 newdev->event_handler = handler;
63 clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT); 95 clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT);
64 clockevents_program_event(newdev, next_event, ktime_get()); 96 tick_dev_program_event(newdev, next_event, 1);
65} 97}
66 98
67/** 99/**