s390/diag: add tracepoint for diagnose calls

To be able to analyse problems in regard to hypervisor overhead
add a tracepoing for diagnose calls. It reports the number of
the diagnose issued, e.g.

            sshd-1385  [002] ....    42.701431: diagnose: nr=0x9c
          <idle>-0     [001] ..s.    43.587528: diagnose: nr=0x9c

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Martin Schwidefsky 2015-08-21 16:05:32 +02:00
parent 1ec2772e0c
commit b5a6b71b19
6 changed files with 98 additions and 14 deletions

View File

@ -33,16 +33,8 @@ enum diag_stat_enum {
NR_DIAG_STAT
};
struct diag_stat {
unsigned int counter[NR_DIAG_STAT];
};
DECLARE_PER_CPU(struct diag_stat, diag_stat);
static inline void diag_stat_inc(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
}
void diag_stat_inc(enum diag_stat_enum nr);
void diag_stat_inc_norecursion(enum diag_stat_enum nr);
/*
* Diagnose 10: Release page range

View File

@ -0,0 +1,43 @@
/*
* Tracepoint header for s390 diagnose calls
*
* Copyright IBM Corp. 2015
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM s390
#if !defined(_TRACE_S390_DIAG_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_S390_DIAG_H
#include <linux/tracepoint.h>
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH asm/trace
#define TRACE_INCLUDE_FILE diag
TRACE_EVENT(diagnose,
TP_PROTO(unsigned short nr),
TP_ARGS(nr),
TP_STRUCT__entry(
__field(unsigned short, nr)
),
TP_fast_assign(
__entry->nr = nr;
),
TP_printk("nr=0x%x", __entry->nr)
);
#ifdef CONFIG_TRACEPOINTS
void trace_diagnose_norecursion(int diag_nr);
#else
static inline void trace_diagnose_norecursion(int diag_nr) { }
#endif
#endif /* _TRACE_S390_DIAG_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -66,6 +66,8 @@ obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o
obj-$(CONFIG_TRACEPOINTS) += trace.o
# vdso
obj-y += vdso64/
obj-$(CONFIG_COMPAT) += vdso32/

View File

@ -10,9 +10,13 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <asm/diag.h>
#include <asm/trace/diag.h>
DEFINE_PER_CPU(struct diag_stat, diag_stat);
EXPORT_PER_CPU_SYMBOL(diag_stat);
struct diag_stat {
unsigned int counter[NR_DIAG_STAT];
};
static DEFINE_PER_CPU(struct diag_stat, diag_stat);
struct diag_desc {
int code;
@ -114,6 +118,20 @@ static int __init show_diag_stat_init(void)
device_initcall(show_diag_stat_init);
void diag_stat_inc(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
trace_diagnose(diag_map[nr].code);
}
EXPORT_SYMBOL(diag_stat_inc);
void diag_stat_inc_norecursion(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
trace_diagnose_norecursion(diag_map[nr].code);
}
EXPORT_SYMBOL(diag_stat_inc_norecursion);
/*
* Diagnose 14: Input spool file manipulation
*/

View File

@ -377,11 +377,11 @@ int smp_vcpu_scheduled(int cpu)
void smp_yield_cpu(int cpu)
{
if (MACHINE_HAS_DIAG9C) {
diag_stat_inc(DIAG_STAT_X09C);
diag_stat_inc_norecursion(DIAG_STAT_X09C);
asm volatile("diag %0,0,0x9c"
: : "d" (pcpu_devices[cpu].address));
} else if (MACHINE_HAS_DIAG44) {
diag_stat_inc(DIAG_STAT_X044);
diag_stat_inc_norecursion(DIAG_STAT_X044);
asm volatile("diag 0,0,0x44");
}
}

29
arch/s390/kernel/trace.c Normal file
View File

@ -0,0 +1,29 @@
/*
* Tracepoint definitions for s390
*
* Copyright IBM Corp. 2015
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/percpu.h>
#define CREATE_TRACE_POINTS
#include <asm/trace/diag.h>
EXPORT_TRACEPOINT_SYMBOL(diagnose);
static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
void trace_diagnose_norecursion(int diag_nr)
{
unsigned long flags;
unsigned int *depth;
local_irq_save(flags);
depth = this_cpu_ptr(&diagnose_trace_depth);
if (*depth == 0) {
(*depth)++;
trace_diagnose(diag_nr);
(*depth)--;
}
local_irq_restore(flags);
}