diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-09 08:33:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-09 08:33:00 -0400 |
commit | 9fd87545c97b91cf9cfa52e914d66863878efe60 (patch) | |
tree | 896bb43afb2fcda367390a32a16f5a98728b91bc | |
parent | 14e2acd8686507f8dee6d6269760d9ed145b2a89 (diff) | |
parent | 2075eb8d95612cadde91ef5be82691d97a2ea6c5 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-hrtimer into timers/range-hrtimers
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 7 | ||||
-rw-r--r-- | include/linux/hrtimer.h | 7 | ||||
-rw-r--r-- | kernel/futex.c | 6 | ||||
-rw-r--r-- | kernel/hrtimer.c | 37 |
4 files changed, 55 insertions, 2 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 5ce07b517c58..2e3148499368 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
17 | #include <linux/cpuidle.h> | 17 | #include <linux/cpuidle.h> |
18 | #include <linux/ktime.h> | 18 | #include <linux/ktime.h> |
19 | #include <linux/hrtimer.h> | ||
19 | 20 | ||
20 | #include "cpuidle.h" | 21 | #include "cpuidle.h" |
21 | 22 | ||
@@ -60,6 +61,12 @@ static void cpuidle_idle_call(void) | |||
60 | return; | 61 | return; |
61 | } | 62 | } |
62 | 63 | ||
64 | /* | ||
65 | * run any timers that can be run now, at this point | ||
66 | * before calculating the idle duration etc. | ||
67 | */ | ||
68 | hrtimer_peek_ahead_timers(); | ||
69 | |||
63 | /* ask the governor for the next state */ | 70 | /* ask the governor for the next state */ |
64 | next_state = cpuidle_curr_governor->select(dev); | 71 | next_state = cpuidle_curr_governor->select(dev); |
65 | if (need_resched()) | 72 | if (need_resched()) |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 95db11f62ff2..508ce20b8f9c 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) | |||
283 | return timer->base->cpu_base->hres_active; | 283 | return timer->base->cpu_base->hres_active; |
284 | } | 284 | } |
285 | 285 | ||
286 | extern void hrtimer_peek_ahead_timers(void); | ||
287 | |||
286 | /* | 288 | /* |
287 | * The resolution of the clocks. The resolution value is returned in | 289 | * The resolution of the clocks. The resolution value is returned in |
288 | * the clock_getres() system call to give application programmers an | 290 | * the clock_getres() system call to give application programmers an |
@@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) | |||
305 | * is expired in the next softirq when the clock was advanced. | 307 | * is expired in the next softirq when the clock was advanced. |
306 | */ | 308 | */ |
307 | static inline void clock_was_set(void) { } | 309 | static inline void clock_was_set(void) { } |
310 | static inline void hrtimer_peek_ahead_timers(void) { } | ||
308 | 311 | ||
309 | static inline void hres_timers_resume(void) { } | 312 | static inline void hres_timers_resume(void) { } |
310 | 313 | ||
@@ -326,6 +329,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) | |||
326 | extern ktime_t ktime_get(void); | 329 | extern ktime_t ktime_get(void); |
327 | extern ktime_t ktime_get_real(void); | 330 | extern ktime_t ktime_get_real(void); |
328 | 331 | ||
332 | |||
333 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); | ||
334 | |||
335 | |||
329 | /* Exported timer functions: */ | 336 | /* Exported timer functions: */ |
330 | 337 | ||
331 | /* Initialize timers: */ | 338 | /* Initialize timers: */ |
diff --git a/kernel/futex.c b/kernel/futex.c index 4cd5b4319b04..8af10027514b 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -1296,10 +1296,14 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1296 | if (!abs_time) | 1296 | if (!abs_time) |
1297 | schedule(); | 1297 | schedule(); |
1298 | else { | 1298 | else { |
1299 | unsigned long slack; | ||
1300 | slack = current->timer_slack_ns; | ||
1301 | if (rt_task(current)) | ||
1302 | slack = 0; | ||
1299 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, | 1303 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, |
1300 | HRTIMER_MODE_ABS); | 1304 | HRTIMER_MODE_ABS); |
1301 | hrtimer_init_sleeper(&t, current); | 1305 | hrtimer_init_sleeper(&t, current); |
1302 | hrtimer_set_expires(&t.timer, *abs_time); | 1306 | hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack); |
1303 | 1307 | ||
1304 | hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); | 1308 | hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); |
1305 | if (!hrtimer_active(&t.timer)) | 1309 | if (!hrtimer_active(&t.timer)) |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index a0222097c57e..eb2cf984959f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1381,6 +1381,36 @@ void hrtimer_interrupt(struct clock_event_device *dev) | |||
1381 | raise_softirq(HRTIMER_SOFTIRQ); | 1381 | raise_softirq(HRTIMER_SOFTIRQ); |
1382 | } | 1382 | } |
1383 | 1383 | ||
1384 | /** | ||
1385 | * hrtimer_peek_ahead_timers -- run soft-expired timers now | ||
1386 | * | ||
1387 | * hrtimer_peek_ahead_timers will peek at the timer queue of | ||
1388 | * the current cpu and check if there are any timers for which | ||
1389 | * the soft expires time has passed. If any such timers exist, | ||
1390 | * they are run immediately and then removed from the timer queue. | ||
1391 | * | ||
1392 | */ | ||
1393 | void hrtimer_peek_ahead_timers(void) | ||
1394 | { | ||
1395 | unsigned long flags; | ||
1396 | struct tick_device *td; | ||
1397 | struct clock_event_device *dev; | ||
1398 | |||
1399 | if (hrtimer_hres_active()) | ||
1400 | return; | ||
1401 | |||
1402 | local_irq_save(flags); | ||
1403 | td = &__get_cpu_var(tick_cpu_device); | ||
1404 | if (!td) | ||
1405 | goto out; | ||
1406 | dev = td->evtdev; | ||
1407 | if (!dev) | ||
1408 | goto out; | ||
1409 | hrtimer_interrupt(dev); | ||
1410 | out: | ||
1411 | local_irq_restore(flags); | ||
1412 | } | ||
1413 | |||
1384 | static void run_hrtimer_softirq(struct softirq_action *h) | 1414 | static void run_hrtimer_softirq(struct softirq_action *h) |
1385 | { | 1415 | { |
1386 | run_hrtimer_pending(&__get_cpu_var(hrtimer_bases)); | 1416 | run_hrtimer_pending(&__get_cpu_var(hrtimer_bases)); |
@@ -1563,9 +1593,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, | |||
1563 | struct restart_block *restart; | 1593 | struct restart_block *restart; |
1564 | struct hrtimer_sleeper t; | 1594 | struct hrtimer_sleeper t; |
1565 | int ret = 0; | 1595 | int ret = 0; |
1596 | unsigned long slack; | ||
1597 | |||
1598 | slack = current->timer_slack_ns; | ||
1599 | if (rt_task(current)) | ||
1600 | slack = 0; | ||
1566 | 1601 | ||
1567 | hrtimer_init_on_stack(&t.timer, clockid, mode); | 1602 | hrtimer_init_on_stack(&t.timer, clockid, mode); |
1568 | hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp)); | 1603 | hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); |
1569 | if (do_nanosleep(&t, mode)) | 1604 | if (do_nanosleep(&t, mode)) |
1570 | goto out; | 1605 | goto out; |
1571 | 1606 | ||