diff options
Diffstat (limited to 'kernel/time/tick-common.c')
| -rw-r--r-- | kernel/time/tick-common.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 7efeedf53ebd..f7c515595b42 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
| @@ -394,6 +394,56 @@ void tick_resume(void) | |||
| 394 | } | 394 | } |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | static DEFINE_RAW_SPINLOCK(tick_freeze_lock); | ||
| 398 | static unsigned int tick_freeze_depth; | ||
| 399 | |||
| 400 | /** | ||
| 401 | * tick_freeze - Suspend the local tick and (possibly) timekeeping. | ||
| 402 | * | ||
| 403 | * Check if this is the last online CPU executing the function and if so, | ||
| 404 | * suspend timekeeping. Otherwise suspend the local tick. | ||
| 405 | * | ||
| 406 | * Call with interrupts disabled. Must be balanced with %tick_unfreeze(). | ||
| 407 | * Interrupts must not be enabled before the subsequent %tick_unfreeze(). | ||
| 408 | */ | ||
| 409 | void tick_freeze(void) | ||
| 410 | { | ||
| 411 | raw_spin_lock(&tick_freeze_lock); | ||
| 412 | |||
| 413 | tick_freeze_depth++; | ||
| 414 | if (tick_freeze_depth == num_online_cpus()) { | ||
| 415 | timekeeping_suspend(); | ||
| 416 | } else { | ||
| 417 | tick_suspend(); | ||
| 418 | tick_suspend_broadcast(); | ||
| 419 | } | ||
| 420 | |||
| 421 | raw_spin_unlock(&tick_freeze_lock); | ||
| 422 | } | ||
| 423 | |||
| 424 | /** | ||
| 425 | * tick_unfreeze - Resume the local tick and (possibly) timekeeping. | ||
| 426 | * | ||
| 427 | * Check if this is the first CPU executing the function and if so, resume | ||
| 428 | * timekeeping. Otherwise resume the local tick. | ||
| 429 | * | ||
| 430 | * Call with interrupts disabled. Must be balanced with %tick_freeze(). | ||
| 431 | * Interrupts must not be enabled after the preceding %tick_freeze(). | ||
| 432 | */ | ||
| 433 | void tick_unfreeze(void) | ||
| 434 | { | ||
| 435 | raw_spin_lock(&tick_freeze_lock); | ||
| 436 | |||
| 437 | if (tick_freeze_depth == num_online_cpus()) | ||
| 438 | timekeeping_resume(); | ||
| 439 | else | ||
| 440 | tick_resume(); | ||
| 441 | |||
| 442 | tick_freeze_depth--; | ||
| 443 | |||
| 444 | raw_spin_unlock(&tick_freeze_lock); | ||
| 445 | } | ||
| 446 | |||
| 397 | /** | 447 | /** |
| 398 | * tick_init - initialize the tick control | 448 | * tick_init - initialize the tick control |
| 399 | */ | 449 | */ |
