diff options
Diffstat (limited to 'kernel/hrtimer.c')
| -rw-r--r-- | kernel/hrtimer.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 2b6e1757aedd..14bc9cfa6399 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -418,8 +418,19 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) | |||
| 418 | /* Switch the timer base, if necessary: */ | 418 | /* Switch the timer base, if necessary: */ |
| 419 | new_base = switch_hrtimer_base(timer, base); | 419 | new_base = switch_hrtimer_base(timer, base); |
| 420 | 420 | ||
| 421 | if (mode == HRTIMER_REL) | 421 | if (mode == HRTIMER_REL) { |
| 422 | tim = ktime_add(tim, new_base->get_time()); | 422 | tim = ktime_add(tim, new_base->get_time()); |
| 423 | /* | ||
| 424 | * CONFIG_TIME_LOW_RES is a temporary way for architectures | ||
| 425 | * to signal that they simply return xtime in | ||
| 426 | * do_gettimeoffset(). In this case we want to round up by | ||
| 427 | * resolution when starting a relative timer, to avoid short | ||
| 428 | * timeouts. This will go away with the GTOD framework. | ||
| 429 | */ | ||
| 430 | #ifdef CONFIG_TIME_LOW_RES | ||
| 431 | tim = ktime_add(tim, base->resolution); | ||
| 432 | #endif | ||
| 433 | } | ||
| 423 | timer->expires = tim; | 434 | timer->expires = tim; |
| 424 | 435 | ||
| 425 | enqueue_hrtimer(timer, new_base); | 436 | enqueue_hrtimer(timer, new_base); |
| @@ -494,6 +505,41 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) | |||
| 494 | return rem; | 505 | return rem; |
| 495 | } | 506 | } |
| 496 | 507 | ||
| 508 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 509 | /** | ||
| 510 | * hrtimer_get_next_event - get the time until next expiry event | ||
| 511 | * | ||
| 512 | * Returns the delta to the next expiry event or KTIME_MAX if no timer | ||
| 513 | * is pending. | ||
| 514 | */ | ||
| 515 | ktime_t hrtimer_get_next_event(void) | ||
| 516 | { | ||
| 517 | struct hrtimer_base *base = __get_cpu_var(hrtimer_bases); | ||
| 518 | ktime_t delta, mindelta = { .tv64 = KTIME_MAX }; | ||
| 519 | unsigned long flags; | ||
| 520 | int i; | ||
| 521 | |||
| 522 | for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) { | ||
| 523 | struct hrtimer *timer; | ||
| 524 | |||
| 525 | spin_lock_irqsave(&base->lock, flags); | ||
| 526 | if (!base->first) { | ||
| 527 | spin_unlock_irqrestore(&base->lock, flags); | ||
| 528 | continue; | ||
| 529 | } | ||
| 530 | timer = rb_entry(base->first, struct hrtimer, node); | ||
| 531 | delta.tv64 = timer->expires.tv64; | ||
| 532 | spin_unlock_irqrestore(&base->lock, flags); | ||
| 533 | delta = ktime_sub(delta, base->get_time()); | ||
| 534 | if (delta.tv64 < mindelta.tv64) | ||
| 535 | mindelta.tv64 = delta.tv64; | ||
| 536 | } | ||
| 537 | if (mindelta.tv64 < 0) | ||
| 538 | mindelta.tv64 = 0; | ||
| 539 | return mindelta; | ||
| 540 | } | ||
| 541 | #endif | ||
| 542 | |||
| 497 | /** | 543 | /** |
| 498 | * hrtimer_init - initialize a timer to the given clock | 544 | * hrtimer_init - initialize a timer to the given clock |
| 499 | * | 545 | * |
