diff options
-rw-r--r-- | arch/s390/include/asm/diag.h | 12 | ||||
-rw-r--r-- | arch/s390/include/asm/trace/diag.h | 43 | ||||
-rw-r--r-- | arch/s390/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/kernel/diag.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/trace.c | 29 |
6 files changed, 98 insertions, 14 deletions
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h index e423cfcaf77d..5fac921c1c42 100644 --- a/arch/s390/include/asm/diag.h +++ b/arch/s390/include/asm/diag.h @@ -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 diff --git a/arch/s390/include/asm/trace/diag.h b/arch/s390/include/asm/trace/diag.h new file mode 100644 index 000000000000..776f307960cc --- /dev/null +++ b/arch/s390/include/asm/trace/diag.h @@ -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> diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index b756c6348ac6..dc167a23b920 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -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/ diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c index 4ddb5200ddf0..f98766ede4e1 100644 --- a/arch/s390/kernel/diag.c +++ b/arch/s390/kernel/diag.c @@ -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 */ diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index f7db48b61dcf..dbd40d448294 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -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"); } } diff --git a/arch/s390/kernel/trace.c b/arch/s390/kernel/trace.c new file mode 100644 index 000000000000..73239bb576c4 --- /dev/null +++ b/arch/s390/kernel/trace.c @@ -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); +} |