diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-19 11:04:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-19 11:04:23 -0500 |
commit | aa3f98037ce3bcf850bb41f7530754d27481a792 (patch) | |
tree | aa539f1e52ea35f7c9f7a3e6e2171d72863e51d4 /arch | |
parent | f6c427663a158056cd8ca71c01f30653e4b313f7 (diff) | |
parent | e5fa443ea05f71b5253818890c6d32174cbab36f (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] qdio: FCP/SCSI write I/O stagnates on LPAR
[S390] Fix futex_atomic_cmpxchg_std inline assembly.
[S390] dcss: Fix Unlikely(x) != y
[S390] sclp: clean up send/receive naming scheme
[S390] etr: fix compile error on !SMP
[S390] qdio: fix qdio_activate timeout handling.
[S390] Initialize per cpu lowcores on cpu hotplug.
[S390] find bit corner case.
[S390] dasd: fix locking in __dasd_device_process_final_queue
[S390] Make sure enabled wait psw is loaded in default_idle.
[S390] Let NR_CPUS default to 32/64 on s390/s390x.
[S390] cio: Do timed recovery on workqueue.
[S390] cio: Remember to initialize recovery_lock.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/Kconfig | 3 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 53 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_std.c | 8 |
5 files changed, 53 insertions, 28 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 92a4f7b4323a..b21444b681b6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -100,7 +100,8 @@ config NR_CPUS | |||
100 | int "Maximum number of CPUs (2-64)" | 100 | int "Maximum number of CPUs (2-64)" |
101 | range 2 64 | 101 | range 2 64 |
102 | depends on SMP | 102 | depends on SMP |
103 | default "32" | 103 | default "32" if !64BIT |
104 | default "64" if 64BIT | ||
104 | help | 105 | help |
105 | This allows you to specify the maximum number of CPUs which this | 106 | This allows you to specify the maximum number of CPUs which this |
106 | kernel will support. The maximum supported value is 64 and the | 107 | kernel will support. The maximum supported value is 64 and the |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index a6a4729e0e94..1c59ec161cf8 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -114,24 +114,27 @@ extern void s390_handle_mcck(void); | |||
114 | static void default_idle(void) | 114 | static void default_idle(void) |
115 | { | 115 | { |
116 | int cpu, rc; | 116 | int cpu, rc; |
117 | int nr_calls = 0; | ||
118 | void *hcpu; | ||
117 | #ifdef CONFIG_SMP | 119 | #ifdef CONFIG_SMP |
118 | struct s390_idle_data *idle; | 120 | struct s390_idle_data *idle; |
119 | #endif | 121 | #endif |
120 | 122 | ||
121 | /* CPU is going idle. */ | 123 | /* CPU is going idle. */ |
122 | cpu = smp_processor_id(); | 124 | cpu = smp_processor_id(); |
123 | 125 | hcpu = (void *)(long)cpu; | |
124 | local_irq_disable(); | 126 | local_irq_disable(); |
125 | if (need_resched()) { | 127 | if (need_resched()) { |
126 | local_irq_enable(); | 128 | local_irq_enable(); |
127 | return; | 129 | return; |
128 | } | 130 | } |
129 | 131 | ||
130 | rc = atomic_notifier_call_chain(&idle_chain, | 132 | rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1, |
131 | S390_CPU_IDLE, (void *)(long) cpu); | 133 | &nr_calls); |
132 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) | 134 | if (rc == NOTIFY_BAD) { |
133 | BUG(); | 135 | nr_calls--; |
134 | if (rc != NOTIFY_OK) { | 136 | __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, |
137 | hcpu, nr_calls, NULL); | ||
135 | local_irq_enable(); | 138 | local_irq_enable(); |
136 | return; | 139 | return; |
137 | } | 140 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 85060659fb12..818bd09c0260 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -626,13 +626,17 @@ static int __cpuinit smp_alloc_lowcore(int cpu) | |||
626 | if (!lowcore) | 626 | if (!lowcore) |
627 | return -ENOMEM; | 627 | return -ENOMEM; |
628 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | 628 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); |
629 | if (!async_stack) | ||
630 | goto out_async_stack; | ||
631 | panic_stack = __get_free_page(GFP_KERNEL); | 629 | panic_stack = __get_free_page(GFP_KERNEL); |
632 | if (!panic_stack) | 630 | if (!panic_stack || !async_stack) |
633 | goto out_panic_stack; | 631 | goto out; |
634 | 632 | /* | |
635 | *lowcore = S390_lowcore; | 633 | * Only need to copy the first 512 bytes from address 0. But since |
634 | * the compiler emits a warning if src == NULL for memcpy use copy_page | ||
635 | * instead. Copies more than needed but this code is not performance | ||
636 | * critical. | ||
637 | */ | ||
638 | copy_page(lowcore, &S390_lowcore); | ||
639 | memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512); | ||
636 | lowcore->async_stack = async_stack + ASYNC_SIZE; | 640 | lowcore->async_stack = async_stack + ASYNC_SIZE; |
637 | lowcore->panic_stack = panic_stack + PAGE_SIZE; | 641 | lowcore->panic_stack = panic_stack + PAGE_SIZE; |
638 | 642 | ||
@@ -653,9 +657,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu) | |||
653 | out_save_area: | 657 | out_save_area: |
654 | free_page(panic_stack); | 658 | free_page(panic_stack); |
655 | #endif | 659 | #endif |
656 | out_panic_stack: | 660 | out: |
657 | free_pages(async_stack, ASYNC_ORDER); | 661 | free_pages(async_stack, ASYNC_ORDER); |
658 | out_async_stack: | ||
659 | free_pages((unsigned long) lowcore, lc_order); | 662 | free_pages((unsigned long) lowcore, lc_order); |
660 | return -ENOMEM; | 663 | return -ENOMEM; |
661 | } | 664 | } |
@@ -719,8 +722,8 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
719 | cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; | 722 | cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; |
720 | cpu_lowcore->current_task = (unsigned long) idle; | 723 | cpu_lowcore->current_task = (unsigned long) idle; |
721 | cpu_lowcore->cpu_data.cpu_nr = cpu; | 724 | cpu_lowcore->cpu_data.cpu_nr = cpu; |
722 | cpu_lowcore->softirq_pending = 0; | 725 | cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce; |
723 | cpu_lowcore->ext_call_fast = 0; | 726 | cpu_lowcore->ipl_device = S390_lowcore.ipl_device; |
724 | eieio(); | 727 | eieio(); |
725 | 728 | ||
726 | while (signal_processor(cpu, sigp_restart) == sigp_busy) | 729 | while (signal_processor(cpu, sigp_restart) == sigp_busy) |
@@ -797,23 +800,43 @@ void cpu_die(void) | |||
797 | 800 | ||
798 | void __init smp_prepare_cpus(unsigned int max_cpus) | 801 | void __init smp_prepare_cpus(unsigned int max_cpus) |
799 | { | 802 | { |
803 | #ifndef CONFIG_64BIT | ||
804 | unsigned long save_area = 0; | ||
805 | #endif | ||
806 | unsigned long async_stack, panic_stack; | ||
807 | struct _lowcore *lowcore; | ||
800 | unsigned int cpu; | 808 | unsigned int cpu; |
809 | int lc_order; | ||
801 | 810 | ||
802 | smp_detect_cpus(); | 811 | smp_detect_cpus(); |
803 | 812 | ||
804 | /* request the 0x1201 emergency signal external interrupt */ | 813 | /* request the 0x1201 emergency signal external interrupt */ |
805 | if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) | 814 | if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) |
806 | panic("Couldn't request external interrupt 0x1201"); | 815 | panic("Couldn't request external interrupt 0x1201"); |
807 | memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); | ||
808 | print_cpu_info(&S390_lowcore.cpu_data); | 816 | print_cpu_info(&S390_lowcore.cpu_data); |
809 | smp_alloc_lowcore(smp_processor_id()); | ||
810 | 817 | ||
818 | /* Reallocate current lowcore, but keep its contents. */ | ||
819 | lc_order = sizeof(long) == 8 ? 1 : 0; | ||
820 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); | ||
821 | panic_stack = __get_free_page(GFP_KERNEL); | ||
822 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | ||
811 | #ifndef CONFIG_64BIT | 823 | #ifndef CONFIG_64BIT |
812 | if (MACHINE_HAS_IEEE) | 824 | if (MACHINE_HAS_IEEE) |
813 | ctl_set_bit(14, 29); /* enable extended save area */ | 825 | save_area = get_zeroed_page(GFP_KERNEL); |
814 | #endif | 826 | #endif |
815 | set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); | 827 | local_irq_disable(); |
816 | 828 | local_mcck_disable(); | |
829 | lowcore_ptr[smp_processor_id()] = lowcore; | ||
830 | *lowcore = S390_lowcore; | ||
831 | lowcore->panic_stack = panic_stack + PAGE_SIZE; | ||
832 | lowcore->async_stack = async_stack + ASYNC_SIZE; | ||
833 | #ifndef CONFIG_64BIT | ||
834 | if (MACHINE_HAS_IEEE) | ||
835 | lowcore->extended_save_area_addr = (u32) save_area; | ||
836 | #endif | ||
837 | set_prefix((u32)(unsigned long) lowcore); | ||
838 | local_mcck_enable(); | ||
839 | local_irq_enable(); | ||
817 | for_each_possible_cpu(cpu) | 840 | for_each_possible_cpu(cpu) |
818 | if (cpu != smp_processor_id()) | 841 | if (cpu != smp_processor_id()) |
819 | smp_create_idle(cpu); | 842 | smp_create_idle(cpu); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 3bbac1293be4..76a5dd1b4ce9 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -744,7 +744,6 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay) | |||
744 | } | 744 | } |
745 | } | 745 | } |
746 | 746 | ||
747 | #ifdef CONFIG_SMP | ||
748 | static void etr_sync_cpu_start(void *dummy) | 747 | static void etr_sync_cpu_start(void *dummy) |
749 | { | 748 | { |
750 | int *in_sync = dummy; | 749 | int *in_sync = dummy; |
@@ -777,7 +776,6 @@ static void etr_sync_cpu_start(void *dummy) | |||
777 | static void etr_sync_cpu_end(void *dummy) | 776 | static void etr_sync_cpu_end(void *dummy) |
778 | { | 777 | { |
779 | } | 778 | } |
780 | #endif /* CONFIG_SMP */ | ||
781 | 779 | ||
782 | /* | 780 | /* |
783 | * Sync the TOD clock using the port refered to by aibp. This port | 781 | * Sync the TOD clock using the port refered to by aibp. This port |
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 28c4500a58d0..d2ffbadb51a7 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval) | |||
293 | 293 | ||
294 | asm volatile( | 294 | asm volatile( |
295 | " sacf 256\n" | 295 | " sacf 256\n" |
296 | " cs %1,%4,0(%5)\n" | 296 | "0: cs %1,%4,0(%5)\n" |
297 | "0: lr %0,%1\n" | 297 | "1: lr %0,%1\n" |
298 | "1: sacf 0\n" | 298 | "2: sacf 0\n" |
299 | EX_TABLE(0b,1b) | 299 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) |
300 | : "=d" (ret), "+d" (oldval), "=m" (*uaddr) | 300 | : "=d" (ret), "+d" (oldval), "=m" (*uaddr) |
301 | : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) | 301 | : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) |
302 | : "cc", "memory" ); | 302 | : "cc", "memory" ); |