diff options
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/process.c | 3 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 45 |
2 files changed, 13 insertions, 35 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 56d75afedbf7..aef494b6b81a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "linux/ptrace.h" | 13 | #include "linux/ptrace.h" |
14 | #include "linux/random.h" | 14 | #include "linux/random.h" |
15 | #include "linux/sched.h" | 15 | #include "linux/sched.h" |
16 | #include "linux/tick.h" | ||
16 | #include "linux/threads.h" | 17 | #include "linux/threads.h" |
17 | #include "asm/pgtable.h" | 18 | #include "asm/pgtable.h" |
18 | #include "asm/uaccess.h" | 19 | #include "asm/uaccess.h" |
@@ -244,9 +245,11 @@ void default_idle(void) | |||
244 | if (need_resched()) | 245 | if (need_resched()) |
245 | schedule(); | 246 | schedule(); |
246 | 247 | ||
248 | tick_nohz_stop_sched_tick(); | ||
247 | switch_timers(1); | 249 | switch_timers(1); |
248 | idle_sleep(10); | 250 | idle_sleep(10); |
249 | switch_timers(0); | 251 | switch_timers(0); |
252 | tick_nohz_restart_sched_tick(); | ||
250 | } | 253 | } |
251 | } | 254 | } |
252 | 255 | ||
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 3cb7135e5c47..2acdc7efb2ac 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -20,41 +20,12 @@ unsigned long long sched_clock(void) | |||
20 | return (unsigned long long)jiffies_64 * (1000000000 / HZ); | 20 | return (unsigned long long)jiffies_64 * (1000000000 / HZ); |
21 | } | 21 | } |
22 | 22 | ||
23 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | ||
24 | static unsigned long long prev_nsecs[NR_CPUS]; | ||
25 | static long long delta[NR_CPUS]; /* Deviation per interval */ | ||
26 | #endif | ||
27 | |||
28 | void timer_handler(int sig, struct uml_pt_regs *regs) | 23 | void timer_handler(int sig, struct uml_pt_regs *regs) |
29 | { | 24 | { |
30 | unsigned long long ticks = 0; | ||
31 | unsigned long flags; | 25 | unsigned long flags; |
32 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | ||
33 | int c = cpu(); | ||
34 | if (prev_nsecs[c]) { | ||
35 | /* We've had 1 tick */ | ||
36 | unsigned long long nsecs = os_nsecs(); | ||
37 | |||
38 | delta[c] += nsecs - prev_nsecs[c]; | ||
39 | prev_nsecs[c] = nsecs; | ||
40 | |||
41 | /* Protect against the host clock being set backwards */ | ||
42 | if (delta[c] < 0) | ||
43 | delta[c] = 0; | ||
44 | |||
45 | ticks += (delta[c] * HZ) / BILLION; | ||
46 | delta[c] -= (ticks * BILLION) / HZ; | ||
47 | } | ||
48 | else prev_nsecs[c] = os_nsecs(); | ||
49 | #else | ||
50 | ticks = 1; | ||
51 | #endif | ||
52 | 26 | ||
53 | local_irq_save(flags); | 27 | local_irq_save(flags); |
54 | while (ticks > 0) { | 28 | do_IRQ(TIMER_IRQ, regs); |
55 | do_IRQ(TIMER_IRQ, regs); | ||
56 | ticks--; | ||
57 | } | ||
58 | local_irq_restore(flags); | 29 | local_irq_restore(flags); |
59 | } | 30 | } |
60 | 31 | ||
@@ -68,10 +39,8 @@ static void itimer_set_mode(enum clock_event_mode mode, | |||
68 | 39 | ||
69 | case CLOCK_EVT_MODE_SHUTDOWN: | 40 | case CLOCK_EVT_MODE_SHUTDOWN: |
70 | case CLOCK_EVT_MODE_UNUSED: | 41 | case CLOCK_EVT_MODE_UNUSED: |
71 | disable_timer(); | ||
72 | break; | ||
73 | case CLOCK_EVT_MODE_ONESHOT: | 42 | case CLOCK_EVT_MODE_ONESHOT: |
74 | BUG(); | 43 | disable_timer(); |
75 | break; | 44 | break; |
76 | 45 | ||
77 | case CLOCK_EVT_MODE_RESUME: | 46 | case CLOCK_EVT_MODE_RESUME: |
@@ -79,13 +48,19 @@ static void itimer_set_mode(enum clock_event_mode mode, | |||
79 | } | 48 | } |
80 | } | 49 | } |
81 | 50 | ||
51 | static int itimer_next_event(unsigned long delta, | ||
52 | struct clock_event_device *evt) | ||
53 | { | ||
54 | return timer_one_shot(delta + 1); | ||
55 | } | ||
56 | |||
82 | static struct clock_event_device itimer_clockevent = { | 57 | static struct clock_event_device itimer_clockevent = { |
83 | .name = "itimer", | 58 | .name = "itimer", |
84 | .rating = 250, | 59 | .rating = 250, |
85 | .cpumask = CPU_MASK_ALL, | 60 | .cpumask = CPU_MASK_ALL, |
86 | .features = CLOCK_EVT_FEAT_PERIODIC, | 61 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
87 | .set_mode = itimer_set_mode, | 62 | .set_mode = itimer_set_mode, |
88 | .set_next_event = NULL, | 63 | .set_next_event = itimer_next_event, |
89 | .shift = 32, | 64 | .shift = 32, |
90 | .irq = 0, | 65 | .irq = 0, |
91 | }; | 66 | }; |