diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 3ed5c7a83c6c..9c0ccb532a45 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <asm/lowcore.h> | 47 | #include <asm/lowcore.h> |
48 | #include <asm/sclp.h> | 48 | #include <asm/sclp.h> |
49 | #include <asm/cpu.h> | 49 | #include <asm/cpu.h> |
50 | #include <asm/vdso.h> | ||
50 | #include "entry.h" | 51 | #include "entry.h" |
51 | 52 | ||
52 | /* | 53 | /* |
@@ -500,6 +501,9 @@ static int __cpuinit smp_alloc_lowcore(int cpu) | |||
500 | goto out; | 501 | goto out; |
501 | lowcore->extended_save_area_addr = (u32) save_area; | 502 | lowcore->extended_save_area_addr = (u32) save_area; |
502 | } | 503 | } |
504 | #else | ||
505 | if (vdso_alloc_per_cpu(cpu, lowcore)) | ||
506 | goto out; | ||
503 | #endif | 507 | #endif |
504 | lowcore_ptr[cpu] = lowcore; | 508 | lowcore_ptr[cpu] = lowcore; |
505 | return 0; | 509 | return 0; |
@@ -522,6 +526,8 @@ static void smp_free_lowcore(int cpu) | |||
522 | #ifndef CONFIG_64BIT | 526 | #ifndef CONFIG_64BIT |
523 | if (MACHINE_HAS_IEEE) | 527 | if (MACHINE_HAS_IEEE) |
524 | free_page((unsigned long) lowcore->extended_save_area_addr); | 528 | free_page((unsigned long) lowcore->extended_save_area_addr); |
529 | #else | ||
530 | vdso_free_per_cpu(cpu, lowcore); | ||
525 | #endif | 531 | #endif |
526 | free_page(lowcore->panic_stack - PAGE_SIZE); | 532 | free_page(lowcore->panic_stack - PAGE_SIZE); |
527 | free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); | 533 | free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); |
@@ -664,6 +670,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
664 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); | 670 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); |
665 | panic_stack = __get_free_page(GFP_KERNEL); | 671 | panic_stack = __get_free_page(GFP_KERNEL); |
666 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | 672 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); |
673 | BUG_ON(!lowcore || !panic_stack || !async_stack); | ||
667 | #ifndef CONFIG_64BIT | 674 | #ifndef CONFIG_64BIT |
668 | if (MACHINE_HAS_IEEE) | 675 | if (MACHINE_HAS_IEEE) |
669 | save_area = get_zeroed_page(GFP_KERNEL); | 676 | save_area = get_zeroed_page(GFP_KERNEL); |
@@ -677,6 +684,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
677 | #ifndef CONFIG_64BIT | 684 | #ifndef CONFIG_64BIT |
678 | if (MACHINE_HAS_IEEE) | 685 | if (MACHINE_HAS_IEEE) |
679 | lowcore->extended_save_area_addr = (u32) save_area; | 686 | lowcore->extended_save_area_addr = (u32) save_area; |
687 | #else | ||
688 | BUG_ON(vdso_alloc_per_cpu(smp_processor_id(), lowcore)); | ||
680 | #endif | 689 | #endif |
681 | set_prefix((u32)(unsigned long) lowcore); | 690 | set_prefix((u32)(unsigned long) lowcore); |
682 | local_mcck_enable(); | 691 | local_mcck_enable(); |
@@ -845,9 +854,11 @@ static ssize_t show_idle_count(struct sys_device *dev, | |||
845 | unsigned long long idle_count; | 854 | unsigned long long idle_count; |
846 | 855 | ||
847 | idle = &per_cpu(s390_idle, dev->id); | 856 | idle = &per_cpu(s390_idle, dev->id); |
848 | spin_lock_irq(&idle->lock); | 857 | spin_lock(&idle->lock); |
849 | idle_count = idle->idle_count; | 858 | idle_count = idle->idle_count; |
850 | spin_unlock_irq(&idle->lock); | 859 | if (idle->idle_enter) |
860 | idle_count++; | ||
861 | spin_unlock(&idle->lock); | ||
851 | return sprintf(buf, "%llu\n", idle_count); | 862 | return sprintf(buf, "%llu\n", idle_count); |
852 | } | 863 | } |
853 | static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL); | 864 | static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL); |
@@ -856,18 +867,17 @@ static ssize_t show_idle_time(struct sys_device *dev, | |||
856 | struct sysdev_attribute *attr, char *buf) | 867 | struct sysdev_attribute *attr, char *buf) |
857 | { | 868 | { |
858 | struct s390_idle_data *idle; | 869 | struct s390_idle_data *idle; |
859 | unsigned long long new_time; | 870 | unsigned long long now, idle_time, idle_enter; |
860 | 871 | ||
861 | idle = &per_cpu(s390_idle, dev->id); | 872 | idle = &per_cpu(s390_idle, dev->id); |
862 | spin_lock_irq(&idle->lock); | 873 | spin_lock(&idle->lock); |
863 | if (idle->in_idle) { | 874 | now = get_clock(); |
864 | new_time = get_clock(); | 875 | idle_time = idle->idle_time; |
865 | idle->idle_time += new_time - idle->idle_enter; | 876 | idle_enter = idle->idle_enter; |
866 | idle->idle_enter = new_time; | 877 | if (idle_enter != 0ULL && idle_enter < now) |
867 | } | 878 | idle_time += now - idle_enter; |
868 | new_time = idle->idle_time; | 879 | spin_unlock(&idle->lock); |
869 | spin_unlock_irq(&idle->lock); | 880 | return sprintf(buf, "%llu\n", idle_time >> 12); |
870 | return sprintf(buf, "%llu\n", new_time >> 12); | ||
871 | } | 881 | } |
872 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); | 882 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); |
873 | 883 | ||