diff options
| -rw-r--r-- | kernel/time/tick-broadcast.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 2bc1f046151c..2f5a38294bf9 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -491,6 +491,18 @@ static void tick_broadcast_clear_oneshot(int cpu) | |||
| 491 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | 491 | cpu_clear(cpu, tick_broadcast_oneshot_mask); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires) | ||
| 495 | { | ||
| 496 | struct tick_device *td; | ||
| 497 | int cpu; | ||
| 498 | |||
| 499 | for_each_cpu_mask_nr(cpu, *mask) { | ||
| 500 | td = &per_cpu(tick_cpu_device, cpu); | ||
| 501 | if (td->evtdev) | ||
| 502 | td->evtdev->next_event = expires; | ||
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 494 | /** | 506 | /** |
| 495 | * tick_broadcast_setup_oneshot - setup the broadcast device | 507 | * tick_broadcast_setup_oneshot - setup the broadcast device |
| 496 | */ | 508 | */ |
| @@ -498,9 +510,32 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 498 | { | 510 | { |
| 499 | /* Set it up only once ! */ | 511 | /* Set it up only once ! */ |
| 500 | if (bc->event_handler != tick_handle_oneshot_broadcast) { | 512 | if (bc->event_handler != tick_handle_oneshot_broadcast) { |
| 513 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; | ||
| 514 | int cpu = smp_processor_id(); | ||
| 515 | cpumask_t mask; | ||
| 516 | |||
| 501 | bc->event_handler = tick_handle_oneshot_broadcast; | 517 | bc->event_handler = tick_handle_oneshot_broadcast; |
| 502 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 518 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); |
| 503 | bc->next_event.tv64 = KTIME_MAX; | 519 | |
| 520 | /* Take the do_timer update */ | ||
| 521 | tick_do_timer_cpu = cpu; | ||
| 522 | |||
| 523 | /* | ||
| 524 | * We must be careful here. There might be other CPUs | ||
| 525 | * waiting for periodic broadcast. We need to set the | ||
| 526 | * oneshot_mask bits for those and program the | ||
| 527 | * broadcast device to fire. | ||
| 528 | */ | ||
| 529 | mask = tick_broadcast_mask; | ||
| 530 | cpu_clear(cpu, mask); | ||
| 531 | cpus_or(tick_broadcast_oneshot_mask, | ||
| 532 | tick_broadcast_oneshot_mask, mask); | ||
| 533 | |||
| 534 | if (was_periodic && !cpus_empty(mask)) { | ||
| 535 | tick_broadcast_init_next_event(&mask, tick_next_period); | ||
| 536 | tick_broadcast_set_event(tick_next_period, 1); | ||
| 537 | } else | ||
| 538 | bc->next_event.tv64 = KTIME_MAX; | ||
| 504 | } | 539 | } |
| 505 | } | 540 | } |
| 506 | 541 | ||
