s390/diag: add a statistic for diagnose calls
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 20 Aug 2015 15:28:44 +0000 (17:28 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 14 Oct 2015 12:32:06 +0000 (14:32 +0200)
Introduce /sys/debug/kernel/diag_stat with a statistic how many diagnose
calls have been done by each CPU in the system.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
19 files changed:
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/hypfs_diag0c.c
arch/s390/hypfs/hypfs_sprp.c
arch/s390/hypfs/hypfs_vm.c
arch/s390/include/asm/appldata.h
arch/s390/include/asm/diag.h
arch/s390/include/asm/kvm_para.h
arch/s390/kernel/cpcmd.c
arch/s390/kernel/diag.c
arch/s390/kernel/early.c
arch/s390/kernel/ipl.c
arch/s390/kernel/processor.c
arch/s390/kernel/smp.c
arch/s390/mm/extmem.c
arch/s390/mm/fault.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/diag_ftp.c
drivers/s390/virtio/virtio_ccw.c
drivers/watchdog/diag288_wdt.c

index 5eeffeefae063584dcea347ef0da728dffe579b9..045035796ca7d59f196740078b4ae4c0f0243717 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include "hypfs.h"
 
@@ -336,7 +337,7 @@ static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)
 
 /* Diagnose 204 functions */
 
-static indiag204(unsigned long subcode, unsigned long size, void *addr)
+static inline int __diag204(unsigned long subcode, unsigned long size, void *addr)
 {
        register unsigned long _subcode asm("0") = subcode;
        register unsigned long _size asm("1") = size;
@@ -351,6 +352,12 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
        return _size;
 }
 
+static int diag204(unsigned long subcode, unsigned long size, void *addr)
+{
+       diag_stat_inc(DIAG_STAT_X204);
+       return __diag204(subcode, size, addr);
+}
+
 /*
  * For the old diag subcode 4 with simple data format we have to use real
  * memory. If we use subcode 6 or 7 with extended data format, we can (and
@@ -505,6 +512,7 @@ static int diag224(void *ptr)
 {
        int rc = -EOPNOTSUPP;
 
+       diag_stat_inc(DIAG_STAT_X224);
        asm volatile(
                "       diag    %1,%2,0x224\n"
                "0:     lhi     %0,0x0\n"
index 24c747a0fcc354a71f9aad4ed6b6e4c55d93d814..0f1927cbba31bf84cc0afa80878861d37822bb92 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/slab.h>
 #include <linux/cpu.h>
+#include <asm/diag.h>
 #include <asm/hypfs.h>
 #include "hypfs.h"
 
@@ -18,6 +19,7 @@
  */
 static void diag0c(struct hypfs_diag0c_entry *entry)
 {
+       diag_stat_inc(DIAG_STAT_X00C);
        asm volatile (
                "       sam31\n"
                "       diag    %0,%0,0x0c\n"
index dd42a26d049d8ab89f660362144a127019b0ab23..c9e5c72f78bd2c9be6621d19a5e0e8eb1ef6dc73 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <asm/compat.h>
+#include <asm/diag.h>
 #include <asm/sclp.h>
 #include "hypfs.h"
 
@@ -22,7 +23,7 @@
 
 #define DIAG304_CMD_MAX                2
 
-static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
+static inline unsigned long __hypfs_sprp_diag304(void *data, unsigned long cmd)
 {
        register unsigned long _data asm("2") = (unsigned long) data;
        register unsigned long _rc asm("3");
@@ -34,6 +35,12 @@ static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
        return _rc;
 }
 
+static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
+{
+       diag_stat_inc(DIAG_STAT_X304);
+       return __hypfs_sprp_diag304(data, cmd);
+}
+
 static void hypfs_sprp_free(const void *data)
 {
        free_page((unsigned long) data);
index afbe07907c10b6304e52b5eb234d33694fd9693a..44feac38ccfc26dacaf57fae0463922bdafb10dd 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include <asm/timex.h>
 #include "hypfs.h"
@@ -66,6 +67,7 @@ static int diag2fc(int size, char* query, void *addr)
        memset(parm_list.aci_grp, 0x40, NAME_LEN);
        rc = -1;
 
+       diag_stat_inc(DIAG_STAT_X2FC);
        asm volatile(
                "       diag    %0,%1,0x2fc\n"
                "0:\n"
index 16887c5fd989d218c063891ec7a62f3da73b69a0..a6263d4e8e569245ece9421efc0affb3889f276b 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef _ASM_S390_APPLDATA_H
 #define _ASM_S390_APPLDATA_H
 
+#include <asm/diag.h>
 #include <asm/io.h>
 
 #define APPLDATA_START_INTERVAL_REC    0x80
@@ -53,6 +54,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
        parm_list.buffer_length = length;
        parm_list.product_id_addr = (unsigned long) id;
        parm_list.buffer_addr = virt_to_phys(buffer);
+       diag_stat_inc(DIAG_STAT_X0DC);
        asm volatile(
                "       diag    %1,%0,0xdc"
                : "=d" (ry)
index 7e91c58072e259345610c3b8a17a93b48dc5d297..e423cfcaf77d694333d286feda0cdaaba09d2430 100644 (file)
@@ -8,6 +8,42 @@
 #ifndef _ASM_S390_DIAG_H
 #define _ASM_S390_DIAG_H
 
+#include <linux/percpu.h>
+
+enum diag_stat_enum {
+       DIAG_STAT_X008,
+       DIAG_STAT_X00C,
+       DIAG_STAT_X010,
+       DIAG_STAT_X014,
+       DIAG_STAT_X044,
+       DIAG_STAT_X064,
+       DIAG_STAT_X09C,
+       DIAG_STAT_X0DC,
+       DIAG_STAT_X204,
+       DIAG_STAT_X210,
+       DIAG_STAT_X224,
+       DIAG_STAT_X250,
+       DIAG_STAT_X258,
+       DIAG_STAT_X288,
+       DIAG_STAT_X2C4,
+       DIAG_STAT_X2FC,
+       DIAG_STAT_X304,
+       DIAG_STAT_X308,
+       DIAG_STAT_X500,
+       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]);
+}
+
 /*
  * Diagnose 10: Release page range
  */
@@ -18,6 +54,7 @@ static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
        start_addr = start_pfn << PAGE_SHIFT;
        end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;
 
+       diag_stat_inc(DIAG_STAT_X010);
        asm volatile(
                "0:     diag    %0,%1,0x10\n"
                "1:\n"
index e0f842308a68f5292cbc4d0b470a3f3eeaec0f62..41393052ac57e1966ca735295be5f20f58ac3c55 100644 (file)
 #define __S390_KVM_PARA_H
 
 #include <uapi/asm/kvm_para.h>
+#include <asm/diag.h>
 
-
-
-static inline long kvm_hypercall0(unsigned long nr)
+static inline long __kvm_hypercall0(unsigned long nr)
 {
        register unsigned long __nr asm("1") = nr;
        register long __rc asm("2");
@@ -40,7 +39,13 @@ static inline long kvm_hypercall0(unsigned long nr)
        return __rc;
 }
 
-static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
+static inline long kvm_hypercall0(unsigned long nr)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall0(nr);
+}
+
+static inline long __kvm_hypercall1(unsigned long nr, unsigned long p1)
 {
        register unsigned long __nr asm("1") = nr;
        register unsigned long __p1 asm("2") = p1;
@@ -51,7 +56,13 @@ static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
        return __rc;
 }
 
-static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall1(nr, p1);
+}
+
+static inline long __kvm_hypercall2(unsigned long nr, unsigned long p1,
                               unsigned long p2)
 {
        register unsigned long __nr asm("1") = nr;
@@ -65,7 +76,14 @@ static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
        return __rc;
 }
 
-static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
+                              unsigned long p2)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall2(nr, p1, p2);
+}
+
+static inline long __kvm_hypercall3(unsigned long nr, unsigned long p1,
                               unsigned long p2, unsigned long p3)
 {
        register unsigned long __nr asm("1") = nr;
@@ -80,8 +98,14 @@ static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
        return __rc;
 }
 
+static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
+                              unsigned long p2, unsigned long p3)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall3(nr, p1, p2, p3);
+}
 
-static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
+static inline long __kvm_hypercall4(unsigned long nr, unsigned long p1,
                               unsigned long p2, unsigned long p3,
                               unsigned long p4)
 {
@@ -98,7 +122,15 @@ static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
        return __rc;
 }
 
-static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
+                              unsigned long p2, unsigned long p3,
+                              unsigned long p4)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall4(nr, p1, p2, p3, p4);
+}
+
+static inline long __kvm_hypercall5(unsigned long nr, unsigned long p1,
                               unsigned long p2, unsigned long p3,
                               unsigned long p4, unsigned long p5)
 {
@@ -116,7 +148,15 @@ static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
        return __rc;
 }
 
-static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
+                              unsigned long p2, unsigned long p3,
+                              unsigned long p4, unsigned long p5)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall5(nr, p1, p2, p3, p4, p5);
+}
+
+static inline long __kvm_hypercall6(unsigned long nr, unsigned long p1,
                               unsigned long p2, unsigned long p3,
                               unsigned long p4, unsigned long p5,
                               unsigned long p6)
@@ -137,6 +177,15 @@ static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
        return __rc;
 }
 
+static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
+                              unsigned long p2, unsigned long p3,
+                              unsigned long p4, unsigned long p5,
+                              unsigned long p6)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __kvm_hypercall6(nr, p1, p2, p3, p4, p5, p6);
+}
+
 /* kvm on s390 is always paravirtualization enabled */
 static inline int kvm_para_available(void)
 {
index 199ec92ef4fe3527fa766042041b197dce182d31..7f768914fb4f94fb47fb9c99cac9e6077a3eca41 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include <asm/cpcmd.h>
 #include <asm/io.h>
@@ -70,6 +71,7 @@ int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
        memcpy(cpcmd_buf, cmd, cmdlen);
        ASCEBC(cpcmd_buf, cmdlen);
 
+       diag_stat_inc(DIAG_STAT_X008);
        if (response) {
                memset(response, 0, rlen);
                response_len = rlen;
index 2f69243bf700c7fed77021d13edc63f5f57aa9dd..4ddb5200ddf0a0f457cde957f49b791715e91ed6 100644 (file)
  */
 
 #include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
 #include <asm/diag.h>
 
+DEFINE_PER_CPU(struct diag_stat, diag_stat);
+EXPORT_PER_CPU_SYMBOL(diag_stat);
+
+struct diag_desc {
+       int code;
+       char *name;
+};
+
+static const struct diag_desc diag_map[NR_DIAG_STAT] = {
+       [DIAG_STAT_X008] = { .code = 0x008, .name = "Console Function" },
+       [DIAG_STAT_X00C] = { .code = 0x00c, .name = "Pseudo Timer" },
+       [DIAG_STAT_X010] = { .code = 0x010, .name = "Release Pages" },
+       [DIAG_STAT_X014] = { .code = 0x014, .name = "Spool File Services" },
+       [DIAG_STAT_X044] = { .code = 0x044, .name = "Voluntary Timeslice End" },
+       [DIAG_STAT_X064] = { .code = 0x064, .name = "NSS Manipulation" },
+       [DIAG_STAT_X09C] = { .code = 0x09c, .name = "Relinquish Timeslice" },
+       [DIAG_STAT_X0DC] = { .code = 0x0dc, .name = "Appldata Control" },
+       [DIAG_STAT_X204] = { .code = 0x204, .name = "Logical-CPU Utilization" },
+       [DIAG_STAT_X210] = { .code = 0x210, .name = "Device Information" },
+       [DIAG_STAT_X224] = { .code = 0x224, .name = "EBCDIC-Name Table" },
+       [DIAG_STAT_X250] = { .code = 0x250, .name = "Block I/O" },
+       [DIAG_STAT_X258] = { .code = 0x258, .name = "Page-Reference Services" },
+       [DIAG_STAT_X288] = { .code = 0x288, .name = "Time Bomb" },
+       [DIAG_STAT_X2C4] = { .code = 0x2c4, .name = "FTP Services" },
+       [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" },
+       [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" },
+       [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" },
+       [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" },
+};
+
+static int show_diag_stat(struct seq_file *m, void *v)
+{
+       struct diag_stat *stat;
+       unsigned long n = (unsigned long) v - 1;
+       int cpu, prec, tmp;
+
+       get_online_cpus();
+       if (n == 0) {
+               seq_puts(m, "         ");
+
+               for_each_online_cpu(cpu) {
+                       prec = 10;
+                       for (tmp = 10; cpu >= tmp; tmp *= 10)
+                               prec--;
+                       seq_printf(m, "%*s%d", prec, "CPU", cpu);
+               }
+               seq_putc(m, '\n');
+       } else if (n <= NR_DIAG_STAT) {
+               seq_printf(m, "diag %03x:", diag_map[n-1].code);
+               for_each_online_cpu(cpu) {
+                       stat = &per_cpu(diag_stat, cpu);
+                       seq_printf(m, " %10u", stat->counter[n-1]);
+               }
+               seq_printf(m, "    %s\n", diag_map[n-1].name);
+       }
+       put_online_cpus();
+       return 0;
+}
+
+static void *show_diag_stat_start(struct seq_file *m, loff_t *pos)
+{
+       return *pos <= nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL;
+}
+
+static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       ++*pos;
+       return show_diag_stat_start(m, pos);
+}
+
+static void show_diag_stat_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations show_diag_stat_sops = {
+       .start  = show_diag_stat_start,
+       .next   = show_diag_stat_next,
+       .stop   = show_diag_stat_stop,
+       .show   = show_diag_stat,
+};
+
+static int show_diag_stat_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &show_diag_stat_sops);
+}
+
+static const struct file_operations show_diag_stat_fops = {
+       .open           = show_diag_stat_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+
+static int __init show_diag_stat_init(void)
+{
+       debugfs_create_file("diag_stat", 0400, NULL, NULL,
+                           &show_diag_stat_fops);
+       return 0;
+}
+
+device_initcall(show_diag_stat_init);
+
 /*
  * Diagnose 14: Input spool file manipulation
  */
-int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
+static inline int __diag14(unsigned long rx, unsigned long ry1,
+                          unsigned long subcode)
 {
        register unsigned long _ry1 asm("2") = ry1;
        register unsigned long _ry2 asm("3") = subcode;
@@ -29,6 +136,12 @@ int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
 
        return rc;
 }
+
+int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
+{
+       diag_stat_inc(DIAG_STAT_X014);
+       return __diag14(rx, ry1, subcode);
+}
 EXPORT_SYMBOL(diag14);
 
 /*
@@ -48,6 +161,7 @@ int diag210(struct diag210 *addr)
        spin_lock_irqsave(&diag210_lock, flags);
        diag210_tmp = *addr;
 
+       diag_stat_inc(DIAG_STAT_X210);
        asm volatile(
                "       lhi     %0,-1\n"
                "       sam31\n"
index 549a73a4b5430ad5522fb7690180625e8c61f787..311a2d6d48e43d338efa48df4b45719688a105b5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pfn.h>
 #include <linux/uaccess.h>
 #include <linux/kernel.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include <asm/ipl.h>
 #include <asm/lowcore.h>
@@ -286,6 +287,7 @@ static __init void detect_diag9c(void)
        int rc;
 
        cpu_address = stap();
+       diag_stat_inc(DIAG_STAT_X09C);
        asm volatile(
                "       diag    %2,0,0x9c\n"
                "0:     la      %0,0\n"
@@ -300,6 +302,7 @@ static __init void detect_diag44(void)
 {
        int rc;
 
+       diag_stat_inc(DIAG_STAT_X044);
        asm volatile(
                "       diag    0,0,0x44\n"
                "0:     la      %0,0\n"
index 52fbef91d1d97e7f87eda96f45d926b041c140ef..f6d8acd7e13654c307a5d54e80bd6e084cf04a13 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/gfp.h>
 #include <linux/crash_dump.h>
 #include <linux/debug_locks.h>
+#include <asm/diag.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -165,7 +166,7 @@ static struct ipl_parameter_block *dump_block_ccw;
 
 static struct sclp_ipl_info sclp_ipl_info;
 
-int diag308(unsigned long subcode, void *addr)
+static inline int __diag308(unsigned long subcode, void *addr)
 {
        register unsigned long _addr asm("0") = (unsigned long) addr;
        register unsigned long _rc asm("1") = 0;
@@ -178,6 +179,12 @@ int diag308(unsigned long subcode, void *addr)
                : "d" (subcode) : "cc", "memory");
        return _rc;
 }
+
+int diag308(unsigned long subcode, void *addr)
+{
+       diag_stat_inc(DIAG_STAT_X308);
+       return __diag308(subcode, addr);
+}
 EXPORT_SYMBOL_GPL(diag308);
 
 /* SYSFS */
index e6e077ae3990ff93672347e8a801877aa8953f95..7ce00e7a709a946058b4bdeaadecba16f969d326 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/seq_file.h>
 #include <linux/delay.h>
 #include <linux/cpu.h>
+#include <asm/diag.h>
 #include <asm/elf.h>
 #include <asm/lowcore.h>
 #include <asm/param.h>
@@ -20,8 +21,10 @@ static DEFINE_PER_CPU(struct cpuid, cpu_id);
 
 void notrace cpu_relax(void)
 {
-       if (!smp_cpu_mtid && MACHINE_HAS_DIAG44)
+       if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) {
+               diag_stat_inc(DIAG_STAT_X044);
                asm volatile("diag 0,0,0x44");
+       }
        barrier();
 }
 EXPORT_SYMBOL(cpu_relax);
index c6355e6f3fcc990c98bdd4f80dfd1a8ac78a0e0b..f7db48b61dcfe11d786f2b518d193b9aa4d3ac45 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/crash_dump.h>
 #include <linux/memblock.h>
 #include <asm/asm-offsets.h>
+#include <asm/diag.h>
 #include <asm/switch_to.h>
 #include <asm/facility.h>
 #include <asm/ipl.h>
@@ -375,11 +376,14 @@ int smp_vcpu_scheduled(int cpu)
 
 void smp_yield_cpu(int cpu)
 {
-       if (MACHINE_HAS_DIAG9C)
+       if (MACHINE_HAS_DIAG9C) {
+               diag_stat_inc(DIAG_STAT_X09C);
                asm volatile("diag %0,0,0x9c"
                             : : "d" (pcpu_devices[cpu].address));
-       else if (MACHINE_HAS_DIAG44)
+       } else if (MACHINE_HAS_DIAG44) {
+               diag_stat_inc(DIAG_STAT_X044);
                asm volatile("diag 0,0,0x44");
+       }
 }
 
 /*
index 23c496957c2232a88ac14d690b00f2004fd8ada9..18fccc303db7e521bc14fa7dabfa6e9a69aa9e92 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/ctype.h>
 #include <linux/ioport.h>
+#include <asm/diag.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/ebcdic.h>
@@ -112,6 +113,7 @@ dcss_set_subcodes(void)
        ry = DCSS_FINDSEGX;
 
        strcpy(name, "dummy");
+       diag_stat_inc(DIAG_STAT_X064);
        asm volatile(
                "       diag    %0,%1,0x64\n"
                "0:     ipm     %2\n"
@@ -205,6 +207,7 @@ dcss_diag(int *func, void *parameter,
        ry = (unsigned long) *func;
 
        /* 64-bit Diag x'64' new subcode, keep in 64-bit addressing mode */
+       diag_stat_inc(DIAG_STAT_X064);
        if (*func > DCSS_SEGEXT)
                asm volatile(
                        "       diag    %0,%1,0x64\n"
index f985856a538b75e8c62cdfec3950357cff8fff0d..77b3938d6bfac04a874f0b57de30c02bdce491c5 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/hugetlb.h>
 #include <asm/asm-offsets.h>
+#include <asm/diag.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
@@ -597,6 +598,7 @@ int pfault_init(void)
 
        if (pfault_disable)
                return -1;
+       diag_stat_inc(DIAG_STAT_X258);
        asm volatile(
                "       diag    %1,%0,0x258\n"
                "0:     j       2f\n"
@@ -618,6 +620,7 @@ void pfault_fini(void)
 
        if (pfault_disable)
                return;
+       diag_stat_inc(DIAG_STAT_X258);
        asm volatile(
                "       diag    %0,0,0x258\n"
                "0:\n"
index c062f1620c58d419514af3ce7b81da8952e11546..cb61f300f8b5d111ce7871a39be43a1b7fe3ca80 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/dasd.h>
 #include <asm/debug.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -76,6 +77,7 @@ static inline int dia250(void *iob, int cmd)
        int rc;
 
        rc = 3;
+       diag_stat_inc(DIAG_STAT_X250);
        asm volatile(
                "       diag    2,%2,0x250\n"
                "0:     ipm     %0\n"
index 12db8db04cddf61832b243709e16c7fc0a1ae5ca..a5ccbf6f0d36941e167ad86d857b508c22322bfd 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/wait.h>
 #include <linux/string.h>
 #include <asm/ctl_reg.h>
+#include <asm/diag.h>
 
 #include "hmcdrv_ftp.h"
 #include "diag_ftp.h"
@@ -102,6 +103,7 @@ static int diag_ftp_2c4(struct diag_ftp_ldfpl *fpl,
 {
        int rc;
 
+       diag_stat_inc(DIAG_STAT_X2C4);
        asm volatile(
                "       diag    %[addr],%[cmd],0x2c4\n"
                "0:     j       2f\n"
index e9fae30fafda03d39df228e500d5f70c0a86e048..b2a1a81e6fc8f048c202b7eca54b2b0b6c22b368 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/kvm_para.h>
 #include <linux/notifier.h>
+#include <asm/diag.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/cio.h>
@@ -366,9 +367,9 @@ static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev,
        kfree(thinint_area);
 }
 
-static inline long do_kvm_notify(struct subchannel_id schid,
-                                unsigned long queue_index,
-                                long cookie)
+static inline long __do_kvm_notify(struct subchannel_id schid,
+                                  unsigned long queue_index,
+                                  long cookie)
 {
        register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY;
        register struct subchannel_id __schid asm("2") = schid;
@@ -383,6 +384,14 @@ static inline long do_kvm_notify(struct subchannel_id schid,
        return __rc;
 }
 
+static inline long do_kvm_notify(struct subchannel_id schid,
+                                unsigned long queue_index,
+                                long cookie)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __do_kvm_notify(schid, queue_index, cookie);
+}
+
 static bool virtio_ccw_kvm_notify(struct virtqueue *vq)
 {
        struct virtio_ccw_vq_info *info = vq->priv;
index a9a5210143ae8442038db98991b430e8bac7ea3c..3db9d0e0673de32546e227f97b1a7ed99679e8dd 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/watchdog.h>
 #include <linux/suspend.h>
 #include <asm/ebcdic.h>
+#include <asm/diag.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
 
@@ -94,12 +95,14 @@ static int __diag288(unsigned int func, unsigned int timeout,
 static int __diag288_vm(unsigned int  func, unsigned int timeout,
                        char *cmd, size_t len)
 {
+       diag_stat_inc(DIAG_STAT_X288);
        return __diag288(func, timeout, virt_to_phys(cmd), len);
 }
 
 static int __diag288_lpar(unsigned int func, unsigned int timeout,
                          unsigned long action)
 {
+       diag_stat_inc(DIAG_STAT_X288);
        return __diag288(func, timeout, action, 0);
 }
 
@@ -141,6 +144,7 @@ static int wdt_stop(struct watchdog_device *dev)
 {
        int ret;
 
+       diag_stat_inc(DIAG_STAT_X288);
        ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0);
        return ret;
 }