diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-07 14:01:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-07 14:01:26 -0500 |
commit | 2c5ea0f2d8c7d4883dd0d8ec3c7e3f3640b4f814 (patch) | |
tree | f6412441325195c16351822cff8da5f2ed5f1cfe | |
parent | fa2dd441df28b9fdfc68f84ae66f1b507cfff0e4 (diff) | |
parent | e17bcb43a26a7111f851b5ff6d1258ecd355de75 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
* git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86:
ACPI: move timer broadcast before busmaster disable
clockevents: warn once when program_event() is called with negative expiry
hrtimers: avoid overflow for large relative timeouts
-rw-r--r-- | drivers/acpi/processor_idle.c | 19 | ||||
-rw-r--r-- | kernel/hrtimer.c | 8 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 5 |
3 files changed, 27 insertions, 5 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b1fbee3f7fe1..2fe34cc73c13 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -531,6 +531,11 @@ static void acpi_processor_idle(void) | |||
531 | 531 | ||
532 | case ACPI_STATE_C3: | 532 | case ACPI_STATE_C3: |
533 | /* | 533 | /* |
534 | * Must be done before busmaster disable as we might | ||
535 | * need to access HPET ! | ||
536 | */ | ||
537 | acpi_state_timer_broadcast(pr, cx, 1); | ||
538 | /* | ||
534 | * disable bus master | 539 | * disable bus master |
535 | * bm_check implies we need ARB_DIS | 540 | * bm_check implies we need ARB_DIS |
536 | * !bm_check implies we need cache flush | 541 | * !bm_check implies we need cache flush |
@@ -557,7 +562,6 @@ static void acpi_processor_idle(void) | |||
557 | /* Get start time (ticks) */ | 562 | /* Get start time (ticks) */ |
558 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 563 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
559 | /* Invoke C3 */ | 564 | /* Invoke C3 */ |
560 | acpi_state_timer_broadcast(pr, cx, 1); | ||
561 | /* Tell the scheduler that we are going deep-idle: */ | 565 | /* Tell the scheduler that we are going deep-idle: */ |
562 | sched_clock_idle_sleep_event(); | 566 | sched_clock_idle_sleep_event(); |
563 | acpi_cstate_enter(cx); | 567 | acpi_cstate_enter(cx); |
@@ -1401,9 +1405,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1401 | if (acpi_idle_suspend) | 1405 | if (acpi_idle_suspend) |
1402 | return(acpi_idle_enter_c1(dev, state)); | 1406 | return(acpi_idle_enter_c1(dev, state)); |
1403 | 1407 | ||
1404 | if (pr->flags.bm_check) | ||
1405 | acpi_idle_update_bm_rld(pr, cx); | ||
1406 | |||
1407 | local_irq_disable(); | 1408 | local_irq_disable(); |
1408 | current_thread_info()->status &= ~TS_POLLING; | 1409 | current_thread_info()->status &= ~TS_POLLING; |
1409 | /* | 1410 | /* |
@@ -1418,13 +1419,21 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1418 | return 0; | 1419 | return 0; |
1419 | } | 1420 | } |
1420 | 1421 | ||
1422 | /* | ||
1423 | * Must be done before busmaster disable as we might need to | ||
1424 | * access HPET ! | ||
1425 | */ | ||
1426 | acpi_state_timer_broadcast(pr, cx, 1); | ||
1427 | |||
1428 | if (pr->flags.bm_check) | ||
1429 | acpi_idle_update_bm_rld(pr, cx); | ||
1430 | |||
1421 | if (cx->type == ACPI_STATE_C3) | 1431 | if (cx->type == ACPI_STATE_C3) |
1422 | ACPI_FLUSH_CPU_CACHE(); | 1432 | ACPI_FLUSH_CPU_CACHE(); |
1423 | 1433 | ||
1424 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1434 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1425 | /* Tell the scheduler that we are going deep-idle: */ | 1435 | /* Tell the scheduler that we are going deep-idle: */ |
1426 | sched_clock_idle_sleep_event(); | 1436 | sched_clock_idle_sleep_event(); |
1427 | acpi_state_timer_broadcast(pr, cx, 1); | ||
1428 | acpi_idle_do_entry(cx); | 1437 | acpi_idle_do_entry(cx); |
1429 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1438 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1430 | 1439 | ||
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 22a25142e4cf..e65dd0b47cdc 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -850,6 +850,14 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) | |||
850 | #ifdef CONFIG_TIME_LOW_RES | 850 | #ifdef CONFIG_TIME_LOW_RES |
851 | tim = ktime_add(tim, base->resolution); | 851 | tim = ktime_add(tim, base->resolution); |
852 | #endif | 852 | #endif |
853 | /* | ||
854 | * Careful here: User space might have asked for a | ||
855 | * very long sleep, so the add above might result in a | ||
856 | * negative number, which enqueues the timer in front | ||
857 | * of the queue. | ||
858 | */ | ||
859 | if (tim.tv64 < 0) | ||
860 | tim.tv64 = KTIME_MAX; | ||
853 | } | 861 | } |
854 | timer->expires = tim; | 862 | timer->expires = tim; |
855 | 863 | ||
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 822beebe664a..5fb139fef9fa 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -78,6 +78,11 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, | |||
78 | unsigned long long clc; | 78 | unsigned long long clc; |
79 | int64_t delta; | 79 | int64_t delta; |
80 | 80 | ||
81 | if (unlikely(expires.tv64 < 0)) { | ||
82 | WARN_ON_ONCE(1); | ||
83 | return -ETIME; | ||
84 | } | ||
85 | |||
81 | delta = ktime_to_ns(ktime_sub(expires, now)); | 86 | delta = ktime_to_ns(ktime_sub(expires, now)); |
82 | 87 | ||
83 | if (delta <= 0) | 88 | if (delta <= 0) |