diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-03-05 08:25:32 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-03-07 10:13:26 -0500 |
commit | b352bc1cbc29134a356b5c16ee2281807a7b984e (patch) | |
tree | e68ff362a8c1bae0510d864551ba81f4f1136cc0 | |
parent | ad2b13536ace08dfcca4cf86b75a5d06efe06373 (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.c | 86 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 3 |
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 | ||
30 | static struct tick_device tick_broadcast_device; | 30 | static struct tick_device tick_broadcast_device; |
31 | /* FIXME: Use cpumask_var_t. */ | 31 | static cpumask_var_t tick_broadcast_mask; |
32 | static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS); | 32 | static cpumask_var_t tmpmask; |
33 | static DECLARE_BITMAP(tmpmask, NR_CPUS); | ||
34 | static DEFINE_RAW_SPINLOCK(tick_broadcast_lock); | 33 | static DEFINE_RAW_SPINLOCK(tick_broadcast_lock); |
35 | static int tick_broadcast_force; | 34 | static int tick_broadcast_force; |
36 | 35 | ||
@@ -50,7 +49,7 @@ struct tick_device *tick_get_broadcast_device(void) | |||
50 | 49 | ||
51 | struct cpumask *tick_get_broadcast_mask(void) | 50 | struct 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. */ | 394 | static cpumask_var_t tick_broadcast_oneshot_mask; |
399 | static 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 | */ |
404 | struct cpumask *tick_get_broadcast_oneshot_mask(void) | 399 | struct 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 | ||
409 | static int tick_broadcast_set_event(ktime_t expires, int force) | 404 | static 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 | */ |
429 | void tick_check_oneshot_broadcast(int cpu) | 424 | void 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) | |||
448 | again: | 443 | again: |
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 | */ |
544 | static void tick_broadcast_clear_oneshot(int cpu) | 536 | static 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 | ||
549 | static void tick_broadcast_init_next_event(struct cpumask *mask, | 541 | static 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 | |||
658 | void __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 = { | |||
416 | void __init tick_init(void) | 416 | void __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); | |||
94 | extern void tick_shutdown_broadcast(unsigned int *cpup); | 94 | extern void tick_shutdown_broadcast(unsigned int *cpup); |
95 | extern void tick_suspend_broadcast(void); | 95 | extern void tick_suspend_broadcast(void); |
96 | extern int tick_resume_broadcast(void); | 96 | extern int tick_resume_broadcast(void); |
97 | 97 | extern void tick_broadcast_init(void); | |
98 | extern void | 98 | extern void |
99 | tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); | 99 | tick_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) { } | |||
119 | static inline void tick_shutdown_broadcast(unsigned int *cpup) { } | 119 | static inline void tick_shutdown_broadcast(unsigned int *cpup) { } |
120 | static inline void tick_suspend_broadcast(void) { } | 120 | static inline void tick_suspend_broadcast(void) { } |
121 | static inline int tick_resume_broadcast(void) { return 0; } | 121 | static inline int tick_resume_broadcast(void) { return 0; } |
122 | static 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 |