diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-06-04 17:13:29 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-06-10 08:43:37 -0400 |
commit | 09e99da766a6a701eb4d72004872d1144291d53b (patch) | |
tree | cbf87ed10f6c64c7669ddd68e539e6d3b474e546 /arch/x86/xen | |
parent | a05e2c371fbe73403793d126ceab93787cb4afd4 (diff) |
xen/time: Free onlined per-cpu data structure if we want to online it again.
If the per-cpu time data structure has been onlined already and
we are trying to online it again, then free the previous copy
before blindly over-writting it.
A developer naturally should not call this function multiple times
but just in case.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r-- | arch/x86/xen/time.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 6a56ae092994..aec0b14b6d76 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -401,6 +401,20 @@ static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) | |||
401 | return ret; | 401 | return ret; |
402 | } | 402 | } |
403 | 403 | ||
404 | void xen_teardown_timer(int cpu) | ||
405 | { | ||
406 | struct clock_event_device *evt; | ||
407 | BUG_ON(cpu == 0); | ||
408 | evt = &per_cpu(xen_clock_events, cpu).evt; | ||
409 | |||
410 | if (evt->irq >= 0) { | ||
411 | unbind_from_irqhandler(evt->irq, NULL); | ||
412 | evt->irq = -1; | ||
413 | kfree(per_cpu(xen_clock_events, cpu).name); | ||
414 | per_cpu(xen_clock_events, cpu).name = NULL; | ||
415 | } | ||
416 | } | ||
417 | |||
404 | void xen_setup_timer(int cpu) | 418 | void xen_setup_timer(int cpu) |
405 | { | 419 | { |
406 | char *name; | 420 | char *name; |
@@ -409,6 +423,8 @@ void xen_setup_timer(int cpu) | |||
409 | 423 | ||
410 | evt = &per_cpu(xen_clock_events, cpu).evt; | 424 | evt = &per_cpu(xen_clock_events, cpu).evt; |
411 | WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); | 425 | WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); |
426 | if (evt->irq >= 0) | ||
427 | xen_teardown_timer(cpu); | ||
412 | 428 | ||
413 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); | 429 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); |
414 | 430 | ||
@@ -429,19 +445,6 @@ void xen_setup_timer(int cpu) | |||
429 | per_cpu(xen_clock_events, cpu).name = name; | 445 | per_cpu(xen_clock_events, cpu).name = name; |
430 | } | 446 | } |
431 | 447 | ||
432 | void xen_teardown_timer(int cpu) | ||
433 | { | ||
434 | struct clock_event_device *evt; | ||
435 | BUG_ON(cpu == 0); | ||
436 | evt = &per_cpu(xen_clock_events, cpu).evt; | ||
437 | |||
438 | if (evt->irq >= 0) { | ||
439 | unbind_from_irqhandler(evt->irq, NULL); | ||
440 | evt->irq = -1; | ||
441 | kfree(per_cpu(xen_clock_events, cpu).name); | ||
442 | per_cpu(xen_clock_events, cpu).name = NULL; | ||
443 | } | ||
444 | } | ||
445 | 448 | ||
446 | void xen_setup_cpu_clockevents(void) | 449 | void xen_setup_cpu_clockevents(void) |
447 | { | 450 | { |