diff options
| -rw-r--r-- | arch/x86/kernel/uv_time.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/kernel/uv_time.c index 583f11d5c480..ec14889628e0 100644 --- a/arch/x86/kernel/uv_time.c +++ b/arch/x86/kernel/uv_time.c | |||
| @@ -123,7 +123,10 @@ static int uv_setup_intr(int cpu, u64 expires) | |||
| 123 | /* Initialize comparator value */ | 123 | /* Initialize comparator value */ |
| 124 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires); | 124 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires); |
| 125 | 125 | ||
| 126 | return (expires < uv_read_rtc(NULL) && !uv_intr_pending(pnode)); | 126 | if (uv_read_rtc(NULL) <= expires) |
| 127 | return 0; | ||
| 128 | |||
| 129 | return !uv_intr_pending(pnode); | ||
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | /* | 132 | /* |
| @@ -223,6 +226,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) | |||
| 223 | 226 | ||
| 224 | next_cpu = head->next_cpu; | 227 | next_cpu = head->next_cpu; |
| 225 | *t = expires; | 228 | *t = expires; |
| 229 | |||
| 226 | /* Will this one be next to go off? */ | 230 | /* Will this one be next to go off? */ |
| 227 | if (next_cpu < 0 || bcpu == next_cpu || | 231 | if (next_cpu < 0 || bcpu == next_cpu || |
| 228 | expires < head->cpu[next_cpu].expires) { | 232 | expires < head->cpu[next_cpu].expires) { |
| @@ -231,7 +235,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) | |||
| 231 | *t = ULLONG_MAX; | 235 | *t = ULLONG_MAX; |
| 232 | uv_rtc_find_next_timer(head, pnode); | 236 | uv_rtc_find_next_timer(head, pnode); |
| 233 | spin_unlock_irqrestore(&head->lock, flags); | 237 | spin_unlock_irqrestore(&head->lock, flags); |
| 234 | return 1; | 238 | return -ETIME; |
| 235 | } | 239 | } |
| 236 | } | 240 | } |
| 237 | 241 | ||
| @@ -244,7 +248,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) | |||
| 244 | * | 248 | * |
| 245 | * Returns 1 if this timer was pending. | 249 | * Returns 1 if this timer was pending. |
| 246 | */ | 250 | */ |
| 247 | static int uv_rtc_unset_timer(int cpu) | 251 | static int uv_rtc_unset_timer(int cpu, int force) |
| 248 | { | 252 | { |
| 249 | int pnode = uv_cpu_to_pnode(cpu); | 253 | int pnode = uv_cpu_to_pnode(cpu); |
| 250 | int bid = uv_cpu_to_blade_id(cpu); | 254 | int bid = uv_cpu_to_blade_id(cpu); |
| @@ -256,14 +260,15 @@ static int uv_rtc_unset_timer(int cpu) | |||
| 256 | 260 | ||
| 257 | spin_lock_irqsave(&head->lock, flags); | 261 | spin_lock_irqsave(&head->lock, flags); |
| 258 | 262 | ||
| 259 | if (head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) | 263 | if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force) |
| 260 | rc = 1; | 264 | rc = 1; |
| 261 | 265 | ||
| 262 | *t = ULLONG_MAX; | 266 | if (rc) { |
| 263 | 267 | *t = ULLONG_MAX; | |
| 264 | /* Was the hardware setup for this timer? */ | 268 | /* Was the hardware setup for this timer? */ |
| 265 | if (head->next_cpu == bcpu) | 269 | if (head->next_cpu == bcpu) |
| 266 | uv_rtc_find_next_timer(head, pnode); | 270 | uv_rtc_find_next_timer(head, pnode); |
| 271 | } | ||
| 267 | 272 | ||
| 268 | spin_unlock_irqrestore(&head->lock, flags); | 273 | spin_unlock_irqrestore(&head->lock, flags); |
| 269 | 274 | ||
| @@ -310,20 +315,20 @@ static void uv_rtc_timer_setup(enum clock_event_mode mode, | |||
| 310 | break; | 315 | break; |
| 311 | case CLOCK_EVT_MODE_UNUSED: | 316 | case CLOCK_EVT_MODE_UNUSED: |
| 312 | case CLOCK_EVT_MODE_SHUTDOWN: | 317 | case CLOCK_EVT_MODE_SHUTDOWN: |
| 313 | uv_rtc_unset_timer(ced_cpu); | 318 | uv_rtc_unset_timer(ced_cpu, 1); |
| 314 | break; | 319 | break; |
| 315 | } | 320 | } |
| 316 | } | 321 | } |
| 317 | 322 | ||
| 318 | static void uv_rtc_interrupt(void) | 323 | static void uv_rtc_interrupt(void) |
| 319 | { | 324 | { |
| 320 | struct clock_event_device *ced = &__get_cpu_var(cpu_ced); | ||
| 321 | int cpu = smp_processor_id(); | 325 | int cpu = smp_processor_id(); |
| 326 | struct clock_event_device *ced = &per_cpu(cpu_ced, cpu); | ||
| 322 | 327 | ||
| 323 | if (!ced || !ced->event_handler) | 328 | if (!ced || !ced->event_handler) |
| 324 | return; | 329 | return; |
| 325 | 330 | ||
| 326 | if (uv_rtc_unset_timer(cpu) != 1) | 331 | if (uv_rtc_unset_timer(cpu, 0) != 1) |
| 327 | return; | 332 | return; |
| 328 | 333 | ||
| 329 | ced->event_handler(ced); | 334 | ced->event_handler(ced); |
