diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2012-03-23 06:13:05 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-03-23 06:13:24 -0400 |
commit | b03d541aa45b52e1b723890121a9fe3920eb438b (patch) | |
tree | 923c4bc9c618614634b536199ec1e4d1c74cdc83 /arch/s390/oprofile | |
parent | 61d84979ab9826c292812059f99248603da28fba (diff) |
[S390] oprofile: Allow multiple users of the measurement alert interrupt
Prepare the measurement facility which is currently only used by oprofile
for multiple users. To achieve that the measurement alert interrupt control
bit needs to be protected. The measurement alert definitions are moved
to a header file and an interrupt mask is added so that users can discard
interrupts if they are for a different measurement subsystem.
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/oprofile')
-rw-r--r-- | arch/s390/oprofile/hwsampler.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index 12bea05a0fc1..f097d516d8c5 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c | |||
@@ -17,8 +17,7 @@ | |||
17 | #include <linux/semaphore.h> | 17 | #include <linux/semaphore.h> |
18 | #include <linux/oom.h> | 18 | #include <linux/oom.h> |
19 | #include <linux/oprofile.h> | 19 | #include <linux/oprofile.h> |
20 | 20 | #include <asm/cpu_mf.h> | |
21 | #include <asm/lowcore.h> | ||
22 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
23 | 22 | ||
24 | #include "hwsampler.h" | 23 | #include "hwsampler.h" |
@@ -30,12 +29,6 @@ | |||
30 | #define ALERT_REQ_MASK 0x4000000000000000ul | 29 | #define ALERT_REQ_MASK 0x4000000000000000ul |
31 | #define BUFFER_FULL_MASK 0x8000000000000000ul | 30 | #define BUFFER_FULL_MASK 0x8000000000000000ul |
32 | 31 | ||
33 | #define EI_IEA (1 << 31) /* invalid entry address */ | ||
34 | #define EI_ISE (1 << 30) /* incorrect SDBT entry */ | ||
35 | #define EI_PRA (1 << 29) /* program request alert */ | ||
36 | #define EI_SACA (1 << 23) /* sampler authorization change alert */ | ||
37 | #define EI_LSDA (1 << 22) /* loss of sample data alert */ | ||
38 | |||
39 | DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); | 32 | DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); |
40 | 33 | ||
41 | struct hws_execute_parms { | 34 | struct hws_execute_parms { |
@@ -232,9 +225,20 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v) | |||
232 | return (unsigned long *) ret; | 225 | return (unsigned long *) ret; |
233 | } | 226 | } |
234 | 227 | ||
235 | /* prototypes for external interrupt handler and worker */ | ||
236 | static void hws_ext_handler(struct ext_code ext_code, | 228 | static void hws_ext_handler(struct ext_code ext_code, |
237 | unsigned int param32, unsigned long param64); | 229 | unsigned int param32, unsigned long param64) |
230 | { | ||
231 | struct hws_cpu_buffer *cb = &__get_cpu_var(sampler_cpu_buffer); | ||
232 | |||
233 | if (!(param32 & CPU_MF_INT_SF_MASK)) | ||
234 | return; | ||
235 | |||
236 | kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; | ||
237 | atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); | ||
238 | |||
239 | if (hws_wq) | ||
240 | queue_work(hws_wq, &cb->worker); | ||
241 | } | ||
238 | 242 | ||
239 | static void worker(struct work_struct *work); | 243 | static void worker(struct work_struct *work); |
240 | 244 | ||
@@ -673,18 +677,6 @@ int hwsampler_activate(unsigned int cpu) | |||
673 | return rc; | 677 | return rc; |
674 | } | 678 | } |
675 | 679 | ||
676 | static void hws_ext_handler(struct ext_code ext_code, | ||
677 | unsigned int param32, unsigned long param64) | ||
678 | { | ||
679 | struct hws_cpu_buffer *cb; | ||
680 | |||
681 | kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; | ||
682 | cb = &__get_cpu_var(sampler_cpu_buffer); | ||
683 | atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); | ||
684 | if (hws_wq) | ||
685 | queue_work(hws_wq, &cb->worker); | ||
686 | } | ||
687 | |||
688 | static int check_qsi_on_setup(void) | 680 | static int check_qsi_on_setup(void) |
689 | { | 681 | { |
690 | int rc; | 682 | int rc; |
@@ -760,23 +752,23 @@ static int worker_check_error(unsigned int cpu, int ext_params) | |||
760 | if (!sdbt || !*sdbt) | 752 | if (!sdbt || !*sdbt) |
761 | return -EINVAL; | 753 | return -EINVAL; |
762 | 754 | ||
763 | if (ext_params & EI_PRA) | 755 | if (ext_params & CPU_MF_INT_SF_PRA) |
764 | cb->req_alert++; | 756 | cb->req_alert++; |
765 | 757 | ||
766 | if (ext_params & EI_LSDA) | 758 | if (ext_params & CPU_MF_INT_SF_LSDA) |
767 | cb->loss_of_sample_data++; | 759 | cb->loss_of_sample_data++; |
768 | 760 | ||
769 | if (ext_params & EI_IEA) { | 761 | if (ext_params & CPU_MF_INT_SF_IAE) { |
770 | cb->invalid_entry_address++; | 762 | cb->invalid_entry_address++; |
771 | rc = -EINVAL; | 763 | rc = -EINVAL; |
772 | } | 764 | } |
773 | 765 | ||
774 | if (ext_params & EI_ISE) { | 766 | if (ext_params & CPU_MF_INT_SF_ISE) { |
775 | cb->incorrect_sdbt_entry++; | 767 | cb->incorrect_sdbt_entry++; |
776 | rc = -EINVAL; | 768 | rc = -EINVAL; |
777 | } | 769 | } |
778 | 770 | ||
779 | if (ext_params & EI_SACA) { | 771 | if (ext_params & CPU_MF_INT_SF_SACA) { |
780 | cb->sample_auth_change_alert++; | 772 | cb->sample_auth_change_alert++; |
781 | rc = -EINVAL; | 773 | rc = -EINVAL; |
782 | } | 774 | } |
@@ -1009,7 +1001,7 @@ int hwsampler_deallocate(void) | |||
1009 | if (hws_state != HWS_STOPPED) | 1001 | if (hws_state != HWS_STOPPED) |
1010 | goto deallocate_exit; | 1002 | goto deallocate_exit; |
1011 | 1003 | ||
1012 | ctl_clear_bit(0, 5); /* set bit 58 CR0 off */ | 1004 | measurement_alert_subclass_unregister(); |
1013 | deallocate_sdbt(); | 1005 | deallocate_sdbt(); |
1014 | 1006 | ||
1015 | hws_state = HWS_DEALLOCATED; | 1007 | hws_state = HWS_DEALLOCATED; |
@@ -1123,7 +1115,7 @@ int hwsampler_shutdown(void) | |||
1123 | mutex_lock(&hws_sem); | 1115 | mutex_lock(&hws_sem); |
1124 | 1116 | ||
1125 | if (hws_state == HWS_STOPPED) { | 1117 | if (hws_state == HWS_STOPPED) { |
1126 | ctl_clear_bit(0, 5); /* set bit 58 CR0 off */ | 1118 | measurement_alert_subclass_unregister(); |
1127 | deallocate_sdbt(); | 1119 | deallocate_sdbt(); |
1128 | } | 1120 | } |
1129 | if (hws_wq) { | 1121 | if (hws_wq) { |
@@ -1198,7 +1190,7 @@ start_all_exit: | |||
1198 | hws_oom = 1; | 1190 | hws_oom = 1; |
1199 | hws_flush_all = 0; | 1191 | hws_flush_all = 0; |
1200 | /* now let them in, 1407 CPUMF external interrupts */ | 1192 | /* now let them in, 1407 CPUMF external interrupts */ |
1201 | ctl_set_bit(0, 5); /* set CR0 bit 58 */ | 1193 | measurement_alert_subclass_register(); |
1202 | 1194 | ||
1203 | return 0; | 1195 | return 0; |
1204 | } | 1196 | } |