aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/oprofile
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-03-23 06:13:05 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-03-23 06:13:24 -0400
commitb03d541aa45b52e1b723890121a9fe3920eb438b (patch)
tree923c4bc9c618614634b536199ec1e4d1c74cdc83 /arch/s390/oprofile
parent61d84979ab9826c292812059f99248603da28fba (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.c52
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
39DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); 32DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer);
40 33
41struct hws_execute_parms { 34struct 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 */
236static void hws_ext_handler(struct ext_code ext_code, 228static 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
239static void worker(struct work_struct *work); 243static 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
676static 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
688static int check_qsi_on_setup(void) 680static 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}