Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 296446
b: refs/heads/master
c: b03d541
h: refs/heads/master
v: v3
  • Loading branch information
Jan Glauber authored and Martin Schwidefsky committed Mar 23, 2012
1 parent bfd5fad commit c97511c
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 61d84979ab9826c292812059f99248603da28fba
refs/heads/master: b03d541aa45b52e1b723890121a9fe3920eb438b
12 changes: 12 additions & 0 deletions trunk/arch/s390/include/asm/cpu_mf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _ASM_S390_CPU_MF_H
#define _ASM_S390_CPU_MF_H

#define CPU_MF_INT_SF_MASK 0xffc00000

#define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */
#define CPU_MF_INT_SF_ISE (1 << 30) /* incorrect SDBT entry */
#define CPU_MF_INT_SF_PRA (1 << 29) /* program request alert */
#define CPU_MF_INT_SF_SACA (1 << 23) /* sampler auth. change alert */
#define CPU_MF_INT_SF_LSDA (1 << 22) /* loss of sample data alert */

#endif
2 changes: 2 additions & 0 deletions trunk/arch/s390/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler);
int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
void service_subclass_irq_register(void);
void service_subclass_irq_unregister(void);
void measurement_alert_subclass_register(void);
void measurement_alert_subclass_unregister(void);

#endif /* _ASM_IRQ_H */
23 changes: 23 additions & 0 deletions trunk/arch/s390/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,26 @@ void service_subclass_irq_unregister(void)
spin_unlock(&sc_irq_lock);
}
EXPORT_SYMBOL(service_subclass_irq_unregister);

static DEFINE_SPINLOCK(ma_subclass_lock);
static int ma_subclass_refcount;

void measurement_alert_subclass_register(void)
{
spin_lock(&ma_subclass_lock);
if (!ma_subclass_refcount)
ctl_set_bit(0, 5);
ma_subclass_refcount++;
spin_unlock(&ma_subclass_lock);
}
EXPORT_SYMBOL(measurement_alert_subclass_register);

void measurement_alert_subclass_unregister(void)
{
spin_lock(&ma_subclass_lock);
ma_subclass_refcount--;
if (!ma_subclass_refcount)
ctl_clear_bit(0, 5);
spin_unlock(&ma_subclass_lock);
}
EXPORT_SYMBOL(measurement_alert_subclass_unregister);
52 changes: 22 additions & 30 deletions trunk/arch/s390/oprofile/hwsampler.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
#include <linux/semaphore.h>
#include <linux/oom.h>
#include <linux/oprofile.h>

#include <asm/lowcore.h>
#include <asm/cpu_mf.h>
#include <asm/irq.h>

#include "hwsampler.h"
Expand All @@ -30,12 +29,6 @@
#define ALERT_REQ_MASK 0x4000000000000000ul
#define BUFFER_FULL_MASK 0x8000000000000000ul

#define EI_IEA (1 << 31) /* invalid entry address */
#define EI_ISE (1 << 30) /* incorrect SDBT entry */
#define EI_PRA (1 << 29) /* program request alert */
#define EI_SACA (1 << 23) /* sampler authorization change alert */
#define EI_LSDA (1 << 22) /* loss of sample data alert */

DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer);

struct hws_execute_parms {
Expand Down Expand Up @@ -232,9 +225,20 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
return (unsigned long *) ret;
}

/* prototypes for external interrupt handler and worker */
static void hws_ext_handler(struct ext_code ext_code,
unsigned int param32, unsigned long param64);
unsigned int param32, unsigned long param64)
{
struct hws_cpu_buffer *cb = &__get_cpu_var(sampler_cpu_buffer);

if (!(param32 & CPU_MF_INT_SF_MASK))
return;

kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);

if (hws_wq)
queue_work(hws_wq, &cb->worker);
}

static void worker(struct work_struct *work);

Expand Down Expand Up @@ -673,18 +677,6 @@ int hwsampler_activate(unsigned int cpu)
return rc;
}

static void hws_ext_handler(struct ext_code ext_code,
unsigned int param32, unsigned long param64)
{
struct hws_cpu_buffer *cb;

kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
cb = &__get_cpu_var(sampler_cpu_buffer);
atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);
if (hws_wq)
queue_work(hws_wq, &cb->worker);
}

static int check_qsi_on_setup(void)
{
int rc;
Expand Down Expand Up @@ -760,23 +752,23 @@ static int worker_check_error(unsigned int cpu, int ext_params)
if (!sdbt || !*sdbt)
return -EINVAL;

if (ext_params & EI_PRA)
if (ext_params & CPU_MF_INT_SF_PRA)
cb->req_alert++;

if (ext_params & EI_LSDA)
if (ext_params & CPU_MF_INT_SF_LSDA)
cb->loss_of_sample_data++;

if (ext_params & EI_IEA) {
if (ext_params & CPU_MF_INT_SF_IAE) {
cb->invalid_entry_address++;
rc = -EINVAL;
}

if (ext_params & EI_ISE) {
if (ext_params & CPU_MF_INT_SF_ISE) {
cb->incorrect_sdbt_entry++;
rc = -EINVAL;
}

if (ext_params & EI_SACA) {
if (ext_params & CPU_MF_INT_SF_SACA) {
cb->sample_auth_change_alert++;
rc = -EINVAL;
}
Expand Down Expand Up @@ -1009,7 +1001,7 @@ int hwsampler_deallocate(void)
if (hws_state != HWS_STOPPED)
goto deallocate_exit;

ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
measurement_alert_subclass_unregister();
deallocate_sdbt();

hws_state = HWS_DEALLOCATED;
Expand Down Expand Up @@ -1123,7 +1115,7 @@ int hwsampler_shutdown(void)
mutex_lock(&hws_sem);

if (hws_state == HWS_STOPPED) {
ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
measurement_alert_subclass_unregister();
deallocate_sdbt();
}
if (hws_wq) {
Expand Down Expand Up @@ -1198,7 +1190,7 @@ int hwsampler_start_all(unsigned long rate)
hws_oom = 1;
hws_flush_all = 0;
/* now let them in, 1407 CPUMF external interrupts */
ctl_set_bit(0, 5); /* set CR0 bit 58 */
measurement_alert_subclass_register();

return 0;
}
Expand Down

0 comments on commit c97511c

Please sign in to comment.