aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-03-05 08:25:32 -0500
committerThomas Gleixner <tglx@linutronix.de>2013-03-07 10:13:26 -0500
commitb352bc1cbc29134a356b5c16ee2281807a7b984e (patch)
treee68ff362a8c1bae0510d864551ba81f4f1136cc0
parentad2b13536ace08dfcca4cf86b75a5d06efe06373 (diff)
tick: Convert broadcast cpu bitmaps to cpumask_var_t
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20130306111537.366394000@linutronix.de Cc: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--kernel/time/tick-broadcast.c86
-rw-r--r--kernel/time/tick-common.c1
-rw-r--r--kernel/time/tick-internal.h3
3 files changed, 46 insertions, 44 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 2fb8cb88df8d..35b887517766 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -28,9 +28,8 @@
28 */ 28 */
29 29
30static struct tick_device tick_broadcast_device; 30static struct tick_device tick_broadcast_device;
31/* FIXME: Use cpumask_var_t. */ 31static cpumask_var_t tick_broadcast_mask;
32static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS); 32static cpumask_var_t tmpmask;
33static DECLARE_BITMAP(tmpmask, NR_CPUS);
34static DEFINE_RAW_SPINLOCK(tick_broadcast_lock); 33static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
35static int tick_broadcast_force; 34static int tick_broadcast_force;
36 35
@@ -50,7 +49,7 @@ struct tick_device *tick_get_broadcast_device(void)
50 49
51struct cpumask *tick_get_broadcast_mask(void) 50struct cpumask *tick_get_broadcast_mask(void)
52{ 51{
53 return to_cpumask(tick_broadcast_mask); 52 return tick_broadcast_mask;
54} 53}
55 54
56/* 55/*
@@ -74,7 +73,7 @@ int tick_check_broadcast_device(struct clock_event_device *dev)
74 73
75 clockevents_exchange_device(tick_broadcast_device.evtdev, dev); 74 clockevents_exchange_device(tick_broadcast_device.evtdev, dev);
76 tick_broadcast_device.evtdev = dev; 75 tick_broadcast_device.evtdev = dev;
77 if (!cpumask_empty(tick_get_broadcast_mask())) 76 if (!cpumask_empty(tick_broadcast_mask))
78 tick_broadcast_start_periodic(dev); 77 tick_broadcast_start_periodic(dev);
79 return 1; 78 return 1;
80} 79}
@@ -123,7 +122,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
123 if (!tick_device_is_functional(dev)) { 122 if (!tick_device_is_functional(dev)) {
124 dev->event_handler = tick_handle_periodic; 123 dev->event_handler = tick_handle_periodic;
125 tick_device_setup_broadcast_func(dev); 124 tick_device_setup_broadcast_func(dev);
126 cpumask_set_cpu(cpu, tick_get_broadcast_mask()); 125 cpumask_set_cpu(cpu, tick_broadcast_mask);
127 tick_broadcast_start_periodic(tick_broadcast_device.evtdev); 126 tick_broadcast_start_periodic(tick_broadcast_device.evtdev);
128 ret = 1; 127 ret = 1;
129 } else { 128 } else {
@@ -134,7 +133,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
134 */ 133 */
135 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { 134 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
136 int cpu = smp_processor_id(); 135 int cpu = smp_processor_id();
137 cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); 136 cpumask_clear_cpu(cpu, tick_broadcast_mask);
138 tick_broadcast_clear_oneshot(cpu); 137 tick_broadcast_clear_oneshot(cpu);
139 } else { 138 } else {
140 tick_device_setup_broadcast_func(dev); 139 tick_device_setup_broadcast_func(dev);
@@ -198,9 +197,8 @@ static void tick_do_periodic_broadcast(void)
198{ 197{
199 raw_spin_lock(&tick_broadcast_lock); 198 raw_spin_lock(&tick_broadcast_lock);
200 199
201 cpumask_and(to_cpumask(tmpmask), 200 cpumask_and(tmpmask, cpu_online_mask, tick_broadcast_mask);
202 cpu_online_mask, tick_get_broadcast_mask()); 201 tick_do_broadcast(tmpmask);
203 tick_do_broadcast(to_cpumask(tmpmask));
204 202
205 raw_spin_unlock(&tick_broadcast_lock); 203 raw_spin_unlock(&tick_broadcast_lock);
206} 204}
@@ -263,13 +261,12 @@ static void tick_do_broadcast_on_off(unsigned long *reason)
263 if (!tick_device_is_functional(dev)) 261 if (!tick_device_is_functional(dev))
264 goto out; 262 goto out;
265 263
266 bc_stopped = cpumask_empty(tick_get_broadcast_mask()); 264 bc_stopped = cpumask_empty(tick_broadcast_mask);
267 265
268 switch (*reason) { 266 switch (*reason) {
269 case CLOCK_EVT_NOTIFY_BROADCAST_ON: 267 case CLOCK_EVT_NOTIFY_BROADCAST_ON:
270 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: 268 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
271 if (!cpumask_test_cpu(cpu, tick_get_broadcast_mask())) { 269 if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
272 cpumask_set_cpu(cpu, tick_get_broadcast_mask());
273 if (tick_broadcast_device.mode == 270 if (tick_broadcast_device.mode ==
274 TICKDEV_MODE_PERIODIC) 271 TICKDEV_MODE_PERIODIC)
275 clockevents_shutdown(dev); 272 clockevents_shutdown(dev);
@@ -279,8 +276,7 @@ static void tick_do_broadcast_on_off(unsigned long *reason)
279 break; 276 break;
280 case CLOCK_EVT_NOTIFY_BROADCAST_OFF: 277 case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
281 if (!tick_broadcast_force && 278 if (!tick_broadcast_force &&
282 cpumask_test_cpu(cpu, tick_get_broadcast_mask())) { 279 cpumask_test_and_clear_cpu(cpu, tick_broadcast_mask)) {
283 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
284 if (tick_broadcast_device.mode == 280 if (tick_broadcast_device.mode ==
285 TICKDEV_MODE_PERIODIC) 281 TICKDEV_MODE_PERIODIC)
286 tick_setup_periodic(dev, 0); 282 tick_setup_periodic(dev, 0);
@@ -288,7 +284,7 @@ static void tick_do_broadcast_on_off(unsigned long *reason)
288 break; 284 break;
289 } 285 }
290 286
291 if (cpumask_empty(tick_get_broadcast_mask())) { 287 if (cpumask_empty(tick_broadcast_mask)) {
292 if (!bc_stopped) 288 if (!bc_stopped)
293 clockevents_shutdown(bc); 289 clockevents_shutdown(bc);
294 } else if (bc_stopped) { 290 } else if (bc_stopped) {
@@ -337,10 +333,10 @@ void tick_shutdown_broadcast(unsigned int *cpup)
337 raw_spin_lock_irqsave(&tick_broadcast_lock, flags); 333 raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
338 334
339 bc = tick_broadcast_device.evtdev; 335 bc = tick_broadcast_device.evtdev;
340 cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); 336 cpumask_clear_cpu(cpu, tick_broadcast_mask);
341 337
342 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { 338 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
343 if (bc && cpumask_empty(tick_get_broadcast_mask())) 339 if (bc && cpumask_empty(tick_broadcast_mask))
344 clockevents_shutdown(bc); 340 clockevents_shutdown(bc);
345 } 341 }
346 342
@@ -376,13 +372,13 @@ int tick_resume_broadcast(void)
376 372
377 switch (tick_broadcast_device.mode) { 373 switch (tick_broadcast_device.mode) {
378 case TICKDEV_MODE_PERIODIC: 374 case TICKDEV_MODE_PERIODIC:
379 if (!cpumask_empty(tick_get_broadcast_mask())) 375 if (!cpumask_empty(tick_broadcast_mask))
380 tick_broadcast_start_periodic(bc); 376 tick_broadcast_start_periodic(bc);
381 broadcast = cpumask_test_cpu(smp_processor_id(), 377 broadcast = cpumask_test_cpu(smp_processor_id(),
382 tick_get_broadcast_mask()); 378 tick_broadcast_mask);
383 break; 379 break;
384 case TICKDEV_MODE_ONESHOT: 380 case TICKDEV_MODE_ONESHOT:
385 if (!cpumask_empty(tick_get_broadcast_mask())) 381 if (!cpumask_empty(tick_broadcast_mask))
386 broadcast = tick_resume_broadcast_oneshot(bc); 382 broadcast = tick_resume_broadcast_oneshot(bc);
387 break; 383 break;
388 } 384 }
@@ -395,15 +391,14 @@ int tick_resume_broadcast(void)
395 391
396#ifdef CONFIG_TICK_ONESHOT 392#ifdef CONFIG_TICK_ONESHOT
397 393
398/* FIXME: use cpumask_var_t. */ 394static cpumask_var_t tick_broadcast_oneshot_mask;
399static DECLARE_BITMAP(tick_broadcast_oneshot_mask, NR_CPUS);
400 395
401/* 396/*
402 * Exposed for debugging: see timer_list.c 397 * Exposed for debugging: see timer_list.c
403 */ 398 */
404struct cpumask *tick_get_broadcast_oneshot_mask(void) 399struct cpumask *tick_get_broadcast_oneshot_mask(void)
405{ 400{
406 return to_cpumask(tick_broadcast_oneshot_mask); 401 return tick_broadcast_oneshot_mask;
407} 402}
408 403
409static int tick_broadcast_set_event(ktime_t expires, int force) 404static int tick_broadcast_set_event(ktime_t expires, int force)
@@ -428,7 +423,7 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
428 */ 423 */
429void tick_check_oneshot_broadcast(int cpu) 424void tick_check_oneshot_broadcast(int cpu)
430{ 425{
431 if (cpumask_test_cpu(cpu, to_cpumask(tick_broadcast_oneshot_mask))) { 426 if (cpumask_test_cpu(cpu, tick_broadcast_oneshot_mask)) {
432 struct tick_device *td = &per_cpu(tick_cpu_device, cpu); 427 struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
433 428
434 clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT); 429 clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT);
@@ -448,13 +443,13 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
448again: 443again:
449 dev->next_event.tv64 = KTIME_MAX; 444 dev->next_event.tv64 = KTIME_MAX;
450 next_event.tv64 = KTIME_MAX; 445 next_event.tv64 = KTIME_MAX;
451 cpumask_clear(to_cpumask(tmpmask)); 446 cpumask_clear(tmpmask);
452 now = ktime_get(); 447 now = ktime_get();
453 /* Find all expired events */ 448 /* Find all expired events */
454 for_each_cpu(cpu, tick_get_broadcast_oneshot_mask()) { 449 for_each_cpu(cpu, tick_broadcast_oneshot_mask) {
455 td = &per_cpu(tick_cpu_device, cpu); 450 td = &per_cpu(tick_cpu_device, cpu);
456 if (td->evtdev->next_event.tv64 <= now.tv64) 451 if (td->evtdev->next_event.tv64 <= now.tv64)
457 cpumask_set_cpu(cpu, to_cpumask(tmpmask)); 452 cpumask_set_cpu(cpu, tmpmask);
458 else if (td->evtdev->next_event.tv64 < next_event.tv64) 453 else if (td->evtdev->next_event.tv64 < next_event.tv64)
459 next_event.tv64 = td->evtdev->next_event.tv64; 454 next_event.tv64 = td->evtdev->next_event.tv64;
460 } 455 }
@@ -462,7 +457,7 @@ again:
462 /* 457 /*
463 * Wakeup the cpus which have an expired event. 458 * Wakeup the cpus which have an expired event.
464 */ 459 */
465 tick_do_broadcast(to_cpumask(tmpmask)); 460 tick_do_broadcast(tmpmask);
466 461
467 /* 462 /*
468 * Two reasons for reprogram: 463 * Two reasons for reprogram:
@@ -518,16 +513,13 @@ void tick_broadcast_oneshot_control(unsigned long reason)
518 513
519 raw_spin_lock_irqsave(&tick_broadcast_lock, flags); 514 raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
520 if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { 515 if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
521 if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { 516 if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
522 cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask());
523 clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); 517 clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
524 if (dev->next_event.tv64 < bc->next_event.tv64) 518 if (dev->next_event.tv64 < bc->next_event.tv64)
525 tick_broadcast_set_event(dev->next_event, 1); 519 tick_broadcast_set_event(dev->next_event, 1);
526 } 520 }
527 } else { 521 } else {
528 if (cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { 522 if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) {
529 cpumask_clear_cpu(cpu,
530 tick_get_broadcast_oneshot_mask());
531 clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); 523 clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
532 if (dev->next_event.tv64 != KTIME_MAX) 524 if (dev->next_event.tv64 != KTIME_MAX)
533 tick_program_event(dev->next_event, 1); 525 tick_program_event(dev->next_event, 1);
@@ -543,7 +535,7 @@ void tick_broadcast_oneshot_control(unsigned long reason)
543 */ 535 */
544static void tick_broadcast_clear_oneshot(int cpu) 536static void tick_broadcast_clear_oneshot(int cpu)
545{ 537{
546 cpumask_clear_cpu(cpu, tick_get_broadcast_oneshot_mask()); 538 cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
547} 539}
548 540
549static void tick_broadcast_init_next_event(struct cpumask *mask, 541static void tick_broadcast_init_next_event(struct cpumask *mask,
@@ -581,15 +573,14 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
581 * oneshot_mask bits for those and program the 573 * oneshot_mask bits for those and program the
582 * broadcast device to fire. 574 * broadcast device to fire.
583 */ 575 */
584 cpumask_copy(to_cpumask(tmpmask), tick_get_broadcast_mask()); 576 cpumask_copy(tmpmask, tick_broadcast_mask);
585 cpumask_clear_cpu(cpu, to_cpumask(tmpmask)); 577 cpumask_clear_cpu(cpu, tmpmask);
586 cpumask_or(tick_get_broadcast_oneshot_mask(), 578 cpumask_or(tick_broadcast_oneshot_mask,
587 tick_get_broadcast_oneshot_mask(), 579 tick_broadcast_oneshot_mask, tmpmask);
588 to_cpumask(tmpmask));
589 580
590 if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { 581 if (was_periodic && !cpumask_empty(tmpmask)) {
591 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); 582 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
592 tick_broadcast_init_next_event(to_cpumask(tmpmask), 583 tick_broadcast_init_next_event(tmpmask,
593 tick_next_period); 584 tick_next_period);
594 tick_broadcast_set_event(tick_next_period, 1); 585 tick_broadcast_set_event(tick_next_period, 1);
595 } else 586 } else
@@ -639,7 +630,7 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
639 * Clear the broadcast mask flag for the dead cpu, but do not 630 * Clear the broadcast mask flag for the dead cpu, but do not
640 * stop the broadcast device! 631 * stop the broadcast device!
641 */ 632 */
642 cpumask_clear_cpu(cpu, tick_get_broadcast_oneshot_mask()); 633 cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
643 634
644 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); 635 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
645} 636}
@@ -663,3 +654,12 @@ bool tick_broadcast_oneshot_available(void)
663} 654}
664 655
665#endif 656#endif
657
658void __init tick_broadcast_init(void)
659{
660 alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
661 alloc_cpumask_var(&tmpmask, GFP_NOWAIT);
662#ifdef CONFIG_TICK_ONESHOT
663 alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
664#endif
665}
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index b1600a6973f4..74413e396acc 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -416,4 +416,5 @@ static struct notifier_block tick_notifier = {
416void __init tick_init(void) 416void __init tick_init(void)
417{ 417{
418 clockevents_register_notifier(&tick_notifier); 418 clockevents_register_notifier(&tick_notifier);
419 tick_broadcast_init();
419} 420}
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index cf3e59ed6dc0..46d9bd02844c 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -94,7 +94,7 @@ extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
94extern void tick_shutdown_broadcast(unsigned int *cpup); 94extern void tick_shutdown_broadcast(unsigned int *cpup);
95extern void tick_suspend_broadcast(void); 95extern void tick_suspend_broadcast(void);
96extern int tick_resume_broadcast(void); 96extern int tick_resume_broadcast(void);
97 97extern void tick_broadcast_init(void);
98extern void 98extern void
99tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); 99tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
100 100
@@ -119,6 +119,7 @@ static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
119static inline void tick_shutdown_broadcast(unsigned int *cpup) { } 119static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
120static inline void tick_suspend_broadcast(void) { } 120static inline void tick_suspend_broadcast(void) { }
121static inline int tick_resume_broadcast(void) { return 0; } 121static inline int tick_resume_broadcast(void) { return 0; }
122static inline void tick_broadcast_init(void) { }
122 123
123/* 124/*
124 * Set the periodic handler in non broadcast mode 125 * Set the periodic handler in non broadcast mode